UPDATE
Add Linux and macOS support, batch class transformations with a disk cache, and add cross-platform release packaging. Also improve runtime namespace handling, keybind editing, and startup behavior.
This commit is contained in:
1 parent
910a126f04
commit
38ff6d387c
29 files changed
+2234
-491
No files matched your search
@@ -12,7 +12,6 @@ pub type JBool = u8;
|
||||
pub type EnvPtr = *mut *const *const c_void;
|
||||
|
||||
pub const JNI_OK: JInt = 0;
|
||||
pub const JNI_VERSION_1_8: JInt = 0x0001_0008;
|
||||
pub const JVMTI_VERSION_1_2: JInt = 0x3001_0200;
|
||||
|
||||
#[repr(C)]
|
||||
@@ -60,9 +59,6 @@ impl Jni {
|
||||
pub unsafe fn new_global_ref(&self, o: JObject) -> JObject {
|
||||
f!(self, 21, unsafe extern "system" fn(EnvPtr, JObject) -> JObject)(self.env, o)
|
||||
}
|
||||
pub unsafe fn delete_local_ref(&self, o: JObject) {
|
||||
f!(self, 23, unsafe extern "system" fn(EnvPtr, JObject))(self.env, o)
|
||||
}
|
||||
pub unsafe fn is_same_object(&self, a: JObject, b: JObject) -> bool {
|
||||
f!(self, 24, unsafe extern "system" fn(EnvPtr, JObject, JObject) -> JBool)(self.env, a, b) != 0
|
||||
}
|
||||
@@ -108,6 +104,15 @@ impl Jni {
|
||||
pub unsafe fn get_array_length(&self, a: JObject) -> JInt {
|
||||
f!(self, 171, unsafe extern "system" fn(EnvPtr, JObject) -> JInt)(self.env, a)
|
||||
}
|
||||
pub unsafe fn get_object_array_element(&self, a: JObject, i: JInt) -> JObject {
|
||||
f!(self, 173, unsafe extern "system" fn(EnvPtr, JObject, JInt) -> JObject)(self.env, a, i)
|
||||
}
|
||||
pub unsafe fn set_object_array_element(&self, a: JObject, i: JInt, v: JObject) {
|
||||
f!(self, 174, unsafe extern "system" fn(EnvPtr, JObject, JInt, JObject))(self.env, a, i, v)
|
||||
}
|
||||
pub unsafe fn ensure_local_capacity(&self, capacity: JInt) -> JInt {
|
||||
f!(self, 26, unsafe extern "system" fn(EnvPtr, JInt) -> JInt)(self.env, capacity)
|
||||
}
|
||||
pub unsafe fn new_object_array(&self, len: JInt, c: JClass, init: JObject) -> JObject {
|
||||
f!(self, 172, unsafe extern "system" fn(EnvPtr, JInt, JClass, JObject) -> JObject)(self.env, len, c, init)
|
||||
}
|
||||
@@ -126,9 +131,6 @@ impl Jni {
|
||||
pub unsafe fn unregister_natives(&self, c: JClass) -> JInt {
|
||||
f!(self, 216, unsafe extern "system" fn(EnvPtr, JClass) -> JInt)(self.env, c)
|
||||
}
|
||||
pub unsafe fn exception_check(&self) -> bool {
|
||||
f!(self, 228, unsafe extern "system" fn(EnvPtr) -> JBool)(self.env) != 0
|
||||
}
|
||||
|
||||
/// Returns "ExceptionClass: message" of the pending exception and clears it.
|
||||
pub unsafe fn take_exception(&self) -> Option<String> {
|
||||
@@ -236,8 +238,8 @@ pub unsafe fn add_capabilities(j: JvmtiPtr, caps: &Capabilities) -> JInt {
|
||||
f(j, caps)
|
||||
}
|
||||
|
||||
/// Installs the ClassFileLoadHook callback (field 5 of jvmtiEventCallbacks) and enables the event.
|
||||
pub unsafe fn enable_class_file_load_hook(j: JvmtiPtr, hook: ClassFileLoadHook) -> Result<(), String> {
|
||||
/// Installs the ClassFileLoadHook callback (field 5 of jvmtiEventCallbacks); the event itself stays off until enabled.
|
||||
pub unsafe fn install_class_file_load_hook(j: JvmtiPtr, hook: ClassFileLoadHook) -> Result<(), String> {
|
||||
let mut callbacks = [0usize; 40];
|
||||
callbacks[4] = hook as usize;
|
||||
let set_callbacks = std::mem::transmute::<*const c_void, unsafe extern "system" fn(JvmtiPtr, *const usize, JInt) -> JInt>(*(*j).add(121));
|
||||
@@ -245,17 +247,28 @@ pub unsafe fn enable_class_file_load_hook(j: JvmtiPtr, hook: ClassFileLoadHook)
|
||||
if rc != 0 {
|
||||
return Err(format!("SetEventCallbacks failed ({rc})"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Turns the ClassFileLoadHook event on or off. It is only on while class bytes are being captured: with the event enabled the
|
||||
/// JVM hands the bytes of every class it loads to the agent, which slows class loading down for the whole game.
|
||||
pub unsafe fn set_class_file_load_hook_enabled(j: JvmtiPtr, enabled: bool) -> Result<(), String> {
|
||||
let set_mode = std::mem::transmute::<*const c_void, unsafe extern "C" fn(JvmtiPtr, JInt, JInt, JObject, ...) -> JInt>(*(*j).add(1));
|
||||
let rc = set_mode(j, 1, EVENT_CLASS_FILE_LOAD_HOOK, std::ptr::null_mut());
|
||||
let rc = set_mode(j, enabled as JInt, EVENT_CLASS_FILE_LOAD_HOOK, std::ptr::null_mut());
|
||||
if rc != 0 {
|
||||
return Err(format!("SetEventNotificationMode failed ({rc})"));
|
||||
return Err(format!("SetEventNotificationMode({enabled}) failed ({rc})"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn retransform_class(j: JvmtiPtr, class: JClass) -> JInt {
|
||||
pub unsafe fn retransform_classes(j: JvmtiPtr, classes: &[JClass]) -> JInt {
|
||||
let f = std::mem::transmute::<*const c_void, unsafe extern "system" fn(JvmtiPtr, JInt, *const JClass) -> JInt>(*(*j).add(151));
|
||||
f(j, 1, &class)
|
||||
f(j, classes.len() as JInt, classes.as_ptr())
|
||||
}
|
||||
|
||||
pub unsafe fn redefine_classes(j: JvmtiPtr, defs: &[ClassDefinition]) -> JInt {
|
||||
let f = std::mem::transmute::<*const c_void, unsafe extern "system" fn(JvmtiPtr, JInt, *const ClassDefinition) -> JInt>(*(*j).add(86));
|
||||
f(j, defs.len() as JInt, defs.as_ptr())
|
||||
}
|
||||
|
||||
pub unsafe fn redefine_class(j: JvmtiPtr, def: &ClassDefinition) -> JInt {
|
||||
|
||||
Reference in new issue
Block a user