From f5ddc6550d4ba6d7667e6c8a93d32dab35123542 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 12 Feb 2023 17:27:36 +0100 Subject: [PATCH] Optimize/improve Protocol packet mapping Also makes it possible to work with packet types of different states in a Protocol --- .../api/protocol/AbstractProtocol.java | 446 +++++++----------- .../viaversion/api/protocol/Protocol.java | 16 +- .../packet/mapping/PacketArrayMappings.java | 55 +++ .../packet/mapping/PacketIdMapping.java | 48 ++ .../packet/mapping/PacketMapping.java | 56 +++ .../packet/mapping/PacketMappings.java | 86 ++++ .../packet/mapping/PacketTypeMapping.java | 54 +++ .../packet/provider/PacketTypeArrayMap.java | 53 +++ .../packet/provider/PacketTypeMap.java | 77 +++ .../packet/provider/PacketTypeMapMap.java | 54 +++ .../packet/provider/PacketTypesProvider.java | 61 +++ .../provider/SimplePacketTypesProvider.java | 67 +++ .../remapper/ProtocolHandlersTest.java | 72 --- 13 files changed, 787 insertions(+), 358 deletions(-) create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketArrayMappings.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketIdMapping.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMapping.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMappings.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketTypeMapping.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeArrayMap.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMap.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMapMap.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypesProvider.java create mode 100644 api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/SimplePacketTypesProvider.java delete mode 100644 common/src/test/java/com/viaversion/viaversion/common/protocol/remapper/ProtocolHandlersTest.java diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java index 083880a73..67dc53958 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java @@ -32,24 +32,41 @@ import com.viaversion.viaversion.api.protocol.packet.PacketType; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType; import com.viaversion.viaversion.api.protocol.packet.State; +import com.viaversion.viaversion.api.protocol.packet.mapping.PacketMapping; +import com.viaversion.viaversion.api.protocol.packet.mapping.PacketMappings; +import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypeMap; +import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; +import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; import com.viaversion.viaversion.exception.CancelException; import com.viaversion.viaversion.exception.InformativeException; -import java.util.Arrays; +import java.util.Collections; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Predicate; import java.util.logging.Level; import org.checkerframework.checker.nullness.qual.Nullable; -public abstract class AbstractProtocol - implements Protocol { - private final Map serverbound = new HashMap<>(); - private final Map clientbound = new HashMap<>(); - private final Map, Object> storedObjects = new HashMap<>(); // currently only used for MetadataRewriters +/** + * Abstract protocol class to handle packet transformation between two protocol versions. + * + * @param unmapped clientbound packet type + * @param mapped clientbound packet type + * @param mapped serverbound packet type + * @param unmapped serverbound packet type + */ +public abstract class AbstractProtocol implements Protocol { protected final Class unmappedClientboundPacketType; protected final Class mappedClientboundPacketType; protected final Class mappedServerboundPacketType; protected final Class unmappedServerboundPacketType; + private final PacketTypesProvider packetTypesProvider; + private final PacketMappings serverboundMappings = PacketMappings.arrayMappings(); + private final PacketMappings clientboundMappings = PacketMappings.arrayMappings(); + private final Map, Object> storedObjects = new HashMap<>(); private boolean initialized; protected AbstractProtocol() { @@ -65,11 +82,12 @@ public abstract class AbstractProtocol newClientboundPackets = new HashMap<>(newConstants.length); - for (C2 newConstant : newConstants) { - newClientboundPackets.put(newConstant.getName(), newConstant); - } + private void registerPacketIdChanges( + Map> unmappedPacketTypes, + Map> mappedPacketTypes, + Predicate registeredPredicate, + BiConsumer registerConsumer + ) { + for (Map.Entry> entry : mappedPacketTypes.entrySet()) { + PacketTypeMap mappedTypes = entry.getValue(); + for (U unmappedType : unmappedPacketTypes.get(entry.getKey()).types()) { + M mappedType = mappedTypes.typeByName(unmappedType.getName()); + if (mappedType == null) { + // No mapped packet of the same name exists + Preconditions.checkArgument(registeredPredicate.test(unmappedType), + "Packet %s in %s has no mapping - it needs to be manually cancelled or remapped", unmappedType, getClass()); + continue; + } - for (C1 packet : unmappedClientboundPacketType.getEnumConstants()) { - C2 mappedPacket = newClientboundPackets.get(packet.getName()); - if (mappedPacket == null) { - // Packet doesn't exist on new client - Preconditions.checkArgument(hasRegisteredClientbound(packet), - "Packet " + packet + " in " + getClass().getSimpleName() + " has no mapping - it needs to be manually cancelled or remapped!"); - continue; - } - - if (!hasRegisteredClientbound(packet)) { - registerClientbound(packet, mappedPacket); + // Register if no custom handler exists and ids are different + if (unmappedType.getId() != mappedType.getId() && !registeredPredicate.test(unmappedType)) { + registerConsumer.accept(unmappedType, mappedType); + } } } } - protected void registerServerboundChannelIdChanges() { - S1[] oldConstants = mappedServerboundPacketType.getEnumConstants(); - Map oldServerboundConstants = new HashMap<>(oldConstants.length); - for (S1 oldConstant : oldConstants) { - oldServerboundConstants.put(oldConstant.getName(), oldConstant); - } - - for (S2 packet : unmappedServerboundPacketType.getEnumConstants()) { - S1 mappedPacket = oldServerboundConstants.get(packet.getName()); - if (mappedPacket == null) { - // Packet doesn't exist on old server - Preconditions.checkArgument(hasRegisteredServerbound(packet), - "Packet " + packet + " in " + getClass().getSimpleName() + " has no mapping - it needs to be manually cancelled or remapped!"); - continue; - } - - if (!hasRegisteredServerbound(packet)) { - registerServerbound(packet, mappedPacket); - } - } - } - - /** - * Register the packets for this protocol. To be overriden. - */ - protected void registerPackets() { - } - @Override public final void loadMappingData() { getMappingData().load(); onMappingDataLoaded(); } + /** + * Register the packets for this protocol. To be overriden. + */ + protected void registerPackets() { + } + /** * Called after {@link #loadMappingData()} is called; load extra mapping data for the protocol. *

@@ -153,65 +162,70 @@ public abstract class AbstractProtocol createPacketTypesProvider() { + return new SimplePacketTypesProvider<>( + packetTypeMap(unmappedClientboundPacketType), + packetTypeMap(mappedClientboundPacketType), + packetTypeMap(mappedServerboundPacketType), + packetTypeMap(unmappedServerboundPacketType) + ); + } + + private

Map> packetTypeMap(Class

packetTypeClass) { + if (packetTypeClass != null) { + Map> map = new EnumMap<>(State.class); + map.put(State.PLAY, PacketTypeMap.of(packetTypeClass)); + return map; + } + return Collections.emptyMap(); + } + + // --------------------------------------------------------------------------------- @Override public void registerServerbound(State state, int unmappedPacketId, int mappedPacketId, PacketHandler handler, boolean override) { - ProtocolPacket protocolPacket = new ProtocolPacket(state, unmappedPacketId, mappedPacketId, handler); - Packet packet = new Packet(state, mappedPacketId); - if (!override && serverbound.containsKey(packet)) { - Via.getPlatform().getLogger().log(Level.WARNING, packet + " already registered!" + + Preconditions.checkArgument(unmappedPacketId != -1, "Unmapped packet id cannot be -1"); + PacketMapping packetMapping = PacketMapping.of(mappedPacketId, handler); + if (!override && serverboundMappings.hasMapping(state, unmappedPacketId)) { + Via.getPlatform().getLogger().log(Level.WARNING, unmappedPacketId + " already registered!" + " If this override is intentional, set override to true. Stacktrace: ", new Exception()); } - serverbound.put(packet, protocolPacket); + serverboundMappings.addMapping(state, unmappedPacketId, packetMapping); } @Override - public void cancelServerbound(State state, int unmappedPacketId, int mappedPacketId) { - registerServerbound(state, unmappedPacketId, mappedPacketId, PacketWrapper::cancel); - } - - @Override - public void cancelServerbound(State state, int mappedPacketId) { - cancelServerbound(state, -1, mappedPacketId); - } - - @Override - public void cancelClientbound(State state, int unmappedPacketId, int mappedPacketId) { - registerClientbound(state, unmappedPacketId, mappedPacketId, PacketWrapper::cancel); - } - - @Override - public void cancelClientbound(State state, int unmappedPacketId) { - cancelClientbound(state, unmappedPacketId, -1); + public void cancelServerbound(State state, int unmappedPacketId) { + registerServerbound(state, unmappedPacketId, unmappedPacketId, PacketWrapper::cancel); } @Override public void registerClientbound(State state, int unmappedPacketId, int mappedPacketId, PacketHandler handler, boolean override) { - ProtocolPacket protocolPacket = new ProtocolPacket(state, unmappedPacketId, mappedPacketId, handler); - Packet packet = new Packet(state, unmappedPacketId); - if (!override && clientbound.containsKey(packet)) { - Via.getPlatform().getLogger().log(Level.WARNING, packet + " already registered!" + + Preconditions.checkArgument(unmappedPacketId != -1, "Unmapped packet id cannot be -1"); + PacketMapping packetMapping = PacketMapping.of(mappedPacketId, handler); + if (!override && clientboundMappings.hasMapping(state, unmappedPacketId)) { + Via.getPlatform().getLogger().log(Level.WARNING, unmappedPacketId + " already registered!" + " If override is intentional, set override to true. Stacktrace: ", new Exception()); } - clientbound.put(packet, protocolPacket); + clientboundMappings.addMapping(state, unmappedPacketId, packetMapping); } + @Override + public void cancelClientbound(State state, int unmappedPacketId) { + registerClientbound(state, unmappedPacketId, unmappedPacketId, PacketWrapper::cancel); + } + + // --------------------------------------------------------------------------------- @Override public void registerClientbound(C1 packetType, @Nullable PacketHandler handler) { - checkPacketType(packetType, unmappedClientboundPacketType == null || packetType.getClass() == unmappedClientboundPacketType); - - //noinspection unchecked - C2 mappedPacket = unmappedClientboundPacketType == mappedClientboundPacketType ? (C2) packetType - : Arrays.stream(mappedClientboundPacketType.getEnumConstants()).filter(en -> en.getName().equals(packetType.getName())).findAny().orElse(null); - Preconditions.checkNotNull(mappedPacket, "Packet type " + packetType + " in " + packetType.getClass().getSimpleName() + " could not be automatically mapped!"); - - registerClientbound(packetType, mappedPacket, handler); + PacketTypeMap mappedPacketTypes = packetTypesProvider.mappedClientboundPacketTypes().get(packetType.state()); + C2 mappedPacketType = mappedPacketType(packetType, mappedPacketTypes, unmappedClientboundPacketType, mappedClientboundPacketType); + registerClientbound(packetType, mappedPacketType, handler); } @Override public void registerClientbound(C1 packetType, @Nullable C2 mappedPacketType, @Nullable PacketHandler handler, boolean override) { - register(clientbound, packetType, mappedPacketType, unmappedClientboundPacketType, mappedClientboundPacketType, handler, override); + register(clientboundMappings, packetType, mappedPacketType, unmappedClientboundPacketType, mappedClientboundPacketType, handler, override); } @Override @@ -221,19 +235,14 @@ public abstract class AbstractProtocol en.getName().equals(packetType.getName())).findAny().orElse(null); - Preconditions.checkNotNull(mappedPacket, "Packet type " + packetType + " in " + packetType.getClass().getSimpleName() + " could not be automatically mapped!"); - - registerServerbound(packetType, mappedPacket, handler); + PacketTypeMap mappedPacketTypes = packetTypesProvider.mappedServerboundPacketTypes().get(packetType.state()); + S1 mappedPacketType = mappedPacketType(packetType, mappedPacketTypes, unmappedServerboundPacketType, mappedServerboundPacketType); + registerServerbound(packetType, mappedPacketType, handler); } @Override public void registerServerbound(S2 packetType, @Nullable S1 mappedPacketType, @Nullable PacketHandler handler, boolean override) { - register(serverbound, packetType, mappedPacketType, unmappedServerboundPacketType, mappedServerboundPacketType, handler, override); + register(serverboundMappings, packetType, mappedPacketType, unmappedServerboundPacketType, mappedServerboundPacketType, handler, override); } @Override @@ -241,66 +250,64 @@ public abstract class AbstractProtocol packetMap, PacketType packetType, @Nullable PacketType mappedPacketType, - Class unmappedPacketEnum, Class mappedPacketEnum, + private void register(PacketMappings packetMappings, PacketType packetType, @Nullable PacketType mappedPacketType, + Class unmappedPacketClass, Class mappedPacketClass, @Nullable PacketHandler handler, boolean override) { - checkPacketType(packetType, unmappedPacketEnum == null || packetType.getClass() == unmappedPacketEnum); - checkPacketType(mappedPacketType, mappedPacketType == null || mappedPacketEnum == null || mappedPacketType.getClass() == mappedPacketEnum); - Preconditions.checkArgument(mappedPacketType == null || packetType.state() == mappedPacketType.state(), "Packet type state does not match mapped packet type state"); + checkPacketType(packetType, unmappedPacketClass == null || unmappedPacketClass.isInstance(packetType)); + if (mappedPacketType != null) { + checkPacketType(mappedPacketType, mappedPacketClass == null || mappedPacketClass.isInstance(mappedPacketType)); + Preconditions.checkArgument(packetType.state() == mappedPacketType.state(), + "Packet type state does not match mapped packet type state"); + Preconditions.checkArgument(packetType.direction() == mappedPacketType.direction(), + "Packet type direction does not match mapped packet type state"); + } - ProtocolPacket protocolPacket = new ProtocolPacket(packetType.state(), packetType, mappedPacketType, handler); - Packet packet = new Packet(packetType.state(), packetType.getId()); - if (!override && packetMap.containsKey(packet)) { - Via.getPlatform().getLogger().log(Level.WARNING, packet + " already registered!" + + PacketMapping packetMapping = PacketMapping.of(mappedPacketType, handler); + if (!override && packetMappings.hasMapping(packetType)) { + Via.getPlatform().getLogger().log(Level.WARNING, packetType + " already registered!" + " If override is intentional, set override to true. Stacktrace: ", new Exception()); } - packetMap.put(packet, protocolPacket); + packetMappings.addMapping(packetType, packetMapping); } - @Override - public boolean hasRegisteredClientbound(C1 packetType) { - return hasRegisteredClientbound(packetType.state(), packetType.getId()); - } + private static M mappedPacketType(U packetType, PacketTypeMap mappedTypes, Class unmappedPacketTypeClass, Class mappedPacketTypeClass) { + Preconditions.checkNotNull(packetType); + checkPacketType(packetType, unmappedPacketTypeClass == null || unmappedPacketTypeClass.isInstance(packetType)); + if (unmappedPacketTypeClass == mappedPacketTypeClass) { + //noinspection unchecked + return (M) packetType; + } - @Override - public boolean hasRegisteredServerbound(S2 packetType) { - return hasRegisteredServerbound(packetType.state(), packetType.getId()); + Preconditions.checkNotNull(mappedTypes, "Mapped packet types not provided for state %s of type class %s", packetType.state(), mappedPacketTypeClass); + M mappedType = mappedTypes.typeByName(packetType.getName()); + if (mappedType != null) { + return mappedType; + } + throw new IllegalArgumentException("Packet type " + packetType + " in " + packetType.getClass().getSimpleName() + " could not be automatically mapped!"); } @Override public boolean hasRegisteredClientbound(State state, int unmappedPacketId) { - Packet packet = new Packet(state, unmappedPacketId); - return clientbound.containsKey(packet); + return clientboundMappings.hasMapping(state, unmappedPacketId); } @Override public boolean hasRegisteredServerbound(State state, int unmappedPacketId) { - Packet packet = new Packet(state, unmappedPacketId); - return serverbound.containsKey(packet); + return serverboundMappings.hasMapping(state, unmappedPacketId); } @Override public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception { - Packet statePacket = new Packet(state, packetWrapper.getId()); - Map packetMap = direction == Direction.CLIENTBOUND ? clientbound : serverbound; - ProtocolPacket protocolPacket = packetMap.get(statePacket); - if (protocolPacket == null) { + PacketMappings mappings = direction == Direction.CLIENTBOUND ? clientboundMappings : serverboundMappings; + int unmappedId = packetWrapper.getId(); + PacketMapping packetMapping = mappings.mappedPacket(state, unmappedId); + if (packetMapping == null) { return; } - // Write packet id - int unmappedId = packetWrapper.getId(); - if (protocolPacket.isMappedOverTypes()) { - packetWrapper.setPacketType(protocolPacket.getMappedPacketType()); - } else { - int mappedId = direction == Direction.CLIENTBOUND ? protocolPacket.getNewId() : protocolPacket.getOldId(); - if (unmappedId != mappedId) { - //noinspection deprecation - packetWrapper.setId(mappedId); - } - } - - PacketHandler handler = protocolPacket.getRemapper(); + // Change packet id and apply remapping + packetMapping.applyType(packetWrapper); + PacketHandler handler = packetMapping.handler(); if (handler != null) { try { handler.handle(packetWrapper); @@ -333,10 +340,8 @@ public abstract class AbstractProtocol packetTypeClass = state == State.PLAY ? (direction == Direction.CLIENTBOUND ? unmappedClientboundPacketType : unmappedServerboundPacketType) : null; - if (packetTypeClass != null) { - PacketType[] enumConstants = packetTypeClass.getEnumConstants(); - PacketType packetType = unmappedPacketId < enumConstants.length && unmappedPacketId >= 0 ? enumConstants[unmappedPacketId] : null; + PacketType packetType = direction == Direction.CLIENTBOUND ? unmappedClientboundPacketType(state, unmappedPacketId) : unmappedServerboundPacketType(state, unmappedPacketId); + if (packetType != null) { Via.getPlatform().getLogger().warning("ERROR IN " + getClass().getSimpleName() + " IN REMAP OF " + packetType + " (" + toNiceHex(unmappedPacketId) + ")"); } else { Via.getPlatform().getLogger().warning("ERROR IN " + getClass().getSimpleName() @@ -345,6 +350,16 @@ public abstract class AbstractProtocol map = packetTypesProvider.unmappedClientboundPacketTypes().get(state); + return map != null ? map.typeById(packetId) : null; + } + + private @Nullable S2 unmappedServerboundPacketType(final State state, final int packetId) { + PacketTypeMap map = packetTypesProvider.unmappedServerboundPacketTypes().get(state); + return map != null ? map.typeById(packetId) : null; + } + public static String toNiceHex(int id) { String hex = Integer.toHexString(id).toUpperCase(); return (hex.length() == 1 ? "0x0" : "0x") + hex; @@ -355,9 +370,9 @@ public abstract class AbstractProtocol packetTypesProvider() { + return packetTypesProvider; + } + @Override public String toString() { return "Protocol:" + getClass().getSimpleName(); } - - public static final class Packet { - private final State state; - private final int packetId; - - public Packet(State state, int packetId) { - this.state = state; - this.packetId = packetId; - } - - public State getState() { - return state; - } - - public int getPacketId() { - return packetId; - } - - @Override - public String toString() { - return "Packet{" + "state=" + state + ", packetId=" + packetId + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Packet that = (Packet) o; - return packetId == that.packetId && state == that.state; - } - - @Override - public int hashCode() { - int result = state != null ? state.hashCode() : 0; - result = 31 * result + packetId; - return result; - } - } - - public static final class ProtocolPacket { - private final State state; - private final int oldId; - private final int newId; - private final PacketType unmappedPacketType; - private final PacketType mappedPacketType; - private final PacketHandler handler; - - @Deprecated - public ProtocolPacket(State state, int oldId, int newId, @Nullable PacketHandler handler) { - this.state = state; - this.oldId = oldId; - this.newId = newId; - this.handler = handler; - this.unmappedPacketType = null; - this.mappedPacketType = null; - } - - public ProtocolPacket(State state, PacketType unmappedPacketType, @Nullable PacketType mappedPacketType, @Nullable PacketHandler handler) { - this.state = state; - this.unmappedPacketType = unmappedPacketType; - if (unmappedPacketType.direction() == Direction.CLIENTBOUND) { - this.oldId = unmappedPacketType.getId(); - this.newId = mappedPacketType != null ? mappedPacketType.getId() : -1; - } else { - // Serverbound switcheroo in old vs. new id caused issues and was counterintuitive - this.oldId = mappedPacketType != null ? mappedPacketType.getId() : -1; - this.newId = unmappedPacketType.getId(); - } - this.mappedPacketType = mappedPacketType; - this.handler = handler; - } - - public State getState() { - return state; - } - - @Deprecated - public int getOldId() { - return oldId; - } - - @Deprecated - public int getNewId() { - return newId; - } - - /** - * Returns the unmapped packet type, or null if mapped over ids. - * This is NOT the same as calling {@link #getOldId()} (think of unmapped vs. old in 1.17→1.16). - * - * @return unmapped packet type, or null if mapped over ids - */ - @Nullable - public PacketType getUnmappedPacketType() { - return unmappedPacketType; - } - - /** - * Returns the mapped packet type, or null if mapped over ids or mapped to no packet type. - * This is NOT the same as calling {@link #getNewId()} (think of mapped vs. new in 1.17→1.16). - * - * @return new packet type, or null if mapped over ids or mapped to no packet type - */ - @Nullable - public PacketType getMappedPacketType() { - return mappedPacketType; - } - - public boolean isMappedOverTypes() { - return unmappedPacketType != null; - } - - @Nullable - public PacketHandler getRemapper() { - return handler; - } - - @Override - public String toString() { - return "ProtocolPacket{" + - "state=" + state + - ", oldId=" + oldId + - ", newId=" + newId + - ", unmappedPacketType=" + unmappedPacketType + - ", mappedPacketType=" + mappedPacketType + - ", handler=" + handler + - '}'; - } - } - - public Map getClientbound() { - return clientbound; - } - - public Map getServerbound() { - return serverbound; - } } diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/Protocol.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/Protocol.java index 6123015bc..78e5dc4d6 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/Protocol.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/Protocol.java @@ -195,7 +195,9 @@ public interface Protocol= 0 && unmappedId < packets.length) { + return packets[unmappedId]; + } + return null; + } + + @Override + public void addMapping(final State state, final int unmappedId, final PacketMapping mapping) { + final int ordinal = state.ordinal(); + PacketMapping[] packets = this.packets[ordinal]; + if (packets == null) { + packets = new PacketMapping[unmappedId + 8]; + this.packets[ordinal] = packets; + } else if (unmappedId >= packets.length) { + packets = Arrays.copyOf(packets, unmappedId + 32); + this.packets[ordinal] = packets; + } + + packets[unmappedId] = mapping; + } +} \ No newline at end of file diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketIdMapping.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketIdMapping.java new file mode 100644 index 000000000..d0d053baa --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketIdMapping.java @@ -0,0 +1,48 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.mapping; + +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class PacketIdMapping implements PacketMapping { + private final int mappedPacketId; + private final PacketHandler handler; + + PacketIdMapping(int mappedPacketId, @Nullable PacketHandler handler) { + this.mappedPacketId = mappedPacketId; + this.handler = handler; + } + + @Override + public void applyType(final PacketWrapper wrapper) { + //noinspection deprecation + wrapper.setId(mappedPacketId); + } + + @Override + public @Nullable PacketHandler handler() { + return handler; + } +} \ No newline at end of file diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMapping.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMapping.java new file mode 100644 index 000000000..c50c8334c --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMapping.java @@ -0,0 +1,56 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.mapping; + +import com.viaversion.viaversion.api.protocol.packet.PacketType; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Packet mapping over packet types or ids containing a packet transformer. + */ +public interface PacketMapping { + + /** + * Applies the changed packet type or id to the given packet wrapper. + * + * @param wrapper packet wrapper + */ + void applyType(PacketWrapper wrapper); + + /** + * Returns a packet transformer to transform a packet from one protocol version to another. + * + * @return packet transformer, or null if no action has to be taken + */ + @Nullable PacketHandler handler(); + + static PacketMapping of(final int mappedPacketId, @Nullable final PacketHandler handler) { + return new PacketIdMapping(mappedPacketId, handler); + } + + static PacketMapping of(@Nullable final PacketType mappedPacketType, @Nullable final PacketHandler handler) { + return new PacketTypeMapping(mappedPacketType, handler); + } +} \ No newline at end of file diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMappings.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMappings.java new file mode 100644 index 000000000..a72b0b9dd --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketMappings.java @@ -0,0 +1,86 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.mapping; + +import com.viaversion.viaversion.api.protocol.packet.PacketType; +import com.viaversion.viaversion.api.protocol.packet.State; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Mappings to transform packets between two protocol versions. + */ +public interface PacketMappings { + + /** + * Returns a packet mapping for the given packet. + * + * @param state protocol stae + * @param unmappedId unmapped packet id + * @return packet mapping if present + */ + @Nullable PacketMapping mappedPacket(State state, int unmappedId); + + /** + * Returns whether the given packet type has a mapping. + * + * @param packetType unmapped packet type + * @return whether the given packet type has a mapping + */ + default boolean hasMapping(PacketType packetType) { + return mappedPacket(packetType.state(), packetType.getId()) != null; + } + + /** + * Returns whether the given packet type has a mapping. + * + * @param state protocol state + * @param unmappedId unmapped packet id + * @return whether the given packet type has a mapping + */ + default boolean hasMapping(State state, int unmappedId) { + return mappedPacket(state, unmappedId) != null; + } + + /** + * Adds a packet mapping. + * + * @param packetType unmapped packet type + * @param mapping packet mapping + */ + default void addMapping(PacketType packetType, PacketMapping mapping) { + addMapping(packetType.state(), packetType.getId(), mapping); + } + + /** + * Adds a packet mapping. + * + * @param state protocol state + * @param unmappedId unmapped packet id + * @param mapping packet mapping + */ + void addMapping(State state, int unmappedId, PacketMapping mapping); + + static PacketMappings arrayMappings() { + return new PacketArrayMappings(); + } +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketTypeMapping.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketTypeMapping.java new file mode 100644 index 000000000..13ad50e14 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/mapping/PacketTypeMapping.java @@ -0,0 +1,54 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.mapping; + +import com.viaversion.viaversion.api.protocol.packet.PacketType; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class PacketTypeMapping implements PacketMapping { + private final PacketType mappedPacketType; + private final PacketHandler handler; + + PacketTypeMapping(@Nullable PacketType mappedPacketType, @Nullable PacketHandler handler) { + this.mappedPacketType = mappedPacketType; + this.handler = handler; + } + + @Override + public void applyType(PacketWrapper wrapper) { + if (mappedPacketType != null) { + wrapper.setPacketType(mappedPacketType); + } + } + + @Override + public @Nullable PacketHandler handler() { + return handler; + } +} + + + + diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeArrayMap.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeArrayMap.java new file mode 100644 index 000000000..42996c019 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeArrayMap.java @@ -0,0 +1,53 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.provider; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class PacketTypeArrayMap

implements PacketTypeMap

{ + private final Map packetsByName; + private final P[] packets; + + PacketTypeArrayMap(Map packetsByName, P[] packets) { + this.packetsByName = packetsByName; + this.packets = packets; + } + + @Override + public @Nullable P typeByName(String packetTypeName) { + return packetsByName.get(packetTypeName); + } + + @Override + public @Nullable P typeById(int packetTypeId) { + return packetTypeId >= 0 && packetTypeId < packets.length ? packets[packetTypeId] : null; + } + + @Override + public Collection

types() { + return Arrays.asList(packets); + } +} \ No newline at end of file diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMap.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMap.java new file mode 100644 index 000000000..e481f30f8 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMap.java @@ -0,0 +1,77 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.provider; + +import com.viaversion.viaversion.api.protocol.packet.PacketType; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import org.checkerframework.checker.nullness.qual.Nullable; + +public interface PacketTypeMap

{ + + /** + * Returns the packet type by the given name. + * + * @param packetTypeName packet type name + * @return packet type if present + */ + @Nullable P typeByName(String packetTypeName); + + /** + * Returns the packet type by the given id. + * + * @param packetTypeId packet type id + * @return packet type if present + */ + @Nullable P typeById(int packetTypeId); + + /** + * Returns a collection of all contained packet types. + * + * @return collection of all packet types + */ + Collection

types(); + + static PacketTypeMap of(final Class enumClass) { + if (!enumClass.isEnum()) { + throw new IllegalArgumentException("Given class is not an enum"); + } + + final S[] types = enumClass.getEnumConstants(); + final Map byName = new HashMap<>(types.length); + for (final S type : types) { + byName.put(type.getName(), type); + } + return of(byName, types); + } + + static PacketTypeMap of(final Map packetsByName, final Int2ObjectMap packetsById) { + return new PacketTypeMapMap<>(packetsByName, packetsById); + } + + static PacketTypeMap of(final Map packetsByName, final T[] packets) { + return new PacketTypeArrayMap<>(packetsByName, packets); + } +} \ No newline at end of file diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMapMap.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMapMap.java new file mode 100644 index 000000000..b3ba7a762 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypeMapMap.java @@ -0,0 +1,54 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.provider; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import java.util.Collection; +import java.util.Map; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class PacketTypeMapMap

implements PacketTypeMap

{ + private final Map packetsByName; + private final Int2ObjectMap

packetsById; + + PacketTypeMapMap(Map packetsByName, + Int2ObjectMap

packetsById) { + this.packetsByName = packetsByName; + this.packetsById = packetsById; + } + + @Override + public @Nullable P typeByName(String packetTypeName) { + return packetsByName.get(packetTypeName); + } + + @Override + public @Nullable P typeById(int packetTypeId) { + return packetsById.get(packetTypeId); + } + + @Override + public Collection

types() { + return packetsById.values(); + } +} \ No newline at end of file diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypesProvider.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypesProvider.java new file mode 100644 index 000000000..9c3caa203 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/PacketTypesProvider.java @@ -0,0 +1,61 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.provider; + +import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; +import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType; +import com.viaversion.viaversion.api.protocol.packet.State; +import java.util.Map; + +public interface PacketTypesProvider { + + /** + * Returns a map of all unmapped clientbound packet types that are expected to be used within a protocol. + * This means that if {@code C1} encompasses more than just {@link State#PLAY} packets, the other types are included as well. + * + * @return map of unmapped clientbound packet types + */ + Map> unmappedClientboundPacketTypes(); + + /** + * Return a map of all unmapped serverbound packet types that are expected to be used within the protocol. + * This means that if {@code S2} encompasses more than just {@link State#PLAY} packets, the other types have to be included as well. + * + * @return map of unmapped serverbound packet types + */ + Map> unmappedServerboundPacketTypes(); + + /** + * Returns a map of all mapped clientbound packet types that are expected to be used within the protocol. + * + * @return map of mapped clientbound packet types + */ + Map> mappedClientboundPacketTypes(); + + /** + * Returns a map of all mapped serverbound packet types that are expected to be used within the protocol. + * + * @return map of mapped serverbound packet types + */ + Map> mappedServerboundPacketTypes(); +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/SimplePacketTypesProvider.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/SimplePacketTypesProvider.java new file mode 100644 index 000000000..40da41c0d --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/provider/SimplePacketTypesProvider.java @@ -0,0 +1,67 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.protocol.packet.provider; + +import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; +import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType; +import com.viaversion.viaversion.api.protocol.packet.State; +import java.util.Map; + +public final class SimplePacketTypesProvider implements PacketTypesProvider { + private final Map> unmappedClientboundPacketTypes; + private final Map> mappedClientboundPacketTypes; + private final Map> mappedServerboundPacketTypes; + private final Map> unmappedServerboundPacketTypes; + + public SimplePacketTypesProvider( + Map> unmappedClientboundPacketTypes, + Map> mappedClientboundPacketTypes, + Map> mappedServerboundPacketTypes, + Map> unmappedServerboundPacketTypes + ) { + this.unmappedClientboundPacketTypes = unmappedClientboundPacketTypes; + this.mappedClientboundPacketTypes = mappedClientboundPacketTypes; + this.mappedServerboundPacketTypes = mappedServerboundPacketTypes; + this.unmappedServerboundPacketTypes = unmappedServerboundPacketTypes; + } + + @Override + public Map> unmappedClientboundPacketTypes() { + return unmappedClientboundPacketTypes; + } + + @Override + public Map> mappedClientboundPacketTypes() { + return mappedClientboundPacketTypes; + } + + @Override + public Map> mappedServerboundPacketTypes() { + return mappedServerboundPacketTypes; + } + + @Override + public Map> unmappedServerboundPacketTypes() { + return unmappedServerboundPacketTypes; + } +} diff --git a/common/src/test/java/com/viaversion/viaversion/common/protocol/remapper/ProtocolHandlersTest.java b/common/src/test/java/com/viaversion/viaversion/common/protocol/remapper/ProtocolHandlersTest.java deleted file mode 100644 index 907d68f67..000000000 --- a/common/src/test/java/com/viaversion/viaversion/common/protocol/remapper/ProtocolHandlersTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion - * Copyright (C) 2023 ViaVersion and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.viaversion.viaversion.common.protocol.remapper; - -import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.protocol.AbstractProtocol; -import com.viaversion.viaversion.api.protocol.AbstractProtocol.ProtocolPacket; -import com.viaversion.viaversion.api.protocol.Protocol; -import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; -import com.viaversion.viaversion.common.dummy.DummyInitializer; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -public class ProtocolHandlersTest { - - private static final Logger LOGGER = Logger.getGlobal(); - private static final boolean WARN = false; - - @BeforeAll - static void init() { - DummyInitializer.init(); - } - - @Test - void testHandlersSize() { - if (!WARN) { - return; - } - - for (final Protocol protocol : Via.getManager().getProtocolManager().getProtocols()) { - if (!(protocol instanceof AbstractProtocol)) { - continue; - } - - final AbstractProtocol abstractProtocol = (AbstractProtocol) protocol; - final List protocolMappings = new ArrayList<>(abstractProtocol.getClientbound().values()); - protocolMappings.addAll(abstractProtocol.getServerbound().values()); - - for (final ProtocolPacket protocolMapping : protocolMappings) { - if (!(protocolMapping.getRemapper() instanceof PacketHandlers)) { - continue; - } - - final PacketHandlers packetHandlers = (PacketHandlers) protocolMapping.getRemapper(); - if (packetHandlers.handlersSize() == 0) { - LOGGER.warning("PacketHandlers instance has no handlers: " + protocolMapping + " in " + protocol.getClass().getSimpleName()); - } else if (packetHandlers.handlersSize() == 1) { - LOGGER.warning("PacketHandlers instance only has a single handler; consider using a PacketHandler lambda instead of extending PacketHandlers: " - + protocolMapping + " in " + protocol.getClass().getSimpleName()); - } - } - } - } -}