il2cpp_bridge_rs/api/wrappers/
application.rs1use crate::api::{cache, internals::Internals};
8use crate::structs::Il2cppString;
9use std::ffi::c_void;
10
11pub struct Application;
13
14impl Application {
15 pub fn unity_version() -> Result<String, String> {
19 match Self::get_string("get_unityVersion") {
20 Ok(ver) if ver.is_empty() => Ok("unknown".to_string()),
21 Ok(ver) => Ok(ver),
22 Err(e) => Err(e),
23 }
24 }
25
26 pub fn version() -> Result<String, String> {
28 Self::get_string("get_version")
29 }
30
31 pub fn identifier() -> Result<String, String> {
35 let id = Self::get_string("get_identifier");
36 if let Ok(val) = &id {
37 if !val.is_empty() {
38 return id;
39 }
40 }
41 let id = Self::get_string("get_bundleIdentifier");
42 if let Ok(val) = &id {
43 if !val.is_empty() {
44 return id;
45 }
46 }
47 Ok("unknown.application".to_string())
48 }
49
50 pub fn data_path() -> Result<String, String> {
54 Self::get_string("get_persistentDataPath")
55 }
56
57 fn get_string(method_name: &str) -> Result<String, String> {
58 let full_name = format!("UnityEngine.Application::{}", method_name);
59
60 let func = Internals::resolve(&full_name);
61 if !func.is_null() {
62 unsafe {
63 let func: extern "C" fn() -> *mut c_void = std::mem::transmute(func);
64 let result = func();
65 if result.is_null() {
66 return Ok(String::new());
67 }
68 let s = result as *mut Il2cppString;
69 return Ok((*s).to_string().unwrap_or_default());
70 }
71 }
72
73 let klass = cache::coremodule()
74 .class("UnityEngine.Application")
75 .ok_or("Class 'UnityEngine.Application' not found")?;
76
77 let method = klass
78 .method(method_name)
79 .ok_or(format!("Method '{}' not found", method_name))?;
80
81 unsafe {
82 let result: Result<*mut Il2cppString, _> = method.call(&[]);
83 match result {
84 Ok(ptr) => {
85 if ptr.is_null() {
86 Ok(String::new())
87 } else {
88 Ok((*ptr).to_string().unwrap_or_default())
89 }
90 }
91 Err(e) => Err(e),
92 }
93 }
94 }
95}