diff options
-rw-r--r-- | config.toml | 2 | ||||
-rw-r--r-- | src/game/mod.rs | 2 | ||||
-rw-r--r-- | src/game/server.rs | 6 | ||||
-rw-r--r-- | src/main.rs | 4 | ||||
-rw-r--r-- | src/spectate/server.rs | 49 |
5 files changed, 38 insertions, 25 deletions
diff --git a/config.toml b/config.toml index 7715000..6eef0ca 100644 --- a/config.toml +++ b/config.toml @@ -4,6 +4,8 @@ bind = "127.0.0.1:8000" [game] bind = "0.0.0.0:4000" tickrate = 1 +tickrate_speedup = 0.1 +tickrate_max = 3 [bot] amount = 10 diff --git a/src/game/mod.rs b/src/game/mod.rs index f59b5d5..3eab9de 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -12,6 +12,8 @@ pub mod server; pub struct Config { bind: SocketAddr, tickrate: f32, + tickrate_speedup: f32, + tickrate_max: f32, } pub struct Game { diff --git a/src/game/server.rs b/src/game/server.rs index f1d10d2..f5de1bf 100644 --- a/src/game/server.rs +++ b/src/game/server.rs @@ -29,19 +29,23 @@ pub async fn game_server(config: Config, state: Arc<State>) -> Result<()> { } async fn game_loop(config: Config, state: Arc<State>) { + let mut speed = config.tickrate; loop { - sleep(Duration::from_secs_f32(1. / config.tickrate)).await; + sleep(Duration::from_secs_f32(1. / speed)).await; let mut g = state.game.write().await; let res = g.tick(); match res { ControlFlow::Continue(()) => { let _ = state.tick.send(false); + speed += config.tickrate_speedup; + speed = speed.min(config.tickrate_max) } ControlFlow::Break(winner) => { info!("winner: {winner:?}"); let p = state.players.read().await; *g = Game::new(p.clone().into_iter().collect()); + speed = config.tickrate; let _ = state.tick.send(true); } } diff --git a/src/main.rs b/src/main.rs index d2f22ff..74d784b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,10 +13,10 @@ async fn main() -> anyhow::Result<()> { env_logger::init_from_env("LOG"); let config = Config::load()?; let state = Arc::new(State { - tick: broadcast::channel(16).0, + tick: broadcast::channel(512).0, game: Game::new(vec![]).into(), players: Default::default(), - chat: broadcast::channel(16).0, + chat: broadcast::channel(512).0, }); spawn(spectate_server(config.spectate, state.clone())); spawn_bots(config.bot, state.clone()).await; diff --git a/src/spectate/server.rs b/src/spectate/server.rs index 3923bc1..da18a77 100644 --- a/src/spectate/server.rs +++ b/src/spectate/server.rs @@ -1,26 +1,24 @@ -use crate::game::protocol::Packet; -use crate::State; - use super::Config; -use anyhow::Result; -use axum::extract; -use axum::extract::connect_info::ConnectInfo; -use axum::extract::ws::Message; -use axum::http::HeaderMap; -use axum::response::Html; +use crate::{game::protocol::Packet, State}; +use anyhow::{anyhow, Result}; use axum::{ - extract::ws::{WebSocket, WebSocketUpgrade}, - response::IntoResponse, + extract::{ + self, + connect_info::ConnectInfo, + ws::{Message, WebSocket, WebSocketUpgrade}, + }, + http::HeaderMap, + response::{Html, IntoResponse}, routing::get, Router, }; use headers::ContentType; use log::{info, warn}; -use std::net::SocketAddr; -use std::str::FromStr; -use std::sync::Arc; -use tokio::spawn; -use tokio::sync::{broadcast, RwLock}; +use std::{net::SocketAddr, str::FromStr, sync::Arc}; +use tokio::{ + spawn, + sync::{broadcast, RwLock}, +}; struct SpectateState { past_events: RwLock<Vec<Packet>>, @@ -30,7 +28,7 @@ struct SpectateState { pub async fn spectate_server(config: Config, state: Arc<State>) -> Result<()> { let sstate = Arc::new(SpectateState { past_events: Default::default(), - events: broadcast::channel(16).0, + events: broadcast::channel(512).0, }); spawn(broadcaster(sstate.clone(), state)); let app = Router::new() @@ -166,10 +164,17 @@ async fn handle_socket( .await?; } let mut live = state.events.subscribe(); - while let Ok(p) = live.recv().await { - socket - .send(Message::Text(serde_json::to_string(&p)?)) - .await?; + + loop { + tokio::select! { + message = socket.recv() => { + message.ok_or(anyhow!("socket end"))??; + } + event = live.recv() => { + socket + .send(Message::Text(serde_json::to_string(&event?)?)) + .await?; + } + } } - Ok(()) } |