3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-12-25 15:50:19 +01:00

Initial 1.12/1.12.1 support. Bug fixes!

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-07-29 17:09:27 -04:00
Ursprung 155b742352
Commit b79e7df039
9 geänderte Dateien mit 133 neuen und 68 gelöschten Zeilen

Datei anzeigen

@ -4,7 +4,7 @@ import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packets.Disconnect; import com.velocitypowered.proxy.protocol.packets.Disconnect;
import com.velocitypowered.proxy.protocol.packets.JoinGame; import com.velocitypowered.proxy.protocol.packets.JoinGame;
import com.velocitypowered.proxy.protocol.packets.Ping; import com.velocitypowered.proxy.protocol.packets.KeepAlive;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.packets.Respawn; import com.velocitypowered.proxy.protocol.packets.Respawn;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@ -18,7 +18,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
@Override @Override
public void handle(MinecraftPacket packet) { public void handle(MinecraftPacket packet) {
if (packet instanceof Ping) { if (packet instanceof KeepAlive) {
// Forward onto the server // Forward onto the server
connection.getChannel().write(packet); connection.getChannel().write(packet);
} else if (packet instanceof Disconnect) { } else if (packet instanceof Disconnect) {

Datei anzeigen

@ -6,11 +6,13 @@ import com.velocitypowered.proxy.data.ServerInfo;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packets.Chat; import com.velocitypowered.proxy.protocol.packets.Chat;
import com.velocitypowered.proxy.protocol.packets.JoinGame; import com.velocitypowered.proxy.protocol.packets.JoinGame;
import com.velocitypowered.proxy.protocol.packets.Ping; import com.velocitypowered.proxy.protocol.packets.KeepAlive;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.packets.Respawn; import com.velocitypowered.proxy.protocol.packets.Respawn;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.EventLoop; import io.netty.channel.EventLoop;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
@ -18,6 +20,8 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class ClientPlaySessionHandler implements MinecraftSessionHandler { public class ClientPlaySessionHandler implements MinecraftSessionHandler {
private static final Logger logger = LogManager.getLogger(ClientPlaySessionHandler.class);
private final ConnectedPlayer player; private final ConnectedPlayer player;
private ScheduledFuture<?> pingTask; private ScheduledFuture<?> pingTask;
private long lastPing = -1; private long lastPing = -1;
@ -35,19 +39,19 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
} }
private void ping() { private void ping() {
long randomId = ThreadLocalRandom.current().nextLong(); long randomId = ThreadLocalRandom.current().nextInt();
lastPing = randomId; lastPing = randomId;
Ping ping = new Ping(); KeepAlive keepAlive = new KeepAlive();
ping.setRandomId(randomId); keepAlive.setRandomId(randomId);
player.getConnection().write(ping); player.getConnection().write(keepAlive);
} }
@Override @Override
public void handle(MinecraftPacket packet) { public void handle(MinecraftPacket packet) {
if (packet instanceof Ping) { if (packet instanceof KeepAlive) {
Ping ping = (Ping) packet; KeepAlive keepAlive = (KeepAlive) packet;
if (ping.getRandomId() != lastPing) { if (keepAlive.getRandomId() != lastPing) {
throw new IllegalStateException("Client sent invalid ping; expected " + lastPing + ", got " + ping.getRandomId()); throw new IllegalStateException("Client sent invalid keepAlive; expected " + lastPing + ", got " + keepAlive.getRandomId());
} }
// Do not forward the packet to the player's server, because we handle pings for all servers already. // Do not forward the packet to the player's server, because we handle pings for all servers already.

Datei anzeigen

@ -1,20 +1,16 @@
package com.velocitypowered.proxy.connection.client; package com.velocitypowered.proxy.connection.client;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.config.VelocityConfiguration; import com.velocitypowered.proxy.config.VelocityConfiguration;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packets.Ping; import com.velocitypowered.proxy.protocol.packets.KeepAlive;
import com.velocitypowered.proxy.protocol.packets.StatusPing;
import com.velocitypowered.proxy.protocol.packets.StatusRequest; import com.velocitypowered.proxy.protocol.packets.StatusRequest;
import com.velocitypowered.proxy.protocol.packets.StatusResponse; import com.velocitypowered.proxy.protocol.packets.StatusResponse;
import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.data.ServerPing; import com.velocitypowered.proxy.data.ServerPing;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.serializer.GsonComponentSerializer;
public class StatusSessionHandler implements MinecraftSessionHandler { public class StatusSessionHandler implements MinecraftSessionHandler {
private final MinecraftConnection connection; private final MinecraftConnection connection;
@ -25,10 +21,10 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
@Override @Override
public void handle(MinecraftPacket packet) { public void handle(MinecraftPacket packet) {
Preconditions.checkArgument(packet instanceof Ping || packet instanceof StatusRequest, Preconditions.checkArgument(packet instanceof StatusPing|| packet instanceof StatusRequest,
"Unrecognized packet type " + packet.getClass().getName()); "Unrecognized packet type " + packet.getClass().getName());
if (packet instanceof Ping) { if (packet instanceof StatusPing) {
// Just send back the client's packet, no processing to do here. // Just send back the client's packet, no processing to do here.
connection.closeWith(packet); connection.closeWith(packet);
return; return;

Datei anzeigen

@ -3,10 +3,14 @@ package com.velocitypowered.proxy.protocol;
import java.util.Arrays; import java.util.Arrays;
public enum ProtocolConstants { ; public enum ProtocolConstants { ;
public static final int MINECRAFT_1_12 = 340; public static final int MINECRAFT_1_12 = 335;
public static final int MINECRAFT_1_12_1 = 338;
public static final int MINECRAFT_1_12_2 = 340;
private static final int[] SUPPORTED_VERSIONS = new int[] { public static final int[] SUPPORTED_VERSIONS = new int[] {
MINECRAFT_1_12 MINECRAFT_1_12,
MINECRAFT_1_12_1,
MINECRAFT_1_12_2
}; };
public static boolean isSupported(int version) { public static boolean isSupported(int version) {

Datei anzeigen

@ -4,67 +4,70 @@ import com.velocitypowered.proxy.protocol.packets.*;
import io.netty.util.collection.IntObjectHashMap; import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap; import io.netty.util.collection.IntObjectMap;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier; import java.util.function.Supplier;
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_12; import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_12;
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_12_1;
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_12_2;
public enum StateRegistry { public enum StateRegistry {
HANDSHAKE { HANDSHAKE {
{ {
SERVERBOUND.register(Handshake.class, Handshake::new, SERVERBOUND.register(Handshake.class, Handshake::new,
generic(0x00)); lowestVersion(0x00));
} }
}, },
STATUS { STATUS {
{ {
SERVERBOUND.register(StatusRequest.class, StatusRequest::new, SERVERBOUND.register(StatusRequest.class, StatusRequest::new,
generic(0x00)); lowestVersion(0x00));
SERVERBOUND.register(Ping.class, Ping::new, SERVERBOUND.register(StatusPing.class, StatusPing::new,
generic(0x01)); lowestVersion(0x01));
CLIENTBOUND.register(StatusResponse.class, StatusResponse::new, CLIENTBOUND.register(StatusResponse.class, StatusResponse::new,
generic(0x00)); lowestVersion(0x00));
CLIENTBOUND.register(Ping.class, Ping::new, CLIENTBOUND.register(StatusPing.class, StatusPing::new,
generic(0x01)); lowestVersion(0x01));
} }
}, },
PLAY { PLAY {
{ {
SERVERBOUND.register(Chat.class, Chat::new, SERVERBOUND.register(Chat.class, Chat::new,
map(0x02, MINECRAFT_1_12)); map(0x03, MINECRAFT_1_12),
SERVERBOUND.register(Ping.class, Ping::new, map(0x02, MINECRAFT_1_12_2));
map(0x0b, MINECRAFT_1_12)); SERVERBOUND.register(KeepAlive.class, KeepAlive::new,
map(0x0C, MINECRAFT_1_12),
map(0x0B, MINECRAFT_1_12_1));
CLIENTBOUND.register(Chat.class, Chat::new, CLIENTBOUND.register(Chat.class, Chat::new,
map(0x0F, MINECRAFT_1_12)); map(0x0F, MINECRAFT_1_12));
CLIENTBOUND.register(Disconnect.class, Disconnect::new, CLIENTBOUND.register(Disconnect.class, Disconnect::new,
map(0x1A, MINECRAFT_1_12)); map(0x1A, MINECRAFT_1_12));
CLIENTBOUND.register(Ping.class, Ping::new, CLIENTBOUND.register(KeepAlive.class, KeepAlive::new,
map(0x1F, MINECRAFT_1_12)); map(0x1F, MINECRAFT_1_12));
CLIENTBOUND.register(JoinGame.class, JoinGame::new, CLIENTBOUND.register(JoinGame.class, JoinGame::new,
map(0x23, MINECRAFT_1_12)); map(0x23, MINECRAFT_1_12));
CLIENTBOUND.register(Respawn.class, Respawn::new, CLIENTBOUND.register(Respawn.class, Respawn::new,
map(0x35, MINECRAFT_1_12)); map(0x34, MINECRAFT_1_12),
map(0x35, MINECRAFT_1_12_2));
} }
}, },
LOGIN { LOGIN {
{ {
SERVERBOUND.register(ServerLogin.class, ServerLogin::new, SERVERBOUND.register(ServerLogin.class, ServerLogin::new,
generic(0x00)); lowestVersion(0x00));
SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new, SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new,
generic(0x01)); lowestVersion(0x01));
CLIENTBOUND.register(Disconnect.class, Disconnect::new, CLIENTBOUND.register(Disconnect.class, Disconnect::new,
generic(0x00)); lowestVersion(0x00));
CLIENTBOUND.register(EncryptionRequest.class, EncryptionRequest::new, CLIENTBOUND.register(EncryptionRequest.class, EncryptionRequest::new,
generic(0x01)); lowestVersion(0x01));
CLIENTBOUND.register(ServerLoginSuccess.class, ServerLoginSuccess::new, CLIENTBOUND.register(ServerLoginSuccess.class, ServerLoginSuccess::new,
generic(0x02)); lowestVersion(0x02));
CLIENTBOUND.register(SetCompression.class, SetCompression::new, CLIENTBOUND.register(SetCompression.class, SetCompression::new,
generic(0x03)); lowestVersion(0x03));
} }
}; };
@ -72,20 +75,25 @@ public enum StateRegistry {
public final PacketRegistry SERVERBOUND = new PacketRegistry(ProtocolConstants.Direction.SERVERBOUND); public final PacketRegistry SERVERBOUND = new PacketRegistry(ProtocolConstants.Direction.SERVERBOUND);
public static class PacketRegistry { public static class PacketRegistry {
private static final IntObjectMap<int[]> LINKED_PROTOCOL_VERSIONS = new IntObjectHashMap<>();
static {
LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_12, new int[] { MINECRAFT_1_12_1 });
LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_12_1, new int[] { MINECRAFT_1_12_2 });
}
private final ProtocolConstants.Direction direction; private final ProtocolConstants.Direction direction;
private final IntObjectMap<ProtocolVersion> versions = new IntObjectHashMap<>(); private final IntObjectMap<ProtocolVersion> versions = new IntObjectHashMap<>();
public PacketRegistry(ProtocolConstants.Direction direction) { public PacketRegistry(ProtocolConstants.Direction direction) {
this.direction = direction; this.direction = direction;
for (int version : ProtocolConstants.SUPPORTED_VERSIONS) {
versions.put(version, new ProtocolVersion(version));
}
} }
public ProtocolVersion getVersion(final int version) { public ProtocolVersion getVersion(final int version) {
ProtocolVersion result = null; ProtocolVersion result = versions.get(version);
for (final IntObjectMap.PrimitiveEntry<ProtocolVersion> entry : this.versions.entries()) {
if (entry.key() <= version) {
result = entry.value();
}
}
if (result == null) { if (result == null) {
throw new IllegalArgumentException("Could not find data for protocol version " + version); throw new IllegalArgumentException("Could not find data for protocol version " + version);
} }
@ -105,6 +113,17 @@ public enum StateRegistry {
} }
version.packetIdToSupplier.put(mapping.id, packetSupplier); version.packetIdToSupplier.put(mapping.id, packetSupplier);
version.packetClassToId.put(clazz, mapping.id); version.packetClassToId.put(clazz, mapping.id);
int[] linked = LINKED_PROTOCOL_VERSIONS.get(mapping.protocolVersion);
if (linked != null) {
links: for (int i : linked) {
// Make sure that later mappings override this one.
for (PacketMapping m : mappings) {
if (i == m.protocolVersion) continue links;
}
register(clazz, packetSupplier, map(mapping.id, i));
}
}
} }
} }
@ -135,6 +154,14 @@ public enum StateRegistry {
} }
return id; return id;
} }
@Override
public String toString() {
return "ProtocolVersion{" +
"id=" + id +
", packetClassToId=" + packetClassToId +
'}';
}
} }
} }
@ -174,7 +201,7 @@ public enum StateRegistry {
return new PacketMapping(id, version); return new PacketMapping(id, version);
} }
private static PacketMapping generic(int id) { private static PacketMapping lowestVersion(int id) {
return new PacketMapping(id, 0); return new PacketMapping(id, MINECRAFT_1_12);
} }
} }

Datei anzeigen

@ -17,6 +17,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
public MinecraftDecoder(ProtocolConstants.Direction direction) { public MinecraftDecoder(ProtocolConstants.Direction direction) {
this.state = StateRegistry.HANDSHAKE; this.state = StateRegistry.HANDSHAKE;
this.direction = Preconditions.checkNotNull(direction, "direction"); this.direction = Preconditions.checkNotNull(direction, "direction");
this.setProtocolVersion(ProtocolConstants.MINECRAFT_1_12);
} }
@Override @Override
@ -57,6 +58,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
public void setState(StateRegistry state) { public void setState(StateRegistry state) {
this.state = state; this.state = state;
this.setProtocolVersion(protocolVersion.id);
} }
public ProtocolConstants.Direction getDirection() { public ProtocolConstants.Direction getDirection() {

Datei anzeigen

@ -17,6 +17,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
public MinecraftEncoder(ProtocolConstants.Direction direction) { public MinecraftEncoder(ProtocolConstants.Direction direction) {
this.state = StateRegistry.HANDSHAKE; this.state = StateRegistry.HANDSHAKE;
this.direction = Preconditions.checkNotNull(direction, "direction"); this.direction = Preconditions.checkNotNull(direction, "direction");
this.setProtocolVersion(ProtocolConstants.MINECRAFT_1_12);
} }
@Override @Override
@ -40,6 +41,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
public void setState(StateRegistry state) { public void setState(StateRegistry state) {
this.state = state; this.state = state;
this.setProtocolVersion(protocolVersion.id);
} }
public ProtocolConstants.Direction getDirection() { public ProtocolConstants.Direction getDirection() {

Datei anzeigen

@ -0,0 +1,45 @@
package com.velocitypowered.proxy.protocol.packets;
import com.velocitypowered.proxy.protocol.ProtocolConstants;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_12_2;
public class KeepAlive implements MinecraftPacket {
private long randomId;
public long getRandomId() {
return randomId;
}
public void setRandomId(long randomId) {
this.randomId = randomId;
}
@Override
public String toString() {
return "KeepAlive{" +
"randomId=" + randomId +
'}';
}
@Override
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
if (protocolVersion >= MINECRAFT_1_12_2) {
randomId = buf.readLong();
} else {
randomId = ProtocolUtils.readVarInt(buf);
}
}
@Override
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
if (protocolVersion >= MINECRAFT_1_12_2) {
buf.writeLong(randomId);
} else {
ProtocolUtils.writeVarInt(buf, (int) randomId);
}
}
}

Datei anzeigen

@ -1,27 +1,12 @@
package com.velocitypowered.proxy.protocol.packets; package com.velocitypowered.proxy.protocol.packets;
import com.velocitypowered.proxy.protocol.ProtocolConstants;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolConstants;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
public class Ping implements MinecraftPacket { public class StatusPing implements MinecraftPacket {
private long randomId; private long randomId;
public long getRandomId() {
return randomId;
}
public void setRandomId(long randomId) {
this.randomId = randomId;
}
@Override
public String toString() {
return "Ping{" +
"randomId=" + randomId +
'}';
}
@Override @Override
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
randomId = buf.readLong(); randomId = buf.readLong();