All wrappers can now modify data. Created setters for all current wrappers.

This commit is contained in:
retrooper committed 2021-09-03 14:18:10 +02:00
1 parent dc6b457e2d
commit 587fb09f4d
40 files changed
+952 -165

No files matched your search

@@ -52,10 +52,21 @@ public class PacketEventsPlugin extends JavaPlugin {
else if (event.getPacketType() == PacketType.Game.Client.CHAT_MESSAGE) {
WrapperGameClientChatMessage chatMessage = new WrapperGameClientChatMessage(event);
String msg = chatMessage.getMessage();
event.getPlayer().sendMessage("modifying " + msg);
chatMessage.setMessage("edited: " + msg);
}
}
});
PacketEvents.get().getEventManager().registerListener(new PacketListenerAbstract(PacketListenerPriority.HIGH) {
public void onPacketReceive(PacketReceiveEvent event) {
if (event.getPacketType() == PacketType.Game.Client.CHAT_MESSAGE) {
WrapperGameClientChatMessage chatMessage = new WrapperGameClientChatMessage(event);
String msg = chatMessage.getMessage();
event.getPlayer().sendMessage("second listener can see: " + msg);
}
}
});
PacketEvents.get().init();
}
@@ -5,10 +5,11 @@ import io.github.retrooper.packetevents.event.ProtocolPacketEvent;
import io.github.retrooper.packetevents.protocol.PacketSide;
import io.github.retrooper.packetevents.utils.netty.buffer.ByteBufAbstract;
import io.github.retrooper.packetevents.utils.netty.channel.ChannelAbstract;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.bukkit.entity.Player;
public class PacketReceiveEvent extends ProtocolPacketEvent {
private PacketWrapper packetWrapper;
public PacketReceiveEvent(ChannelAbstract channel, Player player, ByteBufAbstract byteBuf) {
super(PacketSide.CLIENT, channel, player, byteBuf);
}
@@ -21,4 +22,12 @@ public class PacketReceiveEvent extends ProtocolPacketEvent {
public void call(PacketListenerAbstract listener) {
listener.onPacketReceive(this);
}
public PacketWrapper getPacketWrapper() {
return packetWrapper;
}
public void setPacketWrapper(PacketWrapper packetWrapper) {
this.packetWrapper = packetWrapper;
}
}
@@ -23,10 +23,12 @@ import io.github.retrooper.packetevents.event.ProtocolPacketEvent;
import io.github.retrooper.packetevents.protocol.PacketSide;
import io.github.retrooper.packetevents.utils.netty.buffer.ByteBufAbstract;
import io.github.retrooper.packetevents.utils.netty.channel.ChannelAbstract;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.bukkit.entity.Player;
public class PacketSendEvent extends ProtocolPacketEvent {
private Runnable postTask = null;
private PacketWrapper packetWrapper;
public PacketSendEvent(ChannelAbstract channel, Player player, ByteBufAbstract byteBuf, Runnable postTask) {
super(PacketSide.SERVER, channel, player, byteBuf);
@@ -56,6 +58,14 @@ public class PacketSendEvent extends ProtocolPacketEvent {
this.postTask = postTask;
}
public PacketWrapper getPacketWrapper() {
return packetWrapper;
}
public void setPacketWrapper(PacketWrapper packetWrapper) {
this.packetWrapper = packetWrapper;
}
@Override
public void call(PacketListenerAbstract listener) {
listener.onPacketSend(this);
@@ -35,6 +35,11 @@ public class PacketDecoderLegacy extends ByteToMessageDecoder {
transformedBuf.readerIndex(readerIndex);
});
if (!packetReceiveEvent.isCancelled()) {
if (packetReceiveEvent.getPacketWrapper() != null) {
packetReceiveEvent.getByteBuf().clear();
packetReceiveEvent.getPacketWrapper().writeVarInt(packetReceiveEvent.getPacketID());
packetReceiveEvent.getPacketWrapper().writeData();
}
transformedBuf.readerIndex(firstReaderIndex);
if (needsCompress) {
CompressionManager.recompress(ctx, transformedBuf);
@@ -50,6 +50,11 @@ public class PacketEncoderLegacy extends MessageToMessageEncoder<ByteBuf> {
transformedBuf.readerIndex(readerIndex);
});
if (!packetSendEvent.isCancelled()) {
if (packetSendEvent.getPacketWrapper() != null) {
packetSendEvent.getByteBuf().clear();
packetSendEvent.getPacketWrapper().writeVarInt(packetSendEvent.getPacketID());
packetSendEvent.getPacketWrapper().writeData();
}
transformedBuf.readerIndex(firstReaderIndex);
if (needsCompress) {
@@ -55,6 +55,11 @@ public class PacketDecoderModern extends MessageToMessageDecoder<ByteBuf> {
transformedBuf.readerIndex(readerIndex);
});
if (!packetReceiveEvent.isCancelled()) {
if (packetReceiveEvent.getPacketWrapper() != null) {
packetReceiveEvent.getByteBuf().clear();
packetReceiveEvent.getPacketWrapper().writeVarInt(packetReceiveEvent.getPacketID());
packetReceiveEvent.getPacketWrapper().writeData();
}
transformedBuf.readerIndex(firstReaderIndex);
if (needsCompress) {
CompressionManager.recompress(ctx, transformedBuf);
@@ -50,8 +50,12 @@ public class PacketEncoderModern extends MessageToMessageEncoder<ByteBuf> {
transformedBuf.readerIndex(readerIndex);
});
if (!packetSendEvent.isCancelled()) {
if (packetSendEvent.getPacketWrapper() != null) {
packetSendEvent.getByteBuf().clear();
packetSendEvent.getPacketWrapper().writeVarInt(packetSendEvent.getPacketID());
packetSendEvent.getPacketWrapper().writeData();
}
transformedBuf.readerIndex(firstReaderIndex);
if (needsCompress) {
recompress(ctx, transformedBuf);
}
@@ -120,7 +120,7 @@ public enum ClientVersion {
* @return ClientVersion
*/
@NotNull
public static ClientVersion getClientVersion(int protocolVersion) {
public static ClientVersion getClientVersionByProtocolVersion(int protocolVersion) {
if (protocolVersion == -1) {
return ClientVersion.UNRESOLVED;
} else if (protocolVersion < LOWEST_SUPPORTED_PROTOCOL_VERSION) {
@@ -75,7 +75,7 @@ public class PlayerManager {
//Prioritize asking ViaVersion and ProtocolSupport as they modify the protocol version in the packet we access it from.
if (VersionLookupUtils.isDependencyAvailable()) {
try {
version = ClientVersion.getClientVersion(VersionLookupUtils.getProtocolVersion(player));
version = ClientVersion.getClientVersionByProtocolVersion(VersionLookupUtils.getProtocolVersion(player));
clientVersions.put(channel, version);
return version;
} catch (Exception ex) {
@@ -96,7 +96,7 @@ public class PlayerManager {
//(WE DONT SUPPORT CUSTOM PROTOCOL VERSION HACKS other than viaversion & protocolsupport)
protocolVersion = PacketEvents.get().getServerManager().getVersion().getProtocolVersion();
}
version = ClientVersion.getClientVersion(protocolVersion);
version = ClientVersion.getClientVersionByProtocolVersion(protocolVersion);
clientVersions.put(channel, version);
}
}
@@ -23,5 +23,7 @@ package io.github.retrooper.packetevents.protocol;
* @since 1.8
*/
public enum ConnectionState {
HANDSHAKING, STATUS, LOGIN, GAME
HANDSHAKING, STATUS, LOGIN, GAME;
public static final ConnectionState[] VALUES = values();
}
@@ -0,0 +1,30 @@
/*
* 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 StringUtil {
public static String maximizeLength(String msg, int maxLength) {
if (msg.length() > maxLength) {
return msg.substring(0, maxLength);
}
else {
return msg;
}
}
}
@@ -138,7 +138,7 @@ public final class MinecraftReflection {
public static void init() {
VERSION = PacketEvents.get().getServerManager().getVersion();
V_1_17_OR_HIGHER = VERSION.isNewerThanOrEquals(ServerVersion.v_1_17);
V_1_17_OR_HIGHER = VERSION.isNewerThanOrEquals(ServerVersion.v_1_12);
V_1_12_OR_HIGHER = VERSION.isNewerThanOrEquals(ServerVersion.v_1_12);
USE_MODERN_NETTY_PACKAGE = VERSION.isNewerThan(ServerVersion.v_1_7_10);
try {
//Check if the selected netty location is valid
@@ -30,27 +30,57 @@ import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class PacketWrapper {
public class PacketWrapper<T extends PacketWrapper> {
protected final ClientVersion clientVersion;
private final ServerVersion serverVersion;
public final ByteBufAbstract byteBuf;
private final int packetID;
public PacketWrapper(ClientVersion clientVersion, ServerVersion serverVersion, ByteBufAbstract byteBuf) {
public PacketWrapper(ClientVersion clientVersion, ServerVersion serverVersion, ByteBufAbstract byteBuf, int packetID) {
this.clientVersion = clientVersion;
this.serverVersion = serverVersion;
this.byteBuf = byteBuf;
this.packetID = packetID;
}
public PacketWrapper(PacketReceiveEvent event) {
this.clientVersion = event.getClientVersion();
this.serverVersion = event.getServerVersion();
this.byteBuf = event.getByteBuf();
this.packetID = event.getPacketID();
if (event.getPacketWrapper() == null) {
event.setPacketWrapper(this);
readData();
}
else {
readData((T) event.getPacketWrapper());
}
}
public PacketWrapper(PacketSendEvent event) {
this.clientVersion = ClientVersion.UNKNOWN;
this.clientVersion = event.getClientVersion();
this.serverVersion = event.getServerVersion();
this.byteBuf = event.getByteBuf();
this.packetID = event.getPacketID();
if (event.getPacketWrapper() == null) {
event.setPacketWrapper(this);
readData();
}
else {
readData((T) event.getPacketWrapper());
}
}
public void readData() {
}
public void readData(T wrapper) {
}
public void writeData() {
}
public ClientVersion getClientVersion() {
@@ -65,6 +95,15 @@ public class PacketWrapper {
return byteBuf;
}
public int getPacketID() {
return packetID;
}
public void resetByteBuf() {
byteBuf.clear();
writeVarInt(packetID);
}
public byte readByte() {
return byteBuf.readByte();
}
@@ -204,6 +243,6 @@ public class PacketWrapper {
}
public static PacketWrapper createUniversalPacketWrapper(ByteBufAbstract byteBuf) {
return new PacketWrapper(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), byteBuf);
return new PacketWrapper(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), byteBuf, -1);
}
}
@@ -24,35 +24,30 @@ import io.github.retrooper.packetevents.manager.player.ClientVersion;
import io.github.retrooper.packetevents.utils.netty.buffer.ByteBufAbstract;
import io.github.retrooper.packetevents.utils.netty.buffer.ByteBufUtil;
public abstract class SendablePacketWrapper extends PacketWrapper {
protected final int packetID;
public abstract class SendablePacketWrapper<T extends PacketWrapper> extends PacketWrapper<T> {
protected final int protocolVersion;
public SendablePacketWrapper(int packetID) {
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), ByteBufUtil.buffer());
this.packetID = packetID;
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), ByteBufUtil.buffer(), packetID);
this.protocolVersion = getServerVersion().getProtocolVersion();
writeVarInt(packetID);
}
public SendablePacketWrapper(int protocolVersion, int packetID) {
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), ByteBufUtil.buffer());
this.packetID = packetID;
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), ByteBufUtil.buffer(), packetID);
this.protocolVersion = protocolVersion;
writeVarInt(packetID);
}
public SendablePacketWrapper(ByteBufAbstract byteBuf, int protocolVersion, int packetID) {
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), byteBuf);
this.packetID = packetID;
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), byteBuf, packetID);
this.protocolVersion = protocolVersion;
writeVarInt(packetID);
}
public SendablePacketWrapper(ByteBufAbstract byteBuf, int packetID) {
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), byteBuf);
this.packetID = packetID;
super(ClientVersion.UNKNOWN, PacketEvents.get().getServerManager().getVersion(), byteBuf, packetID);
this.protocolVersion = getServerVersion().getProtocolVersion();
writeVarInt(packetID);
}
@@ -60,7 +55,6 @@ public abstract class SendablePacketWrapper extends PacketWrapper {
//Super constructor, this is when they DON'T want to use the wrapper for sending
public SendablePacketWrapper(PacketSendEvent event) {
super(event);
this.packetID = -1;
this.protocolVersion = -1;
}
@@ -26,11 +26,15 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
/**
* This packet is sent when the client swings their arm.
*/
public class WrapperGameClientAnimation extends PacketWrapper {
private final Hand hand;
public class WrapperGameClientAnimation extends PacketWrapper<WrapperGameClientAnimation> {
private Hand hand;
public WrapperGameClientAnimation(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_9)) {
this.hand = Hand.VALUES[readVarInt()];
} else {
@@ -39,6 +43,18 @@ public class WrapperGameClientAnimation extends PacketWrapper {
}
}
@Override
public void readData(WrapperGameClientAnimation wrapper) {
this.hand = wrapper.hand;
}
@Override
public void writeData() {
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_9)) {
writeVarInt(hand.ordinal());
}
}
/**
* Hand used for the animation.
* On {@link ClientVersion#v_1_9}, an off-hand was introduced and specifies which arm has been swung.
@@ -49,4 +65,8 @@ public class WrapperGameClientAnimation extends PacketWrapper {
public Hand getHand() {
return hand;
}
public void setHand(Hand hand) {
this.hand = hand;
}
}
@@ -20,23 +20,37 @@ package io.github.retrooper.packetevents.wrapper.game.client;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.manager.player.ClientVersion;
import io.github.retrooper.packetevents.utils.StringUtil;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
/**
* This packet is used to send a chat message to the server.
*/
public class WrapperGameClientChatMessage extends PacketWrapper {
private final int packetID;
private final int maxMessageLength;
public class WrapperGameClientChatMessage extends PacketWrapper<WrapperGameClientChatMessage> {
private String message;
public WrapperGameClientChatMessage(PacketReceiveEvent event) {
super(event);
this.packetID = event.getPacketID();
this.maxMessageLength = clientVersion.isNewerThanOrEquals(ClientVersion.v_1_11) ? 256 : 100;
}
@Override
public void readData() {
int maxMessageLength = clientVersion.isNewerThanOrEquals(ClientVersion.v_1_11) ? 256 : 100;
this.message = readString(maxMessageLength);
}
@Override
public void readData(WrapperGameClientChatMessage wrapper) {
this.message = wrapper.message;
}
@Override
public void writeData() {
int maxMessageLength = clientVersion.isNewerThanOrEquals(ClientVersion.v_1_11) ? 256 : 100;
this.message = StringUtil.maximizeLength(this.message, maxMessageLength);
writeString(this.message, maxMessageLength);
}
/**
* The message.
* On {@link ClientVersion#v_1_10} and older clients, the message should never exceed 100 characters.
@@ -49,10 +63,6 @@ public class WrapperGameClientChatMessage extends PacketWrapper {
}
public void setMessage(String message) {
//TODO For now we basically reset the packet, but we don't want that
this.message = message;
byteBuf.clear();
writeVarInt(packetID);
writeString(message, maxMessageLength);
this.message = message;
}
}
@@ -24,16 +24,32 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
/**
* This packet is used when clicking on window buttons. Until 1.14, this was only used by enchantment tables.
*/
public class WrapperGameClientClickWindowButton extends PacketWrapper {
private final byte windowID;
private final byte buttonID;
public class WrapperGameClientClickWindowButton extends PacketWrapper<WrapperGameClientClickWindowButton> {
private byte windowID;
private byte buttonID;
public WrapperGameClientClickWindowButton(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.windowID = readByte();
this.buttonID = readByte();
}
@Override
public void readData(WrapperGameClientClickWindowButton wrapper) {
this.windowID = wrapper.windowID;
this.buttonID = wrapper.buttonID;
}
@Override
public void writeData() {
writeByte(this.windowID);
writeByte(this.buttonID);
}
/**
* The ID of the window.
*
@@ -43,6 +59,10 @@ public class WrapperGameClientClickWindowButton extends PacketWrapper {
return windowID;
}
public void setWindowID(byte windowID) {
this.windowID = windowID;
}
/**
* Meaning depends on the window type.
* Learn more about its meaning on wiki.vg/Protocol.
@@ -52,4 +72,8 @@ public class WrapperGameClientClickWindowButton extends PacketWrapper {
public byte getButtonID() {
return buttonID;
}
public void setButtonID(byte buttonID) {
this.buttonID = buttonID;
}
}
@@ -26,18 +26,37 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
/**
* This packet is sent when Generate is pressed on the Jigsaw Block interface.
*/
public class WrapperGameClientGenerateStructure extends PacketWrapper {
private final Vector3i blockPosition;
private final int levels;
private final boolean keepJigsaws;
public class WrapperGameClientGenerateStructure extends PacketWrapper<WrapperGameClientGenerateStructure> {
private Vector3i blockPosition;
private int levels;
private boolean keepJigsaws;
public WrapperGameClientGenerateStructure(PacketReceiveEvent event) {
super(event);
this.blockPosition = PacketWrapperUtils.readVectorFromLong(readLong());
}
@Override
public void readData() {
long vectorLong = readLong();
this.blockPosition = PacketWrapperUtils.readVectorFromLong(vectorLong);
this.levels = readVarInt();
this.keepJigsaws = readBoolean();
}
@Override
public void readData(WrapperGameClientGenerateStructure wrapper) {
this.blockPosition = wrapper.blockPosition;
this.levels = wrapper.levels;
this.keepJigsaws = wrapper.keepJigsaws;
}
@Override
public void writeData() {
writeLong(PacketWrapperUtils.generateLongFromVector(this.blockPosition));
writeVarInt(this.levels);
writeBoolean(this.keepJigsaws);
}
/**
* The block location of the entity.
*
@@ -47,6 +66,10 @@ public class WrapperGameClientGenerateStructure extends PacketWrapper {
return blockPosition;
}
public void setBlockPosition(Vector3i blockPosition) {
this.blockPosition = blockPosition;
}
/**
* Value of the levels' slider/max depth to generate.
*
@@ -56,6 +79,10 @@ public class WrapperGameClientGenerateStructure extends PacketWrapper {
return levels;
}
public void setLevels(int levels) {
this.levels = levels;
}
/**
* Should we keep the Jigsaws?
*
@@ -64,4 +91,8 @@ public class WrapperGameClientGenerateStructure extends PacketWrapper {
public boolean isKeepingJigsaws() {
return keepJigsaws;
}
public void setKeepJigsaws(boolean keepJigsaws) {
this.keepJigsaws = keepJigsaws;
}
}
@@ -22,27 +22,32 @@ import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.manager.player.ClientVersion;
import io.github.retrooper.packetevents.manager.player.Hand;
import io.github.retrooper.packetevents.utils.vector.Vector3f;
import io.github.retrooper.packetevents.utils.vector.Vector3i;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Optional;
public class WrapperGameClientInteractEntity extends PacketWrapper {
public class WrapperGameClientInteractEntity extends PacketWrapper<WrapperGameClientInteractEntity> {
public enum Type {
INTERACT, ATTACK, INTERACT_AT;
public static final Type[] VALUES = values();
}
private final int entityID;
private final Type type;
private final Optional<Vector3f> target;
private final Optional<Hand> hand;
private final Optional<Boolean> sneaking;
private int entityID;
private Type type;
private Optional<Vector3f> target;
private Optional<Hand> hand;
private Optional<Boolean> sneaking;
public WrapperGameClientInteractEntity(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
if (clientVersion.isOlderThan(ClientVersion.v_1_8)) {
this.entityID = readInt();
int typeIndex = readByte() % Type.VALUES.length;
byte typeIndex = readByte();
this.type = Type.VALUES[typeIndex];
this.target = Optional.empty();
this.hand = Optional.empty();
@@ -51,7 +56,6 @@ public class WrapperGameClientInteractEntity extends PacketWrapper {
this.entityID = readVarInt();
int typeIndex = readVarInt();
this.type = Type.VALUES[typeIndex];
if (type == Type.INTERACT_AT) {
float x = readFloat();
float y = readFloat();
@@ -76,23 +80,78 @@ public class WrapperGameClientInteractEntity extends PacketWrapper {
}
}
@Override
public void readData(WrapperGameClientInteractEntity wrapper) {
this.entityID = wrapper.entityID;
this.type = wrapper.type;
this.target = wrapper.target;
this.hand = wrapper.hand;
this.sneaking = wrapper.sneaking;
}
@Override
public void writeData() {
if (clientVersion.isOlderThan(ClientVersion.v_1_8)) {
writeInt(entityID);
writeByte((byte) type.ordinal());
} else {
writeVarInt(entityID);
writeVarInt(type.ordinal());
if (type == Type.INTERACT_AT) {
Vector3f targetVec = target.orElse(new Vector3f(0.0F, 0.0F, 0.0F));
writeFloat(targetVec.x);
writeFloat(targetVec.y);
writeFloat(targetVec.z);
}
if (clientVersion.isNewerThan(ClientVersion.v_1_8) && (type == Type.INTERACT || type == Type.INTERACT_AT)) {
Hand handValue = hand.orElse(Hand.MAIN_HAND);
writeVarInt(handValue.ordinal());
}
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_16)) {
writeBoolean(sneaking.orElse(false));
}
}
}
public int getEntityID() {
return entityID;
}
public void setEntityID(int entityID) {
this.entityID = entityID;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public Optional<Vector3f> getTarget() {
return target;
}
public void setTarget(Optional<Vector3f> target) {
this.target = target;
}
public Optional<Hand> getHand() {
return hand;
}
public void setHand(Optional<Hand> hand) {
this.hand = hand;
}
public Optional<Boolean> isSneaking() {
return sneaking;
}
public void setSneaking(Optional<Boolean> sneaking) {
this.sneaking = sneaking;
}
}
@@ -27,11 +27,15 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
* The server will frequently send out a (client-bound) keep-alive, each containing a random ID.
* The client is expected to respond with a (server-bound) keep-alive, containing the same ID that the server sent out.
*/
public class WrapperGameClientKeepAlive extends PacketWrapper {
private final long id;
public class WrapperGameClientKeepAlive extends PacketWrapper<WrapperGameClientKeepAlive> {
private long id;
public WrapperGameClientKeepAlive(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_12)) {
this.id = readLong();
} else if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_8)) {
@@ -41,6 +45,22 @@ public class WrapperGameClientKeepAlive extends PacketWrapper {
}
}
@Override
public void readData(WrapperGameClientKeepAlive wrapper) {
this.id = wrapper.id;
}
@Override
public void writeData() {
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_12)) {
writeLong(id);
} else if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_8)) {
writeVarInt((int) id);
} else {
writeInt((int) id);
}
}
/**
* Keep-Alive ID.
*
@@ -49,4 +69,8 @@ public class WrapperGameClientKeepAlive extends PacketWrapper {
public long getID() {
return id;
}
public void setID(long id) {
this.id = id;
}
}
@@ -9,19 +9,34 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
* Minecraft itself uses some plugin channels.
* These internal channels are in the minecraft namespace.
*/
public class WrapperGameClientPluginMessage extends PacketWrapper {
private final String channelName;
private final byte[] data;
public class WrapperGameClientPluginMessage extends PacketWrapper<WrapperGameClientPluginMessage> {
private String channelName;
private byte[] data;
public WrapperGameClientPluginMessage(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.channelName = readString();
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_8)) {
this.data = readByteArray(byteBuf.readableBytes());
} else {
int dataLength = readShort();
this.data = readByteArray(dataLength);
int dataLength = clientVersion.isNewerThanOrEquals(ClientVersion.v_1_8) ? byteBuf.readableBytes() : readShort();
this.data = readByteArray(dataLength);
}
@Override
public void readData(WrapperGameClientPluginMessage wrapper) {
this.channelName = wrapper.channelName;
this.data = wrapper.data;
}
@Override
public void writeData() {
writeString(channelName);
if (clientVersion.isOlderThan(ClientVersion.v_1_8)) {
writeShort(this.data.length);
}
writeByteArray(this.data);
}
/**
@@ -33,6 +48,10 @@ public class WrapperGameClientPluginMessage extends PacketWrapper {
return channelName;
}
public void setChannelName(String channelName) {
this.channelName = channelName;
}
/**
* Any data, depending on the channel.
*
@@ -41,4 +60,8 @@ public class WrapperGameClientPluginMessage extends PacketWrapper {
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
@@ -28,14 +28,28 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
*
* @see io.github.retrooper.packetevents.wrapper.game.server.WrapperGameServerPing
*/
public class WrapperGameClientPong extends PacketWrapper {
private final int id;
public class WrapperGameClientPong extends PacketWrapper<WrapperGameClientPong> {
private int id;
public WrapperGameClientPong(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.id = readInt();
}
@Override
public void readData(WrapperGameClientPong wrapper) {
this.id = wrapper.id;
}
@Override
public void writeData() {
writeInt(id);
}
/**
* ID of the last sent Ping packet.
*
@@ -44,4 +58,8 @@ public class WrapperGameClientPong extends PacketWrapper {
public int getID() {
return id;
}
public void setID(int id) {
this.id = id;
}
}
@@ -21,21 +21,45 @@ package io.github.retrooper.packetevents.wrapper.game.client;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperGameClientSetBeaconEffect extends PacketWrapper {
private final int primaryEffect;
private final int secondaryEffect;
public class WrapperGameClientSetBeaconEffect extends PacketWrapper<WrapperGameClientSetBeaconEffect> {
private int primaryEffect;
private int secondaryEffect;
public WrapperGameClientSetBeaconEffect(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.primaryEffect = readVarInt();
this.secondaryEffect = readVarInt();
}
@Override
public void readData(WrapperGameClientSetBeaconEffect wrapper) {
this.primaryEffect = wrapper.primaryEffect;
this.secondaryEffect = wrapper.secondaryEffect;
}
@Override
public void writeData() {
writeVarInt(primaryEffect);
writeVarInt(secondaryEffect);
}
public int getPrimaryEffect() {
return primaryEffect;
}
public void setPrimaryEffect(int primaryEffect) {
this.primaryEffect = primaryEffect;
}
public int getSecondaryEffect() {
return secondaryEffect;
}
public void setSecondaryEffect(int secondaryEffect) {
this.secondaryEffect = secondaryEffect;
}
}
@@ -26,14 +26,28 @@ import java.util.UUID;
/**
* Teleports the player to the given entity if the player is in spectator mode.
*/
public class WrapperGameClientSpectate extends PacketWrapper {
private final UUID uuid;
public class WrapperGameClientSpectate extends PacketWrapper<WrapperGameClientSpectate> {
private UUID uuid;
public WrapperGameClientSpectate(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.uuid = readUUID();
}
@Override
public void readData(WrapperGameClientSpectate wrapper) {
this.uuid = wrapper.uuid;
}
@Override
public void writeData() {
writeUUID(uuid);
}
/**
* UUID of the entity we want to teleport to.
*
@@ -42,4 +56,8 @@ public class WrapperGameClientSpectate extends PacketWrapper {
public UUID getUUID() {
return uuid;
}
public void setUUID(UUID uuid) {
this.uuid = uuid;
}
}
@@ -27,12 +27,16 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
/**
* This message is sent from the client to the server when the “Done” button is pushed after placing a sign.
*/
public class WrapperGameClientUpdateSign extends PacketWrapper {
private final Vector3i blockPosition;
public class WrapperGameClientUpdateSign extends PacketWrapper<WrapperGameClientUpdateSign> {
private Vector3i blockPosition;
private final String[] textLines = new String[4];
public WrapperGameClientUpdateSign(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_8)) {
long position = readLong();
this.blockPosition = PacketWrapperUtils.readVectorFromLong(position);
@@ -47,6 +51,27 @@ public class WrapperGameClientUpdateSign extends PacketWrapper {
}
}
@Override
public void readData(WrapperGameClientUpdateSign wrapper) {
this.blockPosition = wrapper.blockPosition;
System.arraycopy(wrapper.textLines, 0, this.textLines, 0, 4);
}
@Override
public void writeData() {
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_8)) {
long positionVector = PacketWrapperUtils.generateLongFromVector(blockPosition);
writeLong(positionVector);
} else {
writeInt(blockPosition.x);
writeShort(blockPosition.y);
writeInt(blockPosition.z);
}
for (int i = 0; i < 4; i++) {
writeString(textLines[i], 384);
}
}
/**
* Block location of the sign.
*
@@ -56,6 +81,10 @@ public class WrapperGameClientUpdateSign extends PacketWrapper {
return blockPosition;
}
public void setBlockPosition(Vector3i blockPosition) {
this.blockPosition = blockPosition;
}
/**
* The text lines in the sign.
*
@@ -64,4 +93,8 @@ public class WrapperGameClientUpdateSign extends PacketWrapper {
public String[] getTextLines() {
return textLines;
}
public void setTextLines(String[] textLines) {
System.arraycopy(textLines, 0, this.textLines, 0, 4);
}
}
@@ -22,11 +22,13 @@ import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.manager.player.ClientVersion;
import io.github.retrooper.packetevents.manager.server.ServerVersion;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.utils.StringUtil;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
import java.util.UUID;
public class WrapperGameServerChatMessage extends SendablePacketWrapper {
public class WrapperGameServerChatMessage extends SendablePacketWrapper<WrapperGameServerChatMessage> {
private static final int MODERN_MESSAGE_LENGTH = 262144;
private static final int LEGACY_MESSAGE_LENGTH = 32767;
@@ -37,33 +39,11 @@ public class WrapperGameServerChatMessage extends SendablePacketWrapper {
}
private String jsonMessage;
private final ChatPosition position;
private final UUID senderUUID;
private ChatPosition position;
private UUID senderUUID;
public WrapperGameServerChatMessage(PacketSendEvent event) {
super(event);
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_13)) {
this.jsonMessage = readString(MODERN_MESSAGE_LENGTH);
}
else {
this.jsonMessage = readString();
}
//Is the server 1.8+ or is the client 1.8+? 1.7.10 servers support 1.8 clients, and send the chat position.
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_8) || event.getClientVersion().isNewerThanOrEquals(ClientVersion.v_1_8)) {
byte positionIndex = readByte();
position = ChatPosition.VALUES[positionIndex];
}
else {
//Always chat in 1.7.10 protocol.
position = ChatPosition.CHAT;
}
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_16)) {
this.senderUUID = readUUID();
}
else {
this.senderUUID = new UUID(0L, 0L);
}
}
public WrapperGameServerChatMessage(String jsonMessage, ChatPosition position) {
@@ -80,24 +60,87 @@ public class WrapperGameServerChatMessage extends SendablePacketWrapper {
this.senderUUID = senderUUID;
}
@Override
public void readData() {
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_13)) {
this.jsonMessage = readString(MODERN_MESSAGE_LENGTH);
}
else {
this.jsonMessage = readString(LEGACY_MESSAGE_LENGTH);
}
//Is the server 1.8+ or is the client 1.8+? 1.7.10 servers support 1.8 clients, and send the chat position.
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_8) || getClientVersion().isNewerThanOrEquals(ClientVersion.v_1_8)) {
byte positionIndex = readByte();
position = ChatPosition.VALUES[positionIndex];
}
else {
//Always chat in 1.7.10 protocol.
position = ChatPosition.CHAT;
}
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_16)) {
this.senderUUID = readUUID();
}
else {
this.senderUUID = new UUID(0L, 0L);
}
}
@Override
public void readData(WrapperGameServerChatMessage wrapper) {
this.jsonMessage = wrapper.jsonMessage;
this.position = wrapper.position;
this.senderUUID = wrapper.senderUUID;
}
@Override
public void writeData() {
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_13)) {
writeString(jsonMessage, MODERN_MESSAGE_LENGTH);
}
else {
writeString(jsonMessage, LEGACY_MESSAGE_LENGTH);
}
//Is the server 1.8+ or is the client 1.8+? (1.7.10 servers support 1.8 clients, and send the chat position for 1.8 clients)
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_8) || getClientVersion().isNewerThanOrEquals(ClientVersion.v_1_8)) {
writeByte((byte) position.ordinal());
}
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_16)) {
writeUUID(senderUUID);
}
}
public String getJSONMessage() {
return jsonMessage;
}
public void setJSONMessage(String jsonMessage) {
this.jsonMessage = jsonMessage;
}
public ChatPosition getPosition() {
return position;
}
public void setPosition(ChatPosition position) {
this.position = position;
}
public UUID getSenderUUID() {
return senderUUID;
}
public void setSenderUUID(UUID senderUUID) {
this.senderUUID = senderUUID;
}
@Override
public void createPacket() {
int maxLen = protocolVersion >= 393 ? MODERN_MESSAGE_LENGTH : LEGACY_MESSAGE_LENGTH;
if (jsonMessage.length() > maxLen) {
jsonMessage = jsonMessage.substring(0, maxLen);
}
this.jsonMessage = StringUtil.maximizeLength(jsonMessage, maxLen);
writeString(jsonMessage, maxLen);
writeByte((byte) position.ordinal());
if (protocolVersion >= 735) {
@@ -22,12 +22,11 @@ import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
public class WrapperGameServerHeldItemChange extends SendablePacketWrapper {
private final byte slot;
public class WrapperGameServerHeldItemChange extends SendablePacketWrapper<WrapperGameServerHeldItemChange> {
private byte slot;
public WrapperGameServerHeldItemChange(PacketSendEvent event) {
super(event);
this.slot = readByte();
}
public WrapperGameServerHeldItemChange(byte slot) {
@@ -35,10 +34,28 @@ public class WrapperGameServerHeldItemChange extends SendablePacketWrapper {
this.slot = slot;
}
@Override
public void readData() {
this.slot = readByte();
}
@Override
public void readData(WrapperGameServerHeldItemChange wrapper) {
this.slot = wrapper.slot;
}
@Override
public void writeData() {
writeByte(slot);
}
public byte getSlot() {
return slot;
}
public void setSlot(byte slot) {
this.slot = slot;
}
@Override
public void createPacket() {
@@ -20,6 +20,7 @@ package io.github.retrooper.packetevents.wrapper.game.server;
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
/**
@@ -29,12 +30,11 @@ import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
*
* @see io.github.retrooper.packetevents.wrapper.game.client.WrapperGameClientPong
*/
public class WrapperGameServerPing extends SendablePacketWrapper {
private final int id;
public class WrapperGameServerPing extends SendablePacketWrapper<WrapperGameServerPing> {
private int id;
public WrapperGameServerPing(PacketSendEvent event) {
super(event);
this.id = readInt();
}
public WrapperGameServerPing(int id) {
@@ -42,10 +42,29 @@ public class WrapperGameServerPing extends SendablePacketWrapper {
this.id = id;
}
@Override
public void readData() {
this.id = readInt();
}
@Override
public void readData(WrapperGameServerPing wrapper) {
this.id = wrapper.id;
}
@Override
public void writeData() {
writeInt(id);
}
public int getID() {
return id;
}
public void setID(int id) {
this.id = id;
}
@Override
public void createPacket() {
writeInt(id);
@@ -28,19 +28,12 @@ import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
* Minecraft itself uses some plugin channels.
* These internal channels are in the minecraft namespace.
*/
public class WrapperGameServerPluginMessage extends SendablePacketWrapper {
private final String channelName;
private final byte[] data;
public class WrapperGameServerPluginMessage extends SendablePacketWrapper<WrapperGameServerPluginMessage> {
private String channelName;
private byte[] data;
public WrapperGameServerPluginMessage(PacketSendEvent event) {
super(event);
this.channelName = readString();
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_8)) {
this.data = readByteArray(byteBuf.readableBytes());
} else {
int dataLength = readUnsignedShort();
this.data = readByteArray(dataLength);
}
}
public WrapperGameServerPluginMessage(String channelName, byte[] data) {
@@ -49,6 +42,28 @@ public class WrapperGameServerPluginMessage extends SendablePacketWrapper {
this.data = data;
}
@Override
public void readData() {
this.channelName = readString();
int dataLength = getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_8) ? byteBuf.readableBytes() : readUnsignedShort();
this.data = readByteArray(dataLength);
}
@Override
public void readData(WrapperGameServerPluginMessage wrapper) {
this.channelName = wrapper.channelName;
this.data = wrapper.data;
}
@Override
public void writeData() {
writeString(channelName);
if (getServerVersion().isOlderThan(ServerVersion.v_1_8)) {
writeShort(data.length);
}
writeByteArray(data);
}
/**
* Name of the plugin channel used to send the data.
*
@@ -58,6 +73,10 @@ public class WrapperGameServerPluginMessage extends SendablePacketWrapper {
return channelName;
}
public void setChannelName(String channelName) {
this.channelName = channelName;
}
/**
* Any data, depending on the channel.
*
@@ -67,6 +86,10 @@ public class WrapperGameServerPluginMessage extends SendablePacketWrapper {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
@Override
public void createPacket() {
writeString(channelName);
@@ -27,21 +27,42 @@ import io.github.retrooper.packetevents.wrapper.PacketWrapper;
* This packet is the first packet the client should send.
* It contains important data such as the client's protocol version.
*/
public class WrapperHandshakingClientHandshake extends PacketWrapper {
private final int protocolVersion;
private final ClientVersion clientVersion;
private final String serverAddress;
private final int serverPort;
private final ConnectionState nextConnectionState;
public class WrapperHandshakingClientHandshake extends PacketWrapper<WrapperHandshakingClientHandshake> {
private int protocolVersion;
private ClientVersion clientVersion;
private String serverAddress;
private int serverPort;
private ConnectionState nextConnectionState;
public WrapperHandshakingClientHandshake(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.protocolVersion = readVarInt();
this.clientVersion = ClientVersion.getClientVersion(protocolVersion);
this.clientVersion = ClientVersion.getClientVersionByProtocolVersion(protocolVersion);
this.serverAddress = readString();
this.serverPort = readUnsignedShort();
int nextStateIndex = readVarInt();
this.nextConnectionState = ConnectionState.values()[nextStateIndex];
this.nextConnectionState = ConnectionState.VALUES[nextStateIndex];
}
@Override
public void readData(WrapperHandshakingClientHandshake wrapper) {
this.protocolVersion = wrapper.protocolVersion;
this.clientVersion = wrapper.clientVersion;
this.serverAddress = wrapper.serverAddress;
this.serverPort = wrapper.serverPort;
this.nextConnectionState = wrapper.nextConnectionState;
}
@Override
public void writeData() {
writeVarInt(protocolVersion);
writeString(serverAddress);
writeShort(serverPort);
writeVarInt(nextConnectionState.ordinal());
}
/**
@@ -54,6 +75,11 @@ public class WrapperHandshakingClientHandshake extends PacketWrapper {
return protocolVersion;
}
public void setProtocolVersion(int protocolVersion) {
this.protocolVersion = protocolVersion;
setClientVersion(ClientVersion.getClientVersionByProtocolVersion(protocolVersion));
}
/**
* {@link ClientVersion} of the client.
* This enum maps the protocol versions with the name of the release.
@@ -64,6 +90,11 @@ public class WrapperHandshakingClientHandshake extends PacketWrapper {
return clientVersion;
}
public void setClientVersion(ClientVersion clientVersion) {
this.clientVersion = clientVersion;
setProtocolVersion(clientVersion.getProtocolVersion());
}
/**
* Address of the server.
*
@@ -73,6 +104,10 @@ public class WrapperHandshakingClientHandshake extends PacketWrapper {
return serverAddress;
}
public void setServerAddress(String serverAddress) {
this.serverAddress = serverAddress;
}
/**
* Port of the server.
*
@@ -82,6 +117,10 @@ public class WrapperHandshakingClientHandshake extends PacketWrapper {
return serverPort;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
/**
* The next connection state.
* Should always be {@link ConnectionState#STATUS} or {@link ConnectionState#LOGIN} on the vanilla client.
@@ -91,4 +130,8 @@ public class WrapperHandshakingClientHandshake extends PacketWrapper {
public ConnectionState getNextConnectionState() {
return nextConnectionState;
}
public void setNextConnectionState(ConnectionState nextConnectionState) {
this.nextConnectionState = nextConnectionState;
}
}
@@ -4,12 +4,16 @@ import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.manager.player.ClientVersion;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperLoginClientEncryptionResponse extends PacketWrapper {
private final byte[] sharedSecret;
private final byte[] verifyToken;
public class WrapperLoginClientEncryptionResponse extends PacketWrapper<WrapperLoginClientEncryptionResponse> {
private byte[] sharedSecret;
private byte[] verifyToken;
public WrapperLoginClientEncryptionResponse(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
if (clientVersion.isNewerThanOrEquals(ClientVersion.v_1_10)) {
this.sharedSecret = readByteArray(byteBuf.readableBytes());
this.verifyToken = readByteArray(byteBuf.readableBytes());
@@ -21,11 +25,35 @@ public class WrapperLoginClientEncryptionResponse extends PacketWrapper {
}
}
@Override
public void readData(WrapperLoginClientEncryptionResponse wrapper) {
this.sharedSecret = wrapper.sharedSecret;
this.verifyToken = wrapper.verifyToken;
}
@Override
public void writeData() {
if (clientVersion.isOlderThan(ClientVersion.v_1_10)) {
writeVarInt(sharedSecret.length);
writeVarInt(verifyToken.length);
}
writeByteArray(sharedSecret);
writeByteArray(verifyToken);
}
public byte[] getSharedSecret() {
return this.sharedSecret;
}
public void setSharedSecret(byte[] sharedSecret) {
this.sharedSecret = sharedSecret;
}
public byte[] getVerifyToken() {
return this.verifyToken;
}
public void setVerifyToken(byte[] verifyToken) {
this.verifyToken = verifyToken;
}
}
@@ -21,15 +21,33 @@ package io.github.retrooper.packetevents.wrapper.login.client;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperLoginClientLoginStart extends PacketWrapper {
private final String username;
public class WrapperLoginClientLoginStart extends PacketWrapper<WrapperLoginClientLoginStart> {
private String username;
public WrapperLoginClientLoginStart(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.username = readString(16);
}
@Override
public void readData(WrapperLoginClientLoginStart wrapper) {
this.username = wrapper.username;
}
@Override
public void writeData() {
writeString(username, 16);
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
@@ -3,13 +3,17 @@ package io.github.retrooper.packetevents.wrapper.login.client;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperLoginClientPluginResponse extends PacketWrapper {
private final int messageID;
private final boolean successful;
private final byte[] data;
public class WrapperLoginClientPluginResponse extends PacketWrapper<WrapperLoginClientPluginResponse> {
private int messageID;
private boolean successful;
private byte[] data;
public WrapperLoginClientPluginResponse(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.messageID = readVarInt();
this.successful = readBoolean();
if (this.successful) {
@@ -19,15 +23,43 @@ public class WrapperLoginClientPluginResponse extends PacketWrapper {
}
}
@Override
public void readData(WrapperLoginClientPluginResponse wrapper) {
this.messageID = wrapper.messageID;
this.successful = wrapper.successful;
this.data = wrapper.data;
}
@Override
public void writeData() {
writeVarInt(messageID);
writeBoolean(successful);
if (successful) {
writeByteArray(data);
}
}
public int getMessageID() {
return this.messageID;
}
public void setMessageID(int messageID) {
this.messageID = messageID;
}
public boolean isSuccessful() {
return this.successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
public byte[] getData() {
return this.data;
}
public void setData(byte[] data) {
this.data = data;
}
}
@@ -22,20 +22,19 @@ import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.manager.server.ServerVersion;
import io.github.retrooper.packetevents.protocol.ConnectionState;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.utils.StringUtil;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
/**
* This packet is used by the server to disconnect the client while in the {@link ConnectionState#LOGIN} connection state.
*/
public class WrapperLoginServerDisconnect extends SendablePacketWrapper {
public class WrapperLoginServerDisconnect extends SendablePacketWrapper<WrapperLoginServerDisconnect> {
private static final int MODERN_REASON_LENGTH = 262144;
private static final int LEGACY_REASON_LENGTH = 32767;
private String reason;
public WrapperLoginServerDisconnect(PacketSendEvent event) {
super(event);
int reasonLength = getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_14) ? MODERN_REASON_LENGTH : LEGACY_REASON_LENGTH;
this.reason = readString(reasonLength);
}
public WrapperLoginServerDisconnect(String reason) {
@@ -43,6 +42,22 @@ public class WrapperLoginServerDisconnect extends SendablePacketWrapper {
this.reason = reason;
}
@Override
public void readData() {
int reasonLength = getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_14) ? MODERN_REASON_LENGTH : LEGACY_REASON_LENGTH;
this.reason = readString(reasonLength);
}
@Override
public void readData(WrapperLoginServerDisconnect wrapper) {
this.reason = wrapper.reason;
}
@Override
public void writeData() {
int reasonLength = getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_14) ? MODERN_REASON_LENGTH : LEGACY_REASON_LENGTH;
writeString(reason, reasonLength);
}
/**
* The reason the server disconnected the client. (Specified by the server)
@@ -53,12 +68,14 @@ public class WrapperLoginServerDisconnect extends SendablePacketWrapper {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
@Override
public void createPacket() {
int maxLen = protocolVersion >= 477 ? MODERN_REASON_LENGTH : LEGACY_REASON_LENGTH;
if (reason.length() > maxLen) {
reason = reason.substring(0, maxLen);
}
reason = StringUtil.maximizeLength(reason, maxLen);
writeString(reason, maxLen);
}
}
@@ -20,6 +20,7 @@ package io.github.retrooper.packetevents.wrapper.login.server;
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
import io.github.retrooper.packetevents.wrapper.login.client.WrapperLoginClientEncryptionResponse;
@@ -35,19 +36,13 @@ import java.security.spec.X509EncodedKeySpec;
*
* @see WrapperLoginClientEncryptionResponse
*/
public class WrapperLoginServerEncryptionRequest extends SendablePacketWrapper {
private final String serverID;
private final PublicKey publicKey;
private final byte[] verifyToken;
public class WrapperLoginServerEncryptionRequest extends SendablePacketWrapper<WrapperLoginServerEncryptionRequest> {
private String serverID;
private PublicKey publicKey;
private byte[] verifyToken;
public WrapperLoginServerEncryptionRequest(PacketSendEvent event) {
super(event);
this.serverID = readString(20);
int publicKeyLength = readVarInt();
byte[] publicKeyBytes = readByteArray(publicKeyLength);
this.publicKey = encrypt(publicKeyBytes);
int verifyTokenLength = readVarInt();
this.verifyToken = readByteArray(verifyTokenLength);
}
public WrapperLoginServerEncryptionRequest(String serverID, byte[] publicKeyBytes, byte[] verifyToken) {
@@ -64,6 +59,33 @@ public class WrapperLoginServerEncryptionRequest extends SendablePacketWrapper {
this.verifyToken = verifyToken;
}
@Override
public void readData() {
this.serverID = readString(20);
int publicKeyLength = readVarInt();
byte[] publicKeyBytes = readByteArray(publicKeyLength);
this.publicKey = encrypt(publicKeyBytes);
int verifyTokenLength = readVarInt();
this.verifyToken = readByteArray(verifyTokenLength);
}
@Override
public void readData(WrapperLoginServerEncryptionRequest wrapper) {
this.serverID = wrapper.serverID;
this.publicKey = wrapper.publicKey;
this.verifyToken = wrapper.verifyToken;
}
@Override
public void writeData() {
writeString(serverID, 20);
byte[] encoded = publicKey.getEncoded();
writeVarInt(encoded.length);
writeByteArray(encoded);
writeVarInt(verifyToken.length);
writeByteArray(verifyToken);
}
/**
* This is an empty string on the vanilla client. (1.7.10 and above)
*
@@ -73,6 +95,10 @@ public class WrapperLoginServerEncryptionRequest extends SendablePacketWrapper {
return serverID;
}
public void setServerID(String serverID) {
this.serverID = serverID;
}
/**
* The public key is in DER encoding format.
* More technically, it is in ASN.1 format.
@@ -85,6 +111,10 @@ public class WrapperLoginServerEncryptionRequest extends SendablePacketWrapper {
return publicKey;
}
public void setPublicKey(PublicKey publicKey) {
this.publicKey = publicKey;
}
/**
* The verify token will be encrypted by the client and
* sent to the server via the {@link WrapperLoginClientEncryptionResponse} packet.
@@ -95,6 +125,10 @@ public class WrapperLoginServerEncryptionRequest extends SendablePacketWrapper {
return verifyToken;
}
public void setVerifyToken(byte[] verifyToken) {
this.verifyToken = verifyToken;
}
private PublicKey encrypt(byte[] bytes) {
try {
EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(bytes);
@@ -29,12 +29,16 @@ import java.util.UUID;
/**
* This packet switches the connection state to {@link ConnectionState#GAME}.
*/
public class WrapperLoginServerLoginSuccess extends SendablePacketWrapper {
private final UUID uuid;
private final String username;
public class WrapperLoginServerLoginSuccess extends SendablePacketWrapper<WrapperLoginServerLoginSuccess> {
private UUID uuid;
private String username;
public WrapperLoginServerLoginSuccess(PacketSendEvent event) {
super(event);
}
@Override
public void readData() {
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_16)) {
int[] data = new int[4];
for (int i = 0; i < 4; i++) {
@@ -47,6 +51,25 @@ public class WrapperLoginServerLoginSuccess extends SendablePacketWrapper {
this.username = readString(16);
}
@Override
public void readData(WrapperLoginServerLoginSuccess wrapper) {
this.uuid = wrapper.uuid;
this.username = wrapper.username;
}
@Override
public void writeData() {
if (getServerVersion().isNewerThanOrEquals(ServerVersion.v_1_16)) {
int[] data = serializeUUID(uuid);
for (int i = 0; i < 4; i++) {
writeInt(data[i]);
}
} else {
writeString(uuid.toString(), 36);
}
writeString(username, 16);
}
public WrapperLoginServerLoginSuccess(UUID uuid, String username) {
super(PacketType.Login.Server.LOGIN_SUCCESS.getID());
this.uuid = uuid;
@@ -67,10 +90,18 @@ public class WrapperLoginServerLoginSuccess extends SendablePacketWrapper {
return uuid;
}
public void setUUID(UUID uuid) {
this.uuid = uuid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public void createPacket() {
if (protocolVersion >= 735) {
@@ -22,16 +22,13 @@ import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
public class WrapperLoginServerPluginRequest extends SendablePacketWrapper {
private final int messageID;
private final String channelName;
private final byte[] data;
public class WrapperLoginServerPluginRequest extends SendablePacketWrapper<WrapperLoginServerPluginRequest> {
private int messageID;
private String channelName;
private byte[] data;
public WrapperLoginServerPluginRequest(PacketSendEvent event) {
super(event);
this.messageID = readVarInt();
this.channelName = readString();
this.data = readByteArray(byteBuf.readableBytes());
}
public WrapperLoginServerPluginRequest(int messageID, String channelName, byte[] data) {
@@ -41,18 +38,51 @@ public class WrapperLoginServerPluginRequest extends SendablePacketWrapper {
this.data = data;
}
@Override
public void readData() {
this.messageID = readVarInt();
this.channelName = readString();
this.data = readByteArray(byteBuf.readableBytes());
}
@Override
public void readData(WrapperLoginServerPluginRequest wrapper) {
this.messageID = wrapper.messageID;
this.channelName = wrapper.channelName;
this.data = wrapper.data;
}
@Override
public void writeData() {
writeVarInt(messageID);
writeString(channelName);
writeByteArray(data);
}
public int getMessageID() {
return messageID;
}
public void setMessageID(int messageID) {
this.messageID = messageID;
}
public String getChannelName() {
return channelName;
}
public void setChannelName(String channelName) {
this.channelName = channelName;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
@Override
public void createPacket() {
writeVarInt(messageID);
@@ -22,12 +22,11 @@ import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
public class WrapperLoginServerSetCompression extends SendablePacketWrapper {
private final int threshold;
public class WrapperLoginServerSetCompression extends SendablePacketWrapper<WrapperLoginServerSetCompression> {
private int threshold;
public WrapperLoginServerSetCompression(PacketSendEvent event) {
super(event);
this.threshold = readVarInt();
}
public WrapperLoginServerSetCompression(int threshold) {
@@ -35,10 +34,29 @@ public class WrapperLoginServerSetCompression extends SendablePacketWrapper {
this.threshold = threshold;
}
@Override
public void readData() {
this.threshold = readVarInt();
}
@Override
public void readData(WrapperLoginServerSetCompression wrapper) {
this.threshold = wrapper.threshold;
}
@Override
public void writeData() {
writeVarInt(threshold);
}
public int getThreshold() {
return threshold;
}
public void setThreshold(int threshold) {
this.threshold = threshold;
}
@Override
public void createPacket() {
writeVarInt(threshold);
@@ -3,15 +3,33 @@ package io.github.retrooper.packetevents.wrapper.status.client;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperStatusClientPing extends PacketWrapper {
private final long time;
public class WrapperStatusClientPing extends PacketWrapper<WrapperStatusClientPing> {
private long time;
public WrapperStatusClientPing(PacketReceiveEvent event) {
super(event);
}
@Override
public void readData() {
this.time = readLong();
}
@Override
public void readData(WrapperStatusClientPing wrapper) {
this.time = wrapper.time;
}
@Override
public void writeData() {
writeLong(time);
}
public long getTime() {
return this.time;
return time;
}
public void setTime(long time) {
this.time = time;
}
}
@@ -22,12 +22,11 @@ import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.protocol.PacketType;
import io.github.retrooper.packetevents.wrapper.SendablePacketWrapper;
public class WrapperStatusServerPong extends SendablePacketWrapper {
private final long time;
public class WrapperStatusServerPong extends SendablePacketWrapper<WrapperStatusServerPong> {
private long time;
public WrapperStatusServerPong(PacketSendEvent event) {
super(event);
this.time = readLong();
}
public WrapperStatusServerPong(long time) {
@@ -35,10 +34,29 @@ public class WrapperStatusServerPong extends SendablePacketWrapper {
this.time = time;
}
@Override
public void readData() {
this.time = readLong();
}
@Override
public void readData(WrapperStatusServerPong wrapper) {
this.time = wrapper.time;
}
@Override
public void writeData() {
writeLong(time);
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
@Override
public void createPacket() {
writeLong(time);