mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-24 03:25:29 +01:00
Simplify packet registry
This commit is contained in:
parent
466354cd2c
commit
9ca7c91a76
@ -187,7 +187,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
|||||||
public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x52, "UpdateHealth", "SPacketUpdateHealth");
|
public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x52, "UpdateHealth", "SPacketUpdateHealth");
|
||||||
public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x53, "ScoreboardObjective", "SPacketScoreboardObjective");
|
public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x53, "ScoreboardObjective", "SPacketScoreboardObjective");
|
||||||
public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x54, "Mount", "SPacketSetPassengers");
|
public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x54, "Mount", "SPacketSetPassengers");
|
||||||
public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x55, "ScoreboardTeam$b", "ScoreboardTeam", "SPacketTeams");
|
public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x55, "ScoreboardTeam", "SPacketTeams");
|
||||||
public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x56, "ScoreboardScore", "SPacketUpdateScore");
|
public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x56, "ScoreboardScore", "SPacketUpdateScore");
|
||||||
public static final PacketType SET_SUBTITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x57, "SetSubtitleText");
|
public static final PacketType SET_SUBTITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x57, "SetSubtitleText");
|
||||||
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x58, "UpdateTime", "SPacketTimeUpdate");
|
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x58, "UpdateTime", "SPacketTimeUpdate");
|
||||||
@ -647,7 +647,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
|||||||
/**
|
/**
|
||||||
* Protocol version of all the current IDs.
|
* Protocol version of all the current IDs.
|
||||||
*/
|
*/
|
||||||
private static final MinecraftVersion PROTOCOL_VERSION = MinecraftVersion.NETHER_UPDATE;
|
private static final MinecraftVersion PROTOCOL_VERSION = MinecraftVersion.CAVES_CLIFFS_1;
|
||||||
|
|
||||||
private final Protocol protocol;
|
private final Protocol protocol;
|
||||||
private final Sender sender;
|
private final Sender sender;
|
||||||
@ -935,7 +935,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
|||||||
* Determine if a given class represents a packet class.
|
* Determine if a given class represents a packet class.
|
||||||
* @param packetClass - the class to lookup.
|
* @param packetClass - the class to lookup.
|
||||||
* @return TRUE if this is a packet class, FALSE otherwise.
|
* @return TRUE if this is a packet class, FALSE otherwise.
|
||||||
|
* @deprecated Doesn't really have a purpose
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static boolean hasClass(Class<?> packetClass) {
|
public static boolean hasClass(Class<?> packetClass) {
|
||||||
return PacketRegistry.getPacketType(packetClass) != null;
|
return PacketRegistry.getPacketType(packetClass) != null;
|
||||||
}
|
}
|
||||||
@ -1090,11 +1092,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
|||||||
* @return The packet class, or NULL if not found.
|
* @return The packet class, or NULL if not found.
|
||||||
*/
|
*/
|
||||||
public Class<?> getPacketClass() {
|
public Class<?> getPacketClass() {
|
||||||
try {
|
return PacketRegistry.tryGetPacketClass(this).orElse(null);
|
||||||
return PacketRegistry.getPacketClassFromType(this);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only used by Enum processor
|
// Only used by Enum processor
|
||||||
|
@ -110,22 +110,6 @@ public class PacketTypeEnum implements Iterable<PacketType> {
|
|||||||
public boolean hasMember(PacketType member) {
|
public boolean hasMember(PacketType member) {
|
||||||
return members.contains(member);
|
return members.contains(member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a member by name,
|
|
||||||
* @param name - name of member to retrieve.
|
|
||||||
* @return The member, or NULL if not found.
|
|
||||||
* @deprecated Don't use this
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public PacketType valueOf(String name) {
|
|
||||||
for (PacketType member : members) {
|
|
||||||
if (member.name().equals(name))
|
|
||||||
return member;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve every registered member.
|
* Retrieve every registered member.
|
||||||
|
@ -32,11 +32,11 @@ public class PacketTypeSet {
|
|||||||
* @param type - the type to add.
|
* @param type - the type to add.
|
||||||
*/
|
*/
|
||||||
public synchronized void addType(PacketType type) {
|
public synchronized void addType(PacketType type) {
|
||||||
Class<?> packetClass = getPacketClass(type);
|
Class<?> packetClass = type.getPacketClass();
|
||||||
types.add(Preconditions.checkNotNull(type, "type cannot be NULL."));
|
types.add(Preconditions.checkNotNull(type, "type cannot be NULL."));
|
||||||
|
|
||||||
if (packetClass != null) {
|
if (packetClass != null) {
|
||||||
classes.add(getPacketClass(type));
|
classes.add(type.getPacketClass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,11 +55,11 @@ public class PacketTypeSet {
|
|||||||
* @param type - the type to remove.
|
* @param type - the type to remove.
|
||||||
*/
|
*/
|
||||||
public synchronized void removeType(PacketType type) {
|
public synchronized void removeType(PacketType type) {
|
||||||
Class<?> packetClass = getPacketClass(type);
|
Class<?> packetClass = type.getPacketClass();
|
||||||
types.remove(Preconditions.checkNotNull(type, "type cannot be NULL."));
|
types.remove(Preconditions.checkNotNull(type, "type cannot be NULL."));
|
||||||
|
|
||||||
if (packetClass != null) {
|
if (packetClass != null) {
|
||||||
classes.remove(getPacketClass(type));
|
classes.remove(packetClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,16 +72,7 @@ public class PacketTypeSet {
|
|||||||
removeType(type);
|
removeType(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the packet class associated with a particular type.
|
|
||||||
* @param type - the packet type.
|
|
||||||
* @return The associated packet type.
|
|
||||||
*/
|
|
||||||
protected Class<?> getPacketClass(PacketType type) {
|
|
||||||
return PacketRegistry.getPacketClassFromType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the given packet type exists in the set.
|
* Determine if the given packet type exists in the set.
|
||||||
* @param type - the type to find.
|
* @param type - the type to find.
|
||||||
|
@ -39,14 +39,6 @@ public interface ListenerInvoker {
|
|||||||
*/
|
*/
|
||||||
void invokePacketSending(PacketEvent event);
|
void invokePacketSending(PacketEvent event);
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the associated ID of a packet.
|
|
||||||
* @param packet - the packet.
|
|
||||||
* @return The packet ID.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
int getPacketID(Object packet);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the associated type of a packet.
|
* Retrieve the associated type of a packet.
|
||||||
* @param packet - the packet.
|
* @param packet - the packet.
|
||||||
|
@ -20,6 +20,7 @@ package com.comphenix.protocol.injector;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.protocol.PacketType;
|
||||||
import com.comphenix.protocol.error.RethrowErrorReporter;
|
import com.comphenix.protocol.error.RethrowErrorReporter;
|
||||||
@ -146,13 +147,11 @@ public class PacketConstructor {
|
|||||||
types[i] = Object.class;
|
types[i] = Object.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Class<?> packetType = PacketRegistry.getPacketClassFromType(type, true);
|
|
||||||
|
Class<?> packetClass = PacketRegistry.getPacketClassFromType(type);
|
||||||
if (packetType == null)
|
|
||||||
throw new IllegalArgumentException("Could not find a packet by the type " + type);
|
|
||||||
|
|
||||||
// Find the correct constructor
|
// Find the correct constructor
|
||||||
for (Constructor<?> constructor : packetType.getConstructors()) {
|
for (Constructor<?> constructor : packetClass.getConstructors()) {
|
||||||
Class<?>[] params = constructor.getParameterTypes();
|
Class<?>[] params = constructor.getParameterTypes();
|
||||||
|
|
||||||
if (isCompatible(types, params)) {
|
if (isCompatible(types, params)) {
|
||||||
|
@ -979,12 +979,6 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
|||||||
return phaseLoginCount.get();
|
return phaseLoginCount.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public int getPacketID(Object packet) {
|
|
||||||
return PacketRegistry.getPacketID(packet.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PacketType getPacketType(Object packet) {
|
public PacketType getPacketType(Object packet) {
|
||||||
if (packet == null)
|
if (packet == null)
|
||||||
|
@ -92,11 +92,7 @@ public class StructureCache {
|
|||||||
* @return Created packet.
|
* @return Created packet.
|
||||||
*/
|
*/
|
||||||
public static Object newPacket(PacketType type) {
|
public static Object newPacket(PacketType type) {
|
||||||
Class<?> clazz = PacketRegistry.getPacketClassFromType(type, true);
|
return newPacket(PacketRegistry.getPacketClassFromType(type));
|
||||||
if (clazz != null) {
|
|
||||||
return newPacket(clazz);
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Cannot find associated packet class: " + type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +142,7 @@ public class StructureCache {
|
|||||||
if (result == null) {
|
if (result == null) {
|
||||||
// Use the vanilla class definition
|
// Use the vanilla class definition
|
||||||
final StructureModifier<Object> value = new StructureModifier<>(
|
final StructureModifier<Object> value = new StructureModifier<>(
|
||||||
PacketRegistry.getPacketClassFromType(type, true), MinecraftReflection.getPacketClass(), true);
|
PacketRegistry.getPacketClassFromType(type), MinecraftReflection.getPacketClass(), true);
|
||||||
|
|
||||||
result = structureModifiers.putIfAbsent(type, value);
|
result = structureModifiers.putIfAbsent(type, value);
|
||||||
|
|
||||||
|
@ -1,222 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.HashMap;
|
|
||||||
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.ProtocolLogger;
|
|
||||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
|
|
||||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author dmulloy2
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class NettyProtocolRegistry extends ProtocolRegistry {
|
|
||||||
|
|
||||||
public NettyProtocolRegistry() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized void initialize() {
|
|
||||||
if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.BEE_UPDATE)) {
|
|
||||||
initializeNew();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object[] protocols = enumProtocol.getEnumConstants();
|
|
||||||
|
|
||||||
// ID to Packet class maps
|
|
||||||
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
|
||||||
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
|
||||||
|
|
||||||
Register result = new Register();
|
|
||||||
StructureModifier<Object> modifier = null;
|
|
||||||
|
|
||||||
// Iterate through the protocols
|
|
||||||
for (Object protocol : protocols) {
|
|
||||||
if (modifier == null) {
|
|
||||||
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
|
||||||
for (Entry<Object, Map<Integer, Class<?>>> 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 (Object map : serverMaps.values()) {
|
|
||||||
result.containers.add(new MapContainer(map));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Object map : clientMaps.values()) {
|
|
||||||
result.containers.add(new MapContainer(map));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Object protocol : protocols) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private synchronized void initializeNew() {
|
|
||||||
Object[] protocols = enumProtocol.getEnumConstants();
|
|
||||||
|
|
||||||
// ID to Packet class maps
|
|
||||||
Map<Object, Map<Class<?>, Integer>> serverMaps = Maps.newLinkedHashMap();
|
|
||||||
Map<Object, Map<Class<?>, Integer>> clientMaps = Maps.newLinkedHashMap();
|
|
||||||
|
|
||||||
Register result = new Register();
|
|
||||||
Field mainMapField = null;
|
|
||||||
Field packetMapField = null;
|
|
||||||
|
|
||||||
// Iterate through the protocols
|
|
||||||
for (Object protocol : protocols) {
|
|
||||||
if (mainMapField == null) {
|
|
||||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(protocol.getClass(), true);
|
|
||||||
mainMapField = fuzzy.getField(FuzzyFieldContract.newBuilder()
|
|
||||||
.banModifier(Modifier.STATIC)
|
|
||||||
.requireModifier(Modifier.FINAL)
|
|
||||||
.typeDerivedOf(Map.class)
|
|
||||||
.build());
|
|
||||||
mainMapField.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<Object, Object> directionMap;
|
|
||||||
|
|
||||||
try {
|
|
||||||
directionMap = (Map<Object, Object>) mainMapField.get(protocol);
|
|
||||||
} catch (ReflectiveOperationException ex) {
|
|
||||||
throw new RuntimeException("Failed to access packet map", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Entry<Object, Object> entry : directionMap.entrySet()) {
|
|
||||||
Object holder = entry.getValue();
|
|
||||||
if (packetMapField == null) {
|
|
||||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(holder.getClass(), true);
|
|
||||||
packetMapField = fuzzy.getField(FuzzyFieldContract.newBuilder()
|
|
||||||
.banModifier(Modifier.STATIC)
|
|
||||||
.requireModifier(Modifier.FINAL)
|
|
||||||
.typeDerivedOf(Map.class)
|
|
||||||
.build());
|
|
||||||
packetMapField.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<Class<?>, Integer> packetMap;
|
|
||||||
|
|
||||||
try {
|
|
||||||
packetMap = (Map<Class<?>, Integer>) packetMapField.get(holder);
|
|
||||||
} catch (ReflectiveOperationException ex) {
|
|
||||||
throw new RuntimeException("Failed to access packet map", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
String direction = entry.getKey().toString();
|
|
||||||
if (direction.contains("CLIENTBOUND")) { // Sent by Server
|
|
||||||
serverMaps.put(protocol, packetMap);
|
|
||||||
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
|
|
||||||
clientMaps.put(protocol, packetMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maps we have to occasionally check have changed
|
|
||||||
// TODO: Find equivalent in Object2IntMap
|
|
||||||
|
|
||||||
/* for (Object map : serverMaps.values()) {
|
|
||||||
result.containers.add(new MapContainer(map));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Object map : clientMaps.values()) {
|
|
||||||
result.containers.add(new MapContainer(map));
|
|
||||||
} */
|
|
||||||
|
|
||||||
for (Object protocol : protocols) {
|
|
||||||
Enum<?> enumProtocol = (Enum<?>) protocol;
|
|
||||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
|
||||||
|
|
||||||
// Associate known types
|
|
||||||
if (serverMaps.containsKey(protocol)) {
|
|
||||||
associatePackets(result, reverse(serverMaps.get(protocol)), equivalent, Sender.SERVER);
|
|
||||||
}
|
|
||||||
if (clientMaps.containsKey(protocol)) {
|
|
||||||
associatePackets(result, reverse(clientMaps.get(protocol)), equivalent, Sender.CLIENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exchange (thread safe, as we have only one writer)
|
|
||||||
this.register = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverses a key->value map to value->key
|
|
||||||
* Non-deterministic behavior when multiple keys are mapped to the same value
|
|
||||||
*/
|
|
||||||
private <K, V> Map<V, K> reverse(Map<K, V> map) {
|
|
||||||
Map<V, K> newMap = new HashMap<>(map.size());
|
|
||||||
for (Entry<K, V> entry : map.entrySet()) {
|
|
||||||
newMap.put(entry.getValue(), entry.getKey());
|
|
||||||
}
|
|
||||||
return newMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
|
||||||
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
|
||||||
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
|
||||||
// System.out.println(Arrays.toString(type.getClassNames()) + " -> " + 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 (Exception ex) {
|
|
||||||
ProtocolLogger.debug("Encountered an exception associating packet " + type, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,120 +0,0 @@
|
|||||||
package com.comphenix.protocol.injector.netty;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.PacketType.Protocol;
|
|
||||||
import com.comphenix.protocol.PacketType.Sender;
|
|
||||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
|
||||||
import com.google.common.collect.BiMap;
|
|
||||||
import com.google.common.collect.HashBiMap;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a way of accessing the new netty Protocol enum.
|
|
||||||
* @author Kristian
|
|
||||||
*/
|
|
||||||
|
|
||||||
public abstract class ProtocolRegistry {
|
|
||||||
/**
|
|
||||||
* Represents a register we are currently building.
|
|
||||||
* @author Kristian
|
|
||||||
*/
|
|
||||||
protected static class Register {
|
|
||||||
// The main lookup table
|
|
||||||
public BiMap<PacketType, Class<?>> typeToClass = HashBiMap.create();
|
|
||||||
public volatile Set<PacketType> serverPackets = Sets.newHashSet();
|
|
||||||
public volatile Set<PacketType> clientPackets = Sets.newHashSet();
|
|
||||||
public List<MapContainer> containers = Lists.newArrayList();
|
|
||||||
|
|
||||||
public Register() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the current register is outdated.
|
|
||||||
* @return TRUE if it is, FALSE otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isOutdated() {
|
|
||||||
for (MapContainer container : containers) {
|
|
||||||
if (container.hasChanged()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Class<?> enumProtocol;
|
|
||||||
|
|
||||||
// Current register
|
|
||||||
protected volatile Register register;
|
|
||||||
|
|
||||||
public ProtocolRegistry() {
|
|
||||||
enumProtocol = MinecraftReflection.getEnumProtocolClass();
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve an immutable view of the packet type lookup.
|
|
||||||
* @return The packet type lookup.
|
|
||||||
*/
|
|
||||||
public Map<PacketType, Class<?>> getPacketTypeLookup() {
|
|
||||||
return Collections.unmodifiableMap(register.typeToClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve an immutable view of the class to packet type lookup.
|
|
||||||
* @return The packet type lookup.
|
|
||||||
*/
|
|
||||||
public Map<Class<?>, PacketType> getPacketClassLookup() {
|
|
||||||
return Collections.unmodifiableMap(register.typeToClass.inverse());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve every known client packet, from every protocol.
|
|
||||||
* @return Every client packet.
|
|
||||||
*/
|
|
||||||
public Set<PacketType> getClientPackets() {
|
|
||||||
return Collections.unmodifiableSet(register.clientPackets);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve every known server packet, from every protocol.
|
|
||||||
* @return Every server packet.
|
|
||||||
*/
|
|
||||||
public Set<PacketType> getServerPackets() {
|
|
||||||
return Collections.unmodifiableSet(register.serverPackets);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensure that our local register is up-to-date with Minecraft.
|
|
||||||
* <p>
|
|
||||||
* This operation may block the calling thread.
|
|
||||||
*/
|
|
||||||
public synchronized void synchronize() {
|
|
||||||
// Check if the packet registry has changed
|
|
||||||
if (register.isOutdated()) {
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the packet lookup tables in each protocol.
|
|
||||||
*/
|
|
||||||
protected abstract void initialize();
|
|
||||||
|
|
||||||
protected abstract void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Not a public API
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void _associate(PacketType type, Class<?> clazz) {
|
|
||||||
register.typeToClass.put(type, clazz);
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,44 +17,275 @@
|
|||||||
|
|
||||||
package com.comphenix.protocol.injector.packet;
|
package com.comphenix.protocol.injector.packet;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Map;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.protocol.PacketType;
|
||||||
import com.comphenix.protocol.PacketType.Sender;
|
import com.comphenix.protocol.PacketType.Sender;
|
||||||
import com.comphenix.protocol.injector.netty.NettyProtocolRegistry;
|
import com.comphenix.protocol.ProtocolLogger;
|
||||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
|
import com.comphenix.protocol.reflect.StructureModifier;
|
||||||
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
import com.google.common.base.Function;
|
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static packet registry in Minecraft.
|
* Static packet registry in Minecraft.
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
public class PacketRegistry {
|
public class PacketRegistry {
|
||||||
// The Netty packet registry
|
|
||||||
private static volatile ProtocolRegistry NETTY;
|
|
||||||
|
|
||||||
// Whether or not the registry has been initialized
|
// Whether or not the registry has been initialized
|
||||||
private static volatile boolean INITIALIZED = false;
|
private static volatile boolean INITIALIZED = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a register we are currently building.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
protected static class Register {
|
||||||
|
// The main lookup table
|
||||||
|
private final Map<PacketType, Optional<Class<?>>> typeToClass = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Class<?>, PacketType> classToType = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private volatile Set<PacketType> serverPackets = Sets.newHashSet();
|
||||||
|
private volatile Set<PacketType> clientPackets = Sets.newHashSet();
|
||||||
|
private final List<MapContainer> containers = Lists.newArrayList();
|
||||||
|
|
||||||
|
public Register() {}
|
||||||
|
|
||||||
|
public void registerPacket(PacketType type, Class<?> clazz, Sender sender) {
|
||||||
|
typeToClass.put(type, Optional.of(clazz));
|
||||||
|
classToType.put(clazz, type);
|
||||||
|
if (sender == Sender.CLIENT) {
|
||||||
|
clientPackets.add(type);
|
||||||
|
} else {
|
||||||
|
serverPackets.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addContainer(MapContainer container) {
|
||||||
|
containers.add(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the current register is outdated.
|
||||||
|
* @return TRUE if it is, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isOutdated() {
|
||||||
|
for (MapContainer container : containers) {
|
||||||
|
if (container.hasChanged()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final Class<?> ENUM_PROTOCOL = MinecraftReflection.getEnumProtocolClass();
|
||||||
|
|
||||||
|
// Current register
|
||||||
|
protected static volatile Register REGISTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that our local register is up-to-date with Minecraft.
|
||||||
|
* <p>
|
||||||
|
* This operation may block the calling thread.
|
||||||
|
*/
|
||||||
|
public static synchronized void synchronize() {
|
||||||
|
// Check if the packet registry has changed
|
||||||
|
if (REGISTER.isOutdated()) {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static synchronized Register createOldRegister() {
|
||||||
|
Object[] protocols = ENUM_PROTOCOL.getEnumConstants();
|
||||||
|
|
||||||
|
// ID to Packet class maps
|
||||||
|
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
||||||
|
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
|
Register result = new Register();
|
||||||
|
StructureModifier<Object> modifier = null;
|
||||||
|
|
||||||
|
// Iterate through the protocols
|
||||||
|
for (Object protocol : protocols) {
|
||||||
|
if (modifier == null) {
|
||||||
|
modifier = new StructureModifier<>(protocol.getClass().getSuperclass(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
||||||
|
for (Map.Entry<Object, Map<Integer, Class<?>>> 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 (Object map : serverMaps.values()) {
|
||||||
|
REGISTER.addContainer(new MapContainer(map));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object map : clientMaps.values()) {
|
||||||
|
REGISTER.addContainer(new MapContainer(map));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object protocol : protocols) {
|
||||||
|
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||||
|
PacketType.Protocol equivalent = PacketType.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static synchronized Register createNewRegister() {
|
||||||
|
Object[] protocols = ENUM_PROTOCOL.getEnumConstants();
|
||||||
|
|
||||||
|
// ID to Packet class maps
|
||||||
|
Map<Object, Map<Class<?>, Integer>> serverMaps = Maps.newLinkedHashMap();
|
||||||
|
Map<Object, Map<Class<?>, Integer>> clientMaps = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
|
Register result = new Register();
|
||||||
|
Field mainMapField = null;
|
||||||
|
Field packetMapField = null;
|
||||||
|
|
||||||
|
// Iterate through the protocols
|
||||||
|
for (Object protocol : protocols) {
|
||||||
|
if (mainMapField == null) {
|
||||||
|
FuzzyReflection fuzzy = FuzzyReflection.fromClass(protocol.getClass(), true);
|
||||||
|
mainMapField = fuzzy.getField(FuzzyFieldContract.newBuilder()
|
||||||
|
.banModifier(Modifier.STATIC)
|
||||||
|
.requireModifier(Modifier.FINAL)
|
||||||
|
.typeDerivedOf(Map.class)
|
||||||
|
.build());
|
||||||
|
mainMapField.setAccessible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Object, Object> directionMap;
|
||||||
|
|
||||||
|
try {
|
||||||
|
directionMap = (Map<Object, Object>) mainMapField.get(protocol);
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new RuntimeException("Failed to access packet map", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<Object, Object> entry : directionMap.entrySet()) {
|
||||||
|
Object holder = entry.getValue();
|
||||||
|
if (packetMapField == null) {
|
||||||
|
FuzzyReflection fuzzy = FuzzyReflection.fromClass(holder.getClass(), true);
|
||||||
|
packetMapField = fuzzy.getField(FuzzyFieldContract.newBuilder()
|
||||||
|
.banModifier(Modifier.STATIC)
|
||||||
|
.requireModifier(Modifier.FINAL)
|
||||||
|
.typeDerivedOf(Map.class)
|
||||||
|
.build());
|
||||||
|
packetMapField.setAccessible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Class<?>, Integer> packetMap;
|
||||||
|
|
||||||
|
try {
|
||||||
|
packetMap = (Map<Class<?>, Integer>) packetMapField.get(holder);
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new RuntimeException("Failed to access packet map", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
String direction = entry.getKey().toString();
|
||||||
|
if (direction.contains("CLIENTBOUND")) { // Sent by Server
|
||||||
|
serverMaps.put(protocol, packetMap);
|
||||||
|
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
|
||||||
|
clientMaps.put(protocol, packetMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maps we have to occasionally check have changed
|
||||||
|
// TODO: Find equivalent in Object2IntMap
|
||||||
|
|
||||||
|
/* for (Object map : serverMaps.values()) {
|
||||||
|
result.containers.add(new MapContainer(map));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object map : clientMaps.values()) {
|
||||||
|
result.containers.add(new MapContainer(map));
|
||||||
|
} */
|
||||||
|
|
||||||
|
for (Object protocol : protocols) {
|
||||||
|
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||||
|
PacketType.Protocol equivalent = PacketType.Protocol.fromVanilla(enumProtocol);
|
||||||
|
|
||||||
|
// Associate known types
|
||||||
|
if (serverMaps.containsKey(protocol)) {
|
||||||
|
associatePackets(result, reverse(serverMaps.get(protocol)), equivalent, Sender.SERVER);
|
||||||
|
}
|
||||||
|
if (clientMaps.containsKey(protocol)) {
|
||||||
|
associatePackets(result, reverse(clientMaps.get(protocol)), equivalent, Sender.CLIENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverses a key->value map to value->key
|
||||||
|
* Non-deterministic behavior when multiple keys are mapped to the same value
|
||||||
|
*/
|
||||||
|
private static <K, V> Map<V, K> reverse(Map<K, V> map) {
|
||||||
|
Map<V, K> newMap = new HashMap<>(map.size());
|
||||||
|
for (Map.Entry<K, V> entry : map.entrySet()) {
|
||||||
|
newMap.put(entry.getValue(), entry.getKey());
|
||||||
|
}
|
||||||
|
return newMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void associatePackets(Register register, Map<Integer, Class<?>> lookup, PacketType.Protocol protocol, Sender sender) {
|
||||||
|
for (Map.Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
||||||
|
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
||||||
|
|
||||||
|
try {
|
||||||
|
register.registerPacket(type, entry.getValue(), sender);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ProtocolLogger.debug("Encountered an exception associating packet " + type, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void associate(PacketType type, Class<?> clazz) {
|
||||||
|
if (clazz != null) {
|
||||||
|
REGISTER.typeToClass.put(type, Optional.of(clazz));
|
||||||
|
REGISTER.classToType.put(clazz, type);
|
||||||
|
} else {
|
||||||
|
REGISTER.typeToClass.put(type, Optional.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the packet registry.
|
* Initializes the packet registry.
|
||||||
*/
|
*/
|
||||||
private static void initialize() {
|
private static void initialize() {
|
||||||
if (INITIALIZED) {
|
if (!INITIALIZED) {
|
||||||
if (NETTY == null) {
|
INITIALIZED = true;
|
||||||
throw new IllegalStateException("Failed to initialize packet registry.");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NETTY = new NettyProtocolRegistry();
|
if (MinecraftVersion.BEE_UPDATE.atOrAbove()) {
|
||||||
INITIALIZED = true;
|
REGISTER = createNewRegister();
|
||||||
|
} else {
|
||||||
|
REGISTER = createOldRegister();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,35 +295,7 @@ public class PacketRegistry {
|
|||||||
*/
|
*/
|
||||||
public static boolean isSupported(PacketType type) {
|
public static boolean isSupported(PacketType type) {
|
||||||
initialize();
|
initialize();
|
||||||
return NETTY.getPacketTypeLookup().get(type) != null;
|
return tryGetPacketClass(type).isPresent();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a map of every packet class to every ID.
|
|
||||||
* <p>
|
|
||||||
* Deprecated: Use {@link #getPacketToType()} instead.
|
|
||||||
* @return A map of packet classes and their corresponding ID.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static Map<Class, Integer> getPacketToID() {
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<Class, Integer> result = (Map) Maps.transformValues(
|
|
||||||
NETTY.getPacketClassLookup(), PacketType::getCurrentId);
|
|
||||||
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<Class, PacketType> getPacketToType() {
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<Class, PacketType> result = (Map) NETTY.getPacketClassLookup();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,9 +304,9 @@ public class PacketRegistry {
|
|||||||
*/
|
*/
|
||||||
public static Set<PacketType> getServerPacketTypes() {
|
public static Set<PacketType> getServerPacketTypes() {
|
||||||
initialize();
|
initialize();
|
||||||
NETTY.synchronize();
|
synchronize();
|
||||||
|
|
||||||
return NETTY.getServerPackets();
|
return Collections.unmodifiableSet(REGISTER.serverPackets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,31 +315,9 @@ public class PacketRegistry {
|
|||||||
*/
|
*/
|
||||||
public static Set<PacketType> getClientPacketTypes() {
|
public static Set<PacketType> getClientPacketTypes() {
|
||||||
initialize();
|
initialize();
|
||||||
NETTY.synchronize();
|
synchronize();
|
||||||
|
|
||||||
return NETTY.getClientPackets();
|
return Collections.unmodifiableSet(REGISTER.clientPackets);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the correct packet class from a given packet ID.
|
|
||||||
* <p>
|
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Class<?> searchForPacket(List<String> classNames) {
|
private static Class<?> searchForPacket(List<String> classNames) {
|
||||||
@ -155,55 +336,43 @@ public class PacketRegistry {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the correct packet class from a given type.
|
* Retrieves the correct packet class from a given type.
|
||||||
* <p>
|
*
|
||||||
* Note that forceVanillla will be ignored on MC 1.7.2 and later.
|
|
||||||
* @param type - the packet type.
|
* @param type - the packet type.
|
||||||
* @param forceVanilla - whether or not to look for vanilla classes, not injected classes.
|
* @param forceVanilla - whether or not to look for vanilla classes, not injected classes.
|
||||||
* @return The associated class.
|
* @return The associated class.
|
||||||
|
* @deprecated forceVanilla no longer has any effect
|
||||||
*/
|
*/
|
||||||
public static Class getPacketClassFromType(PacketType type, boolean forceVanilla) {
|
@Deprecated
|
||||||
|
public static Class<?> getPacketClassFromType(PacketType type, boolean forceVanilla) {
|
||||||
|
return getPacketClassFromType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Class<?>> tryGetPacketClass(PacketType type) {
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
// Try the lookup first
|
// Try the lookup first (may be null, so check contains)
|
||||||
Class<?> clazz = NETTY.getPacketTypeLookup().get(type);
|
Optional<Class<?>> res = REGISTER.typeToClass.get(type);
|
||||||
if (clazz != null) {
|
if (res != null) {
|
||||||
return clazz;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then try looking up the class names
|
// Then try looking up the class names
|
||||||
clazz = searchForPacket(type.getClassNames());
|
Class<?> clazz = searchForPacket(type.getClassNames());
|
||||||
|
|
||||||
// cache it for next time
|
// cache it for next time
|
||||||
NETTY._associate(type, clazz);
|
associate(type, clazz);
|
||||||
return clazz;
|
return Optional.ofNullable(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the correct packet class from a given packet ID.
|
* Get the packet class associated with a given type. First attempts to read from the
|
||||||
* <p>
|
* type-to-class mapping, and tries
|
||||||
* This method has been deprecated.
|
* @param type the packet type
|
||||||
* @param packetID - the packet ID.
|
* @return The associated class
|
||||||
* @param forceVanilla - whether or not to look for vanilla classes, not injected classes.
|
|
||||||
* @return The associated class.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public static Class<?> getPacketClassFromType(PacketType type) {
|
||||||
public static Class getPacketClassFromID(int packetID, boolean forceVanilla) {
|
return tryGetPacketClass(type)
|
||||||
initialize();
|
.orElseThrow(() -> new IllegalArgumentException("Could not find packet for type " + type.name()));
|
||||||
return getPacketClassFromID(packetID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the packet ID of a given packet.
|
|
||||||
* <p>
|
|
||||||
* 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).getCurrentId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,7 +381,8 @@ public class PacketRegistry {
|
|||||||
* @return The packet type, or NULL if not found.
|
* @return The packet type, or NULL if not found.
|
||||||
*/
|
*/
|
||||||
public static PacketType getPacketType(Class<?> packet) {
|
public static PacketType getPacketType(Class<?> packet) {
|
||||||
return getPacketType(packet, null);
|
initialize();
|
||||||
|
return REGISTER.classToType.get(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,9 +390,10 @@ public class PacketRegistry {
|
|||||||
* @param packet - the class of the packet.
|
* @param packet - the class of the packet.
|
||||||
* @param sender - the sender of the packet, or NULL.
|
* @param sender - the sender of the packet, or NULL.
|
||||||
* @return The packet type, or NULL if not found.
|
* @return The packet type, or NULL if not found.
|
||||||
|
* @deprecated sender no longer has any effect
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static PacketType getPacketType(Class<?> packet, Sender sender) {
|
public static PacketType getPacketType(Class<?> packet, Sender sender) {
|
||||||
initialize();
|
return getPacketType(packet);
|
||||||
return NETTY.getPacketClassLookup().get(packet);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1292,7 +1292,7 @@ public class MinecraftReflection {
|
|||||||
try {
|
try {
|
||||||
return getMinecraftClass("world.level.ChunkCoordIntPair", "ChunkCoordIntPair");
|
return getMinecraftClass("world.level.ChunkCoordIntPair", "ChunkCoordIntPair");
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
Class<?> packet = PacketRegistry.getPacketClassFromType(PacketType.Play.Server.MULTI_BLOCK_CHANGE);
|
Class<?> packet = PacketType.Play.Server.MULTI_BLOCK_CHANGE.getPacketClass();
|
||||||
|
|
||||||
AbstractFuzzyMatcher<Class<?>> chunkCoordIntContract = FuzzyClassContract.newBuilder().
|
AbstractFuzzyMatcher<Class<?>> chunkCoordIntContract = FuzzyClassContract.newBuilder().
|
||||||
field(FuzzyFieldContract.newBuilder().
|
field(FuzzyFieldContract.newBuilder().
|
||||||
@ -1640,7 +1640,7 @@ public class MinecraftReflection {
|
|||||||
return getMinecraftClass("world.effect.MobEffect", "MobEffect");
|
return getMinecraftClass("world.effect.MobEffect", "MobEffect");
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
// It is the second parameter in Packet41MobEffect
|
// It is the second parameter in Packet41MobEffect
|
||||||
Class<?> packet = PacketRegistry.getPacketClassFromType(PacketType.Play.Server.ENTITY_EFFECT);
|
Class<?> packet = PacketType.Play.Server.ENTITY_EFFECT.getPacketClass();
|
||||||
Constructor<?> constructor = FuzzyReflection.fromClass(packet).getConstructor(
|
Constructor<?> constructor = FuzzyReflection.fromClass(packet).getConstructor(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
parameterCount(2).
|
parameterCount(2).
|
||||||
|
@ -557,12 +557,18 @@ public abstract class EnumWrappers {
|
|||||||
* @return The type of the enum field.
|
* @return The type of the enum field.
|
||||||
*/
|
*/
|
||||||
private static Class<?> getEnum(Class<?> clazz, int index) {
|
private static Class<?> getEnum(Class<?> clazz, int index) {
|
||||||
try {
|
if (clazz == null) {
|
||||||
return FuzzyReflection.fromClass(clazz, true).getFieldListByType(Enum.class).get(index).getType();
|
// not supported in the current version
|
||||||
} catch (Throwable ex) {
|
|
||||||
ProtocolLogger.debug("Exception getting enum from " + clazz + " at index " + index, ex);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Field> enumFields = FuzzyReflection.fromClass(clazz, true).getFieldListByType(Enum.class);
|
||||||
|
if (enumFields.size() <= index) {
|
||||||
|
// also probably not supported
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return enumFields.get(index).getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<Class<?>, EquivalentConverter<?>> getFromNativeMap() {
|
public static Map<Class<?>, EquivalentConverter<?>> getFromNativeMap() {
|
||||||
@ -779,22 +785,17 @@ public abstract class EnumWrappers {
|
|||||||
return new EnumConverter<>(genericClass, specificType);
|
return new EnumConverter<>(genericClass, specificType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Replaced with {@link #getGenericConverter(Class, Class)}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static <T extends Enum<T>> EquivalentConverter<T> getGenericConverter(Class<T> specificType) {
|
|
||||||
return new EnumConverter<>(null, specificType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The common Enum converter
|
* The common Enum converter
|
||||||
*/
|
*/
|
||||||
public static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
|
public static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
|
||||||
private Class<?> genericType;
|
private final Class<?> genericType;
|
||||||
private Class<T> specificType;
|
private final Class<T> specificType;
|
||||||
|
|
||||||
public EnumConverter(Class<?> genericType, Class<T> specificType) {
|
public EnumConverter(Class<?> genericType, Class<T> specificType) {
|
||||||
|
Validate.notNull(specificType, "specificType cannot be null");
|
||||||
|
// would love to check if genericType is null, but it breaks other stuff
|
||||||
|
|
||||||
this.genericType = genericType;
|
this.genericType = genericType;
|
||||||
this.specificType = specificType;
|
this.specificType = specificType;
|
||||||
}
|
}
|
||||||
@ -813,10 +814,6 @@ public abstract class EnumWrappers {
|
|||||||
public Class<T> getSpecificType() {
|
public Class<T> getSpecificType() {
|
||||||
return specificType;
|
return specificType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGenericType(Class<?> genericType) {
|
|
||||||
this.genericType = genericType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface AliasedEnum {
|
public interface AliasedEnum {
|
||||||
|
Loading…
Reference in New Issue
Block a user