somewhat acceptable cli connect

This commit is contained in:
bgkillas 2024-09-28 10:41:11 -04:00
parent 4161929e72
commit 83cae6ce67
6 changed files with 101 additions and 33 deletions

View file

@ -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 [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 ## Thanks
Special thanks to: Special thanks to:
- Contributors. - Contributors.
- @EvaisaDev for allowing to use code from Noita Arena mod. - @EvaisaDev for allowing to use code from Noita Arena mod.
- @dextercd for NoitaPatcher. - @dextercd for NoitaPatcher.
- Creators of other libraries used in this project. - Creators of other libraries used in this project.

View file

@ -61,7 +61,7 @@ pub struct ModmanagerSettings {
} }
impl 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"); info!("Trying to find game path");
if let Some(state) = steam_state { if let Some(state) = steam_state {
let apps = state.client.apps(); 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") { if cfg!(target_os = "windows") {
// Noita uses AppData folder instead of %AppData% // Noita uses AppData folder instead of %AppData%
let appdata_path = PathBuf::from( let appdata_path = PathBuf::from(

View file

@ -31,6 +31,7 @@ use std::{
time::Duration, time::Duration,
}; };
use std::{net::IpAddr, path::PathBuf}; use std::{net::IpAddr, path::PathBuf};
use std::str::FromStr;
use steamworks::{LobbyId, SteamAPIInitError}; use steamworks::{LobbyId, SteamAPIInitError};
use tangled::Peer; use tangled::Peer;
use tracing::info; use tracing::info;
@ -46,7 +47,7 @@ use crate::player_cosmetics::{
player_skin_display_color_picker, shift_hue, player_skin_display_color_picker, shift_hue,
}; };
pub use bookkeeping::{mod_manager, releases, self_update}; pub use bookkeeping::{mod_manager, releases, self_update};
mod net; pub mod net;
mod player_cosmetics; mod player_cosmetics;
pub mod recorder; pub mod recorder;
@ -1185,3 +1186,54 @@ fn peer_role(peer: net::omni::OmniPeerId, netman: &Arc<net::NetManager>) -> Stri
tr("player_player") 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();
}

View file

@ -2,12 +2,12 @@ use eframe::{
egui::{IconData, ViewportBuilder}, egui::{IconData, ViewportBuilder},
NativeOptions, 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::{info, level_filters::LevelFilter};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
#[tokio::main(worker_threads = 2)] #[tokio::main(worker_threads = 2)]
async fn main() -> Result<(), eframe::Error> { async fn main() {
let my_subscriber = tracing_subscriber::FmtSubscriber::builder() let my_subscriber = tracing_subscriber::FmtSubscriber::builder()
.with_env_filter( .with_env_filter(
EnvFilter::builder() EnvFilter::builder()
@ -22,29 +22,31 @@ async fn main() -> Result<(), eframe::Error> {
info!("{:?}", args.launch_cmd); info!("{:?}", args.launch_cmd);
if let Some(replay) = args.replay_folder { if let Some(replay) = args.replay_folder {
replay_file(replay); replay_file(replay)
return Ok(());
} }
else if let Some(lobby) = args.lobby
let icon = image::load_from_memory(include_bytes!("../assets/icon.png")) {
.unwrap() start_cli(lobby)
.to_rgba8(); } else {
let icon = IconData { let icon = image::load_from_memory(include_bytes!("../assets/icon.png"))
width: icon.width(), .unwrap()
height: icon.height(), .to_rgba8();
rgba: icon.into_vec(), let icon = IconData {
}; width: icon.width(),
height: icon.height(),
eframe::run_native( rgba: icon.into_vec(),
"Noita Proxy", // Don't change that, it defines where settings are stored. };
NativeOptions { eframe::run_native(
viewport: ViewportBuilder::default() "Noita Proxy", // Don't change that, it defines where settings are stored.
.with_min_inner_size([800.0, 600.0]) NativeOptions {
.with_icon(icon) viewport: ViewportBuilder::default()
.with_title("Noita Entangled Worlds Proxy"), .with_min_inner_size([800.0, 600.0])
follow_system_theme: false, .with_icon(icon)
..Default::default() .with_title("Noita Entangled Worlds Proxy"),
}, follow_system_theme: false,
Box::new(|cc| Ok(Box::new(App::new(cc, args)))), ..Default::default()
) },
} Box::new(|cc| Ok(Box::new(App::new(cc, args)))),
).unwrap()
}
}

View file

@ -18,7 +18,7 @@ pub(crate) struct MessageRequest<T> {
} }
#[derive(Debug, Decode, Encode)] #[derive(Debug, Decode, Encode)]
pub enum NetMsg { pub(crate) enum NetMsg {
Welcome, Welcome,
EndRun, EndRun,
StartGame { settings: GameSettings }, StartGame { settings: GameSettings },
@ -36,4 +36,4 @@ impl From<MessageRequest<WorldNetMessage>> for MessageRequest<NetMsg> {
dst: value.dst, dst: value.dst,
} }
} }
} }

View file

@ -14,4 +14,7 @@ pub struct Args {
/// path to crashcatcher's replay folder. /// path to crashcatcher's replay folder.
#[argh(option)] #[argh(option)]
pub replay_folder: Option<PathBuf>, pub replay_folder: Option<PathBuf>,
/// steam lobby code.
#[argh(option)]
pub lobby: Option<String>,
} }