mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-18 22:53:16 +00:00
Split noita api stuff into it's own crate
This commit is contained in:
parent
bac266e456
commit
66a5a009e2
11 changed files with 121 additions and 106 deletions
10
ewext/Cargo.lock
generated
10
ewext/Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"}
|
9
ewext/noita_api/Cargo.toml
Normal file
9
ewext/noita_api/Cargo.toml
Normal file
|
@ -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"}
|
68
ewext/noita_api/src/lib.rs
Normal file
68
ewext/noita_api/src/lib.rs
Normal file
|
@ -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<f64> {
|
||||
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<i32> {
|
||||
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<bool> {
|
||||
component_get_value_base(component, field, 1)?;
|
||||
let lua = LuaState::current()?;
|
||||
let ret = lua.to_bool(1);
|
||||
lua.pop_last();
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
|
@ -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<Option<LuaState>> = Cell::default();
|
||||
}
|
||||
|
||||
pub static LUA: LazyLock<Lua51> = 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<R: LuaFnRet> LuaFnRet for eyre::Result<R> {
|
|||
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));
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["noita_api", "noita_api_macro"]
|
||||
|
||||
[package]
|
||||
name = "noita_api_macro"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Grabbed> = OnceLock::new();
|
||||
|
||||
|
|
|
@ -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<Lua51> = 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<RefCell<ExtState>> = 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(),
|
||||
)?;
|
||||
|
||||
|
|
|
@ -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<f64> {
|
||||
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<i32> {
|
||||
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<bool> {
|
||||
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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue