diff --git a/docs/hooks.md b/docs/hooks.md new file mode 100644 index 00000000..ba50542a --- /dev/null +++ b/docs/hooks.md @@ -0,0 +1,8 @@ +# List of available hooks: + + - `ctx.hook.on_world_update()` + - `ctx.hook.on_world_update_client()` + - `ctx.hook.on_world_update_host()` + - `ctx.hook.on_local_player_spawn(my_player)` + - `ctx.hook.on_client_spawned(peer_id, new_playerdata)` + - `ctx.hook.on_should_send_updates()` - called either when we connect, or somebody else connects (and sends "welcome" message) diff --git a/noita-proxy/src/lib.rs b/noita-proxy/src/lib.rs index 3d712e5a..8ab5dde2 100644 --- a/noita-proxy/src/lib.rs +++ b/noita-proxy/src/lib.rs @@ -9,7 +9,7 @@ use bitcode::{Decode, Encode}; use clipboard::{ClipboardContext, ClipboardProvider}; use eframe::egui::{self, Align2, Color32}; use mod_manager::{Modmanager, ModmanagerSettings}; -use net::omni::PeerVariant; +use net::{omni::PeerVariant, NetManagerInit}; use self_update::SelfUpdateManager; use serde::{Deserialize, Serialize}; use steamworks::{LobbyId, SteamAPIInitError}; @@ -42,6 +42,7 @@ struct AppSavedState { addr: String, debug_mode: bool, use_constant_seed: bool, + nickname: Option, } impl Default for AppSavedState { @@ -50,6 +51,7 @@ impl Default for AppSavedState { addr: "127.0.0.1:5123".to_string(), debug_mode: false, use_constant_seed: false, + nickname: None, } } } @@ -87,10 +89,20 @@ impl App { } } + fn get_netman_init(&self) -> NetManagerInit { + let steam_nickname = if let Ok(steam) = &self.steam_state { + Some(steam.get_user_name(steam.get_my_id())) + } else { + None + }; + let my_nickname = self.saved_state.nickname.clone().or(steam_nickname); + NetManagerInit { my_nickname } + } + fn start_server(&mut self) { let bind_addr = "0.0.0.0:5123".parse().unwrap(); let peer = Peer::host(bind_addr, None).unwrap(); - let netman = net::NetManager::new(PeerVariant::Tangled(peer)); + let netman = net::NetManager::new(PeerVariant::Tangled(peer), self.get_netman_init()); self.set_netman_settings(&netman); netman.clone().start(); self.state = AppState::Netman { netman }; @@ -106,7 +118,7 @@ impl App { } fn start_connect(&mut self, addr: SocketAddr) { let peer = Peer::connect(addr, None).unwrap(); - let netman = net::NetManager::new(PeerVariant::Tangled(peer)); + let netman = net::NetManager::new(PeerVariant::Tangled(peer), self.get_netman_init()); netman.clone().start(); self.state = AppState::Netman { netman }; } @@ -116,7 +128,7 @@ impl App { steamworks::LobbyType::Private, self.steam_state.as_ref().unwrap().client.clone(), ); - let netman = net::NetManager::new(PeerVariant::Steam(peer)); + let netman = net::NetManager::new(PeerVariant::Steam(peer), self.get_netman_init()); self.set_netman_settings(&netman); netman.clone().start(); self.state = AppState::Netman { netman }; @@ -133,7 +145,7 @@ impl App { id, self.steam_state.as_ref().unwrap().client.clone(), ); - let netman = net::NetManager::new(PeerVariant::Steam(peer)); + let netman = net::NetManager::new(PeerVariant::Steam(peer), self.get_netman_init()); netman.clone().start(); self.state = AppState::Netman { netman }; } diff --git a/noita-proxy/src/net.rs b/noita-proxy/src/net.rs index 103252a8..67aea336 100644 --- a/noita-proxy/src/net.rs +++ b/noita-proxy/src/net.rs @@ -50,18 +50,23 @@ impl NetInnerState { pub mod omni; +pub struct NetManagerInit { + pub my_nickname: Option, +} + pub struct NetManager { - pub(crate) peer: omni::PeerVariant, - pub(crate) settings: Mutex, - pub(crate) continue_running: AtomicBool, // TODO stop on drop - pub(crate) accept_local: AtomicBool, - pub(crate) local_connected: AtomicBool, - pub(crate) stopped: AtomicBool, - pub(crate) error: Mutex>, + pub peer: omni::PeerVariant, + pub settings: Mutex, + pub continue_running: AtomicBool, // TODO stop on drop + pub accept_local: AtomicBool, + pub local_connected: AtomicBool, + pub stopped: AtomicBool, + pub error: Mutex>, + pub init_settings: NetManagerInit, } impl NetManager { - pub fn new(peer: omni::PeerVariant) -> Arc { + pub fn new(peer: omni::PeerVariant, init: NetManagerInit) -> Arc { Self { peer, settings: Mutex::new(GameSettings { @@ -74,6 +79,7 @@ impl NetManager { local_connected: AtomicBool::new(false), stopped: AtomicBool::new(false), error: Default::default(), + init_settings: init, } .into() } @@ -157,7 +163,12 @@ impl NetManager { "host_id", format!("{:016x}", self.peer.host_id().0), )); - state.try_ws_write(ws_encode_proxy("name", "test_name")); + 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" }, diff --git a/noita-proxy/src/steam_helper.rs b/noita-proxy/src/steam_helper.rs index 01bd698a..7dcd0c35 100644 --- a/noita-proxy/src/steam_helper.rs +++ b/noita-proxy/src/steam_helper.rs @@ -83,4 +83,8 @@ impl SteamState { // ctx.load_texture(name, image, options) } + + pub(crate) fn get_my_id(&self) -> SteamId { + self.client.user().steam_id() + } } diff --git a/quant.ew/files/src/ctx.lua b/quant.ew/files/src/ctx.lua index 4fe4885b..929bac2b 100644 --- a/quant.ew/files/src/ctx.lua +++ b/quant.ew/files/src/ctx.lua @@ -24,6 +24,7 @@ ctx.init = function() end function ctx.dofile_and_add_hooks(path) + print("Loading "..path) local result = dofile_once(path) for key, value in pairs(result) do if string.sub(key, 1, 3) == "on_" then diff --git a/quant.ew/files/src/net_handling.lua b/quant.ew/files/src/net_handling.lua index 14b37a2c..ce3c14c9 100644 --- a/quant.ew/files/src/net_handling.lua +++ b/quant.ew/files/src/net_handling.lua @@ -22,6 +22,7 @@ function net_handling.proxy.seed(_, value) end function net_handling.proxy.peer_id(_, value) + print("My peer_id: "..value) ctx.my_id = value ctx.is_host = ctx.my_id == ctx.host_id end @@ -35,6 +36,11 @@ function net_handling.proxy.host_id(_, value) ctx.is_host = ctx.my_id == ctx.host_id end +function net_handling.proxy.name(_, value) + print("Got name from proxy: "..value) + ctx.my_name = value +end + function net_handling.mod.player(peer_id, value) local input_data = value.i local pos_data = value.p @@ -198,6 +204,7 @@ end function net_handling.mod.welcome(peer_id, _) ctx.events.new_player_just_connected = true + ctx.hook.on_should_send_updates() end function net_handling.mod.heart_pickup(peer_id, heart_pickup) diff --git a/quant.ew/files/src/player_fns.lua b/quant.ew/files/src/player_fns.lua index 726a9f74..ee4fcb70 100644 --- a/quant.ew/files/src/player_fns.lua +++ b/quant.ew/files/src/player_fns.lua @@ -1,7 +1,6 @@ local ctx = dofile_once("mods/quant.ew/files/src/ctx.lua") local inventory_helper = dofile_once("mods/quant.ew/files/src/inventory_helper.lua") local util = dofile_once("mods/quant.ew/files/src/util.lua") -local nickname = dofile_once("mods/quant.ew/files/src/nickname.lua") local ffi = require("ffi") local np = require("noitapatcher") @@ -409,7 +408,7 @@ function player_fns.spawn_player_for(peer_id, x, y, existing_playerdata) local new = EntityLoad("mods/quant.ew/files/entities/client.xml", x, y) local new_playerdata = existing_playerdata or player_fns.make_playerdata_for(new, peer_id) new_playerdata.entity = new - util.tpcall(nickname.addLabel, new, new_playerdata.name, "data/fonts/font_pixel_white.xml", 1) + -- util.tpcall(nickname.addLabel, new, new_playerdata.name, "data/fonts/font_pixel_white.xml", 1) ctx.players[peer_id] = new_playerdata EntitySetName(new, tostring(peer_id)) if ctx.is_host then @@ -430,6 +429,7 @@ function player_fns.spawn_player_for(peer_id, x, y, existing_playerdata) end GlobalsSetValue(global, "1") -- np.SetPlayerEntity(new, peer_id+1) + ctx.hook.on_client_spawned(peer_id, new_playerdata) end function player_fns.respawn_if_necessary() diff --git a/quant.ew/files/src/sync/damage_sync.lua b/quant.ew/files/src/sync/damage_sync.lua index 1da844f8..29f74463 100644 --- a/quant.ew/files/src/sync/damage_sync.lua +++ b/quant.ew/files/src/sync/damage_sync.lua @@ -21,7 +21,7 @@ function module.on_local_player_spawn(my_player) EntityAddComponent2(my_player.entity, "LuaComponent", {script_damage_received = "mods/quant.ew/files/cbs/send_damage_to_host.lua"}) local damage_model = EntityGetFirstComponentIncludingDisabled(my_player.entity, "DamageModelComponent") - ComponentSetValue2(damage_model, "damage_multipliers", "melee", 0) + -- ComponentSetValue2(damage_model, "damage_multipliers", "melee", 0) end end diff --git a/quant.ew/files/src/nickname.lua b/quant.ew/files/src/system/nickname.lua similarity index 65% rename from quant.ew/files/src/nickname.lua rename to quant.ew/files/src/system/nickname.lua index bf45100b..b9b89f4d 100644 --- a/quant.ew/files/src/nickname.lua +++ b/quant.ew/files/src/system/nickname.lua @@ -1,3 +1,9 @@ +local ctx = dofile_once("mods/quant.ew/files/src/ctx.lua") +local net = dofile_once("mods/quant.ew/files/src/net.lua") +local player_fns = dofile_once("mods/quant.ew/files/src/player_fns.lua") + +local rpc = net.new_rpc_namespace() + local util = dofile_once("mods/quant.ew/files/src/util.lua") local nickname = {} @@ -64,15 +70,19 @@ function nickname.calculate_textwidth(text, font) else local c_id = string.byte(l) --GamePrint("Char: ".. l .. ". Id: "..tostring(c_id)) - textwidth = textwidth + font[c_id] + textwidth = textwidth + (font[c_id] or 1) end end return textwidth end -function nickname.addLabel(player_entity, text, font_filename, scale, font) - +function nickname.add_label(player_entity, text, font_filename, scale, font) + local prev_nickname = EntityGetFirstComponentIncludingDisabled(player_entity, "SpriteComponent", "ew_nickname") + if prev_nickname ~= nil then + EntityRemoveComponent(player_entity, prev_nickname) + end + if (scale == nil) then scale = 1 end @@ -82,6 +92,7 @@ function nickname.addLabel(player_entity, text, font_filename, scale, font) local textwidth = nickname.calculate_textwidth(text, font) local nickname_component = EntityAddComponent2(player_entity, "SpriteComponent", { + _tags="ew_nickname", image_file=font_filename, is_text_sprite=true, offset_x=textwidth*0.5, @@ -90,7 +101,7 @@ function nickname.addLabel(player_entity, text, font_filename, scale, font) update_transform_rotation=false, fog_of_war_hole = true, text=text, - z_index="1", + z_index=1, alpha=0.5, emissive = true, has_special_scale=true, @@ -102,4 +113,28 @@ function nickname.addLabel(player_entity, text, font_filename, scale, font) end +function nickname.on_local_player_spawn(my_player) + if ctx.my_name ~= nil then + my_player.name = ctx.my_name + end +end + +function nickname.on_client_spawned(peer_id, player_data) + nickname.add_label(player_data.entity, player_data.name, "data/fonts/font_pixel_white.xml", 0.5) +end + +function nickname.on_should_send_updates() + print("Should send nickname update") + if ctx.my_name ~= nil then + print("Sending name "..ctx.my_name) + rpc.send_name(ctx.my_name) + end +end + +rpc.opts_reliable() +function rpc.send_name(name) + ctx.rpc_player_data.name = name + nickname.add_label(ctx.rpc_player_data.entity, name, "data/fonts/font_pixel_white.xml", 0.5) +end + return nickname \ No newline at end of file diff --git a/quant.ew/files/src/util.lua b/quant.ew/files/src/util.lua index 64aa6b92..85d8b241 100644 --- a/quant.ew/files/src/util.lua +++ b/quant.ew/files/src/util.lua @@ -12,9 +12,12 @@ end function util.print_error(error) local lines = util.string_split(error, "\n") + print("---err start---") for _, line in ipairs(lines) do GamePrint(line) + print(line) end + print("---err end---") end function util.tpcall(fn, ...) diff --git a/quant.ew/init.lua b/quant.ew/init.lua index 6e9ca8f3..8bf70d0f 100755 --- a/quant.ew/init.lua +++ b/quant.ew/init.lua @@ -23,6 +23,9 @@ ctx.dofile_and_add_hooks("mods/quant.ew/files/src/item_sync.lua") ctx.dofile_and_add_hooks("mods/quant.ew/files/src/sync/effect_sync.lua") ctx.dofile_and_add_hooks("mods/quant.ew/files/src/sync/damage_sync.lua") +ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/nickname.lua") + + local version = dofile_once("mods/quant.ew/files/version.lua") or "unknown (dev build)" ModLuaFileAppend("data/scripts/gun/gun.lua", "mods/quant.ew/files/append/gun.lua") @@ -178,6 +181,7 @@ function OnPlayerSpawned( player_entity ) -- This runs when player entity has be end ctx.hook.on_local_player_spawn(my_player) + ctx.hook.on_should_send_updates() GamePrint("Noita Entangled Worlds version "..version)