mirror of
https://github.com/Nan1t/NanoLimbo.git
synced 2025-07-13 13:10:13 +02:00
Modify state registry for multimple versions support
This commit is contained in:
parent
e191c8f90b
commit
f490e00888
@ -16,7 +16,7 @@ public class PacketDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
private Version version;
|
||||
|
||||
public PacketDecoder() {
|
||||
updateVersion(Version.getMinimal());
|
||||
updateVersion(Version.getMin());
|
||||
updateState(State.HANDSHAKING);
|
||||
}
|
||||
|
||||
@ -46,6 +46,6 @@ public class PacketDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
}
|
||||
|
||||
public void updateState(State state) {
|
||||
this.mappings = state.serverBound;
|
||||
this.mappings = state.serverBound.getRegistry(version);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class PacketEncoder extends MessageToByteEncoder<Packet> {
|
||||
private Version version;
|
||||
|
||||
public PacketEncoder() {
|
||||
updateVersion(Version.getMinimal());
|
||||
updateVersion(Version.getMin());
|
||||
updateState(State.HANDSHAKING);
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ public class PacketEncoder extends MessageToByteEncoder<Packet> {
|
||||
}
|
||||
|
||||
public void updateState(State state) {
|
||||
this.registry = state.clientBound;
|
||||
this.registry = state.clientBound.getRegistry(version);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,45 +8,134 @@ import ru.nanit.limbo.protocol.packets.status.PacketStatusPing;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusRequest;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusResponse;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import static ru.nanit.limbo.protocol.registry.Version.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum State {
|
||||
|
||||
HANDSHAKING(0) {
|
||||
{
|
||||
serverBound.register(0x00, PacketHandshake::new);
|
||||
serverBound.register(PacketHandshake::new,
|
||||
map(0x00, Version.getMin(), Version.getMax())
|
||||
);
|
||||
}
|
||||
},
|
||||
STATUS(1) {
|
||||
{
|
||||
serverBound.register(0x01, PacketStatusPing::new);
|
||||
serverBound.register(0x00, PacketStatusRequest::new);
|
||||
clientBound.register(0x00, PacketStatusResponse::new);
|
||||
clientBound.register(0x01, PacketStatusPing::new);
|
||||
serverBound.register(PacketStatusRequest::new,
|
||||
map(0x00, Version.getMin(), Version.getMax())
|
||||
);
|
||||
serverBound.register(PacketStatusPing::new,
|
||||
map(0x01, Version.getMin(), Version.getMax())
|
||||
);
|
||||
clientBound.register(PacketStatusResponse::new,
|
||||
map(0x00, Version.getMin(), Version.getMax())
|
||||
);
|
||||
clientBound.register(PacketStatusPing::new,
|
||||
map(0x01, Version.getMin(), Version.getMax())
|
||||
);
|
||||
}
|
||||
},
|
||||
LOGIN(2) {
|
||||
{
|
||||
serverBound.register(0x00, PacketLoginStart::new);
|
||||
serverBound.register(0x02, PacketLoginPluginResponse::new);
|
||||
clientBound.register(0x00, PacketDisconnect::new);
|
||||
clientBound.register(0x02, PacketLoginSuccess::new);
|
||||
clientBound.register(0x04, PacketLoginPluginRequest::new);
|
||||
serverBound.register(PacketLoginStart::new,
|
||||
map(0x00, Version.getMin(), Version.getMax())
|
||||
);
|
||||
serverBound.register(PacketLoginPluginResponse::new,
|
||||
map(0x02, Version.getMin(), Version.getMax())
|
||||
);
|
||||
clientBound.register(PacketDisconnect::new,
|
||||
map(0x00, Version.getMin(), Version.getMax())
|
||||
);
|
||||
clientBound.register(PacketLoginSuccess::new,
|
||||
map(0x02, Version.getMin(), Version.getMax())
|
||||
);
|
||||
clientBound.register(PacketLoginPluginRequest::new,
|
||||
map(0x04, Version.getMin(), Version.getMax())
|
||||
);
|
||||
}
|
||||
},
|
||||
PLAY(3) {
|
||||
{
|
||||
serverBound.register(0x10, PacketKeepAlive::new);
|
||||
clientBound.register(0x10, PacketDeclareCommands::new);
|
||||
clientBound.register(0x24, PacketJoinGame::new);
|
||||
clientBound.register(0x30, PacketPlayerAbilities::new);
|
||||
clientBound.register(0x34, PacketPlayerPositionAndLook::new);
|
||||
clientBound.register(0x1F, PacketKeepAlive::new);
|
||||
clientBound.register(0x0E, PacketChatMessage::new);
|
||||
clientBound.register(0x0C, PacketBossBar::new);
|
||||
clientBound.register(0x32, PacketPlayerInfo::new);
|
||||
serverBound.register(PacketKeepAlive::new,
|
||||
map(0x0B, V1_9, V1_11_1),
|
||||
map(0x0C, V1_12, V1_12),
|
||||
map(0x0B, V1_12_1, V1_12_2),
|
||||
map(0x0E, V1_13, V1_13_2),
|
||||
map(0x0F, V1_14, V1_15_2),
|
||||
map(0x10, V1_16, V1_16_4),
|
||||
map(0x0F, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketDeclareCommands::new,
|
||||
map(0x11, V1_13, V1_14_4),
|
||||
map(0x12, V1_15, V1_15_2),
|
||||
map(0x11, V1_16, V1_16_1),
|
||||
map(0x10, V1_16_2, V1_16_4),
|
||||
map(0x12, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketJoinGame::new,
|
||||
map(0x23, V1_9, V1_12_2),
|
||||
map(0x25, V1_13, V1_13_2),
|
||||
map(0x25, V1_14, V1_14_4),
|
||||
map(0x26, V1_15, V1_15_2),
|
||||
map(0x25, V1_16, V1_16_1),
|
||||
map(0x24, V1_16_2, V1_16_4),
|
||||
map(0x26, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketPlayerAbilities::new,
|
||||
map(0x2B, V1_9, V1_12),
|
||||
map(0x2C, V1_12_1, V1_12_2),
|
||||
map(0x2E, V1_13, V1_13_2),
|
||||
map(0x31, V1_14, V1_14_4),
|
||||
map(0x32, V1_15, V1_15_2),
|
||||
map(0x31, V1_16, V1_16_1),
|
||||
map(0x30, V1_16_2, V1_16_4),
|
||||
map(0x32, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketPlayerPositionAndLook::new,
|
||||
map(0x2E, V1_9, V1_12),
|
||||
map(0x2F, V1_12_1, V1_12_2),
|
||||
map(0x32, V1_13, V1_13_2),
|
||||
map(0x35, V1_14, V1_14_4),
|
||||
map(0x36, V1_15, V1_15_2),
|
||||
map(0x35, V1_16, V1_16_1),
|
||||
map(0x34, V1_16_2, V1_16_4),
|
||||
map(0x38, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketKeepAlive::new,
|
||||
map(0x1F, V1_9, V1_12_2),
|
||||
map(0x21, V1_13, V1_13_2),
|
||||
map(0x20, V1_14, V1_14_4),
|
||||
map(0x21, V1_15, V1_15_2),
|
||||
map(0x20, V1_16, V1_16_1),
|
||||
map(0x1F, V1_16_2, V1_16_4),
|
||||
map(0x21, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketChatMessage::new,
|
||||
map(0x0F, V1_9, V1_12_2),
|
||||
map(0x0E, V1_13, V1_14_4),
|
||||
map(0x0F, V1_15, V1_15_2),
|
||||
map(0x0E, V1_16, V1_16_4),
|
||||
map(0x0F, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketBossBar::new,
|
||||
map(0x0C, V1_9, V1_14_4),
|
||||
map(0x0D, V1_15, V1_15_2),
|
||||
map(0x0C, V1_16, V1_16_4),
|
||||
map(0x0D, V1_17, V1_17_1)
|
||||
);
|
||||
clientBound.register(PacketPlayerInfo::new,
|
||||
map(0x2D, V1_9, V1_12),
|
||||
map(0x2E, V1_12_1, V1_12_2),
|
||||
map(0x30, V1_13, V1_13_2),
|
||||
map(0x33, V1_14, V1_14_4),
|
||||
map(0x34, V1_15, V1_15_2),
|
||||
map(0x33, V1_16, V1_16_1),
|
||||
map(0x32, V1_16_2, V1_16_4),
|
||||
map(0x36, V1_17, V1_17_1)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -59,8 +148,8 @@ public enum State {
|
||||
}
|
||||
|
||||
private final int stateId;
|
||||
public final PacketRegistry serverBound = new PacketRegistry();
|
||||
public final PacketRegistry clientBound = new PacketRegistry();
|
||||
public final ProtocolMappings serverBound = new ProtocolMappings();
|
||||
public final ProtocolMappings clientBound = new ProtocolMappings();
|
||||
|
||||
State(int stateId) {
|
||||
this.stateId = stateId;
|
||||
@ -70,11 +159,58 @@ public enum State {
|
||||
return STATE_BY_ID.get(stateId);
|
||||
}
|
||||
|
||||
public static class ProtocolMappings {
|
||||
|
||||
private final Map<Version, PacketRegistry> registry = new HashMap<>();
|
||||
|
||||
public PacketRegistry getRegistry(Version version) {
|
||||
return registry.get(version);
|
||||
}
|
||||
|
||||
public void register(Supplier<?> packet, Mapping... mappings) {
|
||||
for (Mapping mapping : mappings) {
|
||||
for (Version ver : getRange(mapping)) {
|
||||
PacketRegistry reg = registry.computeIfAbsent(ver, PacketRegistry::new);
|
||||
reg.register(mapping.packetId, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<Version> getRange(Mapping mapping) {
|
||||
Version from = mapping.from;
|
||||
Version curr = mapping.to;
|
||||
|
||||
if (curr == from)
|
||||
return Collections.singletonList(from);
|
||||
|
||||
List<Version> versions = new LinkedList<>();
|
||||
|
||||
while (curr != from) {
|
||||
versions.add(curr);
|
||||
curr = curr.getPrev();
|
||||
}
|
||||
|
||||
versions.add(from);
|
||||
|
||||
return versions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PacketRegistry {
|
||||
|
||||
private final Version version;
|
||||
private final Map<Integer, Supplier<?>> packetsById = new HashMap<>();
|
||||
private final Map<Class<?>, Integer> packetIdByClass = new HashMap<>();
|
||||
|
||||
public PacketRegistry(Version version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public Version getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public Packet getPacket(int packetId) {
|
||||
Supplier<?> supplier = packetsById.get(packetId);
|
||||
return supplier == null ? null : (Packet) supplier.get();
|
||||
@ -91,4 +227,28 @@ public enum State {
|
||||
|
||||
}
|
||||
|
||||
private static class Mapping {
|
||||
|
||||
private final int packetId;
|
||||
private final Version from;
|
||||
private final Version to;
|
||||
|
||||
public Mapping(int packetId, Version from, Version to) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.packetId = packetId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map packet id to version range
|
||||
* @param packetId Packet id
|
||||
* @param from Minimal version (include)
|
||||
* @param to Last version (include)
|
||||
* @return Created mapping
|
||||
*/
|
||||
private static Mapping map(int packetId, Version from, Version to) {
|
||||
return new Mapping(packetId, from, to);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ public enum Version {
|
||||
V1_10(210),
|
||||
V1_11(315),
|
||||
V1_11_1(316),
|
||||
// 1.11.2 has same protocol number
|
||||
V1_12(335),
|
||||
V1_12_1(338),
|
||||
V1_12_2(340),
|
||||
@ -36,25 +37,20 @@ public enum Version {
|
||||
V1_17(755),
|
||||
V1_17_1(756);
|
||||
|
||||
public static final Map<Integer, Version> VERSION_MAP;
|
||||
private static final Map<Integer, Version> VERSION_MAP;
|
||||
|
||||
static {
|
||||
VERSION_MAP = new HashMap<>();
|
||||
|
||||
Version last = null;
|
||||
for (Version version : values()) {
|
||||
version.prev = last;
|
||||
last = version;
|
||||
VERSION_MAP.put(version.getProtocolNumber(), version);
|
||||
}
|
||||
}
|
||||
|
||||
public static Version getMinimal() {
|
||||
return V1_9;
|
||||
}
|
||||
|
||||
public static Version of(int protocolNumber) {
|
||||
return VERSION_MAP.getOrDefault(protocolNumber, UNDEFINED);
|
||||
}
|
||||
|
||||
private final int protocolNumber;
|
||||
private Version prev;
|
||||
|
||||
Version(int protocolNumber) {
|
||||
this.protocolNumber = protocolNumber;
|
||||
@ -64,4 +60,19 @@ public enum Version {
|
||||
return this.protocolNumber;
|
||||
}
|
||||
|
||||
public Version getPrev() {
|
||||
return prev;
|
||||
}
|
||||
|
||||
public static Version getMin() {
|
||||
return V1_9;
|
||||
}
|
||||
|
||||
public static Version getMax() {
|
||||
return V1_17_1;
|
||||
}
|
||||
|
||||
public static Version of(int protocolNumber) {
|
||||
return VERSION_MAP.getOrDefault(protocolNumber, UNDEFINED);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import io.netty.util.ResourceLeakDetector;
|
||||
import ru.nanit.limbo.configuration.LimboConfig;
|
||||
import ru.nanit.limbo.connection.ClientChannelInitializer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.protocol.registry.State;
|
||||
import ru.nanit.limbo.util.Logger;
|
||||
import ru.nanit.limbo.world.DimensionRegistry;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user