新到这个网站,并兴奋地分享我的第一个问题:)
好的,我将解释一下我目前的设置,以便更好地理解我的问题。
我有两个java应用程序:
逻辑应用程序(发生所有重负载时)
插入指令的应用程序(插入正在运行的游戏中的应用程序)
我对这两个应用程序所做的是使用插入指令的应用程序从游戏中提取信息,然后将其发送到逻辑应用程序。信息/数据的提取是通过java反射api完成的。然后在提取完信息后,通过rmi将其发送到逻辑应用程序(下面将详细介绍)。
我之所以有2个应用程序而不是1个,是因为游戏运行在Java7(旧游戏)上,所以插入指令的应用程序运行在Java7上,我可以在我想要的任何java版本上运行逻辑应用程序。
我在2之间传输数据/信息的方式是通过rmi(远程方法调用)。说明:逻辑应用程序在插入指令的应用程序中调用getter方法,该方法使用反射api从插入指令的游戏中获取字段值并返回。
现在你们已经明白了我基本上在做什么,接下来是我被迷惑了很长一段时间的挑战。
问题:
反射返回的大多数字段值都是可序列化的,因此它们通过rmi没有问题。但是,有些是不可序列化的对象,例如“item”item”是一个对象,它包含3个值:id、name、quantity。所以我的想法是做一个 Package 并发送 Package ,这样问题就解决了,对吗?但是没有,另一个挑战出现了。
突然出现的挑战是:如果我需要知道我在另一个时间取出的对象“item”的数量怎么办?如果我的整个工作是一个应用程序,我会使用反射api通过以下方式获得使用对象的字段: getClassLoader().loadClass("ItemClass").getDeclaredField("Item").get(ObjectThatIPreviouslyFetched);
但是,由于我必须将对象转移到逻辑应用程序,我无法将对象本身转移到“item”,因此我无法返回到该对象并获取更新的信息,除非我再次查找该对象,这是一种资源浪费,并使我的整个过程变慢。
应用程序的工作方式如下:
插入指令的应用程序->反射->游戏->字段值(对象称为item)-> Package 器->rmi->逻辑应用程序(对象信息已发送,但对象本身无法发送,因为它不可变量)
问题摘要(使用上面的指针):我怎样才能取回对象(item),这样我就可以使用反射获得关于它的更新信息。
这是我用来获取字段值(对象)的方法:
/**
*
* @param params owner;fieldName;multiplier
* @param object null if static
* @return returns the value of the object provided.
*/
public Object getFieldValue(String params, Object object) {
String[] paramsSplit = params.split(";");
try {
Class<?> clazz = classLoader.loadClass(paramsSplit[0]);
Field field = clazz.getDeclaredField(paramsSplit[1]);
field.setAccessible(true);
Object o = field.get(object);
if(!paramsSplit[2].equals("0")) return getMultipliedValue((Number) o,paramsSplit[2]);
else return o;
} catch (IllegalAccessException | NoSuchFieldError | ClassNotFoundException | NoSuchFieldException e) {
e.printStackTrace();
}
return null;
}
此方法可在逻辑应用程序中找到,并将插入指令的应用程序附加到正在运行的游戏:
public void inject() {
VirtualMachine vm = null;
try {
vm = VirtualMachine.attach(String.valueOf(pid));
vm.loadAgent(Info.baseLocation());
} catch (AttachNotSupportedException | IOException |
AgentLoadException | AgentInitializationException e) {
e.printStackTrace();
} finally {
try {
if(vm != null) vm.detach();
} catch (IOException e) {
e.printStackTrace();
}
}
}
我希望一切都是可以理解的,我不是一个英语母语,所以我道歉,如果有什么事情似乎不对劲。
谢谢您!
2条答案
按热度按时间t3irkdon1#
这个问题没有“正确”的答案。
我制作了一个存储对象的Map,并为每个对象分配了一个唯一的键。然后我通过rmi发送对象的唯一密钥,现在我可以使用唯一密钥获取对象并随时发送对象的内部信息。
dwbf0jvd2#
如果对象没有循环引用,请尝试json。建议使用gson。
另一种方法是使用unsafe在内存中注册它们,然后使用地址获取对象。尽管你以后必须把它放出来,否则它的焦土就要烧焦了。