mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
Noita heap stuff
This commit is contained in:
parent
ea6a17323a
commit
43dcabe601
8 changed files with 79 additions and 28 deletions
43
noita_api/src/heap.rs
Normal file
43
noita_api/src/heap.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use std::sync::LazyLock;
|
||||
|
||||
struct Msvcr {
|
||||
op_new: unsafe extern "C" fn(n: std::os::raw::c_uint) -> *mut std::os::raw::c_void,
|
||||
// op_delete: unsafe extern "C" fn(*const std::os::raw::c_void),
|
||||
// op_delete_array: unsafe extern "C" fn(*const std::os::raw::c_void),
|
||||
}
|
||||
|
||||
static MSVCR: LazyLock<Msvcr> = LazyLock::new(|| unsafe {
|
||||
println!("Loading MSVCR");
|
||||
let lib = libloading::Library::new("./msvcr120.dll").expect("library to exist");
|
||||
let op_new = *lib.get(b"operator_new\0").expect("symbol to exist");
|
||||
// let op_delete = *lib.get(b"operator_delete\0").expect("symbol to exist");
|
||||
// let op_delete_array = *lib.get(b"operator_delete[]\0").expect("symbol to exist");
|
||||
println!("Load OK");
|
||||
Msvcr {
|
||||
op_new,
|
||||
// op_delete,
|
||||
// op_delete_array,
|
||||
}
|
||||
});
|
||||
|
||||
/// Allocate some memory, using the same allocator noita uses.
|
||||
pub fn raw_new(size: usize) -> *mut std::os::raw::c_void {
|
||||
let size = size as std::os::raw::c_uint;
|
||||
assert!(size > 0, "Doesn't make sense to allocate memory of size 0");
|
||||
unsafe { (MSVCR.op_new)(size) }
|
||||
}
|
||||
|
||||
/// Allocates memory using noita's allocator and moves *value* to it.
|
||||
pub fn place_new<T>(value: T) -> *mut T {
|
||||
let size = size_of::<T>();
|
||||
let place = raw_new(size) as *mut T;
|
||||
unsafe {
|
||||
place.copy_from_nonoverlapping(&value, size);
|
||||
}
|
||||
place
|
||||
}
|
||||
|
||||
/// Same as place_new, but returns &'static mut
|
||||
pub fn place_new_ref<T>(value: T) -> &'static mut T {
|
||||
unsafe { &mut *place_new(value) }
|
||||
}
|
|
@ -17,6 +17,7 @@ pub mod lua;
|
|||
pub mod serialize;
|
||||
pub use noita_api_macro::add_lua_fn;
|
||||
pub mod addr_grabber;
|
||||
pub mod heap;
|
||||
pub mod noita;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -18,6 +18,8 @@ use std::fmt::{Debug, Display, Formatter};
|
|||
use std::ops::{Index, IndexMut};
|
||||
use std::{alloc, ptr, slice};
|
||||
pub use world::*;
|
||||
|
||||
use crate::heap;
|
||||
#[repr(C)]
|
||||
union Buffer {
|
||||
buffer: *const u8,
|
||||
|
@ -71,8 +73,8 @@ impl From<&str> for StdString {
|
|||
size: value.len(),
|
||||
};
|
||||
if res.capacity > 16 {
|
||||
let buffer = Box::leak(Box::new(value));
|
||||
res.buffer.buffer = buffer.as_ptr();
|
||||
let buffer = heap::place_new(value);
|
||||
res.buffer.buffer = buffer.cast();
|
||||
} else {
|
||||
let mut iter = value.as_bytes().iter();
|
||||
res.buffer.sso_buffer = std::array::from_fn(|_| iter.next().copied().unwrap_or(0))
|
||||
|
@ -157,8 +159,8 @@ pub struct CString(pub *const u8);
|
|||
impl From<&str> for CString {
|
||||
fn from(value: &str) -> Self {
|
||||
let value = value.to_owned() + "\0";
|
||||
let str = Box::leak(Box::new(value));
|
||||
CString(str.as_ptr())
|
||||
let str = heap::place_new(value).cast();
|
||||
CString(str)
|
||||
}
|
||||
}
|
||||
impl CString {
|
||||
|
@ -472,7 +474,7 @@ pub struct StdMap<K: 'static, V: 'static> {
|
|||
impl<K: Default + 'static, V: Default + 'static> Default for StdMap<K, V> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
root: Box::leak(Box::new(StdMapNode::default())),
|
||||
root: unsafe { &mut *heap::place_new(StdMapNode::default()) },
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
@ -520,7 +522,7 @@ impl<K: 'static, V: 'static> StdMap<K, V> {
|
|||
if self.is_empty() {
|
||||
self.len += 1;
|
||||
let node = StdMapNode::new(key, value);
|
||||
self.root.parent = Box::leak(Box::new(node)) as *mut _;
|
||||
self.root.parent = heap::place_new(node);
|
||||
None
|
||||
} else {
|
||||
todo!()
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::noita::types::{
|
||||
BitSet, CString, Component, Entity, EntityManager, StdMap, StdString, StdVec, TagManager,
|
||||
use crate::{
|
||||
heap,
|
||||
noita::types::{
|
||||
BitSet, CString, Component, Entity, EntityManager, StdMap, StdString, StdVec, TagManager,
|
||||
},
|
||||
};
|
||||
use std::ptr;
|
||||
#[repr(C)]
|
||||
|
@ -141,7 +144,7 @@ impl ComponentBuffer {
|
|||
unk3: StdVec::null(),
|
||||
unk4: 0,
|
||||
});
|
||||
let com = Box::leak(Box::new(com));
|
||||
let com = heap::place_new(com);
|
||||
let index = self.component_list.len();
|
||||
self.component_list.push((com as *mut C).cast());
|
||||
if self.entities.len() > index {
|
||||
|
@ -184,7 +187,7 @@ impl ComponentBuffer {
|
|||
}
|
||||
self.next[off] = self.end;
|
||||
}
|
||||
com
|
||||
unsafe { &mut *com }
|
||||
}
|
||||
pub fn iter_components(&self, entry: usize) -> ComponentIter {
|
||||
if let Some(off) = self.entity_entry.get(entry) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::heap;
|
||||
use crate::noita::types::component::{ComponentBuffer, ComponentData};
|
||||
use crate::noita::types::{
|
||||
Component, ComponentTypeManager, Inventory2Component, StdMap, StdString, StdVec, Vec2,
|
||||
|
@ -20,7 +21,7 @@ impl EntityManager {
|
|||
children: std::ptr::null_mut(),
|
||||
parent: std::ptr::null_mut(),
|
||||
};
|
||||
let ent = Box::leak(Box::new(ent));
|
||||
let ent = heap::place_new_ref(ent);
|
||||
if let Some(entry) = self.free_ids.pop() {
|
||||
ent.entry = entry;
|
||||
self.entities[entry] = ent;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::heap;
|
||||
use crate::noita::types::objects::{ConfigExplosion, ConfigGridCosmeticParticle};
|
||||
use crate::noita::types::{StdMap, StdString, StdVec, ThiscallFn, Vec2, Vec2i};
|
||||
use shared::world_sync::{Pixel, PixelFlags};
|
||||
|
@ -727,7 +728,7 @@ impl ChunkMap {
|
|||
#[inline]
|
||||
pub fn insert(&mut self, x: isize, y: isize, chunk: Chunk) {
|
||||
let index = (((y - 256) & 511) << 9) | ((x - 256) & 511);
|
||||
self.chunk_array[index.cast_unsigned()] = Box::leak(Box::new(chunk))
|
||||
self.chunk_array[index.cast_unsigned()] = heap::place_new(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue