~starkingdoms/starkingdoms

63edaa7afd40eadc480643cb54febfdf5c96d47a — core 29 days ago 22aa5c9
feat: listen server
2 files changed, 73 insertions(+), 12 deletions(-)

M crates/unified/src/main.rs
M crates/unified/src/server/player.rs
M crates/unified/src/main.rs => crates/unified/src/main.rs +72 -11
@@ 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
                    }
                }
            }
        }
    }
}

M crates/unified/src/server/player.rs => crates/unified/src/server/player.rs +1 -1
@@ 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>();