Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-24 23:30:26 +01:00
Initial 1.12/1.12.1 support. Bug fixes!
Dieser Commit ist enthalten in:
Ursprung
155b742352
Commit
b79e7df039
@ -4,7 +4,7 @@ import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.packets.Disconnect;
|
||||
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.protocol.packets.Respawn;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@ -18,7 +18,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
@Override
|
||||
public void handle(MinecraftPacket packet) {
|
||||
if (packet instanceof Ping) {
|
||||
if (packet instanceof KeepAlive) {
|
||||
// Forward onto the server
|
||||
connection.getChannel().write(packet);
|
||||
} else if (packet instanceof Disconnect) {
|
||||
|
@ -6,11 +6,13 @@ import com.velocitypowered.proxy.data.ServerInfo;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.packets.Chat;
|
||||
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.protocol.packets.Respawn;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.EventLoop;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
@ -18,6 +20,8 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
private static final Logger logger = LogManager.getLogger(ClientPlaySessionHandler.class);
|
||||
|
||||
private final ConnectedPlayer player;
|
||||
private ScheduledFuture<?> pingTask;
|
||||
private long lastPing = -1;
|
||||
@ -35,19 +39,19 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
private void ping() {
|
||||
long randomId = ThreadLocalRandom.current().nextLong();
|
||||
long randomId = ThreadLocalRandom.current().nextInt();
|
||||
lastPing = randomId;
|
||||
Ping ping = new Ping();
|
||||
ping.setRandomId(randomId);
|
||||
player.getConnection().write(ping);
|
||||
KeepAlive keepAlive = new KeepAlive();
|
||||
keepAlive.setRandomId(randomId);
|
||||
player.getConnection().write(keepAlive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MinecraftPacket packet) {
|
||||
if (packet instanceof Ping) {
|
||||
Ping ping = (Ping) packet;
|
||||
if (ping.getRandomId() != lastPing) {
|
||||
throw new IllegalStateException("Client sent invalid ping; expected " + lastPing + ", got " + ping.getRandomId());
|
||||
if (packet instanceof KeepAlive) {
|
||||
KeepAlive keepAlive = (KeepAlive) packet;
|
||||
if (keepAlive.getRandomId() != lastPing) {
|
||||
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.
|
||||
|
@ -1,20 +1,16 @@
|
||||
package com.velocitypowered.proxy.connection.client;
|
||||
|
||||
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.config.VelocityConfiguration;
|
||||
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.StatusResponse;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.data.ServerPing;
|
||||
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 {
|
||||
private final MinecraftConnection connection;
|
||||
@ -25,10 +21,10 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
@Override
|
||||
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());
|
||||
|
||||
if (packet instanceof Ping) {
|
||||
if (packet instanceof StatusPing) {
|
||||
// Just send back the client's packet, no processing to do here.
|
||||
connection.closeWith(packet);
|
||||
return;
|
||||
|
@ -3,10 +3,14 @@ package com.velocitypowered.proxy.protocol;
|
||||
import java.util.Arrays;
|
||||
|
||||
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[] {
|
||||
MINECRAFT_1_12
|
||||
public static final int[] SUPPORTED_VERSIONS = new int[] {
|
||||
MINECRAFT_1_12,
|
||||
MINECRAFT_1_12_1,
|
||||
MINECRAFT_1_12_2
|
||||
};
|
||||
|
||||
public static boolean isSupported(int version) {
|
||||
|
@ -4,67 +4,70 @@ import com.velocitypowered.proxy.protocol.packets.*;
|
||||
import io.netty.util.collection.IntObjectHashMap;
|
||||
import io.netty.util.collection.IntObjectMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
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_1;
|
||||
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_12_2;
|
||||
|
||||
public enum StateRegistry {
|
||||
HANDSHAKE {
|
||||
{
|
||||
SERVERBOUND.register(Handshake.class, Handshake::new,
|
||||
generic(0x00));
|
||||
lowestVersion(0x00));
|
||||
}
|
||||
},
|
||||
STATUS {
|
||||
{
|
||||
SERVERBOUND.register(StatusRequest.class, StatusRequest::new,
|
||||
generic(0x00));
|
||||
SERVERBOUND.register(Ping.class, Ping::new,
|
||||
generic(0x01));
|
||||
lowestVersion(0x00));
|
||||
SERVERBOUND.register(StatusPing.class, StatusPing::new,
|
||||
lowestVersion(0x01));
|
||||
|
||||
CLIENTBOUND.register(StatusResponse.class, StatusResponse::new,
|
||||
generic(0x00));
|
||||
CLIENTBOUND.register(Ping.class, Ping::new,
|
||||
generic(0x01));
|
||||
lowestVersion(0x00));
|
||||
CLIENTBOUND.register(StatusPing.class, StatusPing::new,
|
||||
lowestVersion(0x01));
|
||||
}
|
||||
},
|
||||
PLAY {
|
||||
{
|
||||
SERVERBOUND.register(Chat.class, Chat::new,
|
||||
map(0x02, MINECRAFT_1_12));
|
||||
SERVERBOUND.register(Ping.class, Ping::new,
|
||||
map(0x0b, MINECRAFT_1_12));
|
||||
map(0x03, MINECRAFT_1_12),
|
||||
map(0x02, MINECRAFT_1_12_2));
|
||||
SERVERBOUND.register(KeepAlive.class, KeepAlive::new,
|
||||
map(0x0C, MINECRAFT_1_12),
|
||||
map(0x0B, MINECRAFT_1_12_1));
|
||||
|
||||
CLIENTBOUND.register(Chat.class, Chat::new,
|
||||
map(0x0F, MINECRAFT_1_12));
|
||||
CLIENTBOUND.register(Disconnect.class, Disconnect::new,
|
||||
map(0x1A, MINECRAFT_1_12));
|
||||
CLIENTBOUND.register(Ping.class, Ping::new,
|
||||
CLIENTBOUND.register(KeepAlive.class, KeepAlive::new,
|
||||
map(0x1F, MINECRAFT_1_12));
|
||||
CLIENTBOUND.register(JoinGame.class, JoinGame::new,
|
||||
map(0x23, MINECRAFT_1_12));
|
||||
CLIENTBOUND.register(Respawn.class, Respawn::new,
|
||||
map(0x35, MINECRAFT_1_12));
|
||||
map(0x34, MINECRAFT_1_12),
|
||||
map(0x35, MINECRAFT_1_12_2));
|
||||
}
|
||||
},
|
||||
LOGIN {
|
||||
{
|
||||
SERVERBOUND.register(ServerLogin.class, ServerLogin::new,
|
||||
generic(0x00));
|
||||
lowestVersion(0x00));
|
||||
SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new,
|
||||
generic(0x01));
|
||||
lowestVersion(0x01));
|
||||
|
||||
CLIENTBOUND.register(Disconnect.class, Disconnect::new,
|
||||
generic(0x00));
|
||||
lowestVersion(0x00));
|
||||
CLIENTBOUND.register(EncryptionRequest.class, EncryptionRequest::new,
|
||||
generic(0x01));
|
||||
lowestVersion(0x01));
|
||||
CLIENTBOUND.register(ServerLoginSuccess.class, ServerLoginSuccess::new,
|
||||
generic(0x02));
|
||||
lowestVersion(0x02));
|
||||
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 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 IntObjectMap<ProtocolVersion> versions = new IntObjectHashMap<>();
|
||||
|
||||
public PacketRegistry(ProtocolConstants.Direction direction) {
|
||||
this.direction = direction;
|
||||
for (int version : ProtocolConstants.SUPPORTED_VERSIONS) {
|
||||
versions.put(version, new ProtocolVersion(version));
|
||||
}
|
||||
}
|
||||
|
||||
public ProtocolVersion getVersion(final int version) {
|
||||
ProtocolVersion result = null;
|
||||
for (final IntObjectMap.PrimitiveEntry<ProtocolVersion> entry : this.versions.entries()) {
|
||||
if (entry.key() <= version) {
|
||||
result = entry.value();
|
||||
}
|
||||
}
|
||||
ProtocolVersion result = versions.get(version);
|
||||
if (result == null) {
|
||||
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.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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProtocolVersion{" +
|
||||
"id=" + id +
|
||||
", packetClassToId=" + packetClassToId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +201,7 @@ public enum StateRegistry {
|
||||
return new PacketMapping(id, version);
|
||||
}
|
||||
|
||||
private static PacketMapping generic(int id) {
|
||||
return new PacketMapping(id, 0);
|
||||
private static PacketMapping lowestVersion(int id) {
|
||||
return new PacketMapping(id, MINECRAFT_1_12);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
public MinecraftDecoder(ProtocolConstants.Direction direction) {
|
||||
this.state = StateRegistry.HANDSHAKE;
|
||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||
this.setProtocolVersion(ProtocolConstants.MINECRAFT_1_12);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -57,6 +58,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
public void setState(StateRegistry state) {
|
||||
this.state = state;
|
||||
this.setProtocolVersion(protocolVersion.id);
|
||||
}
|
||||
|
||||
public ProtocolConstants.Direction getDirection() {
|
||||
|
@ -17,6 +17,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||
public MinecraftEncoder(ProtocolConstants.Direction direction) {
|
||||
this.state = StateRegistry.HANDSHAKE;
|
||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||
this.setProtocolVersion(ProtocolConstants.MINECRAFT_1_12);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,6 +41,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||
|
||||
public void setState(StateRegistry state) {
|
||||
this.state = state;
|
||||
this.setProtocolVersion(protocolVersion.id);
|
||||
}
|
||||
|
||||
public ProtocolConstants.Direction getDirection() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +1,12 @@
|
||||
package com.velocitypowered.proxy.protocol.packets;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class Ping implements MinecraftPacket {
|
||||
public class StatusPing implements MinecraftPacket {
|
||||
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
|
||||
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||
randomId = buf.readLong();
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren