Compare commits

...

1 commit

Author SHA1 Message Date
VitalikObject
5226bfd386 x86 version 2025-03-29 23:38:45 +02:00
16 changed files with 103 additions and 82 deletions

View file

@ -1,2 +1,5 @@
[build]
target = "armv7-linux-androideabi"
[target.i686-linux-android]
linker = "C:\\android-ndk-r27c\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\i686-linux-android22-clang++.cmd"
rustflags = [
"-C", "link-arg=C:\\android-ndk-r27c\\toolchains\\llvm\\prebuilt\\windows-x86_64\\lib\\clang\\18\\lib\\linux\\libclang_rt.builtins-i686-android.a"
]

4
libserver/build.rs Normal file
View file

@ -0,0 +1,4 @@
fn main() {
println!("cargo:rustc-link-search=native=C:\\android-ndk-r27c\\toolchains\\llvm\\prebuilt\\windows-x86_64\\lib\\clang\\18\\lib\\linux");
println!("cargo:rustc-link-lib=static=clang_rt.builtins-i686-android.a");
}

View file

@ -4,7 +4,7 @@ pub struct ByteStream(pub *const u8);
impl ByteStream {
pub fn new(initial_capacity: usize) -> Self {
import!(byte_stream_ctor(ptr: *const u8, initial_capacity: i32) -> () = 0x1A0DA8 + 1);
import!(byte_stream_ctor(ptr: *const u8, initial_capacity: i32) -> () = 0x2688E6);
let instance = malloc(40);
byte_stream_ctor(instance, initial_capacity as i32);
Self(instance)

View file

@ -1,5 +1,6 @@
use proc_maps::Pid;
use std::{ffi::c_void, sync::LazyLock};
use std::fs::File;
use std::io::{self, BufRead};
pub static LIBG_BASE: LazyLock<usize> = LazyLock::new(|| get_module_base("libg.so").unwrap());
@ -7,7 +8,7 @@ macro_rules! import {
($name:ident($($arg_name:ident: $arg_type:ty),*) -> $ret_type:ty = $rva:expr) => {
pub fn $name($($arg_name: $arg_type,)*) -> $ret_type {
unsafe {
type FuncType = unsafe extern "C" fn($($arg_type,)*) -> $ret_type;
type FuncType = unsafe extern "cdecl" fn($($arg_type,)*) -> $ret_type;
::std::mem::transmute::<usize, FuncType>(*crate::ffi_util::LIBG_BASE + $rva)($($arg_name,)*)
}
}
@ -18,8 +19,8 @@ pub fn disable_event_tracker() {
// Causes crashes in logic functions due to being not initialized
// useless SC analytics.
const EVENT_TRACKER_FUNCTIONS: &[i32] = &[0x14BCC0, 0x14BA1C, 0x14BB4C, 0x14BA88, 0x1A39A0];
const TRACK_FUNCTIONS: &[i32] = &[0x1A3E58, 0x14BE64, 0x14BC58];
const EVENT_TRACKER_FUNCTIONS: &[i32] = &[0x1DF9F4, 0x1DF664, 0x1DF7E8, 0x1DF6FC, 0x26CC51];
const TRACK_FUNCTIONS: &[i32] = &[0x26D41B, 0x1DFC4C, 0x1DF966];
unsafe {
for &addr in EVENT_TRACKER_FUNCTIONS.iter().chain(TRACK_FUNCTIONS) {
@ -31,7 +32,7 @@ pub fn disable_event_tracker() {
libc::PROT_READ | libc::PROT_WRITE | libc::PROT_EXEC,
);
std::slice::from_raw_parts_mut(addr as *mut u8, 2).copy_from_slice(&[0x70, 0x47]);
std::slice::from_raw_parts_mut(addr as *mut u8, 1).copy_from_slice(&[0xC3]);
}
}
}
@ -39,17 +40,19 @@ pub fn disable_event_tracker() {
pub(crate) use import;
pub fn get_module_base(shared_object_name: &str) -> Option<usize> {
const ELF_MAGIC: u32 = 0x464C457F;
let path = "/proc/self/maps";
let file = File::open(path).ok()?;
let reader = io::BufReader::new(file);
proc_maps::get_process_maps(std::process::id() as Pid)
.ok()?
.into_iter()
.filter(|range| {
range
.filename()
.map(|p| p.to_string_lossy().ends_with(shared_object_name))
.unwrap_or(false)
})
.find(|range| unsafe { *(range.start() as *const u32) } == ELF_MAGIC)
.map(|range| range.start())
}
for line in reader.lines() {
let line = line.ok()?;
if line.contains(shared_object_name) {
let address_str = line.split_whitespace().next().unwrap_or("");
let address = usize::from_str_radix(&address_str.split('-').next().unwrap_or(""), 16)
.ok()?;
return Some(address);
}
}
None
}

View file

@ -58,11 +58,21 @@ struct ServerConfig {
pub database_path: String,
}
import!(malloc(amount: usize) -> *const u8 = 0x56A20);
import!(free(ptr: *const u8) -> () = 0x56A2C);
pub fn malloc(amount: usize) -> *const u8 {
unsafe extern "C" {
fn malloc(amount: usize) -> *const u8;
}
unsafe {
malloc(amount)
}
}
//import!(malloc(amount: usize) -> *const u8 = 0x56A20);
import!(free(ptr: *const u8) -> () = 0x54590);
fn server_main(config: ServerConfig) {
const TCP_ADDR: &str = "127.0.0.1:9339";
const TCP_ADDR: &str = "0.0.0.0:9339";
info!("starting server...");

View file

@ -14,16 +14,16 @@ pub struct LogicClientAvatar(pub *const u8);
impl LogicClientAvatar {
pub fn new() -> Self {
import!(logic_client_avatar_ctor(ptr: *const u8) -> () = 0x1164A4 + 1);
import!(logic_client_avatar_ctor(ptr: *const u8) -> () = 0x186AD8);
let instance = malloc(296);
logic_client_avatar_ctor(instance);
Self(instance)
}
pub fn get_default_avatar() -> Self {
import!(logic_avatar_set_resource_count(ptr: *const u8, data: *const u8, count: i32) -> () = 0x114E7C + 1);
import!(logic_data_tables_get_gold_data() -> *const u8 = 0x12D4F8 + 1);
import!(logic_data_tables_get_elixir_data() -> *const u8 = 0x12D510 + 1);
import!(logic_avatar_set_resource_count(ptr: *const u8, data: *const u8, count: i32) -> () = 0x184536);
import!(logic_data_tables_get_gold_data() -> *const u8 = 0x1AD200);
import!(logic_data_tables_get_elixir_data() -> *const u8 = 0x1AD224);
let avatar = Self::new();
logic_avatar_set_resource_count(avatar.0, logic_data_tables_get_gold_data(), 750);
@ -38,12 +38,12 @@ impl LogicClientAvatar {
}
pub fn decode(&mut self, stream: &mut ByteStream) {
import!(logic_client_avatar_decode(ptr: *const u8, s: *const u8) -> () = 0x1174AC + 1);
import!(logic_client_avatar_decode(ptr: *const u8, s: *const u8) -> () = 0x188826);
logic_client_avatar_decode(self.0, stream.0);
}
pub fn encode(&self, stream: &mut ByteStream) {
import!(logic_client_avatar_encode(ptr: *const u8, s: *const u8) -> () = 0x115D24 + 1);
import!(logic_client_avatar_encode(ptr: *const u8, s: *const u8) -> () = 0x185E8C);
logic_client_avatar_encode(self.0, stream.0);
}
}
@ -53,24 +53,24 @@ pub struct LogicNpcAvatar(pub *const u8);
impl LogicNpcAvatar {
pub fn new() -> Self {
import!(logic_npc_avatar_ctor(ptr: *const u8) -> () = 0x117FE4 + 1);
import!(logic_npc_avatar_ctor(ptr: *const u8) -> () = 0x189AA2);
let instance = malloc(112);
logic_npc_avatar_ctor(instance);
Self(instance)
}
pub fn set_npc_data(&mut self, data: &LogicNpcData) {
import!(logic_npc_avatar_set_npc_data(ptr: *const u8, data: *const u8) -> () = 0x118008 + 1);
import!(logic_npc_avatar_set_npc_data(ptr: *const u8, data: *const u8) -> () = 0x189AE6);
logic_npc_avatar_set_npc_data(self.0, data.0);
}
pub fn decode(&mut self, stream: &mut ByteStream) {
import!(logic_npc_avatar_decode(ptr: *const u8, s: *const u8) -> () = 0x1180E4 + 1);
import!(logic_npc_avatar_decode(ptr: *const u8, s: *const u8) -> () = 0x189C86);
logic_npc_avatar_decode(self.0, stream.0);
}
pub fn encode(&self, stream: &mut ByteStream) {
import!(logic_npc_avatar_encode(ptr: *const u8, s: *const u8) -> () = 0x117FB8 + 1);
import!(logic_npc_avatar_encode(ptr: *const u8, s: *const u8) -> () = 0x189A12);
logic_npc_avatar_encode(self.0, stream.0);
}
}

View file

@ -24,7 +24,7 @@ pub struct LogicCommandManager(pub *const u8);
impl LogicCommandManager {
pub fn add_command(&self, command: &LogicCommand) {
import!(logic_command_manager_add_command(ptr: *const u8, command: *const u8) -> () = 0x11CA20 + 1);
import!(logic_command_manager_add_command(ptr: *const u8, command: *const u8) -> () = 0x191888);
logic_command_manager_add_command(self.0, command.0);
}
}
@ -33,7 +33,7 @@ pub struct LogicChangeAvatarNameCommand(pub LogicCommand);
impl LogicChangeAvatarNameCommand {
pub fn new() -> Self {
import!(logic_change_avatar_name_command_ctor(ptr: *const u8) -> () = 0x14F7D8 + 1);
import!(logic_change_avatar_name_command_ctor(ptr: *const u8) -> () = 0x1E5762);
let instance = malloc(20);
logic_change_avatar_name_command_ctor(instance);
Self(LogicCommand(instance))

View file

@ -5,7 +5,7 @@ pub struct LogicClientHome(pub *const u8);
impl LogicClientHome {
pub fn new() -> Self {
import!(logic_client_home_ctor(ptr: *const u8) -> () = 0x144900 + 1);
import!(logic_client_home_ctor(ptr: *const u8) -> () = 0x1D3CE2);
let instance = malloc(48);
logic_client_home_ctor(instance);

View file

@ -5,7 +5,7 @@ pub struct LogicJSONNode(pub *const u8);
impl LogicJSONNode {
pub fn new_json_object() -> Self {
import!(logic_json_object_ctor(ptr: *const u8) -> () = 0x1A1DF0 + 1);
import!(logic_json_object_ctor(ptr: *const u8) -> () = 0x26A3A4);
let instance = malloc(28);
logic_json_object_ctor(instance);
Self(instance)

View file

@ -25,7 +25,7 @@ impl LogicLevel {
}
pub fn save_to_json(&self, json: &mut LogicJSONNode) {
import!(logic_level_save_to_json(ptr: *const u8, json: *const u8) -> () = 0x147A48 + 1);
import!(logic_level_save_to_json(ptr: *const u8, json: *const u8) -> () = 0x1D8C56);
logic_level_save_to_json(self.0, json.0);
}
}

View file

@ -13,7 +13,7 @@ pub struct LogicGameMode(pub *const u8);
impl LogicGameMode {
pub fn new() -> Self {
import!(logic_game_mode_ctor(ptr: *const u8) -> () = 0x149E0C + 1);
import!(logic_game_mode_ctor(ptr: *const u8) -> () = 0x1DC75A);
let instance = malloc(68);
logic_game_mode_ctor(instance);
@ -26,7 +26,7 @@ impl LogicGameMode {
logic_client_avatar: &LogicClientAvatar,
seconds_since_last_save: i32,
) {
import!(logic_game_mode_load_home_state(lgm: *const u8, lch: *const u8, lca: *const u8, ssls: i32, a5: i32, a6: i32, a7: i32) -> () = 0x14ACCA + 1);
import!(logic_game_mode_load_home_state(lgm: *const u8, lch: *const u8, lca: *const u8, ssls: i32, a5: i32, a6: i32, a7: i32) -> () = 0x1DE0C6);
logic_game_mode_load_home_state(
self.0,
@ -46,7 +46,7 @@ impl LogicGameMode {
logic_client_avatar: &LogicClientAvatar,
seconds_since_last_save: i32,
) {
import!(logic_game_mode_load_npc_attack_state(lgm: *const u8, lch: *const u8, lna: *const u8, lca: *const u8, ssls: i32) -> () = 0x14A1D8 + 1);
import!(logic_game_mode_load_npc_attack_state(lgm: *const u8, lch: *const u8, lna: *const u8, lca: *const u8, ssls: i32) -> () = 0x1DCE08);
logic_game_mode_load_npc_attack_state(
self.0,
@ -80,7 +80,7 @@ impl LogicGameMode {
}
pub fn update_one_sub_tick(&self) {
import!(logic_game_mode_update_one_sub_tick(ptr: *const u8) -> () = 0x14A8EC + 1);
import!(logic_game_mode_update_one_sub_tick(ptr: *const u8) -> () = 0x1DDA14);
logic_game_mode_update_one_sub_tick(self.0);
}
@ -89,7 +89,7 @@ impl LogicGameMode {
debug_json: Option<&mut LogicJSONNode>,
include_game_objects: bool,
) -> i32 {
import!(logic_game_mode_calculate_checksum(ptr: *const u8, debug_json: *const u8, include_game_objects: bool) -> i32 = 0x14AB54 + 1);
import!(logic_game_mode_calculate_checksum(ptr: *const u8, debug_json: *const u8, include_game_objects: bool) -> i32 = 0x1DDE0C);
logic_game_mode_calculate_checksum(
self.0,

View file

@ -23,7 +23,7 @@ pub struct ExtendedSetEncryptionMessage(pub PiranhaMessage);
impl ExtendedSetEncryptionMessage {
pub fn new() -> Self {
import!(set_encryption_message_ctor(ptr: *const u8) -> () = 0x16F324 + 1);
import!(set_encryption_message_ctor(ptr: *const u8) -> () = 0x21BAE4);
let instance = malloc(60);
set_encryption_message_ctor(instance);
Self(PiranhaMessage(instance))
@ -50,7 +50,7 @@ pub struct LoginOkMessage(pub PiranhaMessage);
impl LoginOkMessage {
pub fn new() -> Self {
import!(login_ok_message_ctor(ptr: *const u8) -> () = 0x1629FC + 1);
import!(login_ok_message_ctor(ptr: *const u8) -> () = 0x2058F0);
let instance = malloc(124);
login_ok_message_ctor(instance);
@ -104,7 +104,7 @@ pub struct KeepAliveServerMessage(pub PiranhaMessage);
impl KeepAliveServerMessage {
pub fn new() -> Self {
import!(keep_alive_server_message_ctor(ptr: *const u8) -> () = 0x161838 + 1);
import!(keep_alive_server_message_ctor(ptr: *const u8) -> () = 0x20390C);
let instance = malloc(48);
keep_alive_server_message_ctor(instance);
Self(PiranhaMessage(instance))

View file

@ -16,7 +16,7 @@ pub struct OwnHomeDataMessage(pub PiranhaMessage);
impl OwnHomeDataMessage {
pub fn new() -> Self {
import!(own_home_data_message_ctor(ptr: *const u8) -> () = 0x16CD30 + 1);
import!(own_home_data_message_ctor(ptr: *const u8) -> () = 0x21790E);
let instance = malloc(104);
own_home_data_message_ctor(instance);
@ -60,7 +60,7 @@ pub struct OutOfSyncMessage(pub PiranhaMessage);
impl OutOfSyncMessage {
pub fn new() -> Self {
import!(out_of_sync_message_ctor(ptr: *const u8) -> () = 0x16CB60 + 1);
import!(out_of_sync_message_ctor(ptr: *const u8) -> () = 0x2175CE);
let instance = malloc(64);
out_of_sync_message_ctor(instance);
Self(PiranhaMessage(instance))
@ -83,7 +83,7 @@ pub struct AvailableServerCommandMessage(pub PiranhaMessage);
impl AvailableServerCommandMessage {
pub fn new() -> Self {
import!(available_server_command_message_ctor(ptr: *const u8) -> () = 0x16B870 + 1);
import!(available_server_command_message_ctor(ptr: *const u8) -> () = 0x215520);
let instance = malloc(100);
available_server_command_message_ctor(instance);
Self(PiranhaMessage(instance))
@ -106,7 +106,7 @@ pub struct NpcDataMessage(pub PiranhaMessage);
impl NpcDataMessage {
pub fn new() -> Self {
import!(npc_data_message_ctor(ptr: *const u8) -> () = 0x16C9E8 + 1);
import!(npc_data_message_ctor(ptr: *const u8) -> () = 0x217340);
let instance = malloc(64);
npc_data_message_ctor(instance);
Self(PiranhaMessage(instance))

View file

@ -15,7 +15,7 @@ pub struct Connection {
impl Messaging {
pub fn new(fd: i32) -> Self {
import!(messaging_ctor(ptr: *const u8, queue_size: i32) -> () = 0x17476C + 1);
import!(messaging_ctor(ptr: *const u8, queue_size: i32) -> () = 0x224D8E);
let instance = malloc(300);
messaging_ctor(instance, 50);
@ -28,7 +28,7 @@ impl Messaging {
}
pub fn set_encrypters(&mut self, encrypter: RC4Encrypter, decrypter: RC4Encrypter) {
import!(messaging_set_encrypters(ptr: *const u8, en: *const u8, de: *const u8, a4: i32) -> () = 0x17469C + 1);
import!(messaging_set_encrypters(ptr: *const u8, en: *const u8, de: *const u8, a4: i32) -> () = 0x224C54);
messaging_set_encrypters(self.0, encrypter.0, decrypter.0, 0);
}
@ -37,19 +37,19 @@ impl Messaging {
}
pub fn on_receive(&mut self) {
import!(messaging_on_receive(ptr: *const u8, connection: *mut Connection) -> () = 0x175118 + 1);
import!(messaging_on_receive(ptr: *const u8, connection: *mut Connection) -> () = 0x225CE6);
unsafe { messaging_on_receive(self.0, std::mem::transmute(self.0.wrapping_add(64))) }
}
pub fn next_message(&mut self) -> Option<PiranhaMessage> {
import!(messaging_next_message(ptr: *const u8) -> usize = 0x174A92 + 1);
import!(messaging_next_message(ptr: *const u8) -> usize = 0x22529E);
let message = messaging_next_message(self.0);
(message != 0).then_some(PiranhaMessage(message as *const u8))
}
pub fn send(&mut self, message: PiranhaMessage) {
import!(messaging_send(ptr: *const u8, message: *const u8) -> () = 0x174BD8 + 1);
import!(messaging_send(ptr: *const u8, message: *const u8) -> () = 0x225492);
info!(
"Messaging::send: sending message of type {}",
message.get_message_type()
@ -59,7 +59,7 @@ impl Messaging {
}
pub fn on_wakeup(&mut self) {
import!(messaging_on_wakeup(ptr: *const u8, connection: *mut Connection) -> () = 0x1749A4 + 1);
import!(messaging_on_wakeup(ptr: *const u8, connection: *mut Connection) -> () = 0x225118);
unsafe { messaging_on_wakeup(self.0, std::mem::transmute(self.0.wrapping_add(64))) }
}
@ -68,7 +68,7 @@ impl Messaging {
}
pub fn scramble_nonce_using_mersenne_twister(seed: i32, nonce: &mut [u8]) {
import!(messaging_scramble_nonce_using_mersenne_twister(seed: i32, nonce: *const u8, nonce_len: i32) -> () = 0x1A62E4 + 1);
import!(messaging_scramble_nonce_using_mersenne_twister(seed: i32, nonce: *const u8, nonce_len: i32) -> () = 0x2710FE);
messaging_scramble_nonce_using_mersenne_twister(seed, nonce.as_ptr(), nonce.len() as i32);
}
}
@ -94,7 +94,7 @@ impl LogicMagicMessageFactory {
pub const RC4_KEY: &str = "fhsd6f86f67rt8fw78fw789we78r9789wer6re";
pub fn new() -> Self {
import!(logic_magic_message_factory_ctor(ptr: *mut u8) -> () = 0x1497DC + 1);
import!(logic_magic_message_factory_ctor(ptr: *mut u8) -> () = 0x1DBD3E);
let mut instance = Self { vtable: 0 };
unsafe {
@ -110,7 +110,7 @@ pub struct RC4Encrypter(*const u8);
impl RC4Encrypter {
pub fn new(key: &str, nonce: &str) -> Self {
import!(rc4_encrypter_ctor(ptr: *const u8, key: *const u8, nonce: *const u8) -> () = 0x188D0C + 1);
import!(rc4_encrypter_ctor(ptr: *const u8, key: *const u8, nonce: *const u8) -> () = 0x243DD2);
let instance = malloc(268);
rc4_encrypter_ctor(instance, ScString::from(key).0, ScString::from(nonce).0);
@ -118,7 +118,7 @@ impl RC4Encrypter {
}
pub fn new_with_nonce_bytes(key: &str, nonce: &[u8]) -> Self {
import!(rc4_encrypter_ctor(ptr: *const u8, key: *const u8, nonce: *const u8, nonce_len: i32) -> () = 0x188CD8 + 1);
import!(rc4_encrypter_ctor(ptr: *const u8, key: *const u8, nonce: *const u8, nonce_len: i32) -> () = 0x243D6E);
let instance = malloc(268);
let nonce_bytes = malloc(nonce.len());

View file

@ -6,7 +6,7 @@ pub struct ResourceManager;
impl ResourceManager {
pub fn get_json(path: &str) -> LogicJSONNode {
import!(resource_manager_get_json(path: *const u8) -> *const u8 = 0x18A750 + 1);
import!(resource_manager_get_json(path: *const i8) -> *const u8 = 0x246802);
LogicJSONNode(resource_manager_get_json(
CString::new(path).unwrap().as_ptr(),
))
@ -18,7 +18,7 @@ struct DataLoaderFactory(*const u8);
impl DataLoaderFactory {
pub fn new() -> Self {
import!(data_loader_factory_ctor(ptr: *const u8) -> () = 0x18967C + 1);
import!(data_loader_factory_ctor(ptr: *const u8) -> () = 0x244C8E);
let instance = malloc(4);
data_loader_factory_ctor(instance);
@ -31,7 +31,7 @@ struct ResourceListener(*const u8);
impl ResourceListener {
pub fn new() -> Self {
import!(resource_listener_ctor(ptr: *const u8) -> () = 0x189464 + 1);
import!(resource_listener_ctor(ptr: *const u8) -> () = 0x244968);
let instance = malloc(20);
resource_listener_ctor(instance);
@ -39,12 +39,12 @@ impl ResourceListener {
}
pub fn add_file(&self, name: &str) {
import!(resource_listener_add_file(ptr: *const u8, name: *const u8, a3: i32, a4: i32, a5: i32, a6: i32) -> () = 0x18B1C0 + 1);
import!(resource_listener_add_file(ptr: *const u8, name: *const u8, a3: i32, a4: i32, a5: i32, a6: i32) -> () = 0x2477FC);
resource_listener_add_file(self.0, ScString::from(name).0, -1, -1, -1, -1);
}
pub fn start_loading(&self) {
import!(resource_listener_start_loading(ptr: *const u8) -> () = 0x18B50C + 1);
import!(resource_listener_start_loading(ptr: *const u8) -> () = 0x247D98);
resource_listener_start_loading(self.0);
}
}
@ -94,16 +94,15 @@ pub fn init() {
const NPCS_COUNT: usize = 48;
const PREBASES_COUNT: usize = 11;
import!(resource_manager_init(factory: DataLoaderFactory, a2: *const u8) -> () = 0x18B898 + 1);
import!(resource_manager_resource_to_load() -> i32 = 0x1894B8 + 1);
import!(resource_manager_load_next_resource() -> () = 0x18A9EC + 1);
import!(logic_data_tables_init() -> () = 0x12CF54 + 1);
import!(logic_resources_create_data_table_resources_array() -> *const u8 = 0x136978 + 1);
import!(resource_manager_get_csv(csv: *const u8) -> *const u8 = 0x18A816 + 1);
import!(logic_resources_load(data_table_resources_array: *const u8, index: i32, csv: *const u8) -> *const u8 = 0x1368A8 + 1);
import!(resource_manager_init(factory: DataLoaderFactory, a2: *const u8) -> () = 0x2483E2);
import!(resource_manager_resource_to_load() -> i32 = 0x2449E2);
import!(resource_manager_load_next_resource() -> () = 0x246BDC);
import!(logic_data_tables_init() -> () = 0x1AC81E);
import!(logic_resources_create_data_table_resources_array() -> *const u8 = 0x1BC2A4);
import!(resource_manager_get_csv(csv: *const u8) -> *const u8 = 0x24690A);
import!(logic_resources_load(data_table_resources_array: *const u8, index: i32, csv: *const u8) -> *const u8 = 0x1BC154);
let data_loader_factory = DataLoaderFactory::new();
resource_manager_init(data_loader_factory, [0x00].as_ptr());
logic_data_tables_init();

View file

@ -14,7 +14,7 @@ where
S: AsRef<str>,
{
fn from(value: S) -> Self {
import!(string_ctor(ptr: *const u8, data: *const u8) -> () = 0x176748 + 1);
import!(string_ctor(ptr: *const u8, data: *const i8) -> () = 0x22826A);
let sc_string = malloc(32);
string_ctor(sc_string, CString::new(value.as_ref()).unwrap().as_ptr());
@ -26,7 +26,7 @@ impl fmt::Display for ScString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let length = unsafe { *(self.0.wrapping_add(4) as *const i32) as usize };
if length + 1 > 8 {
let c_string = unsafe { *(self.0.wrapping_add(8) as *const *const u8) };
let c_string = unsafe { *(self.0.wrapping_add(8) as *const *const i8) };
unsafe {
write!(
f,
@ -39,7 +39,7 @@ impl fmt::Display for ScString {
write!(
f,
"{}",
CStr::from_ptr(self.0.wrapping_add(8) as *const u8)
CStr::from_ptr(self.0.wrapping_add(8) as *const i8)
.to_string_lossy()
.to_string()
)
@ -61,7 +61,7 @@ pub struct StringBuilder(pub *const u8);
impl StringBuilder {
pub fn new() -> Self {
import!(string_builder_ctor(ptr: *const u8) -> () = 0x1772BA + 1);
import!(string_builder_ctor(ptr: *const u8) -> () = 0x2295C4);
let instance = malloc(12);
string_builder_ctor(instance);
@ -71,9 +71,11 @@ impl StringBuilder {
impl fmt::Display for StringBuilder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
import!(string_builder_to_string(sc_str: *const u8, ptr: *const u8) -> () = 0x1772D8 + 1);
let sc_str = ScString::from("");
string_builder_to_string(sc_str.0, self.0);
write!(f, "{sc_str}")
unsafe {
let buffer = *(self.0.wrapping_add(8) as *const *const u8);
let length = *(self.0.wrapping_add(0) as *const i32);
let buffer = std::slice::from_raw_parts(buffer, (length - 1) as usize);
write!(f, "{}", String::from_utf8_lossy(buffer))
}
}
}