Attempt to fix a NPE with packet sending

Addresses #88
This commit is contained in:
Dan Mulloy 2015-06-09 14:19:37 -04:00
parent 423cc320f6
commit 0d18bd2734
7 changed files with 33 additions and 22 deletions

View File

@ -64,6 +64,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
public static final ReportType REPORT_CANNOT_INTERCEPT_CLIENT_PACKET = new ReportType("Unable to intercept a read client packet.");
public static final ReportType REPORT_CANNOT_EXECUTE_IN_CHANNEL_THREAD = new ReportType("Cannot execute code in channel thread.");
public static final ReportType REPORT_CANNOT_FIND_GET_VERSION = new ReportType("Cannot find getVersion() in NetworkMananger");
public static final ReportType REPORT_CANNOT_SEND_PACKET = new ReportType("Unable to send packet %s to %s");
/**
* Indicates that a packet has bypassed packet listeners.
@ -668,8 +669,9 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
} else {
MinecraftMethods.getSendPacketMethod().invoke(getPlayerConnection(), packet);
}
} catch (Exception e) {
throw new RuntimeException("Unable to send server packet " + packet, e);
} catch (Throwable ex) {
ProtocolLibrary.getErrorReporter().reportWarning(factory.getPlugin(),
Report.newBuilder(REPORT_CANNOT_SEND_PACKET).messageParam(packet, playerName).error(ex).build());
}
}

View File

@ -126,7 +126,7 @@ class NetworkServerInjector extends PlayerInjector {
return;
if (!tryInjectManager()) {
Class<?> serverHandlerClass = MinecraftReflection.getNetServerHandlerClass();
Class<?> serverHandlerClass = MinecraftReflection.getPlayerConnectionClass();
// Try to override the proxied object
if (proxyServerField != null) {

View File

@ -188,7 +188,7 @@ public abstract class PlayerInjector implements SocketInjector {
// Retrieve the server handler
if (serverHandlerField == null) {
serverHandlerField = FuzzyReflection.fromObject(notchEntity).getFieldByType(
"NetServerHandler", MinecraftReflection.getNetServerHandlerClass());
"NetServerHandler", MinecraftReflection.getPlayerConnectionClass());
proxyServerField = getProxyField(notchEntity, serverHandlerField);
}
@ -402,7 +402,7 @@ public abstract class PlayerInjector implements SocketInjector {
FuzzyReflection reflection = FuzzyReflection.fromObject(currentHandler, true);
// It might be
return reflection.getFieldByType("NetServerHandler", MinecraftReflection.getNetServerHandlerClass());
return reflection.getFieldByType("NetServerHandler", MinecraftReflection.getPlayerConnectionClass());
} catch (RuntimeException e) {
// Damn
@ -428,7 +428,7 @@ public abstract class PlayerInjector implements SocketInjector {
Class<?> clazz = obj.getClass();
return MinecraftReflection.getNetLoginHandlerClass().equals(clazz) ||
MinecraftReflection.getNetServerHandlerClass().equals(clazz);
MinecraftReflection.getPlayerConnectionClass().equals(clazz);
}
/**
@ -601,7 +601,7 @@ public abstract class PlayerInjector implements SocketInjector {
final Object handler = getNetHandler(true);
// Is this a net server class?
if (MinecraftReflection.getNetServerHandlerClass().isAssignableFrom(handler.getClass())) {
if (MinecraftReflection.getPlayerConnectionClass().isAssignableFrom(handler.getClass())) {
setUpdatedPlayer(
(Player) MinecraftReflection.getBukkitEntity(getEntityPlayer(handler))
);

View File

@ -5,6 +5,7 @@ import org.bukkit.entity.Player;
import com.comphenix.protocol.injector.BukkitUnwrapper;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.google.common.base.Preconditions;
/**
* Retrieve the content of well-known fields in Minecraft.
@ -29,7 +30,7 @@ public class MinecraftFields {
if (NETWORK_ACCESSOR == null) {
Class<?> networkClass = MinecraftReflection.getNetworkManagerClass();
Class<?> connectionClass = MinecraftReflection.getNetServerHandlerClass();
Class<?> connectionClass = MinecraftReflection.getPlayerConnectionClass();
NETWORK_ACCESSOR = Accessors.getFieldAccessor(connectionClass, networkClass, true);
}
// Retrieve the network manager
@ -41,7 +42,7 @@ public class MinecraftFields {
}
/**
* Retrieve the player connection (or NetServerHandler) associated with a player.
* Retrieve the PlayerConnection (or NetServerHandler) associated with a player.
* @param player - the player.
* @return The player connection.
*/
@ -51,8 +52,10 @@ public class MinecraftFields {
// Retrieve player connection from a native instance
private static Object getPlayerConnection(Object nmsPlayer) {
Preconditions.checkNotNull(nmsPlayer, "nmsPlayer cannot be null!");
if (CONNECTION_ACCESSOR == null) {
Class<?> connectionClass = MinecraftReflection.getNetServerHandlerClass();
Class<?> connectionClass = MinecraftReflection.getPlayerConnectionClass();
CONNECTION_ACCESSOR = Accessors.getFieldAccessor(nmsPlayer.getClass(), connectionClass, true);
}
return CONNECTION_ACCESSOR.get(nmsPlayer);

View File

@ -41,7 +41,7 @@ public class MinecraftMethods {
*/
public static Method getSendPacketMethod() {
if (sendPacketMethod == null) {
Class<?> serverHandlerClass = MinecraftReflection.getNetServerHandlerClass();
Class<?> serverHandlerClass = MinecraftReflection.getPlayerConnectionClass();
try {
sendPacketMethod = FuzzyReflection.fromClass(serverHandlerClass).getMethodByName("sendPacket.*");

View File

@ -463,7 +463,7 @@ public class MinecraftReflection {
* @return TRUE if it is, FALSE otherwise.
*/
public static boolean isServerHandler(Object obj) {
return obj != null && getNetServerHandlerClass().isAssignableFrom(obj.getClass());
return obj != null && getPlayerConnectionClass().isAssignableFrom(obj.getClass());
}
/**
@ -685,7 +685,7 @@ public class MinecraftReflection {
}
// Select a method with one Minecraft object parameter
Method selected = FuzzyReflection.fromClass(getNetServerHandlerClass()).
Method selected = FuzzyReflection.fromClass(getPlayerConnectionClass()).
getMethod(FuzzyMethodContract.newBuilder().
parameterMatches(paketContract, 0).
parameterCount(1).
@ -974,16 +974,16 @@ public class MinecraftReflection {
}
/**
* Retrieve the NetServerHandler class (or PlayerConnection)
* @return The NetServerHandler class.
* Retrieve the PlayerConnection class (or NetServerHandler)
* @return The PlayerConnection class.
*/
public static Class<?> getNetServerHandlerClass() {
public static Class<?> getPlayerConnectionClass() {
try {
return getMinecraftClass("NetServerHandler", "PlayerConnection");
return getMinecraftClass("PlayerConnection", "NetServerHandler");
} catch (RuntimeException e) {
try {
// Use the player connection field
return setMinecraftClass("NetServerHandler",
return setMinecraftClass("PlayerConnection",
FuzzyReflection.fromClass(getEntityPlayerClass()).
getFieldByType("playerConnection", getNetHandlerClass()).getType()
);
@ -1012,7 +1012,7 @@ public class MinecraftReflection {
FuzzyFieldContract.newBuilder().typeMatches(playerConnection).build()
).getType();
return setMinecraftClass("NetServerHandler", fieldType);
return setMinecraftClass("PlayerConnection", fieldType);
}
}
}
@ -1025,7 +1025,7 @@ public class MinecraftReflection {
try {
return getMinecraftClass("INetworkManager", "NetworkManager");
} catch (RuntimeException e) {
Constructor<?> selected = FuzzyReflection.fromClass(getNetServerHandlerClass()).
Constructor<?> selected = FuzzyReflection.fromClass(getPlayerConnectionClass()).
getConstructor(FuzzyMethodContract.newBuilder().
parameterSuperOf(getMinecraftServerClass(), 0).
parameterSuperOf(getEntityPlayerClass(), 2).
@ -1304,7 +1304,7 @@ public class MinecraftReflection {
} else {
serverConnectionContract.
method(FuzzyMethodContract.newBuilder().
parameterExactType(getNetServerHandlerClass()));
parameterExactType(getPlayerConnectionClass()));
selected = FuzzyReflection.fromClass(getMinecraftServerClass()).
getMethod(FuzzyMethodContract.newBuilder().
@ -1454,7 +1454,7 @@ public class MinecraftReflection {
field(FuzzyFieldContract.newBuilder().
typeDerivedOf(List.class)).
method(FuzzyMethodContract.newBuilder().
parameterExactType(getNetServerHandlerClass())).
parameterExactType(getPlayerConnectionClass())).
build();
Field selected = FuzzyReflection.fromClass(MinecraftReflection.getMinecraftServerClass(), true).

View File

@ -11,6 +11,7 @@ import net.minecraft.server.v1_8_R3.IChatBaseComponent;
import net.minecraft.server.v1_8_R3.IChatBaseComponent.ChatSerializer;
import net.minecraft.server.v1_8_R3.NBTCompressedStreamTools;
import net.minecraft.server.v1_8_R3.PacketPlayOutUpdateAttributes.AttributeSnapshot;
import net.minecraft.server.v1_8_R3.PlayerConnection;
import net.minecraft.server.v1_8_R3.ServerPing;
import net.minecraft.server.v1_8_R3.ServerPing.ServerData;
import net.minecraft.server.v1_8_R3.ServerPing.ServerPingPlayerSample;
@ -94,6 +95,11 @@ public class MinecraftReflectionTest {
assertEquals(ChunkCoordIntPair.class, MinecraftReflection.getChunkCoordIntPair());
}
@Test
public void testPlayerConnection() {
assertEquals(PlayerConnection.class, MinecraftReflection.getPlayerConnectionClass());
}
@Test
public void testServerPing() {
assertEquals(ServerPing.class, MinecraftReflection.getServerPingClass());