diff --git a/ewext/src/lib.rs b/ewext/src/lib.rs index 01adeeb9..63443d62 100644 --- a/ewext/src/lib.rs +++ b/ewext/src/lib.rs @@ -5,17 +5,6 @@ pub extern "C" fn _Unwind_Resume() {} use addr_grabber::{grab_addrs, grabbed_fns, grabbed_globals}; use bimap::BiHashMap; use eyre::{bail, Context, OptionExt}; -use std::num::NonZero; -use std::{ - arch::asm, - borrow::Cow, - cell::{LazyCell, RefCell}, - ffi::{c_int, c_void}, - sync::{LazyLock, Mutex, OnceLock}, - thread, - time::Instant, -}; - use modules::{entity_sync::EntitySync, Module, ModuleCtx}; use net::NetManager; use noita::{ntypes::Entity, pixel::NoitaPixelRun, ParticleWorldState}; @@ -27,8 +16,19 @@ use noita_api::{ DamageModelComponent, EntityID, }; use noita_api_macro::add_lua_fn; +use rustc_hash::FxHashMap; use shared::des::Gid; use shared::{NoitaInbound, PeerId, ProxyKV}; +use std::num::NonZero; +use std::{ + arch::asm, + borrow::Cow, + cell::{LazyCell, RefCell}, + ffi::{c_int, c_void}, + sync::{LazyLock, Mutex, OnceLock}, + thread, + time::Instant, +}; mod addr_grabber; mod modules; mod net; @@ -63,6 +63,7 @@ struct ExtState { particle_world_state: Option, modules: Modules, player_entity_map: BiHashMap, + fps_by_player: FxHashMap, sync_rate: i32, } @@ -250,6 +251,7 @@ fn with_every_module( let mut ctx = ModuleCtx { net, player_map: &mut state.player_entity_map, + fps_by_player: &mut state.fps_by_player, sync_rate: state.sync_rate, }; let mut errs = Vec::new(); @@ -419,7 +421,8 @@ pub unsafe extern "C" fn luaopen_ewext0(lua: *mut lua_State) -> c_int { ExtState::with_global(|state| { let entity = lua.to_string(1)?.parse::()?; let mut peer = lua.to_string(2)?.parse::()?; - let mut rng: u64 = u32::from_ne_bytes(lua.to_string(3)?.parse::()?.to_ne_bytes()) as u64; + let mut rng: u64 = + u32::from_ne_bytes(lua.to_string(3)?.parse::()?.to_ne_bytes()) as u64; if rng == 0 { rng = 1; } @@ -488,11 +491,21 @@ pub unsafe extern "C" fn luaopen_ewext0(lua: *mut lua_State) -> c_int { fn send_sync_rate(lua: LuaState) -> eyre::Result<()> { let rate = lua.to_string(1)?.parse::()?; ExtState::with_global(|state| { - state.sync_rate = rate.max(1).min(60); + state.sync_rate = rate.clamp(1, 60); Ok(()) })? } add_lua_fn!(send_sync_rate); + + fn set_player_fps(lua: LuaState) -> eyre::Result<()> { + let peer = PeerId::from_hex(&lua.to_string(1)?)?; + let fps = lua.to_string(2)?.parse::()?; + ExtState::with_global(|state| { + state.fps_by_player.insert(peer, fps); + Ok(()) + })? + } + add_lua_fn!(set_player_fps); } println!("Initializing ewext - Ok"); 1 diff --git a/ewext/src/modules.rs b/ewext/src/modules.rs index ec5c7243..9237525c 100644 --- a/ewext/src/modules.rs +++ b/ewext/src/modules.rs @@ -1,6 +1,7 @@ use bimap::BiHashMap; use eyre::Ok; use noita_api::EntityID; +use rustc_hash::FxHashMap; use shared::PeerId; use crate::{my_peer_id, net::NetManager}; @@ -10,6 +11,7 @@ pub(crate) mod entity_sync; pub(crate) struct ModuleCtx<'a> { pub(crate) net: &'a mut NetManager, pub(crate) player_map: &'a mut BiHashMap, + pub(crate) fps_by_player: &'a mut FxHashMap, pub(crate) sync_rate: i32, } impl ModuleCtx<'_> { diff --git a/ewext/src/modules/entity_sync.rs b/ewext/src/modules/entity_sync.rs index acfaae35..01835bed 100644 --- a/ewext/src/modules/entity_sync.rs +++ b/ewext/src/modules/entity_sync.rs @@ -146,7 +146,7 @@ impl EntitySync { RemoteDes::EntityUpdate(vec) => { self.remote_models .entry(source) - .or_default() + .or_insert(RemoteDiffModel::new(source)) .apply_diff(&vec); } RemoteDes::ExitedInterest => { @@ -156,7 +156,7 @@ impl EntitySync { RemoteDes::Projectiles(vec) => { self.remote_models .entry(source) - .or_default() + .or_insert(RemoteDiffModel::new(source)) .spawn_projectiles(&vec); } RemoteDes::RequestGrab(lid) => { @@ -360,4 +360,4 @@ fn send_remotedes( message: RemoteMessage::RemoteDes(remote_des), })?; Ok(()) -} \ No newline at end of file +} diff --git a/ewext/src/modules/entity_sync/diff_model.rs b/ewext/src/modules/entity_sync/diff_model.rs index edbd3c1a..71544604 100644 --- a/ewext/src/modules/entity_sync/diff_model.rs +++ b/ewext/src/modules/entity_sync/diff_model.rs @@ -50,7 +50,6 @@ pub(crate) struct LocalDiffModel { tracker: LocalDiffModelTracker, } -#[derive(Default)] pub(crate) struct RemoteDiffModel { tracked: BiHashMap, entity_infos: FxHashMap, @@ -61,6 +60,23 @@ pub(crate) struct RemoteDiffModel { grab_request: Vec, pending_remove: Vec, pending_death_notify: Vec<(Lid, Option)>, + peer_id: PeerId, +} + +impl RemoteDiffModel { + pub fn new(peer_id: PeerId) -> Self { + Self { + tracked: Default::default(), + entity_infos: Default::default(), + lid_to_gid: Default::default(), + waiting_for_lid: Default::default(), + backtrack: Default::default(), + grab_request: Default::default(), + pending_remove: Default::default(), + pending_death_notify: Default::default(), + peer_id, + } + } } impl Default for LocalDiffModel { @@ -275,7 +291,7 @@ impl LocalDiffModelTracker { .find(|var| var.name().unwrap_or("".into()) == "ew_peer_id") { game_print(var.value_string()?); - info.laser = Some(PeerId(var.value_string()?.parse::()?)) + info.laser = Some(PeerId::from_hex(&var.value_string()?)?) } } } @@ -947,29 +963,30 @@ impl RemoteDiffModel { entity.remove_component(*limb)? }; } + let m = *ctx.fps_by_player.get(&my_peer_id()).unwrap_or(&60) as f32 + / *ctx.fps_by_player.get(&self.peer_id).unwrap_or(&60) as f32; + let (vx, vy) = (entity_info.vx * m, entity_info.vy * m); if entity_info.phys.is_empty() || entity_info.kolmi_enabled { entity.set_position(entity_info.x, entity_info.y, Some(entity_info.r))?; if let Some(vel) = entity.try_get_first_component::(None)? { - vel.set_m_velocity((entity_info.vx, entity_info.vy))?; + vel.set_m_velocity((vx, vy))?; } if let Some(worm) = entity.try_get_first_component::(None)? { - worm.set_m_target_vec((entity_info.vx, entity_info.vy))?; + worm.set_m_target_vec((vx, vy))?; } else if let Some(worm) = entity.try_get_first_component::(None)? { - worm.set_m_target_vec((entity_info.vx, entity_info.vy))?; + worm.set_m_target_vec((vx, vy))?; } else if let Some(vel) = entity.try_get_first_component::(None)? { - vel.set_m_velocity((entity_info.vx, entity_info.vy))?; + vel.set_m_velocity((vx, vy))?; } } - //local m = host_fps / ctx.my_player.fps TODO - //vx, vy = vx * m, vy * m if let Some(damage) = entity.try_get_first_component::(None)? { @@ -1008,9 +1025,9 @@ impl RemoteDiffModel { x, y, p.angle.into(), - p.vx.into(), - p.vy.into(), - p.av.into(), + (p.vx * m).into(), + (p.vy * m).into(), + (p.av * m).into(), )?; } } diff --git a/quant.ew/files/system/player_sync.lua b/quant.ew/files/system/player_sync.lua index 91cf7fa0..1bb136a2 100644 --- a/quant.ew/files/system/player_sync.lua +++ b/quant.ew/files/system/player_sync.lua @@ -166,6 +166,7 @@ local function update_fps() end function rpc.update_fps(fps) + ewext.set_player_fps(ctx.rpc_peer_id, fps) ctx.rpc_player_data.fps = fps end @@ -313,6 +314,7 @@ function module.on_world_update() local last = ctx.my_player.fps update_fps() if ctx.my_player.fps ~= last then + ewext.set_player_fps(ctx.my_id, ctx.my_player.fps) rpc.update_fps(ctx.my_player.fps) end end