From 66a5a009e20230e1c9dc6201e5625387022ff2b1 Mon Sep 17 00:00:00 2001 From: IQuant Date: Mon, 25 Nov 2024 17:44:56 +0300 Subject: [PATCH] Split noita api stuff into it's own crate --- ewext/Cargo.lock | 10 +++ ewext/Cargo.toml | 1 + ewext/noita_api/Cargo.toml | 9 +++ ewext/noita_api/src/lib.rs | 68 ++++++++++++++++++ .../lua_state.rs => noita_api/src/lua.rs} | 22 +++--- .../src/lua}/lua_bindings.rs | 0 ewext/noita_api_macro/Cargo.toml | 4 ++ ewext/noita_api_macro/src/lib.rs | 8 +-- ewext/src/addr_grabber.rs | 6 +- ewext/src/lib.rs | 30 +++----- ewext/src/noita.rs | 69 ------------------- 11 files changed, 121 insertions(+), 106 deletions(-) create mode 100644 ewext/noita_api/Cargo.toml create mode 100644 ewext/noita_api/src/lib.rs rename ewext/{src/lua_state.rs => noita_api/src/lua.rs} (87%) rename ewext/{src => noita_api/src/lua}/lua_bindings.rs (100%) diff --git a/ewext/Cargo.lock b/ewext/Cargo.lock index 15abab14..75b404b5 100644 --- a/ewext/Cargo.lock +++ b/ewext/Cargo.lock @@ -46,6 +46,7 @@ dependencies = [ "eyre", "iced-x86", "libloading", + "noita_api", "noita_api_macro", ] @@ -129,6 +130,15 @@ dependencies = [ "adler2", ] +[[package]] +name = "noita_api" +version = "0.1.0" +dependencies = [ + "eyre", + "libloading", + "noita_api_macro", +] + [[package]] name = "noita_api_macro" version = "0.1.0" diff --git a/ewext/Cargo.toml b/ewext/Cargo.toml index a4651d81..4c0d1862 100644 --- a/ewext/Cargo.toml +++ b/ewext/Cargo.toml @@ -17,3 +17,4 @@ backtrace = "0.3.74" iced-x86 = "1.21.0" noita_api_macro = {path = "noita_api_macro"} eyre = "0.6.12" +noita_api = {path = "noita_api"} \ No newline at end of file diff --git a/ewext/noita_api/Cargo.toml b/ewext/noita_api/Cargo.toml new file mode 100644 index 00000000..5c084336 --- /dev/null +++ b/ewext/noita_api/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "noita_api" +version = "0.1.0" +edition = "2021" + +[dependencies] +eyre = "0.6.12" +libloading = "0.8.5" +noita_api_macro = {path = "../noita_api_macro"} diff --git a/ewext/noita_api/src/lib.rs b/ewext/noita_api/src/lib.rs new file mode 100644 index 00000000..77daa5b4 --- /dev/null +++ b/ewext/noita_api/src/lib.rs @@ -0,0 +1,68 @@ +pub mod lua; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct EntityID(pub isize); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct ComponentID(pub isize); + +pub struct Obj(pub usize); + +pub struct Color(pub u32); + +noita_api_macro::generate_components!(); + +pub mod raw { + use super::{Color, ComponentID, EntityID, Obj}; + use std::borrow::Cow; + + use crate::lua::LuaState; + + noita_api_macro::generate_api!(); + + fn component_get_value_base( + component: ComponentID, + field: &str, + expected_results: i32, + ) -> eyre::Result<()> { + let lua = LuaState::current()?; + lua.get_global(c"ComponentGetValue2"); + lua.push_integer(component.0); + lua.push_string(field); + lua.call(2, expected_results); + Ok(()) + } + + pub(crate) fn component_get_value_number( + component: ComponentID, + field: &str, + ) -> eyre::Result { + component_get_value_base(component, field, 1)?; + let lua = LuaState::current()?; + let ret = lua.to_number(1); + lua.pop_last(); + Ok(ret) + } + + pub(crate) fn component_get_value_integer( + component: ComponentID, + field: &str, + ) -> eyre::Result { + component_get_value_base(component, field, 1)?; + let lua = LuaState::current()?; + let ret = lua.to_integer(1); + lua.pop_last(); + Ok(ret as i32) + } + + pub(crate) fn component_get_value_bool( + component: ComponentID, + field: &str, + ) -> eyre::Result { + component_get_value_base(component, field, 1)?; + let lua = LuaState::current()?; + let ret = lua.to_bool(1); + lua.pop_last(); + Ok(ret) + } +} diff --git a/ewext/src/lua_state.rs b/ewext/noita_api/src/lua.rs similarity index 87% rename from ewext/src/lua_state.rs rename to ewext/noita_api/src/lua.rs index aa591ac7..4c91522e 100644 --- a/ewext/src/lua_state.rs +++ b/ewext/noita_api/src/lua.rs @@ -1,20 +1,24 @@ +pub mod lua_bindings; + use std::{ cell::Cell, ffi::{c_char, c_int, CStr}, mem, slice, + sync::LazyLock, }; use eyre::{bail, Context, OptionExt}; - -use crate::{ - lua_bindings::{lua_CFunction, lua_State, LUA_GLOBALSINDEX}, - LUA, -}; +use lua_bindings::{lua_CFunction, lua_State, Lua51, LUA_GLOBALSINDEX}; thread_local! { static CURRENT_LUA_STATE: Cell> = Cell::default(); } +pub static LUA: LazyLock = LazyLock::new(|| unsafe { + let lib = libloading::Library::new("./lua51.dll").expect("library to exist"); + Lua51::from_library(lib).expect("library to be lua") +}); + #[derive(Clone, Copy)] pub struct LuaState { lua: *mut lua_State, @@ -36,7 +40,7 @@ impl LuaState { CURRENT_LUA_STATE.set(Some(self)); } - pub(crate) fn raw(&self) -> *mut lua_State { + pub fn raw(&self) -> *mut lua_State { self.lua } @@ -117,12 +121,12 @@ impl LuaState { } } -pub(crate) trait LuaFnRet { +pub trait LuaFnRet { fn do_return(self, lua: LuaState) -> c_int; } /// Function intends to return several values that it has on stack. -pub(crate) struct ValuesOnStack(pub(crate) c_int); +pub struct ValuesOnStack(pub c_int); impl LuaFnRet for ValuesOnStack { fn do_return(self, _lua: LuaState) -> c_int { @@ -141,7 +145,7 @@ impl LuaFnRet for eyre::Result { match self { Ok(ok) => ok.do_return(lua), Err(err) => unsafe { - lua.raise_error(format!("Error in ewext call: {:?}", err)); + lua.raise_error(format!("Error in rust call: {:?}", err)); }, } } diff --git a/ewext/src/lua_bindings.rs b/ewext/noita_api/src/lua/lua_bindings.rs similarity index 100% rename from ewext/src/lua_bindings.rs rename to ewext/noita_api/src/lua/lua_bindings.rs diff --git a/ewext/noita_api_macro/Cargo.toml b/ewext/noita_api_macro/Cargo.toml index d584faf6..5e189928 100644 --- a/ewext/noita_api_macro/Cargo.toml +++ b/ewext/noita_api_macro/Cargo.toml @@ -1,3 +1,7 @@ +[workspace] +resolver = "2" +members = ["noita_api", "noita_api_macro"] + [package] name = "noita_api_macro" version = "0.1.0" diff --git a/ewext/noita_api_macro/src/lib.rs b/ewext/noita_api_macro/src/lib.rs index 2521a2b5..d2c73078 100644 --- a/ewext/noita_api_macro/src/lib.rs +++ b/ewext/noita_api_macro/src/lib.rs @@ -201,7 +201,7 @@ fn generate_code_for_component(com: Component) -> proc_macro2::TokenStream { quote! { #[derive(Clone, Copy, PartialEq, Eq)] - pub struct #component_name(pub(crate) ComponentID); + pub struct #component_name(pub ComponentID); impl #component_name { #(#impls)* @@ -271,7 +271,7 @@ fn generate_code_for_api_fn(api_fn: ApiFn) -> proc_macro2::TokenStream { quote! { #[doc = #fn_doc] - pub(crate) fn #fn_name(#(#args,)*) -> eyre::Result<#ret_type> { + pub fn #fn_name(#(#args,)*) -> eyre::Result<#ret_type> { let lua = LuaState::current()?; lua.get_global(#fn_name_c); @@ -304,9 +304,9 @@ pub fn add_lua_fn(item: TokenStream) -> TokenStream { let fn_name_c = name_to_c_literal(fn_name); quote! { unsafe extern "C" fn #bridge_fn_name(lua: *mut lua_State) -> c_int { - let lua_state = LuaState::new(lua); + let lua_state = noita_api::lua::LuaState::new(lua); lua_state.make_current(); - crate::lua_state::LuaFnRet::do_return(#fn_name_ident(lua_state), lua_state) + noita_api::lua::LuaFnRet::do_return(#fn_name_ident(lua_state), lua_state) } LUA.lua_pushcclosure(lua, Some(#bridge_fn_name), 0); diff --git a/ewext/src/addr_grabber.rs b/ewext/src/addr_grabber.rs index 91d13859..794a78ab 100644 --- a/ewext/src/addr_grabber.rs +++ b/ewext/src/addr_grabber.rs @@ -1,11 +1,9 @@ use std::{mem, os::raw::c_void, ptr, sync::OnceLock}; use iced_x86::{Decoder, DecoderOptions, Mnemonic}; +use noita_api::lua::LuaState; -use crate::{ - lua_state::LuaState, - noita::ntypes::{EntityManager, ThiscallFn}, -}; +use crate::noita::ntypes::{EntityManager, ThiscallFn}; static GRABBED: OnceLock = OnceLock::new(); diff --git a/ewext/src/lib.rs b/ewext/src/lib.rs index f9c5db29..cdfaca22 100644 --- a/ewext/src/lib.rs +++ b/ewext/src/lib.rs @@ -1,31 +1,21 @@ -use crate::noita::api::DamageModelComponent; use std::{ arch::asm, cell::{LazyCell, RefCell}, ffi::{c_int, c_void}, - sync::LazyLock, time::Instant, }; use addr_grabber::{grab_addrs, grabbed_fns, grabbed_globals}; use eyre::bail; -use lua_bindings::{lua_State, Lua51}; -use lua_state::{LuaState, ValuesOnStack}; -use noita::{ntypes::Entity, pixel::NoitaPixelRun, ParticleWorldState}; -use noita_api_macro::add_lua_fn; -mod lua_bindings; -pub mod lua_state; +use noita::{ntypes::Entity, pixel::NoitaPixelRun, ParticleWorldState}; +use noita_api::lua::{lua_bindings::lua_State, LuaState, ValuesOnStack, LUA}; +use noita_api_macro::add_lua_fn; pub mod noita; mod addr_grabber; -static LUA: LazyLock = LazyLock::new(|| unsafe { - let lib = libloading::Library::new("./lua51.dll").expect("library to exist"); - Lua51::from_library(lib).expect("library to be lua") -}); - thread_local! { static STATE: LazyCell> = LazyCell::new(|| { println!("Initializing ExtState"); @@ -69,7 +59,7 @@ fn encode_area(lua: LuaState) -> ValuesOnStack { let runs = unsafe { pws.encode_area(start_x, start_y, end_x, end_y, encoded_buffer) }; unsafe { LUA.lua_pushinteger(lua, runs as isize) }; }); - lua_state::ValuesOnStack(1) + ValuesOnStack(1) } fn make_ephemerial(lua: LuaState) -> eyre::Result<()> { @@ -105,12 +95,12 @@ fn bench_fn(_lua: LuaState) -> eyre::Result<()> { let start = Instant::now(); let iters = 10000; for _ in 0..iters { - let player = noita::api::raw::entity_get_closest_with_tag(0.0, 0.0, "player_unit".into())?; - noita::api::raw::entity_set_transform(player, 0.0, Some(0.0), None, None, None)?; + let player = noita_api::raw::entity_get_closest_with_tag(0.0, 0.0, "player_unit".into())?; + noita_api::raw::entity_set_transform(player, 0.0, Some(0.0), None, None, None)?; } let elapsed = start.elapsed(); - noita::api::raw::game_print( + noita_api::raw::game_print( format!( "Took {}us to test, {}ns per call", elapsed.as_micros(), @@ -123,15 +113,15 @@ fn bench_fn(_lua: LuaState) -> eyre::Result<()> { } fn test_fn(_lua: LuaState) -> eyre::Result<()> { - let player = noita::api::raw::entity_get_closest_with_tag(0.0, 0.0, "player_unit".into())?; - let damage_model = DamageModelComponent(noita::api::raw::entity_get_first_component( + let player = noita_api::raw::entity_get_closest_with_tag(0.0, 0.0, "player_unit".into())?; + let damage_model = noita_api::DamageModelComponent(noita_api::raw::entity_get_first_component( player, "DamageModelComponent".into(), None, )?); let hp = damage_model.hp()?; - noita::api::raw::game_print( + noita_api::raw::game_print( format!("Component: {:?}, Hp: {}", damage_model.0, hp * 25.0).into(), )?; diff --git a/ewext/src/noita.rs b/ewext/src/noita.rs index 9e33151c..cb55abf9 100644 --- a/ewext/src/noita.rs +++ b/ewext/src/noita.rs @@ -3,75 +3,6 @@ use std::{ffi::c_void, mem}; pub(crate) mod ntypes; pub(crate) mod pixel; -pub mod api { - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub struct EntityID(isize); - - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub struct ComponentID(isize); - - pub struct Obj(usize); - - pub struct Color(u32); - - noita_api_macro::generate_components!(); - - pub mod raw { - use super::{Color, ComponentID, EntityID, Obj}; - use std::borrow::Cow; - - use crate::LuaState; - - noita_api_macro::generate_api!(); - - fn component_get_value_base( - component: ComponentID, - field: &str, - expected_results: i32, - ) -> eyre::Result<()> { - let lua = LuaState::current()?; - lua.get_global(c"ComponentGetValue2"); - lua.push_integer(component.0); - lua.push_string(field); - lua.call(2, expected_results); - Ok(()) - } - - pub(crate) fn component_get_value_number( - component: ComponentID, - field: &str, - ) -> eyre::Result { - component_get_value_base(component, field, 1)?; - let lua = LuaState::current()?; - let ret = lua.to_number(1); - lua.pop_last(); - Ok(ret) - } - - pub(crate) fn component_get_value_integer( - component: ComponentID, - field: &str, - ) -> eyre::Result { - component_get_value_base(component, field, 1)?; - let lua = LuaState::current()?; - let ret = lua.to_integer(1); - lua.pop_last(); - Ok(ret as i32) - } - - pub(crate) fn component_get_value_bool( - component: ComponentID, - field: &str, - ) -> eyre::Result { - component_get_value_base(component, field, 1)?; - let lua = LuaState::current()?; - let ret = lua.to_bool(1); - lua.pop_last(); - Ok(ret) - } - } -} - pub(crate) struct ParticleWorldState { pub(crate) _world_ptr: *mut c_void, pub(crate) chunk_map_ptr: *mut c_void,