2014-05-03 18:59:52 +02:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
|
|
|
|
* http://www.mod-buildcraft.com
|
|
|
|
*
|
|
|
|
* BuildCraft is distributed under the terms of the Minecraft Mod Public
|
|
|
|
* License 1.0, or MMPL. Please check the contents of the license located in
|
|
|
|
* http://www.mod-buildcraft.com/MMPL-1.0.txt
|
|
|
|
*/
|
2014-01-06 19:57:54 +01:00
|
|
|
package buildcraft.core.network;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2014-06-14 13:42:13 +02:00
|
|
|
import java.lang.reflect.Array;
|
2014-01-06 19:57:54 +01:00
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Comparator;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.TreeMap;
|
|
|
|
|
2014-05-03 18:59:52 +02:00
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
import io.netty.buffer.Unpooled;
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
import net.minecraft.entity.Entity;
|
2014-01-06 19:57:54 +01:00
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
2014-01-11 17:27:53 +01:00
|
|
|
import net.minecraft.entity.player.EntityPlayerMP;
|
2014-06-07 16:10:18 +02:00
|
|
|
import net.minecraft.inventory.Container;
|
2014-01-06 19:57:54 +01:00
|
|
|
import net.minecraft.tileentity.TileEntity;
|
2014-06-08 11:58:55 +02:00
|
|
|
import net.minecraft.world.World;
|
2014-05-03 18:59:52 +02:00
|
|
|
|
2014-06-22 11:49:59 +02:00
|
|
|
import cpw.mods.fml.common.FMLCommonHandler;
|
|
|
|
|
2014-02-16 12:10:01 +01:00
|
|
|
import buildcraft.BuildCraftCore;
|
2014-05-01 19:34:01 +02:00
|
|
|
import buildcraft.api.core.JavaTools;
|
2014-02-16 12:10:01 +01:00
|
|
|
import buildcraft.core.DefaultProps;
|
2014-02-23 11:59:30 +01:00
|
|
|
import buildcraft.core.network.serializers.ClassMapping;
|
|
|
|
import buildcraft.core.network.serializers.ClassSerializer;
|
|
|
|
import buildcraft.core.network.serializers.SerializationContext;
|
2014-06-14 13:42:13 +02:00
|
|
|
import buildcraft.core.utils.Utils;
|
2014-02-16 12:10:01 +01:00
|
|
|
import buildcraft.transport.Pipe;
|
2014-01-06 19:57:54 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This is a first implementation of a RPC connector, using the regular tile
|
|
|
|
* synchronization layers as a communication protocol. As a result, these
|
|
|
|
* RPCs must be sent and received by a tile entity.
|
|
|
|
*/
|
2014-05-03 18:59:52 +02:00
|
|
|
public final class RPCHandler {
|
2014-06-15 19:27:17 +02:00
|
|
|
|
2014-03-08 20:33:36 +01:00
|
|
|
public static int MAX_PACKET_SIZE = 30 * 1024;
|
|
|
|
|
2014-05-03 18:59:52 +02:00
|
|
|
private static Map<String, RPCHandler> handlers = new TreeMap<String, RPCHandler>();
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-15 19:27:17 +02:00
|
|
|
private Class<? extends Object> handledClass;
|
2014-05-24 21:15:47 +02:00
|
|
|
|
2014-01-06 19:57:54 +01:00
|
|
|
private Map<String, Integer> methodsMap = new TreeMap<String, Integer>();
|
2014-01-08 22:43:25 +01:00
|
|
|
|
|
|
|
class MethodMapping {
|
|
|
|
Method method;
|
2014-06-15 19:27:17 +02:00
|
|
|
Class[] parameters;
|
2014-02-23 11:59:30 +01:00
|
|
|
ClassSerializer [] mappings;
|
2014-01-08 22:43:25 +01:00
|
|
|
boolean hasInfo = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private MethodMapping [] methods;
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-15 19:27:17 +02:00
|
|
|
private RPCHandler(Class<? extends Object> c) {
|
2014-05-24 21:05:23 +02:00
|
|
|
handledClass = c;
|
2014-05-01 19:34:01 +02:00
|
|
|
Method [] sortedMethods = JavaTools.getAllMethods (c).toArray(new Method [0]);
|
2014-01-08 22:43:25 +01:00
|
|
|
|
2014-05-03 18:59:52 +02:00
|
|
|
LinkedList<MethodMapping> mappings = new LinkedList<MethodMapping>();
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-05-03 18:59:52 +02:00
|
|
|
Arrays.sort(sortedMethods, new Comparator<Method>() {
|
2014-01-06 19:57:54 +01:00
|
|
|
@Override
|
|
|
|
public int compare(Method o1, Method o2) {
|
|
|
|
return o1.getName().compareTo(o2.getName());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-05-03 18:59:52 +02:00
|
|
|
LinkedList<Method> rpcMethods = new LinkedList<Method>();
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-03-08 18:51:55 +01:00
|
|
|
for (Method sortedMethod : sortedMethods) {
|
|
|
|
if (sortedMethod.getAnnotation (RPC.class) != null) {
|
2014-03-29 17:51:08 +01:00
|
|
|
sortedMethod.setAccessible(true);
|
2014-03-08 18:51:55 +01:00
|
|
|
methodsMap.put(sortedMethod.getName(), rpcMethods.size());
|
|
|
|
rpcMethods.add(sortedMethod);
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-01-08 22:43:25 +01:00
|
|
|
MethodMapping mapping = new MethodMapping();
|
2014-03-08 18:51:55 +01:00
|
|
|
mapping.method = sortedMethod;
|
|
|
|
mapping.parameters = sortedMethod.getParameterTypes();
|
2014-02-23 15:33:28 +01:00
|
|
|
mapping.mappings = new ClassSerializer [mapping.parameters.length];
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-01-08 22:43:25 +01:00
|
|
|
for (int j = 0; j < mapping.parameters.length; ++j) {
|
2014-05-03 18:59:52 +02:00
|
|
|
if (int.class.equals(mapping.parameters[j])) {
|
2014-01-06 19:57:54 +01:00
|
|
|
// accepted
|
2014-05-03 18:59:52 +02:00
|
|
|
} else if (char.class.equals(mapping.parameters[j])) {
|
2014-01-11 13:59:30 +01:00
|
|
|
// accepted
|
2014-05-03 18:59:52 +02:00
|
|
|
} else if (float.class.equals(mapping.parameters[j])) {
|
2014-02-01 17:19:07 +01:00
|
|
|
// accepted
|
2014-01-08 22:43:25 +01:00
|
|
|
} else if (mapping.parameters [j].equals(RPCMessageInfo.class)) {
|
|
|
|
mapping.hasInfo = true;
|
2014-01-06 19:57:54 +01:00
|
|
|
} else {
|
2014-01-08 22:43:25 +01:00
|
|
|
mapping.mappings [j] = ClassMapping.get(mapping.parameters [j]);
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
}
|
2014-01-08 22:43:25 +01:00
|
|
|
|
|
|
|
mappings.add(mapping);
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-08 22:43:25 +01:00
|
|
|
methods = mappings.toArray(new MethodMapping [mappings.size()]);
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
2014-06-22 11:49:59 +02:00
|
|
|
private static RPCHandler getHandler(Object object) {
|
|
|
|
Class<?> clas;
|
|
|
|
|
|
|
|
if (object instanceof Class<?>) {
|
|
|
|
clas = (Class<?>) object;
|
|
|
|
} else {
|
|
|
|
clas = object.getClass();
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
2014-06-22 11:49:59 +02:00
|
|
|
if (!handlers.containsKey(clas.getName())) {
|
|
|
|
handlers.put(clas.getName(), new RPCHandler(clas));
|
|
|
|
}
|
|
|
|
|
|
|
|
return handlers.get(clas.getName());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void rpcServer(Object object, String method, Object... actuals) {
|
2014-06-08 11:58:55 +02:00
|
|
|
BuildCraftPacket packet = createPacket(object, method, actuals);
|
2014-01-06 19:57:54 +01:00
|
|
|
|
|
|
|
if (packet != null) {
|
2014-06-07 16:10:18 +02:00
|
|
|
if (packet instanceof PacketRPCTile) {
|
|
|
|
for (PacketRPCTile p : ((PacketRPCTile) packet).breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
|
|
|
|
BuildCraftCore.instance.sendToServer(p);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BuildCraftCore.instance.sendToServer(packet);
|
2014-03-08 18:51:55 +01:00
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
public static void rpcPlayer(EntityPlayer player, Object object, String method, Object... actuals) {
|
|
|
|
BuildCraftPacket packet = createPacket(object, method, actuals);
|
2014-01-06 19:57:54 +01:00
|
|
|
|
|
|
|
if (packet != null) {
|
2014-06-07 16:10:18 +02:00
|
|
|
if (packet instanceof PacketRPCTile) {
|
|
|
|
for (PacketRPCTile p : ((PacketRPCTile) packet).breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
|
|
|
|
BuildCraftCore.instance.sendToPlayer(player, p);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BuildCraftCore.instance.sendToPlayer(player, packet);
|
2014-03-08 20:33:36 +01:00
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-22 11:49:59 +02:00
|
|
|
public static void rpcBroadcastWorldPlayers(World world, Object object, String method, Object... actuals) {
|
2014-06-08 11:58:55 +02:00
|
|
|
RPCHandler.rpcBroadcastPlayersAtDistance(world, object, method, DefaultProps.NETWORK_UPDATE_RANGE, actuals);
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
public static void rpcBroadcastPlayersAtDistance(World world, Object object, String method, int maxDistance,
|
|
|
|
Object... actuals) {
|
|
|
|
BuildCraftPacket packet = createPacket(object, method, actuals);
|
2014-01-11 17:27:53 +01:00
|
|
|
|
|
|
|
if (packet != null) {
|
2014-06-08 11:58:55 +02:00
|
|
|
if (packet instanceof PacketRPCTile) {
|
|
|
|
TileEntity tile = (TileEntity) object;
|
2014-01-11 17:27:53 +01:00
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
for (PacketRPCTile p : ((PacketRPCTile) packet)
|
|
|
|
.breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
for (Object o : world.playerEntities) {
|
|
|
|
EntityPlayerMP player = (EntityPlayerMP) o;
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
if (Math.abs(player.posX - tile.xCoord) <= maxDistance
|
|
|
|
&& Math.abs(player.posY - tile.yCoord) <= maxDistance
|
|
|
|
&& Math.abs(player.posZ - tile.zCoord) <= maxDistance) {
|
|
|
|
BuildCraftCore.instance.sendToPlayer(player, p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (Object o : world.playerEntities) {
|
|
|
|
EntityPlayerMP player = (EntityPlayerMP) o;
|
2014-02-01 17:19:07 +01:00
|
|
|
|
2014-02-16 12:10:01 +01:00
|
|
|
BuildCraftCore.instance.sendToPlayer(player, packet);
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-22 11:49:59 +02:00
|
|
|
public static void rpcBroadcastAllPlayers(Object object, String method, Object... actuals) {
|
|
|
|
BuildCraftPacket packet = createPacket(object, method, actuals);
|
|
|
|
|
|
|
|
if (packet != null) {
|
|
|
|
for (Object o : FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().playerEntityList) {
|
|
|
|
EntityPlayerMP player = (EntityPlayerMP) o;
|
|
|
|
|
|
|
|
BuildCraftCore.instance.sendToPlayer(player, packet);
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
2014-06-22 11:49:59 +02:00
|
|
|
}
|
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-22 11:49:59 +02:00
|
|
|
public static void receiveStaticRPC(Class clas, RPCMessageInfo info, ByteBuf data) {
|
|
|
|
if (clas != null) {
|
|
|
|
getHandler(clas).internalRpcReceive(clas, info, data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void receiveRPC(Object obj, RPCMessageInfo info, ByteBuf data) {
|
|
|
|
if (obj != null) {
|
|
|
|
getHandler(obj.getClass()).internalRpcReceive(obj, info, data);
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-15 19:27:17 +02:00
|
|
|
private PacketRPCPipe createRCPPacketPipe(Pipe<?> pipe, String method, Object ... actuals) {
|
2014-02-15 22:29:48 +01:00
|
|
|
ByteBuf data = Unpooled.buffer();
|
2014-01-06 19:57:54 +01:00
|
|
|
|
|
|
|
try {
|
2014-02-01 17:19:07 +01:00
|
|
|
TileEntity tile = pipe.container;
|
|
|
|
|
2014-01-08 22:43:25 +01:00
|
|
|
// In order to save space on message, we assuming dimensions ids
|
|
|
|
// small. Maybe worth using a varint instead
|
2014-02-15 22:29:48 +01:00
|
|
|
data.writeShort(tile.getWorldObj().provider.dimensionId);
|
2014-01-06 19:57:54 +01:00
|
|
|
data.writeInt(tile.xCoord);
|
|
|
|
data.writeInt(tile.yCoord);
|
|
|
|
data.writeInt(tile.zCoord);
|
|
|
|
|
2014-02-01 17:19:07 +01:00
|
|
|
writeParameters(method, data, actuals);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
|
2014-02-16 12:10:01 +01:00
|
|
|
byte [] bytes = new byte [data.readableBytes()];
|
|
|
|
data.readBytes(bytes);
|
|
|
|
|
|
|
|
return new PacketRPCPipe(bytes);
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
private static BuildCraftPacket createPacket(Object object, String method, Object... actuals) {
|
|
|
|
BuildCraftPacket packet = null;
|
2014-02-01 17:19:07 +01:00
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
if (object instanceof Container) {
|
2014-06-22 11:49:59 +02:00
|
|
|
packet = getHandler(object).createRCPPacketContainer(method, actuals);
|
2014-06-08 11:58:55 +02:00
|
|
|
} else if (object instanceof TileEntity) {
|
2014-06-22 11:49:59 +02:00
|
|
|
packet = getHandler(object).createRCPPacketTile((TileEntity) object, method, actuals);
|
2014-06-08 11:58:55 +02:00
|
|
|
} else if (object instanceof Entity) {
|
2014-06-22 11:49:59 +02:00
|
|
|
packet = getHandler(object).createRCPPacketEntity((Entity) object, method, actuals);
|
|
|
|
} else if (object instanceof Class<?>) {
|
|
|
|
packet = getHandler(object).createRCPPacketStatic((Class<?>) object, method, actuals);
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
return packet;
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
private byte[] getBytes(String method, Object... actuals) {
|
2014-06-07 16:10:18 +02:00
|
|
|
ByteBuf data = Unpooled.buffer();
|
|
|
|
|
|
|
|
try {
|
|
|
|
writeParameters(method, data, actuals);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
byte [] bytes = new byte [data.readableBytes()];
|
2014-06-07 16:10:18 +02:00
|
|
|
data.readBytes(bytes);
|
|
|
|
|
2014-06-08 11:58:55 +02:00
|
|
|
return bytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
private PacketRPCTile createRCPPacketTile(TileEntity tile, String method, Object... actuals) {
|
|
|
|
return new PacketRPCTile(tile, getBytes(method, actuals));
|
|
|
|
}
|
|
|
|
|
|
|
|
private PacketRPCGui createRCPPacketContainer(String method, Object... actuals) {
|
|
|
|
return new PacketRPCGui(getBytes(method, actuals));
|
|
|
|
}
|
|
|
|
|
|
|
|
private PacketRPCEntity createRCPPacketEntity(Entity entity, String method, Object... actuals) {
|
|
|
|
return new PacketRPCEntity(entity, getBytes(method, actuals));
|
2014-06-07 16:10:18 +02:00
|
|
|
}
|
|
|
|
|
2014-06-22 11:49:59 +02:00
|
|
|
private BuildCraftPacket createRCPPacketStatic(Class<?> clas, String method, Object[] actuals) {
|
|
|
|
return new PacketRPCStatic(clas, getBytes(method, actuals));
|
|
|
|
}
|
|
|
|
|
2014-02-23 11:59:30 +01:00
|
|
|
private void writeParameters(String method, ByteBuf data, Object... actuals)
|
|
|
|
throws IOException, IllegalArgumentException,
|
|
|
|
IllegalAccessException {
|
2014-02-01 17:19:07 +01:00
|
|
|
if (!methodsMap.containsKey(method)) {
|
2014-02-23 11:59:30 +01:00
|
|
|
throw new RuntimeException(method + " is not a callable method of "
|
2014-05-24 21:05:23 +02:00
|
|
|
+ handledClass.getName());
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int methodIndex = methodsMap.get(method);
|
2014-02-23 11:59:30 +01:00
|
|
|
MethodMapping m = methods[methodIndex];
|
2014-05-03 18:59:52 +02:00
|
|
|
Class[] formals = m.parameters;
|
2014-02-01 17:19:07 +01:00
|
|
|
|
2014-02-23 11:59:30 +01:00
|
|
|
int expectedParameters = m.hasInfo ? formals.length - 1
|
|
|
|
: formals.length;
|
2014-02-01 17:19:07 +01:00
|
|
|
|
|
|
|
if (expectedParameters != actuals.length) {
|
|
|
|
// We accept formals + 1 as an argument, in order to support the
|
|
|
|
// special last argument RPCMessageInfo
|
|
|
|
|
|
|
|
throw new RuntimeException(getClass().getName() + "." + method
|
2014-02-23 11:59:30 +01:00
|
|
|
+ " expects " + m.parameters.length + " parameters, not "
|
|
|
|
+ actuals.length);
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
data.writeShort(methodIndex);
|
|
|
|
|
2014-02-23 11:59:30 +01:00
|
|
|
SerializationContext context = new SerializationContext();
|
|
|
|
|
2014-02-01 17:19:07 +01:00
|
|
|
for (int i = 0; i < actuals.length; ++i) {
|
2014-06-14 13:42:13 +02:00
|
|
|
if (!writePrimitive(data, formals[i], actuals[i])) {
|
2014-02-23 11:59:30 +01:00
|
|
|
m.mappings[i].write(data, actuals[i], context);
|
2014-02-01 17:19:07 +01:00
|
|
|
}
|
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
2014-06-15 19:27:17 +02:00
|
|
|
private boolean writePrimitive(ByteBuf data, Class<?> formal, Object actual) {
|
2014-06-14 13:42:13 +02:00
|
|
|
if (int.class.equals(formal)) {
|
|
|
|
data.writeInt((Integer) actual);
|
|
|
|
} else if (float.class.equals(formal)) {
|
|
|
|
data.writeFloat((Float) actual);
|
|
|
|
} else if (double.class.equals(formal)) {
|
|
|
|
data.writeDouble((Double) actual);
|
|
|
|
} else if (char.class.equals(formal)) {
|
|
|
|
data.writeChar((Character) actual);
|
|
|
|
} else if (boolean.class.equals(formal)) {
|
|
|
|
data.writeBoolean((Boolean) actual);
|
|
|
|
} else if (String.class.equals(formal)) {
|
|
|
|
Utils.writeUTF(data, (String) actual);
|
|
|
|
} else if (formal.isArray()) {
|
|
|
|
Object[] array = (Object[]) actual;
|
2014-06-15 19:27:17 +02:00
|
|
|
Class<?> componentType = formal.getComponentType();
|
2014-06-14 13:42:13 +02:00
|
|
|
data.writeInt(array.length);
|
2014-06-22 11:49:59 +02:00
|
|
|
for (Object element : array) {
|
|
|
|
writePrimitive(data, componentType, element);
|
2014-06-14 13:42:13 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-02-16 12:10:01 +01:00
|
|
|
private void internalRpcReceive (Object o, RPCMessageInfo info, ByteBuf data) {
|
2014-01-06 19:57:54 +01:00
|
|
|
try {
|
|
|
|
short methodIndex = data.readShort();
|
|
|
|
|
2014-01-08 22:43:25 +01:00
|
|
|
MethodMapping m = methods [methodIndex];
|
2014-05-03 18:59:52 +02:00
|
|
|
Class[] formals = m.parameters;
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-06-15 19:27:17 +02:00
|
|
|
Object[] actuals = new Object [formals.length];
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-01-08 22:43:25 +01:00
|
|
|
int expectedParameters = m.hasInfo ? formals.length - 1 : formals.length;
|
2014-01-06 19:57:54 +01:00
|
|
|
|
2014-02-23 11:59:30 +01:00
|
|
|
SerializationContext context = new SerializationContext();
|
|
|
|
|
2014-01-06 19:57:54 +01:00
|
|
|
for (int i = 0; i < expectedParameters; ++i) {
|
2014-06-14 13:42:13 +02:00
|
|
|
if (!readPrimitive(data, formals[i], actuals, i)) {
|
2014-02-23 11:59:30 +01:00
|
|
|
actuals [i] = m.mappings [i].read (data, actuals [i], context);
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-08 22:43:25 +01:00
|
|
|
if (m.hasInfo) {
|
2014-01-06 19:57:54 +01:00
|
|
|
actuals [actuals.length - 1] = info;
|
|
|
|
}
|
|
|
|
|
2014-02-01 17:19:07 +01:00
|
|
|
m.method.invoke(o, actuals);
|
2014-01-06 19:57:54 +01:00
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
} catch (InvocationTargetException e) {
|
|
|
|
e.printStackTrace();
|
2014-01-08 22:43:25 +01:00
|
|
|
} catch (InstantiationException e) {
|
2014-01-11 17:27:53 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
} catch (ClassNotFoundException e) {
|
2014-01-08 22:43:25 +01:00
|
|
|
e.printStackTrace();
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-06-15 19:27:17 +02:00
|
|
|
private boolean readPrimitive(ByteBuf data, Class<?> formal, Object[] actuals, int i) {
|
2014-06-14 13:42:13 +02:00
|
|
|
if (int.class.equals(formal)) {
|
|
|
|
actuals[i] = data.readInt();
|
|
|
|
} else if (float.class.equals(formal)) {
|
|
|
|
actuals[i] = data.readFloat();
|
|
|
|
} else if (double.class.equals(formal)) {
|
|
|
|
actuals[i] = data.readDouble();
|
|
|
|
} else if (char.class.equals(formal)) {
|
|
|
|
actuals[i] = data.readChar();
|
|
|
|
} else if (boolean.class.equals(formal)) {
|
|
|
|
actuals[i] = data.readBoolean();
|
|
|
|
} else if (String.class.equals(formal)) {
|
|
|
|
actuals[i] = Utils.readUTF(data);
|
|
|
|
} else if (formal.isArray()) {
|
|
|
|
final int size = data.readInt();
|
2014-06-15 19:27:17 +02:00
|
|
|
Class<?> componentType = formal.getComponentType();
|
2014-06-14 13:42:13 +02:00
|
|
|
Object[] a = (Object[]) Array.newInstance(componentType, size);
|
|
|
|
for (int z = 0; z < size; z++) {
|
|
|
|
readPrimitive(data, componentType, a, z);
|
|
|
|
}
|
|
|
|
actuals[i] = a;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2014-01-06 19:57:54 +01:00
|
|
|
}
|