Fix crash when nonexistant material is added.

This commit is contained in:
IQuant 2024-08-11 13:57:25 +03:00
parent c27b56bfff
commit 554f14ca44
7 changed files with 46 additions and 4 deletions

View file

@ -1,5 +1,6 @@
# List of available hooks: # List of available hooks:
- `ctx.hook.on_world_initialized()`
- `ctx.hook.on_world_update()` - `ctx.hook.on_world_update()`
- `ctx.hook.on_world_update_client()` - `ctx.hook.on_world_update_client()`
- `ctx.hook.on_world_update_host()` - `ctx.hook.on_world_update_host()`

View file

@ -1,4 +1,4 @@
use std::mem; use std::{env, mem};
use bitcode::{Decode, Encode}; use bitcode::{Decode, Encode};
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
@ -120,7 +120,6 @@ impl WorldManager {
inbound_model: Default::default(), inbound_model: Default::default(),
outbound_model: Default::default(), outbound_model: Default::default(),
authority_map: Default::default(), authority_map: Default::default(),
// TODO this needs to be persisted between proxy restarts.
chunk_storage, chunk_storage,
chunk_state: Default::default(), chunk_state: Default::default(),
emitted_messages: Default::default(), emitted_messages: Default::default(),
@ -237,6 +236,12 @@ impl WorldManager {
} }
pub(crate) fn get_noita_updates(&mut self) -> Vec<Vec<u8>> { pub(crate) fn get_noita_updates(&mut self) -> Vec<Vec<u8>> {
// Sends random data to noita to check if it crashes.
if env::var_os("NP_WORLD_SYNC_TEST").is_some() && self.current_update % 10 == 0 {
let chunk_data = ChunkData::make_random();
self.inbound_model
.apply_chunk_data(ChunkCoord(0, 0), chunk_data)
}
let updates = self.inbound_model.get_all_noita_updates(); let updates = self.inbound_model.get_all_noita_updates();
self.inbound_model.reset_change_tracking(); self.inbound_model.reset_change_tracking();
updates updates

View file

@ -36,6 +36,23 @@ pub(crate) struct ChunkDelta {
runs: Arc<Vec<PixelRun<Option<CompactPixel>>>>, runs: Arc<Vec<PixelRun<Option<CompactPixel>>>>,
} }
impl ChunkData {
pub(crate) fn make_random() -> Self {
let mut runner = PixelRunner::new();
for i in 0..CHUNK_SIZE * CHUNK_SIZE {
runner.put_pixel(
Pixel {
flags: PixelFlags::Normal,
material: (i as u16) % 512,
}
.to_compact(),
)
}
let runs = runner.build();
ChunkData { runs }
}
}
impl WorldModel { impl WorldModel {
fn to_chunk_coords(x: i32, y: i32) -> (ChunkCoord, usize) { fn to_chunk_coords(x: i32, y: i32) -> (ChunkCoord, usize) {
let chunk_x = x.div_euclid(CHUNK_SIZE as i32); let chunk_x = x.div_euclid(CHUNK_SIZE as i32);

View file

@ -34,7 +34,7 @@ impl Pixel {
}, },
} }
} }
fn to_compact(self) -> CompactPixel { pub fn to_compact(self) -> CompactPixel {
let flag_bit = if self.flags == PixelFlags::Normal { let flag_bit = if self.flags == PixelFlags::Normal {
0 0
} else { } else {

View file

@ -37,6 +37,8 @@ struct __attribute__ ((__packed__)) EncodedArea {
]]) ]])
world.last_material_id = 0
world.EncodedAreaHeader = ffi.typeof("struct EncodedAreaHeader") world.EncodedAreaHeader = ffi.typeof("struct EncodedAreaHeader")
world.PixelRun = ffi.typeof("struct PixelRun") world.PixelRun = ffi.typeof("struct PixelRun")
world.EncodedArea = ffi.typeof("struct EncodedArea") world.EncodedArea = ffi.typeof("struct EncodedArea")
@ -211,9 +213,11 @@ function world.decode(grid_world, header, pixel_runs)
end end
if current_material ~= new_material and new_material ~= 0 then if current_material ~= new_material and new_material ~= 0 then
if new_material > world.last_material_id then
goto next_pixel
end
local mat_ptr = world_ffi.get_material_ptr(new_material) local mat_ptr = world_ffi.get_material_ptr(new_material)
if mat_ptr == nil then if mat_ptr == nil then
GamePrint("NULL mat_ptr encountered")
goto next_pixel goto next_pixel
end end
local pixel = world_ffi.construct_cell(grid_world, x, y, mat_ptr, nil) local pixel = world_ffi.construct_cell(grid_world, x, y, mat_ptr, nil)

View file

@ -21,6 +21,20 @@ local CHUNK_SIZE = 128
local iter = 0 local iter = 0
function world_sync.on_world_initialized()
local c = 0
while true do
local name = CellFactory_GetName(c)
if name == "unknown" then
break
end
c = c + 1
end
c = c - 1
print("Last material id: "..c)
world.last_material_id = c
end
function world_sync.on_world_update() function world_sync.on_world_update()
local grid_world = world_ffi.get_grid_world() local grid_world = world_ffi.get_grid_world()

View file

@ -153,6 +153,7 @@ function OnWorldInitialized() -- This is called once the game world is initializ
else else
GameRemoveFlagRun("ew_flag_this_is_host") GameRemoveFlagRun("ew_flag_this_is_host")
end end
ctx.hook.on_world_initialized()
end end