mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-13 09:17:28 +07:00
Added basic RMI-like system for network evens
This commit is contained in:
125
core/src/io/anuke/mindustry/net/Invoke.java
Normal file
125
core/src/io/anuke/mindustry/net/Invoke.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
|
import com.badlogic.gdx.utils.reflect.Method;
|
||||||
|
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.net.Net.SendMode;
|
||||||
|
import io.anuke.mindustry.net.Packets.InvokePacket;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.ucore.util.IOUtils;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class Invoke {
|
||||||
|
private static ObjectMap<Class, ObjectMap<String, Method>> methods = new ObjectMap<>();
|
||||||
|
private static ObjectMap<String, Class> classes = new ObjectMap<>();
|
||||||
|
|
||||||
|
public static void on(Class<?> type, String methodName, Object... args){
|
||||||
|
try {
|
||||||
|
Method method = getMethod(type, methodName);
|
||||||
|
InvokePacket packet = new InvokePacket();
|
||||||
|
packet.args = args;
|
||||||
|
packet.type = type;
|
||||||
|
packet.method = method;
|
||||||
|
packet.args = args;
|
||||||
|
Net.send(packet, SendMode.tcp);
|
||||||
|
method.invoke(null, args);
|
||||||
|
}catch (ReflectionException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeObjects(ByteBuffer buffer, Object[] objects){
|
||||||
|
for(Object o : objects){
|
||||||
|
Class type = o.getClass();
|
||||||
|
|
||||||
|
if(type == int.class){
|
||||||
|
buffer.putInt((Integer)o);
|
||||||
|
}else if(type == float.class){
|
||||||
|
buffer.putFloat((Float)o);
|
||||||
|
}else if(type == short.class){
|
||||||
|
buffer.putShort((Short)o);
|
||||||
|
}else if(type == boolean.class){
|
||||||
|
buffer.put((byte)((Boolean)o ? 1 : 0));
|
||||||
|
}else if(type == byte.class){
|
||||||
|
buffer.put((Byte)o);
|
||||||
|
}else if(type == long.class){
|
||||||
|
buffer.putLong((Long)o);
|
||||||
|
}else if(type == short.class){
|
||||||
|
buffer.putShort((Short)o);
|
||||||
|
}else if(type == Tile.class){
|
||||||
|
buffer.putInt(((Tile)o).packedPosition());
|
||||||
|
}else if(type == String.class){
|
||||||
|
IOUtils.writeString(buffer, (String)o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object[] readObjects(ByteBuffer buffer, Class[] types){
|
||||||
|
Object[] result = new Object[types.length];
|
||||||
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
Class type = types[i];
|
||||||
|
Object obj = null;
|
||||||
|
|
||||||
|
if(type == int.class){
|
||||||
|
obj = buffer.getInt();
|
||||||
|
}else if(type == float.class){
|
||||||
|
obj = buffer.getFloat();
|
||||||
|
}else if(type == short.class){
|
||||||
|
obj = buffer.getShort();
|
||||||
|
}else if(type == boolean.class){
|
||||||
|
obj = buffer.get() == 1;
|
||||||
|
}else if(type == byte.class){
|
||||||
|
obj = buffer.get();
|
||||||
|
}else if(type == long.class){
|
||||||
|
obj = buffer.getLong();
|
||||||
|
}else if(type == short.class){
|
||||||
|
obj = buffer.getShort();
|
||||||
|
}else if(type == Tile.class){
|
||||||
|
obj = Vars.world.tile(buffer.getInt());
|
||||||
|
}else if(type == String.class){
|
||||||
|
obj = IOUtils.readString(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(obj != null){
|
||||||
|
result[i] = obj;
|
||||||
|
}else{
|
||||||
|
throw new RuntimeException("Unable to read object of type '" + type + "'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Class findClass(String name) throws ReflectionException{
|
||||||
|
Class cl = classes.get(name);
|
||||||
|
if(cl == null){
|
||||||
|
cl = ClassReflection.forName(name);
|
||||||
|
classes.put(name, cl);
|
||||||
|
}
|
||||||
|
return cl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Method getMethod(Class type, String methodname) throws ReflectionException{
|
||||||
|
ObjectMap<String, Method> map = methods.get(type);
|
||||||
|
|
||||||
|
if(map == null){
|
||||||
|
map = new ObjectMap<>();
|
||||||
|
methods.put(type, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
Method method = map.get(methodname);
|
||||||
|
|
||||||
|
if(method == null){
|
||||||
|
method = ClassReflection.getMethod(type, methodname, null);
|
||||||
|
map.put(methodname, method);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return method;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package io.anuke.mindustry.net;
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Pools;
|
import com.badlogic.gdx.utils.Pools;
|
||||||
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
|
import com.badlogic.gdx.utils.reflect.Method;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.SyncEntity;
|
import io.anuke.mindustry.entities.SyncEntity;
|
||||||
|
@ -3,7 +3,9 @@ package io.anuke.mindustry.net;
|
|||||||
import com.badlogic.gdx.utils.Base64Coder;
|
import com.badlogic.gdx.utils.Base64Coder;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
|
import com.badlogic.gdx.utils.reflect.Method;
|
||||||
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||||
|
import com.sun.tools.internal.ws.wsdl.document.Import;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.SyncEntity;
|
import io.anuke.mindustry.entities.SyncEntity;
|
||||||
@ -31,6 +33,33 @@ public class Packets {
|
|||||||
public String addressTCP;
|
public String addressTCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class InvokePacket implements Packet{
|
||||||
|
public Object[] args;
|
||||||
|
public Method method;
|
||||||
|
public Class type;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(ByteBuffer buffer) {
|
||||||
|
IOUtils.writeString(buffer, method.getName());
|
||||||
|
IOUtils.writeString(buffer, type.getName());
|
||||||
|
Invoke.writeObjects(buffer, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuffer buffer) {
|
||||||
|
String methodname = IOUtils.readString(buffer);
|
||||||
|
String typename = IOUtils.readString(buffer);
|
||||||
|
|
||||||
|
try {
|
||||||
|
type = Invoke.findClass(typename);
|
||||||
|
method = Invoke.getMethod(type, methodname);
|
||||||
|
args = Invoke.readObjects(buffer, method.getParameterTypes());
|
||||||
|
}catch (ReflectionException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class WorldData extends Streamable{
|
public static class WorldData extends Streamable{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ public class Registrator {
|
|||||||
PlayerAdminPacket.class,
|
PlayerAdminPacket.class,
|
||||||
AdministerRequestPacket.class,
|
AdministerRequestPacket.class,
|
||||||
TracePacket.class,
|
TracePacket.class,
|
||||||
|
InvokePacket.class,
|
||||||
};
|
};
|
||||||
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
|
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user