diff --git a/README.md b/README.md index cf4cb751..d21fe5e6 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,21 @@ After that, just start a new Noita game on everyone's PCs, and you should be in [The mods listed here](https://docs.google.com/spreadsheets/d/1nMdqzrLCav_diXbNPB9RgxPcCQzDPgXdEv-klKWJyS0) have been tested by the community, it is publically editable so please add any untested mod with your findings + +## Cli connect + +can also connect via cli, just run `noita_proxy --lobby [steam_code/ip and port]` + +## Connecting via steam without steam version of game + +to connect via steam without the steam version of game, since its more stable you can do the following + +on all clients run the game with the NP_APPID=480 environemental variable, you can do that by making a bat/bash file to set that before running the executable + ## Thanks Special thanks to: - Contributors. - @EvaisaDev for allowing to use code from Noita Arena mod. - @dextercd for NoitaPatcher. - - Creators of other libraries used in this project. + - Creators of other libraries used in this project. \ No newline at end of file diff --git a/noita-proxy/src/bookkeeping/mod_manager.rs b/noita-proxy/src/bookkeeping/mod_manager.rs index 07a2686e..c2b54368 100644 --- a/noita-proxy/src/bookkeeping/mod_manager.rs +++ b/noita-proxy/src/bookkeeping/mod_manager.rs @@ -61,7 +61,7 @@ pub struct ModmanagerSettings { } impl ModmanagerSettings { - fn try_find_game_path(&mut self, steam_state: Option<&mut SteamState>) { + pub fn try_find_game_path(&mut self, steam_state: Option<&mut SteamState>) { info!("Trying to find game path"); if let Some(state) = steam_state { let apps = state.client.apps(); @@ -79,7 +79,7 @@ impl ModmanagerSettings { } } - fn try_find_save_path(&mut self) { + pub fn try_find_save_path(&mut self) { if cfg!(target_os = "windows") { // Noita uses AppData folder instead of %AppData% let appdata_path = PathBuf::from( diff --git a/noita-proxy/src/lib.rs b/noita-proxy/src/lib.rs index 1e4a49fa..c5a951eb 100644 --- a/noita-proxy/src/lib.rs +++ b/noita-proxy/src/lib.rs @@ -31,6 +31,7 @@ use std::{ time::Duration, }; use std::{net::IpAddr, path::PathBuf}; +use std::str::FromStr; use steamworks::{LobbyId, SteamAPIInitError}; use tangled::Peer; use tracing::info; @@ -46,7 +47,7 @@ use crate::player_cosmetics::{ player_skin_display_color_picker, shift_hue, }; pub use bookkeeping::{mod_manager, releases, self_update}; -mod net; +pub mod net; mod player_cosmetics; pub mod recorder; @@ -1185,3 +1186,54 @@ fn peer_role(peer: net::omni::OmniPeerId, netman: &Arc) -> Stri tr("player_player") } } + +pub fn start_cli(lobby: String) +{ + let mut state = steam_helper::SteamState::new().unwrap(); + let my_nickname = Some(state.get_user_name(state.get_my_id())); + let mut mod_manager = ModmanagerSettings{game_exe_path: PathBuf::new(), game_save_path: Some(PathBuf::new())}; + mod_manager.try_find_game_path(Some(&mut state)); + mod_manager.try_find_save_path(); + let run_save_state = if let Ok(path) = std::env::current_exe() { + SaveState::new(path.parent().unwrap().join("save_state")) + } else { + SaveState::new("./save_state/".into()) + }; + let player_path = player_path(mod_manager.mod_path()); + let mut cosmetics = (false, false, false); + if let Some(path) = &mod_manager.game_save_path { + let flags = path.join("save00/persistent/flags"); + let hat = flags.join("secret_hat").exists(); + let amulet = flags.join("secret_amulet").exists(); + let gem = flags.join("secret_amulet_gem").exists(); + if !hat { + cosmetics.0 = false + } + if !amulet { + cosmetics.1 = false + } + if !gem { + cosmetics.2 = false + } + } + let netmaninit = NetManagerInit { + my_nickname, + save_state: run_save_state, + player_color: PlayerColor::default(), + cosmetics, + mod_path: mod_manager.mod_path(), + player_path: player_path.clone(), + }; + let varient = if lobby.contains('.') + { + PeerVariant::Tangled(Peer::connect(SocketAddr::from_str(&lobby).unwrap(), None).unwrap()) + } else { + let peer = net::steam_networking::SteamPeer::new_connect( + lobby.trim().parse().map(LobbyId::from_raw).unwrap(), + state.client, + ); + PeerVariant::Steam(peer) + }; + let netman = net::NetManager::new(varient, netmaninit); + netman.clone().start_inner(player_path).unwrap(); +} \ No newline at end of file diff --git a/noita-proxy/src/main.rs b/noita-proxy/src/main.rs index 50e94991..07fc6f0c 100644 --- a/noita-proxy/src/main.rs +++ b/noita-proxy/src/main.rs @@ -2,12 +2,12 @@ use eframe::{ egui::{IconData, ViewportBuilder}, NativeOptions, }; -use noita_proxy::{args::Args, recorder::replay_file, App}; +use noita_proxy::{args::Args, recorder::replay_file, start_cli, App}; use tracing::{info, level_filters::LevelFilter}; use tracing_subscriber::EnvFilter; #[tokio::main(worker_threads = 2)] -async fn main() -> Result<(), eframe::Error> { +async fn main() { let my_subscriber = tracing_subscriber::FmtSubscriber::builder() .with_env_filter( EnvFilter::builder() @@ -22,29 +22,31 @@ async fn main() -> Result<(), eframe::Error> { info!("{:?}", args.launch_cmd); if let Some(replay) = args.replay_folder { - replay_file(replay); - return Ok(()); + replay_file(replay) } - - let icon = image::load_from_memory(include_bytes!("../assets/icon.png")) - .unwrap() - .to_rgba8(); - let icon = IconData { - width: icon.width(), - height: icon.height(), - rgba: icon.into_vec(), - }; - - eframe::run_native( - "Noita Proxy", // Don't change that, it defines where settings are stored. - NativeOptions { - viewport: ViewportBuilder::default() - .with_min_inner_size([800.0, 600.0]) - .with_icon(icon) - .with_title("Noita Entangled Worlds Proxy"), - follow_system_theme: false, - ..Default::default() - }, - Box::new(|cc| Ok(Box::new(App::new(cc, args)))), - ) -} + else if let Some(lobby) = args.lobby + { + start_cli(lobby) + } else { + let icon = image::load_from_memory(include_bytes!("../assets/icon.png")) + .unwrap() + .to_rgba8(); + let icon = IconData { + width: icon.width(), + height: icon.height(), + rgba: icon.into_vec(), + }; + eframe::run_native( + "Noita Proxy", // Don't change that, it defines where settings are stored. + NativeOptions { + viewport: ViewportBuilder::default() + .with_min_inner_size([800.0, 600.0]) + .with_icon(icon) + .with_title("Noita Entangled Worlds Proxy"), + follow_system_theme: false, + ..Default::default() + }, + Box::new(|cc| Ok(Box::new(App::new(cc, args)))), + ).unwrap() + } +} \ No newline at end of file diff --git a/noita-proxy/src/net/messages.rs b/noita-proxy/src/net/messages.rs index 9e813dc0..3e370fe3 100644 --- a/noita-proxy/src/net/messages.rs +++ b/noita-proxy/src/net/messages.rs @@ -18,7 +18,7 @@ pub(crate) struct MessageRequest { } #[derive(Debug, Decode, Encode)] -pub enum NetMsg { +pub(crate) enum NetMsg { Welcome, EndRun, StartGame { settings: GameSettings }, @@ -36,4 +36,4 @@ impl From> for MessageRequest { dst: value.dst, } } -} +} \ No newline at end of file diff --git a/noita-proxy/src/util/args.rs b/noita-proxy/src/util/args.rs index 5f7ddef2..d2cc7e81 100644 --- a/noita-proxy/src/util/args.rs +++ b/noita-proxy/src/util/args.rs @@ -14,4 +14,7 @@ pub struct Args { /// path to crashcatcher's replay folder. #[argh(option)] pub replay_folder: Option, + /// steam lobby code. + #[argh(option)] + pub lobby: Option, }