@@ 5,14 5,14 @@ use starkingdoms::client_plugins::ClientPluginGroup;
#[cfg(not(target_arch = "wasm32"))]
use starkingdoms::server_plugins::ServerPluginGroup;
use starkingdoms::shared_plugins::SharedPluginGroup;
-use std::net::SocketAddr;
+use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::process::exit;
use std::str::FromStr;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::filter::Directive;
use tracing_subscriber::util::SubscriberInitExt;
-#[derive(Parser, Debug)]
+#[derive(Parser, Debug, Clone)]
#[command(version, about)]
enum Cli {
Client {
@@ 27,22 27,16 @@ enum Cli {
tick_rate: f64,
#[arg(short = 'C', long)]
max_clients: usize,
+ #[arg(long, action)]
+ with_client: bool
},
#[cfg(all(not(target_arch = "wasm32"), feature = "particle_editor"))]
ParticleEditor {},
}
-fn main() -> AppExit {
- let cli = Cli::parse();
+fn run(cli: Cli) -> AppExit {
let mut app = App::new();
- tracing_subscriber::fmt()
- .with_env_filter(
- EnvFilter::from_default_env().add_directive(Directive::from_str("naga=error").unwrap()),
- )
- .finish()
- .init();
-
match cli {
Cli::Client { server } => {
app.add_plugins(ClientPluginGroup { server });
@@ 53,6 47,7 @@ fn main() -> AppExit {
bind,
tick_rate,
max_clients,
+ ..
} => {
if cfg!(target_family = "wasm") {
eprintln!("the server cannot run on webassembly");
@@ 74,3 69,69 @@ fn main() -> AppExit {
app.run()
}
+
+fn main() -> AppExit {
+ let cli = Cli::parse();
+
+ tracing_subscriber::fmt()
+ .with_env_filter(
+ EnvFilter::from_default_env().add_directive(Directive::from_str("naga=error").unwrap()),
+ )
+ .finish()
+ .init();
+
+ match cli {
+ Cli::Client { .. } => { run(cli) },
+ Cli::ParticleEditor { .. } => { run(cli) },
+ Cli::Server { with_client, bind, .. } => {
+ if !with_client {
+ run(cli)
+ } else {
+ warn!("-----------------------------------------");
+ warn!("RUNNING IN EXPERIMENTAL LISTENSERVER MODE");
+ warn!("-----------------------------------------");
+ warn!("This mode is HIGHLY EXPERIMENTAL, relies on janky threading, and may or may not work at all.");
+ warn!("Use at your own risk. If weird things happen, try running separately.");
+ warn!("-----------------------------------------");
+ warn!("RUNNING IN EXPERIMENTAL LISTENSERVER MODE");
+ warn!("-----------------------------------------");
+
+ let scli_clone = cli.clone();
+ let server_thread = std::thread::spawn(move || {
+ info!("starting server thread...");
+ run(scli_clone)
+ });
+ info!("starting client thread...");
+ let is_multicast = bind.ip().is_unspecified();
+
+ let target_ip = if is_multicast {
+ if bind.ip().is_ipv4() { IpAddr::V4(Ipv4Addr::LOCALHOST) } else { IpAddr::V6(Ipv6Addr::LOCALHOST) }
+ } else {
+ bind.ip()
+ };
+ let target_port = bind.port();
+ let target_ip_str = match target_ip {
+ IpAddr::V4(a) => a.to_string(),
+ IpAddr::V6(a) => format!("[{a}]"),
+ };
+ let target_url = format!("ws://{target_ip_str}:{target_port}");
+ info!("starting the client with autocalculated target server url {target_url}");
+
+ let cli2 = Cli::Client { server: target_url };
+
+ let clt_exit = run(cli2);
+
+ info!("waiting for server to exit...");
+ let srv_exit = server_thread.join().unwrap();
+
+ match srv_exit {
+ AppExit::Error(c) => AppExit::Error(c),
+ _ => match clt_exit {
+ AppExit::Error(c) => AppExit::Error(c),
+ _ => AppExit::Success
+ }
+ }
+ }
+ }
+ }
+}
@@ 61,7 61,7 @@ fn disconnect_part(
disconnect_part(other_joint, entity, joints, q_joints, q_peer, processed_peers, commands.reborrow());
}
}
- for ppeer in &processed_peers {
+ for ppeer in processed_peers {
commands.entity(*ppeer).remove::<Peer>();
}
commands.entity(entity).remove::<ImpulseJoint>();