geforkt von Mirrors/Velocity
Initial remapping support, fix protocol crap.
Dieser Commit ist enthalten in:
Ursprung
47bea89146
Commit
6b5cd703f0
@ -2,6 +2,7 @@ package com.velocitypowered.proxy.connection.backend;
|
|||||||
|
|
||||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
import com.velocitypowered.proxy.protocol.packets.*;
|
import com.velocitypowered.proxy.protocol.packets.*;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||||
@ -46,7 +47,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
PluginMessage pm = (PluginMessage) packet;
|
PluginMessage pm = (PluginMessage) packet;
|
||||||
try {
|
try {
|
||||||
PluginMessage newPacket = pm;
|
PluginMessage newPacket = pm;
|
||||||
if (!canForwardMessage(newPacket)) {
|
if (!canForwardPluginMessage(newPacket)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +73,10 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleUnknown(ByteBuf buf) {
|
public void handleUnknown(ByteBuf buf) {
|
||||||
connection.getProxyPlayer().getConnection().write(buf.retain());
|
ClientPlaySessionHandler playerHandler =
|
||||||
|
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
||||||
|
ByteBuf remapped = playerHandler.getIdRemapper().remap(buf, ProtocolConstants.Direction.CLIENTBOUND);
|
||||||
|
connection.getProxyPlayer().getConnection().write(remapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -80,7 +84,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canForwardMessage(PluginMessage message) {
|
private boolean canForwardPluginMessage(PluginMessage message) {
|
||||||
// TODO: Update for 1.13
|
// TODO: Update for 1.13
|
||||||
ClientPlaySessionHandler playerHandler =
|
ClientPlaySessionHandler playerHandler =
|
||||||
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
||||||
|
@ -8,8 +8,10 @@ import com.velocitypowered.proxy.data.scoreboard.Score;
|
|||||||
import com.velocitypowered.proxy.data.scoreboard.Scoreboard;
|
import com.velocitypowered.proxy.data.scoreboard.Scoreboard;
|
||||||
import com.velocitypowered.proxy.data.scoreboard.Team;
|
import com.velocitypowered.proxy.data.scoreboard.Team;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
import com.velocitypowered.proxy.protocol.packets.*;
|
import com.velocitypowered.proxy.protocol.packets.*;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
|
import com.velocitypowered.proxy.protocol.remap.EntityIdRemapper;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||||
import com.velocitypowered.proxy.util.ThrowableUtils;
|
import com.velocitypowered.proxy.util.ThrowableUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
@ -39,6 +41,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
private PluginMessage brandMessage;
|
private PluginMessage brandMessage;
|
||||||
private int currentDimension;
|
private int currentDimension;
|
||||||
private Scoreboard serverScoreboard = new Scoreboard();
|
private Scoreboard serverScoreboard = new Scoreboard();
|
||||||
|
private EntityIdRemapper idRemapper;
|
||||||
|
|
||||||
public ClientPlaySessionHandler(ConnectedPlayer player) {
|
public ClientPlaySessionHandler(ConnectedPlayer player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@ -95,7 +98,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleUnknown(ByteBuf buf) {
|
public void handleUnknown(ByteBuf buf) {
|
||||||
player.getConnectedServer().getChannel().write(buf.retain());
|
ByteBuf remapped = idRemapper.remap(buf, ProtocolConstants.Direction.SERVERBOUND);
|
||||||
|
player.getConnectedServer().getChannel().write(remapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -123,6 +127,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
spawned = true;
|
spawned = true;
|
||||||
currentDimension = joinGame.getDimension();
|
currentDimension = joinGame.getDimension();
|
||||||
player.getConnection().delayedWrite(joinGame);
|
player.getConnection().delayedWrite(joinGame);
|
||||||
|
idRemapper = EntityIdRemapper.getMapper(joinGame.getEntityId(), player.getConnection().getProtocolVersion());
|
||||||
} else {
|
} else {
|
||||||
// In order to handle switching to another server we will need send three packets:
|
// In order to handle switching to another server we will need send three packets:
|
||||||
// - The join game packet from the backend server
|
// - The join game packet from the backend server
|
||||||
@ -130,6 +135,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// - Another respawn with the correct dimension
|
// - Another respawn with the correct dimension
|
||||||
// We can't simply ignore the packet with the different dimension. If you try to be smart about it it doesn't
|
// We can't simply ignore the packet with the different dimension. If you try to be smart about it it doesn't
|
||||||
// work.
|
// work.
|
||||||
|
idRemapper.setServerEntityId(joinGame.getEntityId());
|
||||||
player.getConnection().delayedWrite(joinGame);
|
player.getConnection().delayedWrite(joinGame);
|
||||||
int tempDim = joinGame.getDimension() == 0 ? -1 : 0;
|
int tempDim = joinGame.getDimension() == 0 ? -1 : 0;
|
||||||
player.getConnection().delayedWrite(new Respawn(tempDim, joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType()));
|
player.getConnection().delayedWrite(new Respawn(tempDim, joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType()));
|
||||||
@ -304,4 +310,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
public Set<String> getClientPluginMsgChannels() {
|
public Set<String> getClientPluginMsgChannels() {
|
||||||
return clientPluginMsgChannels;
|
return clientPluginMsgChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityIdRemapper getIdRemapper() {
|
||||||
|
return idRemapper;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,8 +107,7 @@ public enum StateRegistry {
|
|||||||
private static final IntObjectMap<int[]> LINKED_PROTOCOL_VERSIONS = new IntObjectHashMap<>();
|
private static final IntObjectMap<int[]> LINKED_PROTOCOL_VERSIONS = new IntObjectHashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_10, new int[] { MINECRAFT_1_11 });
|
LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_10, new int[] { MINECRAFT_1_11, MINECRAFT_1_11_1, MINECRAFT_1_12 });
|
||||||
LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_11, new int[] { MINECRAFT_1_11_1, MINECRAFT_1_12 });
|
|
||||||
LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_12, new int[] { MINECRAFT_1_12_1 });
|
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 });
|
LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_12_1, new int[] { MINECRAFT_1_12_2 });
|
||||||
}
|
}
|
||||||
@ -142,6 +141,7 @@ public enum StateRegistry {
|
|||||||
if (version == null) {
|
if (version == null) {
|
||||||
throw new IllegalArgumentException("Unknown protocol version " + mapping.protocolVersion);
|
throw new IllegalArgumentException("Unknown protocol version " + mapping.protocolVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
version.packetIdToSupplier.put(mapping.id, packetSupplier);
|
version.packetIdToSupplier.put(mapping.id, packetSupplier);
|
||||||
version.packetClassToId.put(clazz, mapping.id);
|
version.packetClassToId.put(clazz, mapping.id);
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class ScoreboardSetScore implements MinecraftPacket {
|
|||||||
this.entity = ProtocolUtils.readString(buf, 40);
|
this.entity = ProtocolUtils.readString(buf, 40);
|
||||||
this.action = buf.readByte();
|
this.action = buf.readByte();
|
||||||
this.objective = ProtocolUtils.readString(buf, 16);
|
this.objective = ProtocolUtils.readString(buf, 16);
|
||||||
if (this.action == 0) {
|
if (this.action != 1) {
|
||||||
value = ProtocolUtils.readVarInt(buf);
|
value = ProtocolUtils.readVarInt(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ public class ScoreboardSetScore implements MinecraftPacket {
|
|||||||
ProtocolUtils.writeString(buf, entity);
|
ProtocolUtils.writeString(buf, entity);
|
||||||
buf.writeByte(action);
|
buf.writeByte(action);
|
||||||
ProtocolUtils.writeString(buf, objective);
|
ProtocolUtils.writeString(buf, objective);
|
||||||
if (this.action == 0) {
|
if (this.action != 1) {
|
||||||
ProtocolUtils.writeVarInt(buf, value);
|
ProtocolUtils.writeVarInt(buf, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.velocitypowered.proxy.protocol.remap;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class DummyEntityIdRemapper implements EntityIdRemapper {
|
||||||
|
public static final DummyEntityIdRemapper INSTANCE = new DummyEntityIdRemapper();
|
||||||
|
|
||||||
|
private DummyEntityIdRemapper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf remap(ByteBuf original, ProtocolConstants.Direction direction) {
|
||||||
|
return original.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClientEntityId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getServerEntityId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setServerEntityId(int id) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.velocitypowered.proxy.protocol.remap;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a protocol-specific entity ID remapper for certain Minecraft packets. This is mostly required to support
|
||||||
|
* old versions of Minecraft. For Minecraft 1.9 clients and above, Velocity can use a more efficient method based on
|
||||||
|
* sending JoinGame packets multiple times.
|
||||||
|
*/
|
||||||
|
public interface EntityIdRemapper {
|
||||||
|
/**
|
||||||
|
* Remaps the entity IDs in this packet so that they apply to the player.
|
||||||
|
* @param original the packet to remap
|
||||||
|
* @param direction the direction of the packet
|
||||||
|
* @return a remapped packet, which may either be a retained version of the original buffer or an entirely new buffer
|
||||||
|
*/
|
||||||
|
ByteBuf remap(ByteBuf original, ProtocolConstants.Direction direction);
|
||||||
|
|
||||||
|
int getClientEntityId();
|
||||||
|
|
||||||
|
int getServerEntityId();
|
||||||
|
|
||||||
|
void setServerEntityId(int id);
|
||||||
|
|
||||||
|
static EntityIdRemapper getMapper(int eid, int protocolVersion) {
|
||||||
|
return DummyEntityIdRemapper.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
@ -4,32 +4,35 @@ import com.velocitypowered.proxy.protocol.packets.Handshake;
|
|||||||
import com.velocitypowered.proxy.protocol.packets.KeepAlive;
|
import com.velocitypowered.proxy.protocol.packets.KeepAlive;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
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;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class PacketRegistryTest {
|
class PacketRegistryTest {
|
||||||
private StateRegistry.PacketRegistry setupRegistry() {
|
private StateRegistry.PacketRegistry setupRegistry() {
|
||||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(ProtocolConstants.Direction.CLIENTBOUND);
|
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(ProtocolConstants.Direction.CLIENTBOUND);
|
||||||
registry.register(Handshake.class, Handshake::new, new StateRegistry.PacketMapping(0x00, ProtocolConstants.MINECRAFT_1_12));
|
registry.register(Handshake.class, Handshake::new, new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12));
|
||||||
return registry;
|
return registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void packetRegistryWorks() {
|
void packetRegistryWorks() {
|
||||||
StateRegistry.PacketRegistry registry = setupRegistry();
|
StateRegistry.PacketRegistry registry = setupRegistry();
|
||||||
MinecraftPacket packet = registry.getVersion(ProtocolConstants.MINECRAFT_1_12).createPacket(0);
|
MinecraftPacket packet = registry.getVersion(MINECRAFT_1_12).createPacket(0);
|
||||||
assertNotNull(packet, "Packet was not found in registry");
|
assertNotNull(packet, "Packet was not found in registry");
|
||||||
assertEquals(Handshake.class, packet.getClass(), "Registry returned wrong class");
|
assertEquals(Handshake.class, packet.getClass(), "Registry returned wrong class");
|
||||||
|
|
||||||
assertEquals(0, registry.getVersion(ProtocolConstants.MINECRAFT_1_12).getPacketId(packet), "Registry did not return the correct packet ID");
|
assertEquals(0, registry.getVersion(MINECRAFT_1_12).getPacketId(packet), "Registry did not return the correct packet ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void packetRegistryLinkingWorks() {
|
void packetRegistryLinkingWorks() {
|
||||||
StateRegistry.PacketRegistry registry = setupRegistry();
|
StateRegistry.PacketRegistry registry = setupRegistry();
|
||||||
MinecraftPacket packet = registry.getVersion(ProtocolConstants.MINECRAFT_1_12_1).createPacket(0);
|
MinecraftPacket packet = registry.getVersion(MINECRAFT_1_12_1).createPacket(0);
|
||||||
assertNotNull(packet, "Packet was not found in registry");
|
assertNotNull(packet, "Packet was not found in registry");
|
||||||
assertEquals(Handshake.class, packet.getClass(), "Registry returned wrong class");
|
assertEquals(Handshake.class, packet.getClass(), "Registry returned wrong class");
|
||||||
assertEquals(0, registry.getVersion(ProtocolConstants.MINECRAFT_1_12_1).getPacketId(packet), "Registry did not return the correct packet ID");
|
assertEquals(0, registry.getVersion(MINECRAFT_1_12_1).getPacketId(packet), "Registry did not return the correct packet ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -38,4 +41,14 @@ class PacketRegistryTest {
|
|||||||
assertThrows(IllegalArgumentException.class, () -> registry.register(Handshake.class, Handshake::new));
|
assertThrows(IllegalArgumentException.class, () -> registry.register(Handshake.class, Handshake::new));
|
||||||
assertThrows(IllegalArgumentException.class, () -> registry.getVersion(0).getPacketId(new Handshake()));
|
assertThrows(IllegalArgumentException.class, () -> registry.getVersion(0).getPacketId(new Handshake()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void registrySuppliesCorrectPacketsByProtocol() {
|
||||||
|
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(ProtocolConstants.Direction.CLIENTBOUND);
|
||||||
|
registry.register(Handshake.class, Handshake::new, new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12),
|
||||||
|
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12_1));
|
||||||
|
assertEquals(Handshake.class, registry.getVersion(MINECRAFT_1_12).createPacket(0x00).getClass());
|
||||||
|
assertEquals(Handshake.class, registry.getVersion(MINECRAFT_1_12_1).createPacket(0x01).getClass());
|
||||||
|
assertEquals(Handshake.class, registry.getVersion(MINECRAFT_1_12_2).createPacket(0x01).getClass());
|
||||||
|
}
|
||||||
}
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren