From c1ae6f14fce16f04e7a8ba6c84d1fce1f797a1c6 Mon Sep 17 00:00:00 2001 From: Dan Mulloy Date: Wed, 18 May 2016 20:47:08 -0400 Subject: [PATCH] Add some debug info for #202 Also /really/ make sure it's only called once --- .../comphenix/protocol/ProtocolLogger.java | 10 + .../injector/netty/NettyProtocolRegistry.java | 219 +++--- .../injector/packet/PacketRegistry.java | 641 +++++++++--------- 3 files changed, 441 insertions(+), 429 deletions(-) diff --git a/modules/API/src/main/java/com/comphenix/protocol/ProtocolLogger.java b/modules/API/src/main/java/com/comphenix/protocol/ProtocolLogger.java index 793db821..bb2a09d1 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/ProtocolLogger.java +++ b/modules/API/src/main/java/com/comphenix/protocol/ProtocolLogger.java @@ -32,6 +32,10 @@ public class ProtocolLogger { ProtocolLogger.logger = plugin.getLogger(); } + private static boolean isDebugEnabled() { + return ProtocolLibrary.getConfig().isDebug(); + } + /** * Logs a message to console with a given level. * @param level Logging level @@ -60,4 +64,10 @@ public class ProtocolLogger { public static void log(Level level, String message, Throwable ex) { logger.log(level, message, ex); } + + public static void debug(String message, Object... args) { + if (isDebugEnabled()) { + log("[Debug] " + message, args); + } + } } \ No newline at end of file diff --git a/modules/API/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolRegistry.java b/modules/API/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolRegistry.java index e06f7a10..55a339ba 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolRegistry.java +++ b/modules/API/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolRegistry.java @@ -1,108 +1,111 @@ -/** - * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. - * Copyright (C) 2015 dmulloy2 - * - * 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ -package com.comphenix.protocol.injector.netty; - -import java.util.Map; -import java.util.Map.Entry; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Protocol; -import com.comphenix.protocol.PacketType.Sender; -import com.comphenix.protocol.injector.netty.ProtocolRegistry; -import com.comphenix.protocol.injector.packet.MapContainer; -import com.comphenix.protocol.reflect.StructureModifier; -import com.google.common.collect.Maps; - -/** - * @author dmulloy2 - */ - -public class NettyProtocolRegistry extends ProtocolRegistry { - - public NettyProtocolRegistry() { - super(); - } - - @Override - protected synchronized void initialize() { - Object[] protocols = enumProtocol.getEnumConstants(); - - // ID to Packet class maps - Map>> serverMaps = Maps.newLinkedHashMap(); - Map>> clientMaps = Maps.newLinkedHashMap(); - - Register result = new Register(); - StructureModifier modifier = null; - - // Iterate through the protocols - for (Object protocol : protocols) { - if (modifier == null) - modifier = new StructureModifier(protocol.getClass().getSuperclass(), false); - StructureModifier>>> maps = modifier.withTarget(protocol).withType(Map.class); - for (Entry>> entry : maps.read(0).entrySet()) { - String direction = entry.getKey().toString(); - if (direction.contains("CLIENTBOUND")) { // Sent by Server - serverMaps.put(protocol, entry.getValue()); - } else if (direction.contains("SERVERBOUND")) { // Sent by Client - clientMaps.put(protocol, entry.getValue()); - } - } - } - - // Maps we have to occasionally check have changed - for (Map> map : serverMaps.values()) { - result.containers.add(new MapContainer(map)); - } - - for (Map> map : clientMaps.values()) { - result.containers.add(new MapContainer(map)); - } - - for (int i = 0; i < protocols.length; i++) { - Object protocol = protocols[i]; - Enum enumProtocol = (Enum) protocol; - Protocol equivalent = Protocol.fromVanilla(enumProtocol); - - // Associate known types - if (serverMaps.containsKey(protocol)) - associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER); - if (clientMaps.containsKey(protocol)) - associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT); - } - - // Exchange (thread safe, as we have only one writer) - this.register = result; - } - - @Override - protected void associatePackets(Register register, Map> lookup, Protocol protocol, Sender sender) { - for (Entry> entry : lookup.entrySet()) { - PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue()); - - try { - register.typeToClass.put(type, entry.getValue()); - - if (sender == Sender.SERVER) - register.serverPackets.add(type); - if (sender == Sender.CLIENT) - register.clientPackets.add(type); - } catch (IllegalArgumentException ex) { - // Sometimes this happens with fake packets, just ignore it - } - } - } -} +/** + * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. + * Copyright (C) 2015 dmulloy2 + * + * 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ +package com.comphenix.protocol.injector.netty; + +import java.util.Map; +import java.util.Map.Entry; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLogger; +import com.comphenix.protocol.PacketType.Protocol; +import com.comphenix.protocol.PacketType.Sender; +import com.comphenix.protocol.injector.netty.ProtocolRegistry; +import com.comphenix.protocol.injector.packet.MapContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import com.google.common.collect.Maps; + +/** + * @author dmulloy2 + */ + +public class NettyProtocolRegistry extends ProtocolRegistry { + + public NettyProtocolRegistry() { + super(); + } + + @Override + protected synchronized void initialize() { + ProtocolLogger.debug("NettyProtocolRegistry#initialize()"); // Debug for issue #202 + + Object[] protocols = enumProtocol.getEnumConstants(); + + // ID to Packet class maps + Map>> serverMaps = Maps.newLinkedHashMap(); + Map>> clientMaps = Maps.newLinkedHashMap(); + + Register result = new Register(); + StructureModifier modifier = null; + + // Iterate through the protocols + for (Object protocol : protocols) { + if (modifier == null) + modifier = new StructureModifier(protocol.getClass().getSuperclass(), false); + StructureModifier>>> maps = modifier.withTarget(protocol).withType(Map.class); + for (Entry>> entry : maps.read(0).entrySet()) { + String direction = entry.getKey().toString(); + if (direction.contains("CLIENTBOUND")) { // Sent by Server + serverMaps.put(protocol, entry.getValue()); + } else if (direction.contains("SERVERBOUND")) { // Sent by Client + clientMaps.put(protocol, entry.getValue()); + } + } + } + + // Maps we have to occasionally check have changed + for (Map> map : serverMaps.values()) { + result.containers.add(new MapContainer(map)); + } + + for (Map> map : clientMaps.values()) { + result.containers.add(new MapContainer(map)); + } + + for (int i = 0; i < protocols.length; i++) { + Object protocol = protocols[i]; + Enum enumProtocol = (Enum) protocol; + Protocol equivalent = Protocol.fromVanilla(enumProtocol); + + // Associate known types + if (serverMaps.containsKey(protocol)) + associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER); + if (clientMaps.containsKey(protocol)) + associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT); + } + + // Exchange (thread safe, as we have only one writer) + this.register = result; + } + + @Override + protected void associatePackets(Register register, Map> lookup, Protocol protocol, Sender sender) { + for (Entry> entry : lookup.entrySet()) { + PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue()); + + try { + register.typeToClass.put(type, entry.getValue()); + + if (sender == Sender.SERVER) + register.serverPackets.add(type); + if (sender == Sender.CLIENT) + register.clientPackets.add(type); + } catch (IllegalArgumentException ex) { + // Sometimes this happens with fake packets, just ignore it + } + } + } +} diff --git a/modules/API/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java b/modules/API/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java index 9d0d562d..979f5f87 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java +++ b/modules/API/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java @@ -1,322 +1,321 @@ -/* - * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. - * Copyright (C) 2012 Kristian S. Stangeland - * - * 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -package com.comphenix.protocol.injector.packet; - -import java.util.Collections; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Sender; -import com.comphenix.protocol.error.ReportType; -import com.comphenix.protocol.injector.netty.NettyProtocolRegistry; -import com.comphenix.protocol.injector.netty.ProtocolRegistry; -import com.comphenix.protocol.reflect.FieldAccessException; -import com.google.common.base.Function; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -/** - * Static packet registry in Minecraft. - * @author Kristian - */ -@SuppressWarnings("rawtypes") -public class PacketRegistry { - public static final ReportType REPORT_CANNOT_CORRECT_TROVE_MAP = new ReportType("Unable to correct no entry value."); - - public static final ReportType REPORT_INSUFFICIENT_SERVER_PACKETS = new ReportType("Too few server packets detected: %s"); - public static final ReportType REPORT_INSUFFICIENT_CLIENT_PACKETS = new ReportType("Too few client packets detected: %s"); - - // Two different packet registry - private static volatile ProtocolRegistry NETTY; - - // Cached for Netty - private static volatile Set LEGACY_SERVER_PACKETS; - private static volatile Set LEGACY_CLIENT_PACKETS; - private static volatile Map LEGACY_PREVIOUS_PACKETS; - - // Whether or not the registry has - private static boolean INITIALIZED; - - /** - * Initialize the packet registry. - */ - private static void initialize() { - if (INITIALIZED) { - // Make sure they were initialized - if (NETTY == null) - throw new IllegalStateException("No initialized registry."); - return; - } - - // Check for netty - NETTY = new NettyProtocolRegistry(); - } - - /** - * Determine if the given packet type is supported on the current server. - * @param type - the type to check. - * @return TRUE if it is, FALSE otherwise. - */ - public static boolean isSupported(PacketType type) { - initialize(); - return NETTY.getPacketTypeLookup().containsKey(type); - } - - /** - * Retrieve a map of every packet class to every ID. - *

- * Deprecated: Use {@link #getPacketToType()} instead. - * @return A map of packet classes and their corresponding ID. - */ - @Deprecated - public static Map getPacketToID() { - initialize(); - - @SuppressWarnings("unchecked") - Map result = (Map) Maps.transformValues( - NETTY.getPacketClassLookup(), - new Function() { - @Override - public Integer apply(PacketType type) { - return type.getLegacyId(); - }; - }); - return result; - } - - /** - * Retrieve a map of every packet class to the respective packet type. - * @return A map of packet classes and their corresponding packet type. - */ - public static Map getPacketToType() { - initialize(); - - @SuppressWarnings("unchecked") - Map result = (Map) NETTY.getPacketClassLookup(); - return result; - } - - /** - * Retrieve the injected proxy classes handlig each packet ID. - *

- * This is not supported in 1.7.2 and later. - * @return Injected classes. - */ - @Deprecated - public static Map getOverwrittenPackets() { - initialize(); - throw new IllegalStateException("Not supported on Netty."); - } - - /** - * Retrieve the vanilla classes handling each packet ID. - * @return Vanilla classes. - */ - @Deprecated - public static Map getPreviousPackets() { - initialize(); - - // Construct it first - if (LEGACY_PREVIOUS_PACKETS == null) { - Map map = Maps.newHashMap(); - - for (Entry> entry : NETTY.getPacketTypeLookup().entrySet()) { - map.put(entry.getKey().getLegacyId(), entry.getValue()); - } - LEGACY_PREVIOUS_PACKETS = Collections.unmodifiableMap(map); - } - return LEGACY_PREVIOUS_PACKETS; - } - - /** - * Retrieve every known and supported server packet. - *

- * Deprecated: Use {@link #getServerPacketTypes()} instead. - * @return An immutable set of every known server packet. - * @throws FieldAccessException If we're unable to retrieve the server packet data from Minecraft. - */ - @Deprecated - public static Set getServerPackets() throws FieldAccessException { - initialize(); - - if (LEGACY_SERVER_PACKETS == null) { - LEGACY_SERVER_PACKETS = toLegacy(NETTY.getServerPackets()); - } - return LEGACY_SERVER_PACKETS; - } - - /** - * Retrieve every known and supported server packet type. - * @return Every server packet type. - */ - public static Set getServerPacketTypes() { - initialize(); - - NETTY.synchronize(); - return NETTY.getServerPackets(); - } - - /** - * Retrieve every known and supported client packet. - *

- * Deprecated: Use {@link #getClientPacketTypes()} instead. - * @return An immutable set of every known client packet. - * @throws FieldAccessException If we're unable to retrieve the client packet data from Minecraft. - */ - @Deprecated - public static Set getClientPackets() throws FieldAccessException { - initialize(); - - if (LEGACY_CLIENT_PACKETS == null) { - LEGACY_CLIENT_PACKETS = toLegacy(NETTY.getClientPackets()); - } - return LEGACY_CLIENT_PACKETS; - } - - /** - * Retrieve every known and supported server packet type. - * @return Every server packet type. - */ - public static Set getClientPacketTypes() { - initialize(); - - NETTY.synchronize(); - return NETTY.getClientPackets(); - } - - /** - * Convert a set of packet types to a set of integers based on the legacy packet ID. - * @param types - packet type. - * @return Set of integers. - */ - public static Set toLegacy(Set types) { - Set result = Sets.newHashSet(); - - for (PacketType type : types) - result.add(type.getLegacyId()); - return Collections.unmodifiableSet(result); - } - - /** - * Convert a set of legacy packet IDs to packet types. - * @param ids - legacy packet IDs. - * @return Set of packet types. - */ - public static Set toPacketTypes(Set ids) { - return toPacketTypes(ids, null); - } - - /** - * Convert a set of legacy packet IDs to packet types. - * @param ids - legacy packet IDs. - * @param preference - the sender preference, if any. - * @return Set of packet types. - */ - public static Set toPacketTypes(Set ids, Sender preference) { - Set result = Sets.newHashSet(); - - for (int id : ids) - result.add(PacketType.fromLegacy(id, preference)); - return Collections.unmodifiableSet(result); - } - - /** - * Retrieves the correct packet class from a given packet ID. - *

- * Deprecated: Use {@link #getPacketClassFromType(PacketType)} instead. - * @param packetID - the packet ID. - * @return The associated class. - */ - @Deprecated - public static Class getPacketClassFromID(int packetID) { - initialize(); - return NETTY.getPacketTypeLookup().get(PacketType.findLegacy(packetID)); - } - - /** - * Retrieves the correct packet class from a given type. - * @param type - the packet type. - * @return The associated class. - */ - public static Class getPacketClassFromType(PacketType type) { - return getPacketClassFromType(type, false); - } - - /** - * Retrieves the correct packet class from a given type. - *

- * Note that forceVanillla will be ignored on MC 1.7.2 and later. - * @param type - the packet type. - * @param forceVanilla - whether or not to look for vanilla classes, not injected classes. - * @return The associated class. - */ - public static Class getPacketClassFromType(PacketType type, boolean forceVanilla) { - initialize(); - return NETTY.getPacketTypeLookup().get(type); - } - - /** - * Retrieves the correct packet class from a given packet ID. - *

- * This method has been deprecated. - * @param packetID - the packet ID. - * @param forceVanilla - whether or not to look for vanilla classes, not injected classes. - * @return The associated class. - */ - @Deprecated - public static Class getPacketClassFromID(int packetID, boolean forceVanilla) { - initialize(); - return getPacketClassFromID(packetID); - } - - /** - * Retrieve the packet ID of a given packet. - *

- * Deprecated: Use {@link #getPacketType(Class)}. - * @param packet - the type of packet to check. - * @return The legacy ID of the given packet. - * @throws IllegalArgumentException If this is not a valid packet. - */ - @Deprecated - public static int getPacketID(Class packet) { - initialize(); - return NETTY.getPacketClassLookup().get(packet).getLegacyId(); - } - - /** - * Retrieve the packet type of a given packet. - * @param packet - the class of the packet. - * @return The packet type, or NULL if not found. - */ - public static PacketType getPacketType(Class packet) { - return getPacketType(packet, null); - } - - /** - * Retrieve the packet type of a given packet. - * @param packet - the class of the packet. - * @param sender - the sender of the packet, or NULL. - * @return The packet type, or NULL if not found. - */ - public static PacketType getPacketType(Class packet, Sender sender) { - initialize(); - return NETTY.getPacketClassLookup().get(packet); - } +/* + * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. + * Copyright (C) 2012 Kristian S. Stangeland + * + * 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ + +package com.comphenix.protocol.injector.packet; + +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.PacketType.Sender; +import com.comphenix.protocol.error.ReportType; +import com.comphenix.protocol.injector.netty.NettyProtocolRegistry; +import com.comphenix.protocol.injector.netty.ProtocolRegistry; +import com.comphenix.protocol.reflect.FieldAccessException; +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +/** + * Static packet registry in Minecraft. + * @author Kristian + */ +@SuppressWarnings("rawtypes") +public class PacketRegistry { + public static final ReportType REPORT_CANNOT_CORRECT_TROVE_MAP = new ReportType("Unable to correct no entry value."); + + public static final ReportType REPORT_INSUFFICIENT_SERVER_PACKETS = new ReportType("Too few server packets detected: %s"); + public static final ReportType REPORT_INSUFFICIENT_CLIENT_PACKETS = new ReportType("Too few client packets detected: %s"); + + // Two different packet registry + private static volatile ProtocolRegistry NETTY; + + // Cached for Netty + private static volatile Set LEGACY_SERVER_PACKETS; + private static volatile Set LEGACY_CLIENT_PACKETS; + private static volatile Map LEGACY_PREVIOUS_PACKETS; + + // Whether or not the registry has + private static boolean INITIALIZED; + + /** + * Initializes the packet registry. + */ + private static void initialize() { + if (INITIALIZED) { + if (NETTY == null) { + throw new IllegalStateException("Failed to initialize packet registry."); + } + } + + INITIALIZED = true; + NETTY = new NettyProtocolRegistry(); + } + + /** + * Determine if the given packet type is supported on the current server. + * @param type - the type to check. + * @return TRUE if it is, FALSE otherwise. + */ + public static boolean isSupported(PacketType type) { + initialize(); + return NETTY.getPacketTypeLookup().containsKey(type); + } + + /** + * Retrieve a map of every packet class to every ID. + *

+ * Deprecated: Use {@link #getPacketToType()} instead. + * @return A map of packet classes and their corresponding ID. + */ + @Deprecated + public static Map getPacketToID() { + initialize(); + + @SuppressWarnings("unchecked") + Map result = (Map) Maps.transformValues( + NETTY.getPacketClassLookup(), + new Function() { + @Override + public Integer apply(PacketType type) { + return type.getLegacyId(); + }; + }); + return result; + } + + /** + * Retrieve a map of every packet class to the respective packet type. + * @return A map of packet classes and their corresponding packet type. + */ + public static Map getPacketToType() { + initialize(); + + @SuppressWarnings("unchecked") + Map result = (Map) NETTY.getPacketClassLookup(); + return result; + } + + /** + * Retrieve the injected proxy classes handlig each packet ID. + *

+ * This is not supported in 1.7.2 and later. + * @return Injected classes. + */ + @Deprecated + public static Map getOverwrittenPackets() { + initialize(); + throw new IllegalStateException("Not supported on Netty."); + } + + /** + * Retrieve the vanilla classes handling each packet ID. + * @return Vanilla classes. + */ + @Deprecated + public static Map getPreviousPackets() { + initialize(); + + // Construct it first + if (LEGACY_PREVIOUS_PACKETS == null) { + Map map = Maps.newHashMap(); + + for (Entry> entry : NETTY.getPacketTypeLookup().entrySet()) { + map.put(entry.getKey().getLegacyId(), entry.getValue()); + } + LEGACY_PREVIOUS_PACKETS = Collections.unmodifiableMap(map); + } + return LEGACY_PREVIOUS_PACKETS; + } + + /** + * Retrieve every known and supported server packet. + *

+ * Deprecated: Use {@link #getServerPacketTypes()} instead. + * @return An immutable set of every known server packet. + * @throws FieldAccessException If we're unable to retrieve the server packet data from Minecraft. + */ + @Deprecated + public static Set getServerPackets() throws FieldAccessException { + initialize(); + + if (LEGACY_SERVER_PACKETS == null) { + LEGACY_SERVER_PACKETS = toLegacy(NETTY.getServerPackets()); + } + return LEGACY_SERVER_PACKETS; + } + + /** + * Retrieve every known and supported server packet type. + * @return Every server packet type. + */ + public static Set getServerPacketTypes() { + initialize(); + + NETTY.synchronize(); + return NETTY.getServerPackets(); + } + + /** + * Retrieve every known and supported client packet. + *

+ * Deprecated: Use {@link #getClientPacketTypes()} instead. + * @return An immutable set of every known client packet. + * @throws FieldAccessException If we're unable to retrieve the client packet data from Minecraft. + */ + @Deprecated + public static Set getClientPackets() throws FieldAccessException { + initialize(); + + if (LEGACY_CLIENT_PACKETS == null) { + LEGACY_CLIENT_PACKETS = toLegacy(NETTY.getClientPackets()); + } + return LEGACY_CLIENT_PACKETS; + } + + /** + * Retrieve every known and supported server packet type. + * @return Every server packet type. + */ + public static Set getClientPacketTypes() { + initialize(); + + NETTY.synchronize(); + return NETTY.getClientPackets(); + } + + /** + * Convert a set of packet types to a set of integers based on the legacy packet ID. + * @param types - packet type. + * @return Set of integers. + */ + public static Set toLegacy(Set types) { + Set result = Sets.newHashSet(); + + for (PacketType type : types) + result.add(type.getLegacyId()); + return Collections.unmodifiableSet(result); + } + + /** + * Convert a set of legacy packet IDs to packet types. + * @param ids - legacy packet IDs. + * @return Set of packet types. + */ + public static Set toPacketTypes(Set ids) { + return toPacketTypes(ids, null); + } + + /** + * Convert a set of legacy packet IDs to packet types. + * @param ids - legacy packet IDs. + * @param preference - the sender preference, if any. + * @return Set of packet types. + */ + public static Set toPacketTypes(Set ids, Sender preference) { + Set result = Sets.newHashSet(); + + for (int id : ids) + result.add(PacketType.fromLegacy(id, preference)); + return Collections.unmodifiableSet(result); + } + + /** + * Retrieves the correct packet class from a given packet ID. + *

+ * Deprecated: Use {@link #getPacketClassFromType(PacketType)} instead. + * @param packetID - the packet ID. + * @return The associated class. + */ + @Deprecated + public static Class getPacketClassFromID(int packetID) { + initialize(); + return NETTY.getPacketTypeLookup().get(PacketType.findLegacy(packetID)); + } + + /** + * Retrieves the correct packet class from a given type. + * @param type - the packet type. + * @return The associated class. + */ + public static Class getPacketClassFromType(PacketType type) { + return getPacketClassFromType(type, false); + } + + /** + * Retrieves the correct packet class from a given type. + *

+ * Note that forceVanillla will be ignored on MC 1.7.2 and later. + * @param type - the packet type. + * @param forceVanilla - whether or not to look for vanilla classes, not injected classes. + * @return The associated class. + */ + public static Class getPacketClassFromType(PacketType type, boolean forceVanilla) { + initialize(); + return NETTY.getPacketTypeLookup().get(type); + } + + /** + * Retrieves the correct packet class from a given packet ID. + *

+ * This method has been deprecated. + * @param packetID - the packet ID. + * @param forceVanilla - whether or not to look for vanilla classes, not injected classes. + * @return The associated class. + */ + @Deprecated + public static Class getPacketClassFromID(int packetID, boolean forceVanilla) { + initialize(); + return getPacketClassFromID(packetID); + } + + /** + * Retrieve the packet ID of a given packet. + *

+ * Deprecated: Use {@link #getPacketType(Class)}. + * @param packet - the type of packet to check. + * @return The legacy ID of the given packet. + * @throws IllegalArgumentException If this is not a valid packet. + */ + @Deprecated + public static int getPacketID(Class packet) { + initialize(); + return NETTY.getPacketClassLookup().get(packet).getLegacyId(); + } + + /** + * Retrieve the packet type of a given packet. + * @param packet - the class of the packet. + * @return The packet type, or NULL if not found. + */ + public static PacketType getPacketType(Class packet) { + return getPacketType(packet, null); + } + + /** + * Retrieve the packet type of a given packet. + * @param packet - the class of the packet. + * @param sender - the sender of the packet, or NULL. + * @return The packet type, or NULL if not found. + */ + public static PacketType getPacketType(Class packet, Sender sender) { + initialize(); + return NETTY.getPacketClassLookup().get(packet); + } } \ No newline at end of file