fix some crashes

This commit is contained in:
bgkillas 2025-07-21 21:35:54 -04:00
parent 0519d6ed64
commit b7ccd4d9ec
5 changed files with 105 additions and 79 deletions

View file

@ -107,7 +107,7 @@ impl ExtState {
}
}
pub fn ephemerial(entity_id: isize) -> eyre::Result<()> {
pub fn ephemerial(entity_id: usize) -> eyre::Result<()> {
ExtState::with_global(|state| {
if let Some(entity) = state.globals.entity_manager_mut().get_entity_mut(entity_id) {
entity.filename_index = 0;
@ -115,7 +115,7 @@ pub fn ephemerial(entity_id: isize) -> eyre::Result<()> {
})
}
fn make_ephemerial(lua: LuaState) -> eyre::Result<()> {
let entity_id = lua.to_integer(1);
let entity_id = lua.to_integer(1).cast_unsigned();
ephemerial(entity_id)?;
Ok(())
}

View file

@ -2397,7 +2397,7 @@ pub fn init_remote_entity(
.try_get_first_component_including_disabled::<PhysicsBody2Component>(ComponentTag::None)
.is_none()
{
ephemerial(entity.0.get())?
ephemerial(entity.0.get().cast_unsigned())?
}
Ok(())

View file

@ -160,6 +160,13 @@ impl<T: Debug> Debug for StdVec<T> {
}
}
impl<T> StdVec<T> {
pub fn copy(&self) -> Self {
Self {
start: self.start,
end: self.end,
cap: self.cap,
}
}
pub fn capacity(&self) -> usize {
unsafe { self.cap.offset_from_unsigned(self.start) }
}
@ -170,10 +177,20 @@ impl<T> StdVec<T> {
self.start == self.end
}
pub fn get(&self, index: usize) -> Option<&T> {
unsafe { self.start.add(index).as_ref() }
let ptr = unsafe { self.start.add(index) };
if self.end > ptr {
unsafe { ptr.as_ref() }
} else {
None
}
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
unsafe { self.start.add(index).as_mut() }
let ptr = unsafe { self.start.add(index) };
if self.end > ptr {
unsafe { ptr.as_mut() }
} else {
None
}
}
fn alloc(&mut self, n: usize) {
if self.cap >= unsafe { self.end.add(n) } {

View file

@ -53,50 +53,54 @@ pub struct ComponentTypeManager {
#[derive(Debug)]
pub struct ComponentManager {
pub vtable: &'static ComponentManagerVTable,
pub end: isize,
pub end: usize,
unk: [isize; 2],
pub entity_entry: StdVec<isize>,
pub entity_entry: StdVec<usize>,
unk2: [isize; 6],
pub next: *mut isize,
pub next: *mut usize,
unk3: [isize; 2],
pub component_list: StdVec<*mut ComponentData>,
}
impl ComponentManager {
pub fn iter_components(&self, ent: &'static Entity) -> ComponentIter {
unsafe {
if let Some(off) = self.entity_entry.start.offset(ent.entry).as_ref() {
ComponentIter {
component_list: self.component_list.start as *const *const ComponentData,
off: *off,
next: self.next,
end: self.end,
}
} else {
ComponentIter {
component_list: std::ptr::null_mut(),
off: 0,
next: std::ptr::null_mut(),
end: 0,
}
if let Some(off) = self.entity_entry.get(ent.entry) {
ComponentIter {
component_list: self.component_list.copy(),
off: *off,
next: self.next,
end: self.end,
}
} else {
ComponentIter {
component_list: StdVec {
start: std::ptr::null_mut(),
end: std::ptr::null_mut(),
cap: std::ptr::null_mut(),
},
off: 0,
next: std::ptr::null_mut(),
end: 0,
}
}
}
pub fn iter_components_mut(&mut self, ent: &'static Entity) -> ComponentIterMut {
unsafe {
if let Some(off) = self.entity_entry.start.offset(ent.entry).as_ref() {
ComponentIterMut {
component_list: self.component_list.start,
off: *off,
next: self.next,
end: self.end,
}
} else {
ComponentIterMut {
component_list: std::ptr::null_mut(),
off: 0,
next: std::ptr::null_mut(),
end: 0,
}
if let Some(off) = self.entity_entry.get(ent.entry) {
ComponentIterMut {
component_list: self.component_list.copy(),
off: *off,
next: self.next,
end: self.end,
}
} else {
ComponentIterMut {
component_list: StdVec {
start: std::ptr::null_mut(),
end: std::ptr::null_mut(),
cap: std::ptr::null_mut(),
},
off: 0,
next: std::ptr::null_mut(),
end: 0,
}
}
}
@ -104,10 +108,10 @@ impl ComponentManager {
#[derive(Debug)]
pub struct ComponentIter {
component_list: *const *const ComponentData,
off: isize,
end: isize,
next: *const isize,
component_list: StdVec<*mut ComponentData>,
off: usize,
end: usize,
next: *const usize,
}
impl Iterator for ComponentIter {
@ -117,22 +121,18 @@ impl Iterator for ComponentIter {
if self.off == self.end {
return None;
}
let com = self.component_list.offset(self.off).as_ref()?.as_ref();
if let Some(n) = self.next.offset(self.off).as_ref() {
self.off = *n
} else {
self.off = self.end
}
let com = self.component_list.get(self.off)?.as_ref();
self.off = self.next.add(self.off).read();
com
}
}
}
#[derive(Debug)]
pub struct ComponentIterMut {
component_list: *const *mut ComponentData,
off: isize,
end: isize,
next: *const isize,
component_list: StdVec<*mut ComponentData>,
off: usize,
end: usize,
next: *const usize,
}
impl Iterator for ComponentIterMut {
@ -142,12 +142,8 @@ impl Iterator for ComponentIterMut {
if self.off == self.end {
return None;
}
let com = self.component_list.offset(self.off).as_ref()?.as_mut();
if let Some(n) = self.next.offset(self.off).as_ref() {
self.off = *n
} else {
self.off = self.end
}
let com = self.component_list.get(self.off)?.as_mut();
self.off = self.next.add(self.off).read();
com
}
}

View file

@ -1,5 +1,6 @@
use crate::noita::types::component::{ComponentData, ComponentManager};
use crate::noita::types::{StdMap, StdString, StdVec, Vec2};
use std::cmp::Ordering;
use std::slice;
impl EntityManager {
pub fn get_entity_with_tag(
@ -22,27 +23,39 @@ impl EntityManager {
self.entity_buckets.get_mut(n as usize)?.get(0)?.as_mut()
}
}
pub fn get_entity(&self, id: isize) -> Option<&'static Entity> {
unsafe {
let o = self.entities.as_ref()[id as usize..]
.iter()
.find_map(|c| c.as_ref().map(|c| c.id - c.entry))
.unwrap_or(id);
let start = self.entities.start.offset(id - o);
let list = slice::from_raw_parts(start, self.entities.len() - (id - o) as usize);
list.iter().find_map(|c| c.as_ref().filter(|c| c.id == id))
pub fn get_entity(&self, id: usize) -> Option<&'static Entity> {
for ent in self
.entities
.as_ref()
.iter()
.filter_map(|c| unsafe { c.as_ref() })
{
match ent.id.cmp(&id) {
Ordering::Less => {}
Ordering::Equal => return Some(ent),
Ordering::Greater => {
return None;
}
}
}
None
}
pub fn get_entity_mut(&mut self, id: isize) -> Option<&'static mut Entity> {
unsafe {
let o = self.entities.as_ref()[id as usize..]
.iter()
.find_map(|c| c.as_ref().map(|c| c.id - c.entry))
.unwrap_or(id);
let start = self.entities.start.offset(id - o);
let list = slice::from_raw_parts(start, self.entities.len() - (id - o) as usize);
list.iter().find_map(|c| c.as_mut().filter(|c| c.id == id))
pub fn get_entity_mut(&mut self, id: usize) -> Option<&'static mut Entity> {
for ent in self
.entities
.as_ref()
.iter()
.filter_map(|c| unsafe { c.as_mut() })
{
match ent.id.cmp(&id) {
Ordering::Less => {}
Ordering::Equal => return Some(ent),
Ordering::Greater => {
return None;
}
}
}
None
}
pub fn iter_entities_with_tag(
&self,
@ -165,8 +178,8 @@ impl BitSet<8> {
#[repr(C)]
#[derive(Debug)]
pub struct Entity {
pub id: isize,
pub entry: isize,
pub id: usize,
pub entry: usize,
pub filename_index: usize,
pub kill_flag: isize,
unknown1: isize,
@ -409,7 +422,7 @@ pub struct Inventory {
unk1: isize,
unk2: isize,
unk3: isize,
pub held_item_id: isize,
pub held_item_id: usize,
unk5: isize,
unk6: isize,
unk7b1: bool,