World sync version selection

This commit is contained in:
IQuant 2024-06-06 15:25:01 +03:00
parent e52686edc2
commit 74ebce7989
9 changed files with 111 additions and 60 deletions

View file

@ -1,5 +1,8 @@
run:
cd noita-proxy && NP_APPID=480 NP_SKIP_MOD_CHECK=1 cargo run
run-rel:
cd noita-proxy && NP_APPID=480 NP_SKIP_MOD_CHECK=1 cargo run --release
run2:
cd noita-proxy && NP_APPID=480 NP_SKIP_MOD_CHECK=1 NP_NOITA_ADDR=127.0.0.1:21252 cargo run

View file

@ -7,7 +7,7 @@ use std::{
use bitcode::{Decode, Encode};
use clipboard::{ClipboardContext, ClipboardProvider};
use eframe::egui::{self, Align2, Color32, InnerResponse, Margin, TextureOptions, Ui};
use eframe::egui::{self, Align2, Color32, InnerResponse, Margin, RichText, TextureOptions, Ui};
use mod_manager::{Modmanager, ModmanagerSettings};
use net::{omni::PeerVariant, NetManagerInit};
use self_update::SelfUpdateManager;
@ -27,6 +27,7 @@ pub mod steam_helper;
pub struct GameSettings {
seed: u64,
debug_mode: bool,
world_sync_version: u32,
}
enum AppState {
@ -44,6 +45,7 @@ struct AppSavedState {
use_constant_seed: bool,
nickname: Option<String>,
times_started: u32,
world_sync_version: u32,
}
impl Default for AppSavedState {
@ -54,6 +56,7 @@ impl Default for AppSavedState {
use_constant_seed: false,
nickname: None,
times_started: 0,
world_sync_version: 1,
}
}
}
@ -81,6 +84,13 @@ fn filled_group<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Inne
frame.show(ui, add_contents)
}
fn heading_with_underline(ui: &mut Ui, text: impl Into<RichText>) {
ui.vertical_centered_justified(|ui| {
ui.heading(text);
});
ui.separator();
}
impl App {
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
let mut saved_state: AppSavedState = cc
@ -190,21 +200,31 @@ impl App {
ui.allocate_ui_at_rect(settings_rect.shrink(item_spacing), |ui| {
filled_group(ui, |ui| {
ui.set_min_size(ui.available_size());
ui.vertical_centered_justified(|ui| {
ui.heading("Game settings");
});
ui.separator();
ui.checkbox(&mut self.saved_state.debug_mode, "Debug mode");
heading_with_underline(ui, "Game settings");
ui.label("Debug settings");
ui.checkbox(&mut self.saved_state.debug_mode, "Debug/cheat mode");
ui.checkbox(&mut self.saved_state.use_constant_seed, "Use fixed seed");
ui.add_space(20.0);
ui.label("World sync version to use:");
ui.horizontal(|ui| {
ui.radio_value(&mut self.saved_state.world_sync_version, 1, "v1");
ui.radio_value(
&mut self.saved_state.world_sync_version,
2,
"v2 (experimental)",
);
});
});
});
ui.allocate_ui_at_rect(steam_connect_rect.shrink(item_spacing), |ui| {
filled_group(ui, |ui| {
ui.set_min_size(ui.available_size());
ui.vertical_centered_justified(|ui| {
ui.heading("Connect using steam");
});
ui.separator();
heading_with_underline(ui, "Connect using steam");
match &self.steam_state {
Ok(_) => {
if ui.button("Create lobby").clicked() {
@ -234,10 +254,9 @@ impl App {
ui.allocate_ui_at_rect(ip_connect_rect.shrink(item_spacing), |ui| {
filled_group(ui, |ui| {
ui.set_min_size(ui.available_size());
ui.vertical_centered_justified(|ui| {
ui.heading("Connect by ip");
});
ui.separator();
heading_with_underline(ui, "Connect by ip");
ui.label("Note: steam networking is more reliable. Use it, if possible.");
if ui.button("Host").clicked() {
self.start_server();

View file

@ -27,6 +27,13 @@ pub(crate) fn ws_encode_proxy(key: &'static str, value: impl Display) -> tungste
tungstenite::Message::Binary(buf)
}
pub(crate) fn ws_encode_proxy_opt(key: &'static str, value: impl Display) -> tungstenite::Message {
let mut buf = Vec::new();
buf.push(2);
write!(buf, "proxy_opt {} {}", key, value).unwrap();
tungstenite::Message::Binary(buf)
}
pub fn ws_encode_proxy_bin(key: u8, data: &[u8]) -> tungstenite::Message {
let mut buf = Vec::new();
buf.push(3);
@ -84,6 +91,7 @@ impl NetManager {
// seed: 1663107061,
seed: 1663107066,
debug_mode: false,
world_sync_version: 1,
}),
continue_running: AtomicBool::new(true),
accept_local: AtomicBool::new(false),
@ -160,38 +168,7 @@ impl NetManager {
.inspect_err(|e| error!("Could not init websocket: {}", e))
.ok();
if state.ws.is_some() {
info!("New stream connected");
let stream_ref = &state.ws.as_ref().unwrap().get_ref();
stream_ref.set_nonblocking(true).ok();
stream_ref
.set_read_timeout(Some(Duration::from_millis(1)))
.expect("can set read timeout");
let settings = self.settings.lock().unwrap();
state.try_ws_write(ws_encode_proxy("seed", settings.seed));
let value = self.peer.my_id().expect("Has peer id at this point");
state.try_ws_write(ws_encode_proxy("peer_id", format!("{:016x}", value.0)));
state.try_ws_write(ws_encode_proxy(
"host_id",
format!("{:016x}", self.peer.host_id().0),
));
if let Some(nickname) = &self.init_settings.my_nickname {
info!("Chosen nickname: {}", nickname);
state.try_ws_write(ws_encode_proxy("name", nickname));
} else {
info!("No nickname chosen");
}
state.try_ws_write(ws_encode_proxy(
"debug",
if settings.debug_mode { "true" } else { "false" },
));
state.try_ws_write(ws_encode_proxy("ready", ""));
// TODO? those are currently ignored by mod
for id in self.peer.iter_peer_ids() {
state.try_ws_write(ws_encode_proxy("join", id));
}
info!("Settings sent")
self.on_ws_connection(&mut state);
}
}
}
@ -278,6 +255,46 @@ impl NetManager {
Ok(())
}
fn on_ws_connection(self: &Arc<NetManager>, state: &mut NetInnerState) {
info!("New stream connected");
let stream_ref = &state.ws.as_ref().unwrap().get_ref();
stream_ref.set_nonblocking(true).ok();
stream_ref
.set_read_timeout(Some(Duration::from_millis(1)))
.expect("can set read timeout");
let settings = self.settings.lock().unwrap();
state.try_ws_write(ws_encode_proxy("seed", settings.seed));
let value = self.peer.my_id().expect("Has peer id at this point");
state.try_ws_write(ws_encode_proxy("peer_id", format!("{:016x}", value.0)));
state.try_ws_write(ws_encode_proxy(
"host_id",
format!("{:016x}", self.peer.host_id().0),
));
if let Some(nickname) = &self.init_settings.my_nickname {
info!("Chosen nickname: {}", nickname);
state.try_ws_write(ws_encode_proxy("name", nickname));
} else {
info!("No nickname chosen");
}
state.try_ws_write(ws_encode_proxy(
"debug",
if settings.debug_mode { "true" } else { "false" },
));
state.try_ws_write(ws_encode_proxy_opt(
"world_sync_version",
settings.world_sync_version,
));
state.try_ws_write(ws_encode_proxy("ready", ""));
// TODO? those are currently ignored by mod
for id in self.peer.iter_peer_ids() {
state.try_ws_write(ws_encode_proxy("join", id));
}
info!("Settings sent")
}
pub(crate) fn handle_mod_message(
&self,
msg: Result<tungstenite::Message, tungstenite::Error>,

View file

@ -2,6 +2,7 @@ local ctx = {
ready = false,
lib = {},
hook = {},
proxy_opt = {},
}
setmetatable(ctx.hook, {

View file

@ -79,6 +79,7 @@ function net.init()
kind = "proxy",
key = res[1],
value = res[2],
value2 = res[3],
}
end
elseif string.byte(msg, 1, 1) == 1 then
@ -118,7 +119,7 @@ function net.init()
end
if msg_decoded ~= nil and net_handling[msg_decoded.kind] ~= nil and net_handling[msg_decoded.kind][msg_decoded.key] ~= nil then
if ctx.ready or msg_decoded.kind ~= "mod" then
util.tpcall(net_handling[msg_decoded.kind][msg_decoded.key], msg_decoded.peer_id, msg_decoded.value)
util.tpcall(net_handling[msg_decoded.kind][msg_decoded.key], msg_decoded.peer_id, msg_decoded.value, msg_decoded.value2)
end
-- GamePrint("NetHnd: "..msg_decoded.kind.." "..msg_decoded.key)
end

View file

@ -40,6 +40,11 @@ function net_handling.proxy.name(_, value)
ctx.my_name = value
end
function net_handling.proxy.proxy_opt(_, key, value)
print("Proxy opt: "..key.." = "..value)
ctx.proxy_opt[key] = value
end
function net_handling.mod.player(peer_id, value)
local input_data = value.i
local pos_data = value.p

View file

@ -17,7 +17,7 @@ local KEY_WORLD_FRAME = 0
local KEY_WORLD_END = 1
local initialized_chunks = {}
local CHUNK_SIZE = 256
local CHUNK_SIZE = 128
function world_sync.on_world_update_host()

View file

@ -17,18 +17,6 @@ local inventory_helper = dofile_once("mods/quant.ew/files/src/inventory_helper.l
local pretty = dofile_once("mods/quant.ew/files/lib/pretty_print.lua")
local perk_fns = dofile_once("mods/quant.ew/files/src/perk_fns.lua")
-- ctx.dofile_and_add_hooks("mods/quant.ew/files/src/world_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/item_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/enemy_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/effect_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/damage_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/nickname.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/debug.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/world_sync2.lua")
local version = dofile_once("mods/quant.ew/files/version.lua") or "unknown (dev build)"
print("Noita EW version: "..version)
@ -45,6 +33,22 @@ ModMagicNumbersFileAdd("mods/quant.ew/files/magic.xml")
local my_player = nil
local function load_modules()
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/item_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/enemy_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/effect_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/damage_sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/nickname.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/debug.lua")
if ctx.proxy_opt.world_sync_version == "1" then
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/world_sync_v1.lua")
else
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/world_sync_v2.lua")
end
end
function OnProjectileFired(shooter_id, projectile_id, initial_rng, position_x, position_y, target_x, target_y, send_message,
unknown1, multicast_index, unknown3)
if not EntityHasTag(shooter_id, "player_unit") and not EntityHasTag(shooter_id, "ew_client") then
@ -336,6 +340,7 @@ function OnModPreInit()
register_localizations("mods/quant.ew/translations.csv", 1)
ctx.init()
net.init()
load_modules()
end
function OnModPostInit()