Add some debug info for #208
Dieser Commit ist enthalten in:
Ursprung
1c36c41050
Commit
4330bae47f
@ -1,104 +1,108 @@
|
|||||||
/**
|
/**
|
||||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
* Copyright (C) 2015 dmulloy2
|
* Copyright (C) 2015 dmulloy2
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
* 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
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
* the License, or (at your option) any later version.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* 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;
|
* 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
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
* 02111-1307 USA
|
* 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
package com.comphenix.protocol.injector.netty;
|
package com.comphenix.protocol.injector.netty;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.protocol.PacketType;
|
||||||
import com.comphenix.protocol.PacketType.Protocol;
|
import com.comphenix.protocol.PacketType.Protocol;
|
||||||
import com.comphenix.protocol.PacketType.Sender;
|
import com.comphenix.protocol.PacketType.Sender;
|
||||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
import com.comphenix.protocol.injector.packet.MapContainer;
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
import com.comphenix.protocol.reflect.StructureModifier;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author dmulloy2
|
* @author dmulloy2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class NettyProtocolRegistry extends ProtocolRegistry {
|
public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||||
|
|
||||||
@Override
|
public NettyProtocolRegistry() {
|
||||||
protected synchronized void initialize() {
|
super();
|
||||||
Object[] protocols = enumProtocol.getEnumConstants();
|
}
|
||||||
|
|
||||||
// ID to Packet class maps
|
@Override
|
||||||
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
protected synchronized void initialize() {
|
||||||
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
Object[] protocols = enumProtocol.getEnumConstants();
|
||||||
|
|
||||||
Register result = new Register();
|
// ID to Packet class maps
|
||||||
StructureModifier<Object> modifier = null;
|
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
||||||
|
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
||||||
// Iterate through the protocols
|
|
||||||
for (Object protocol : protocols) {
|
Register result = new Register();
|
||||||
if (modifier == null)
|
StructureModifier<Object> modifier = null;
|
||||||
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
|
||||||
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
// Iterate through the protocols
|
||||||
for (Entry<Object, Map<Integer, Class<?>>> entry : maps.read(0).entrySet()) {
|
for (Object protocol : protocols) {
|
||||||
String direction = entry.getKey().toString();
|
if (modifier == null)
|
||||||
if (direction.contains("CLIENTBOUND")) { // Sent by Server
|
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
||||||
serverMaps.put(protocol, entry.getValue());
|
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
||||||
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
|
for (Entry<Object, Map<Integer, Class<?>>> entry : maps.read(0).entrySet()) {
|
||||||
clientMaps.put(protocol, entry.getValue());
|
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 occationally check have changed
|
}
|
||||||
for (Map<Integer, Class<?>> map : serverMaps.values()) {
|
}
|
||||||
result.containers.add(new MapContainer(map));
|
}
|
||||||
}
|
|
||||||
|
// Maps we have to occasionally check have changed
|
||||||
for (Map<Integer, Class<?>> map : clientMaps.values()) {
|
for (Map<Integer, Class<?>> map : serverMaps.values()) {
|
||||||
result.containers.add(new MapContainer(map));
|
result.containers.add(new MapContainer(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < protocols.length; i++) {
|
for (Map<Integer, Class<?>> map : clientMaps.values()) {
|
||||||
Object protocol = protocols[i];
|
result.containers.add(new MapContainer(map));
|
||||||
Enum<?> enumProtocol = (Enum<?>) protocol;
|
}
|
||||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
|
||||||
|
for (int i = 0; i < protocols.length; i++) {
|
||||||
// Associate known types
|
Object protocol = protocols[i];
|
||||||
if (serverMaps.containsKey(protocol))
|
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||||
associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER);
|
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
||||||
if (clientMaps.containsKey(protocol))
|
|
||||||
associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT);
|
// Associate known types
|
||||||
}
|
if (serverMaps.containsKey(protocol))
|
||||||
|
associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER);
|
||||||
// Exchange (thread safe, as we have only one writer)
|
if (clientMaps.containsKey(protocol))
|
||||||
this.register = result;
|
associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Exchange (thread safe, as we have only one writer)
|
||||||
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
this.register = result;
|
||||||
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
}
|
||||||
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
|
||||||
|
@Override
|
||||||
try {
|
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
||||||
register.typeToClass.put(type, entry.getValue());
|
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
||||||
|
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
||||||
if (sender == Sender.SERVER)
|
|
||||||
register.serverPackets.add(type);
|
try {
|
||||||
if (sender == Sender.CLIENT)
|
register.typeToClass.put(type, entry.getValue());
|
||||||
register.clientPackets.add(type);
|
|
||||||
} catch (IllegalArgumentException ex) {
|
if (sender == Sender.SERVER)
|
||||||
// Sometimes this happens with fake packets, just ignore it
|
register.serverPackets.add(type);
|
||||||
}
|
if (sender == Sender.CLIENT)
|
||||||
}
|
register.clientPackets.add(type);
|
||||||
}
|
} catch (IllegalArgumentException ex) {
|
||||||
}
|
// Sometimes this happens with fake packets, just ignore it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -29,6 +29,8 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
||||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||||
@ -577,6 +579,8 @@ public class FuzzyReflection {
|
|||||||
* @return Every field.
|
* @return Every field.
|
||||||
*/
|
*/
|
||||||
public Set<Field> getFields() {
|
public Set<Field> getFields() {
|
||||||
|
Validate.notNull(source, "source cannot be null!");
|
||||||
|
|
||||||
// We will only consider private fields in the declared class
|
// We will only consider private fields in the declared class
|
||||||
if (forceAccess)
|
if (forceAccess)
|
||||||
return setUnion(source.getDeclaredFields(), source.getFields());
|
return setUnion(source.getDeclaredFields(), source.getFields());
|
||||||
|
@ -582,26 +582,35 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
|||||||
* @param packet - the packet.
|
* @param packet - the packet.
|
||||||
*/
|
*/
|
||||||
protected void handleLogin(Class<?> packetClass, Object packet) {
|
protected void handleLogin(Class<?> packetClass, Object packet) {
|
||||||
Class<?> loginClass = PACKET_LOGIN_CLIENT;
|
try {
|
||||||
FieldAccessor loginClient = LOGIN_GAME_PROFILE;
|
Class<?> loginClass = PACKET_LOGIN_CLIENT;
|
||||||
|
FieldAccessor loginClient = LOGIN_GAME_PROFILE;
|
||||||
|
|
||||||
// Initialize packet class and login
|
// Initialize packet class and login
|
||||||
if (loginClass == null) {
|
if (loginClass == null) {
|
||||||
loginClass = PacketType.Login.Client.START.getPacketClass();
|
loginClass = PacketType.Login.Client.START.getPacketClass();
|
||||||
PACKET_LOGIN_CLIENT = loginClass;
|
PACKET_LOGIN_CLIENT = loginClass;
|
||||||
}
|
}
|
||||||
if (loginClient == null) {
|
if (loginClient == null) {
|
||||||
loginClient = Accessors.getFieldAccessor(PACKET_LOGIN_CLIENT, MinecraftReflection.getGameProfileClass(), true);
|
loginClient = Accessors.getFieldAccessor(PACKET_LOGIN_CLIENT, MinecraftReflection.getGameProfileClass(), true);
|
||||||
LOGIN_GAME_PROFILE = loginClient;
|
LOGIN_GAME_PROFILE = loginClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we are dealing with the login packet
|
// See if we are dealing with the login packet
|
||||||
if (loginClass.equals(packetClass)) {
|
if (loginClass.equals(packetClass)) {
|
||||||
// GameProfile profile = (GameProfile) loginClient.get(packet);
|
// GameProfile profile = (GameProfile) loginClient.get(packet);
|
||||||
WrappedGameProfile profile = WrappedGameProfile.fromHandle(loginClient.get(packet));
|
WrappedGameProfile profile = WrappedGameProfile.fromHandle(loginClient.get(packet));
|
||||||
|
|
||||||
// Save the channel injector
|
// Save the channel injector
|
||||||
factory.cacheInjector(profile.getName(), this);
|
factory.cacheInjector(profile.getName(), this);
|
||||||
|
}
|
||||||
|
} catch (NullPointerException ex) {
|
||||||
|
System.err.println(String.format("[ProtocolLib] Encountered NPE in handleLogin(%s, %s)", packetClass, packet));
|
||||||
|
System.err.println("PACKET_LOGIN_CLIENT = " + PACKET_LOGIN_CLIENT);
|
||||||
|
System.err.println("LOGIN_GAME_PROFILE = " + LOGIN_GAME_PROFILE);
|
||||||
|
System.err.println("GameProfile class = " + MinecraftReflection.getGameProfileClass());
|
||||||
|
System.err.println("Provide this information in a new or existing issue");
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ import com.comphenix.protocol.PacketType.Sender;
|
|||||||
import com.comphenix.protocol.injector.netty.NettyProtocolRegistry;
|
import com.comphenix.protocol.injector.netty.NettyProtocolRegistry;
|
||||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_9_R2.PacketLoginInStart;
|
||||||
|
|
||||||
public class PacketTypeTest {
|
public class PacketTypeTest {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
@ -26,6 +28,12 @@ public class PacketTypeTest {
|
|||||||
assertEquals(PacketType.Play.Client.STEER_VEHICLE, PacketType.findCurrent(Protocol.PLAY, Sender.CLIENT, "SteerVehicle"));
|
assertEquals(PacketType.Play.Client.STEER_VEHICLE, PacketType.findCurrent(Protocol.PLAY, Sender.CLIENT, "SteerVehicle"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoginStart() {
|
||||||
|
// This packet is critical for handleLoin
|
||||||
|
assertEquals(PacketLoginInStart.class, PacketType.Login.Client.START.getPacketClass());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ensureAllExist() {
|
public void ensureAllExist() {
|
||||||
boolean missing = false;
|
boolean missing = false;
|
||||||
|
@ -4,18 +4,6 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import net.minecraft.server.v1_9_R2.ChatComponentText;
|
|
||||||
import net.minecraft.server.v1_9_R2.ChunkCoordIntPair;
|
|
||||||
import net.minecraft.server.v1_9_R2.DataWatcher;
|
|
||||||
import net.minecraft.server.v1_9_R2.IBlockData;
|
|
||||||
import net.minecraft.server.v1_9_R2.IChatBaseComponent;
|
|
||||||
import net.minecraft.server.v1_9_R2.IChatBaseComponent.ChatSerializer;
|
|
||||||
import net.minecraft.server.v1_9_R2.NBTCompressedStreamTools;
|
|
||||||
import net.minecraft.server.v1_9_R2.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
|
||||||
import net.minecraft.server.v1_9_R2.PlayerConnection;
|
|
||||||
import net.minecraft.server.v1_9_R2.ServerPing;
|
|
||||||
import net.minecraft.server.v1_9_R2.ServerPing.ServerData;
|
|
||||||
import net.minecraft.server.v1_9_R2.ServerPing.ServerPingPlayerSample;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -28,6 +16,20 @@ import org.junit.runner.RunWith;
|
|||||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||||
|
|
||||||
import com.comphenix.protocol.BukkitInitialization;
|
import com.comphenix.protocol.BukkitInitialization;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_9_R2.ChatComponentText;
|
||||||
|
import net.minecraft.server.v1_9_R2.ChunkCoordIntPair;
|
||||||
|
import net.minecraft.server.v1_9_R2.DataWatcher;
|
||||||
|
import net.minecraft.server.v1_9_R2.IBlockData;
|
||||||
|
import net.minecraft.server.v1_9_R2.IChatBaseComponent;
|
||||||
|
import net.minecraft.server.v1_9_R2.IChatBaseComponent.ChatSerializer;
|
||||||
|
import net.minecraft.server.v1_9_R2.NBTCompressedStreamTools;
|
||||||
|
import net.minecraft.server.v1_9_R2.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
||||||
|
import net.minecraft.server.v1_9_R2.PlayerConnection;
|
||||||
|
import net.minecraft.server.v1_9_R2.ServerPing;
|
||||||
|
import net.minecraft.server.v1_9_R2.ServerPing.ServerData;
|
||||||
|
import net.minecraft.server.v1_9_R2.ServerPing.ServerPingPlayerSample;
|
||||||
|
|
||||||
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
|
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
|
||||||
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
|
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
|
||||||
@ -136,4 +138,9 @@ public class MinecraftReflectionTest {
|
|||||||
Object nmsStack = MinecraftReflection.getMinecraftItemStack(stack);
|
Object nmsStack = MinecraftReflection.getMinecraftItemStack(stack);
|
||||||
assertEquals(stack, MinecraftReflection.getBukkitItemStack(nmsStack));
|
assertEquals(stack, MinecraftReflection.getBukkitItemStack(nmsStack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGameProfile() {
|
||||||
|
assertEquals(GameProfile.class, MinecraftReflection.getGameProfileClass());
|
||||||
|
}
|
||||||
}
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren