openlegends-server 0.3.0

OpenLegends Game Server
Documentation
mod argument;
mod connection;
mod log;

use argument::Argument;
use log::Log;

use clap::Parser;
use native_tls::{Identity, TlsAcceptor};
use std::{
    fs::File,
    io::{Read, Result},
    net::TcpListener,
    sync::Arc,
    thread,
};

fn main() -> Result<()> {
    let argument = Argument::parse();

    let mut pfx = vec![];
    File::open(argument.identity)
        .unwrap()
        .read_to_end(&mut pfx)
        .unwrap();

    let acceptor = Arc::new(
        TlsAcceptor::new(Identity::from_pkcs12(&pfx, &argument.password).unwrap()).unwrap(),
    );

    let listener = TcpListener::bind(&argument.address)?;

    log::notice(format!("Server listening on `{}`", argument.address));

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let log = Log::new(stream.peer_addr()?.to_string());

                log.notice("New client connected".to_string());

                thread::spawn({
                    let acceptor = acceptor.clone();
                    move || {
                        connection::handle(acceptor.accept(stream).unwrap(), log);
                    }
                });
            }
            Err(e) => log::error(format!("Failed to accept connection: `{e}`")),
        }
    }

    Ok(())
}