在 Java 中通过引用获取对象
Getting an Object by reference in Java
这个网站的新手,很高兴分享我的第一个问题:)
好的,我将解释我目前的设置,以便更好地理解我的问题。
我有 2 java 个应用程序:
- 逻辑应用程序(发生所有重负载的地方)
- 已检测的应用程序(应用程序已检测到 运行ning 游戏)
我对这 2 个应用程序所做的是使用 Instrumented Application 从游戏中提取信息,然后将其发送到逻辑应用程序。
information/data 的提取是通过 Java 反射 API 完成的。然后在提取信息后,通过 RMI 将其发送到逻辑应用程序(更多内容见下文)。
我有 2 个应用程序而不是 1 个的原因是因为游戏 运行s 在 Java 7(旧游戏)上,所以 Instrumented Application 运行s 在 Java 7,我可以 运行 Logic 应用程序在我想要的任何 java 版本上。
我在两者之间传输data/information的方式是通过RMI(远程方法调用)。
说明:Logic 应用程序在 Instrumented App 调用 getter 方法,该方法使用反射 API 从它被检测到的游戏中获取字段值并 return 它。
现在你们已经了解了我基本上在做什么,现在是我被迷惑了很长一段时间的挑战。
问题:
大多数由反射 return 编辑的字段值都是可序列化的,因此它们可以毫无问题地通过 RMI。但是,有些是不可序列化的对象,例如“Item”。
“Item”是一个对象,它包含 3 个值:ID、名称、数量。所以我的想法是制作一个包装器并发送包装器,这样问题就解决了吗?但是没有,另一个挑战突然出现了。
突然出现的挑战是:如果我需要知道我在另一个时间取出的对象“Item”的数量怎么办?如果我的整个事情是 1 个应用程序,我会使用反射 API 通过以下方式使用对象获取字段:
getClassLoader().loadClass("ItemClass").getDeclaredField("Item").get(ObjectThatIPreviouslyFetched);
但是由于我必须将对象转移到逻辑应用程序,我无法将对象本身“项目”转移,所以我无法 return 到该对象并获得更新的信息,除非我再次查找该对象浪费资源并使我的整个过程变慢。
应用程序是这样工作的:
Instrumented App -> Reflection -> Game -> Field Value (Object called Item) -> Wrapper -> RMI -> Logic Application(对象信息已发送,但对象本身由于不可序列化而无法发送)
问题摘要(使用上面的指针):如何取回对象(项目)以便使用反射获取有关它的更新信息。
这是我获取字段值(对象)的方法:
/**
*
* @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;
}
此方法可在逻辑应用程序中找到,并将 Instrumented 应用程序附加到 运行ning 游戏:
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();
}
}
}
我希望一切都可以理解,我不是英语母语,所以如果有什么不对的地方,我深表歉意。
谢谢!
此问题没有“正确”答案。
我打算制作一个存储对象的地图,并为每个对象分配一个唯一的键。然后我通过RMI发送对象的唯一键,现在我可以使用唯一键获取对象并随时发送对象的内部信息。
如果对象没有循环引用,请尝试 JSON。推荐使用 GSON。
另一种方法是使用 UnSafe 在内存中注册它们,然后使用地址获取对象。尽管您稍后必须释放它,否则它会变成焦土。
这个网站的新手,很高兴分享我的第一个问题:)
好的,我将解释我目前的设置,以便更好地理解我的问题。
我有 2 java 个应用程序:
- 逻辑应用程序(发生所有重负载的地方)
- 已检测的应用程序(应用程序已检测到 运行ning 游戏)
我对这 2 个应用程序所做的是使用 Instrumented Application 从游戏中提取信息,然后将其发送到逻辑应用程序。 information/data 的提取是通过 Java 反射 API 完成的。然后在提取信息后,通过 RMI 将其发送到逻辑应用程序(更多内容见下文)。
我有 2 个应用程序而不是 1 个的原因是因为游戏 运行s 在 Java 7(旧游戏)上,所以 Instrumented Application 运行s 在 Java 7,我可以 运行 Logic 应用程序在我想要的任何 java 版本上。
我在两者之间传输data/information的方式是通过RMI(远程方法调用)。 说明:Logic 应用程序在 Instrumented App 调用 getter 方法,该方法使用反射 API 从它被检测到的游戏中获取字段值并 return 它。
现在你们已经了解了我基本上在做什么,现在是我被迷惑了很长一段时间的挑战。
问题:
大多数由反射 return 编辑的字段值都是可序列化的,因此它们可以毫无问题地通过 RMI。但是,有些是不可序列化的对象,例如“Item”。 “Item”是一个对象,它包含 3 个值:ID、名称、数量。所以我的想法是制作一个包装器并发送包装器,这样问题就解决了吗?但是没有,另一个挑战突然出现了。
突然出现的挑战是:如果我需要知道我在另一个时间取出的对象“Item”的数量怎么办?如果我的整个事情是 1 个应用程序,我会使用反射 API 通过以下方式使用对象获取字段:
getClassLoader().loadClass("ItemClass").getDeclaredField("Item").get(ObjectThatIPreviouslyFetched);
但是由于我必须将对象转移到逻辑应用程序,我无法将对象本身“项目”转移,所以我无法 return 到该对象并获得更新的信息,除非我再次查找该对象浪费资源并使我的整个过程变慢。
应用程序是这样工作的:
Instrumented App -> Reflection -> Game -> Field Value (Object called Item) -> Wrapper -> RMI -> Logic Application(对象信息已发送,但对象本身由于不可序列化而无法发送)
问题摘要(使用上面的指针):如何取回对象(项目)以便使用反射获取有关它的更新信息。
这是我获取字段值(对象)的方法:
/**
*
* @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;
}
此方法可在逻辑应用程序中找到,并将 Instrumented 应用程序附加到 运行ning 游戏:
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();
}
}
}
我希望一切都可以理解,我不是英语母语,所以如果有什么不对的地方,我深表歉意。
谢谢!
此问题没有“正确”答案。
我打算制作一个存储对象的地图,并为每个对象分配一个唯一的键。然后我通过RMI发送对象的唯一键,现在我可以使用唯一键获取对象并随时发送对象的内部信息。
如果对象没有循环引用,请尝试 JSON。推荐使用 GSON。
另一种方法是使用 UnSafe 在内存中注册它们,然后使用地址获取对象。尽管您稍后必须释放它,否则它会变成焦土。