commit 34090f3110ff5b9295b904f6803b33899065310b
parent bcec1f5651e9c9c5971bef9f7f02aef481418198
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Mon, 29 Jul 2024 16:02:13 +0200

fix(native/composer_hooks): load when composer starts

Diffstat:
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/Feature.kt | 2+-
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/ComposerHooks.kt | 8+++++++-
Mnative/rust/Cargo.lock | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mnative/rust/Cargo.toml | 1+
Mnative/rust/src/modules/composer_hook.rs | 40+++++++++++++++++++++++++++-------------
5 files changed, 90 insertions(+), 15 deletions(-)

diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/Feature.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/Feature.kt @@ -10,7 +10,7 @@ abstract class Feature( lateinit var context: ModContext lateinit var registerNextActivityCallback: ((Activity) -> Unit) -> Unit - protected fun defer(block: () -> Unit) { + protected fun defer(block: suspend () -> Unit) { context.coroutineScope.launch { runCatching { block() diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/ComposerHooks.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/ComposerHooks.kt @@ -211,7 +211,13 @@ class ComposerHooks: Feature("ComposerHooks") { context.log.error("Failed to load composer loader script", it) }.getOrNull() ?: return context.native.setComposerLoader(""" - (() => { const _getImportsFunctionName = "$getImportsFunctionName"; $loaderScript })(); + const i = setInterval(() => { + try { + require('composer_core/src/DeviceBridge').toString(); + clearInterval(i); + (() => { const _getImportsFunctionName = "$getImportsFunctionName"; $loaderScript })(); + } catch (e) {} + }, 200) """.trimIndent().trim()) } diff --git a/native/rust/Cargo.lock b/native/rust/Cargo.lock @@ -185,6 +185,17 @@ dependencies = [ ] [[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -338,6 +349,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] name = "proc-macro2" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -382,6 +399,36 @@ dependencies = [ ] [[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] name = "regex" version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -481,6 +528,7 @@ dependencies = [ "once_cell", "paste", "procfs", + "rand", "serde_json", "zstd", ] @@ -533,6 +581,12 @@ dependencies = [ ] [[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] name = "wasm-bindgen" version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/native/rust/Cargo.toml b/native/rust/Cargo.toml @@ -16,5 +16,6 @@ nix = { version = "0.29.0", features = ["fs"] } once_cell = "1.19.0" paste = "1.0.15" procfs = "0.16.0" +rand = "0.8.5" serde_json = "1.0.120" zstd = "0.13.2" diff --git a/native/rust/src/modules/composer_hook.rs b/native/rust/src/modules/composer_hook.rs @@ -1,6 +1,6 @@ #![allow(dead_code, unused_imports)] -use super::util::composer_utils::ComposerModule; +use super::util::composer_utils::{ComposerModule, ModuleTag}; use std::{collections::HashMap, ffi::{c_void, CStr}, sync::Mutex}; use jni::{objects::JString, sys::jobject, JNIEnv}; use once_cell::sync::Lazy; @@ -94,7 +94,8 @@ def_hook!( |arg0: *mut c_void, arg1: *const u8, arg2: i32| { let handle = aasset_manager_open_original.unwrap()(arg0, arg1, arg2); - if !handle.is_null() && CStr::from_ptr(arg1).to_str().unwrap().ends_with("blizzard.composermodule") { + let path = Lazy::new(|| CStr::from_ptr(arg1).to_str().unwrap()); + if !handle.is_null() && path.starts_with("bridge_observables") { let asset_buffer = aasset_get_buffer_original.unwrap()(handle); let asset_length = aasset_get_length_original.unwrap()(handle); debug!("asset buffer: {:p}, length: {}", asset_buffer, asset_length); @@ -106,17 +107,32 @@ def_hook!( let mut composer_module = ComposerModule::parse(decompressed).expect("Failed to parse composer module"); let mut tags = composer_module.get_tags(); + let mut new_tags = Vec::new(); - for (tag1, tag2) in tags.iter_mut() { - if tag1.to_string().unwrap().ends_with("BlizzardEventLogger.js") { - let mut buffer = Vec::new(); - buffer.extend(composer_loader.as_bytes()); - buffer.extend(tag2.get_buffer()); - tag2.set_buffer(buffer); - debug!("composer loader injected in {}", tag1.to_string().unwrap()); + for (tag1, _) in tags.iter_mut() { + let name = tag1.to_string().unwrap(); + if !name.ends_with("src/utils/converter.js") { + continue; } + + let old_file_name = name.split_once(".").unwrap().0.to_owned() + rand::random::<u32>().to_string().as_str(); + tag1.set_buffer((old_file_name.to_owned() + ".js").as_bytes().to_vec()); + let original_module_path = path.split_once(".").unwrap().0.to_owned() + "/" + &old_file_name; + + let hooked_module = format!("{};module.exports = require(\"{}\");", composer_loader, original_module_path); + + new_tags.push( + ( + ModuleTag::new(128, name.as_bytes().to_vec()), + ModuleTag::new(128, hooked_module.as_bytes().to_vec()) + ) + ); + + debug!("composer loader injected in {}", name); + break; } + tags.extend(new_tags); composer_module.set_tags(tags); let compressed = composer_module.to_bytes(); @@ -151,10 +167,8 @@ def_hook!( |arg0: *mut c_void, arg1: *mut c_void, arg2: *mut c_void, arg3: *const u8, arg4: *const u8, arg5: *const u8, arg6: *mut c_void, arg7: u32| { #[cfg(target_arch = "aarch64")] { - if GLOBAL_INSTANCE.is_none() || GLOBAL_CTX.is_none() { - GLOBAL_INSTANCE = Some(arg0); - GLOBAL_CTX = Some(arg1); - } + GLOBAL_INSTANCE = Some(arg0); + GLOBAL_CTX = Some(arg1); } js_eval_original.unwrap()(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) }