Preparing for multiple versions support

This commit is contained in:
Nanit 2021-10-28 22:24:01 +03:00
parent 62fbc0e8f2
commit e191c8f90b
6 changed files with 58 additions and 22 deletions

View File

@ -96,9 +96,9 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
if (packet instanceof PacketHandshake) {
PacketHandshake handshake = (PacketHandshake) packet;
clientVersion = handshake.getVersion();
updateState(State.getById(handshake.getNextState()));
updateStateAndVersion(handshake.getNextState(), clientVersion);
Logger.debug("Pinged from " + address);
Logger.debug("Pinged from %s [%s]", address, clientVersion.toString());
if (server.getConfig().getInfoForwarding().isLegacy()) {
String[] split = handshake.getHost().split("\00");
@ -245,6 +245,18 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
channel.pipeline().get(PacketEncoder.class).updateState(state);
}
public void updateStateAndVersion(State state, Version version){
this.state = state;
PacketDecoder decoder = channel.pipeline().get(PacketDecoder.class);
PacketEncoder encoder = channel.pipeline().get(PacketEncoder.class);
decoder.updateVersion(version);
decoder.updateState(state);
encoder.updateVersion(version);
encoder.updateState(state);
}
private void setAddress(String host) {
this.address = new InetSocketAddress(host, ((InetSocketAddress)this.address).getPort());
}

View File

@ -5,6 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import ru.nanit.limbo.protocol.*;
import ru.nanit.limbo.protocol.registry.State;
import ru.nanit.limbo.protocol.registry.Version;
import ru.nanit.limbo.util.Logger;
import java.util.List;
@ -12,8 +13,10 @@ import java.util.List;
public class PacketDecoder extends MessageToMessageDecoder<ByteBuf> {
private State.PacketRegistry mappings;
private Version version;
public PacketDecoder() {
updateVersion(Version.getMinimal());
updateState(State.HANDSHAKING);
}
@ -27,7 +30,7 @@ public class PacketDecoder extends MessageToMessageDecoder<ByteBuf> {
if (packet != null) {
try {
packet.decode(msg, );
packet.decode(msg, version);
} catch (Exception e) {
Logger.warning("Cannot decode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage());
}
@ -38,6 +41,10 @@ public class PacketDecoder extends MessageToMessageDecoder<ByteBuf> {
}
}
public void updateVersion(Version version) {
this.version = version;
}
public void updateState(State state) {
this.mappings = state.serverBound;
}

View File

@ -7,13 +7,16 @@ import ru.nanit.limbo.protocol.ByteMessage;
import ru.nanit.limbo.protocol.Packet;
import ru.nanit.limbo.protocol.PreEncodedPacket;
import ru.nanit.limbo.protocol.registry.State;
import ru.nanit.limbo.protocol.registry.Version;
import ru.nanit.limbo.util.Logger;
public class PacketEncoder extends MessageToByteEncoder<Packet> {
private State.PacketRegistry registry;
private Version version;
public PacketEncoder() {
updateVersion(Version.getMinimal());
updateState(State.HANDSHAKING);
}
@ -38,12 +41,16 @@ public class PacketEncoder extends MessageToByteEncoder<Packet> {
msg.writeVarInt(packetId);
try {
packet.encode(msg, );
packet.encode(msg, version);
} catch (Exception e) {
Logger.warning("Cannot encode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage());
}
}
public void updateVersion(Version version) {
this.version = version;
}
public void updateState(State state) {
this.registry = state.clientBound;
}

View File

@ -2,13 +2,17 @@ package ru.nanit.limbo.protocol;
import ru.nanit.limbo.protocol.registry.Version;
import java.util.HashMap;
import java.util.Map;
public class PreEncodedPacket implements PacketOut {
private final PacketOut packet;
private byte[] message;
private final Map<Version, byte[]> versionMessages;
public PreEncodedPacket(PacketOut packet) {
this.packet = packet;
this.versionMessages = new HashMap<>();
}
public PacketOut getWrappedPacket() {
@ -16,16 +20,24 @@ public class PreEncodedPacket implements PacketOut {
}
public PreEncodedPacket encodePacket() {
ByteMessage encodedMessage = ByteMessage.create();
packet.encode(encodedMessage, );
this.message = encodedMessage.toByteArray();
encodedMessage.release();
for (Version version : Version.values()) {
ByteMessage encodedMessage = ByteMessage.create();
packet.encode(encodedMessage, version);
byte[] message = encodedMessage.toByteArray();
versionMessages.put(version, message);
encodedMessage.release();
}
return this;
}
@Override
public void encode(ByteMessage msg, Version version) {
msg.writeBytes(message);
byte[] message = versionMessages.get(version);
if (message != null) {
msg.writeBytes(message);
}
}
public static PreEncodedPacket of(PacketOut packet) {

View File

@ -2,14 +2,16 @@ package ru.nanit.limbo.protocol.packets;
import ru.nanit.limbo.protocol.ByteMessage;
import ru.nanit.limbo.protocol.Packet;
import ru.nanit.limbo.protocol.PacketIn;
import ru.nanit.limbo.protocol.registry.State;
import ru.nanit.limbo.protocol.registry.Version;
public class PacketHandshake implements Packet {
public class PacketHandshake implements PacketIn {
private Version version;
private String host;
private int port;
private int nextState;
private State nextState;
public Version getVersion() {
return version;
@ -19,16 +21,12 @@ public class PacketHandshake implements Packet {
return host;
}
public int getNextState() {
return nextState;
public int getPort() {
return port;
}
@Override
public void encode(ByteMessage msg, Version version) {
msg.writeVarInt(this.version.getProtocolNumber());
msg.writeString(host);
msg.writeShort(port);
msg.writeVarInt(nextState);
public State getNextState() {
return nextState;
}
@Override
@ -36,6 +34,6 @@ public class PacketHandshake implements Packet {
this.version = Version.of(msg.readVarInt());
this.host = msg.readString();
this.port = msg.readUnsignedShort();
this.nextState = msg.readVarInt();
this.nextState = State.getById(msg.readVarInt());
}
}

View File

@ -20,7 +20,7 @@ public class PacketStatusResponse implements PacketOut {
public void encode(ByteMessage msg, Version version) {
String ver = server.getConfig().getPingData().getVersion();
String desc = server.getConfig().getPingData().getDescription();
String json = getResponseJson(ver, Version.getMinimal().getProtocolNumber(),
String json = getResponseJson(ver, version.getProtocolNumber(),
server.getConfig().getMaxPlayers(), server.getConnections().getCount(), desc);
msg.writeString(json);