forked from lavina/lavina
1
0
Fork 0
lavina/src/projections/irc.rs

86 lines
2.7 KiB
Rust

use std::net::SocketAddr;
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;
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();
},
}
}
}
pub async fn launch(config: ServerConfig, players: PlayerRegistry) -> Result<Terminator> {
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)
}