2023-02-07 15:21:00 +00:00
|
|
|
use std::net::SocketAddr;
|
|
|
|
|
2023-02-09 18:19:03 +00:00
|
|
|
use serde::Deserialize;
|
2023-02-07 15:21:00 +00:00
|
|
|
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter};
|
|
|
|
use tokio::net::{TcpListener, TcpStream};
|
|
|
|
use tokio::sync::oneshot::channel;
|
|
|
|
|
|
|
|
use crate::core::player::{PlayerRegistry, Updates};
|
|
|
|
use crate::prelude::*;
|
|
|
|
use crate::protos::irc::*;
|
|
|
|
use crate::util::Terminator;
|
|
|
|
|
2023-02-09 18:19:03 +00:00
|
|
|
#[derive(Deserialize, Debug)]
|
2023-02-07 15:21:00 +00:00
|
|
|
pub struct ServerConfig {
|
|
|
|
pub listen_on: SocketAddr,
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn handle_socket(
|
|
|
|
mut stream: TcpStream,
|
|
|
|
socket_addr: SocketAddr,
|
|
|
|
mut players: PlayerRegistry,
|
|
|
|
) {
|
|
|
|
let (reader, writer) = stream.split();
|
|
|
|
let mut reader = BufReader::new(reader);
|
|
|
|
let mut writer = BufWriter::new(writer);
|
|
|
|
|
|
|
|
let mut buffer = vec![];
|
|
|
|
|
|
|
|
// let (player_id, mut player_handle) = players.create_player().await;
|
|
|
|
// let mut sub = player_handle.subscribe().await;
|
|
|
|
|
|
|
|
loop {
|
|
|
|
select! {
|
|
|
|
biased;
|
|
|
|
res = reader.read_until(b'\n', &mut buffer) => {
|
|
|
|
match res {
|
|
|
|
Ok(len) => if len == 0 {
|
|
|
|
log::info!("Terminating socket");
|
|
|
|
break;
|
|
|
|
},
|
|
|
|
Err(err) => log::warn!("Failed to read from socket: {err}"),
|
|
|
|
}
|
|
|
|
let parsed = parse_client_message(&buffer[..]);
|
|
|
|
match parsed {
|
|
|
|
Ok((rest, msg)) => {
|
|
|
|
log::info!("Incoming IRC message: {msg:?}");
|
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
log::warn!("Failed to parse IRC message: {err}");
|
|
|
|
},
|
|
|
|
}
|
|
|
|
buffer.clear();
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-09 18:19:03 +00:00
|
|
|
pub async fn launch(config: &ServerConfig, players: PlayerRegistry) -> Result<Terminator> {
|
2023-02-07 15:21:00 +00:00
|
|
|
log::info!("Starting IRC projection");
|
|
|
|
let (signal, mut rx) = channel();
|
|
|
|
let listener = TcpListener::bind(config.listen_on).await?;
|
|
|
|
log::debug!("Listener started");
|
|
|
|
|
|
|
|
let handle = tokio::task::spawn(async move {
|
|
|
|
loop {
|
|
|
|
select! {
|
|
|
|
biased;
|
|
|
|
_ = &mut rx => break,
|
|
|
|
new_conn = listener.accept() => {
|
|
|
|
match new_conn {
|
|
|
|
Ok((stream, socket_addr)) => {
|
|
|
|
log::debug!("Incoming connection from {socket_addr}");
|
|
|
|
let handle = tokio::task::spawn(handle_socket(stream, socket_addr, players.clone()));
|
|
|
|
},
|
|
|
|
Err(err) => log::warn!("Failed to accept new connection: {err}"),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
log::info!("Stopping IRC projection");
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
|
|
|
|
let terminator = Terminator::from_raw(signal, handle);
|
|
|
|
Ok(terminator)
|
|
|
|
}
|