diff options
Diffstat (limited to 'server/src/state.rs')
-rw-r--r-- | server/src/state.rs | 114 |
1 files changed, 24 insertions, 90 deletions
diff --git a/server/src/state.rs b/server/src/state.rs index fe5f846e..ad9eeb1c 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -15,32 +15,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -use crate::{ - data::DataIndex, - entity::bot::BotDriver, - server::{Server, ServerState}, - ConnectionID, -}; +use crate::{entity::bot::BotDriver, server::Server, ConnectionID}; use anyhow::{anyhow, bail, Result}; use clap::{Parser, ValueEnum}; use hurrycurry_bot::algos::ALGO_CONSTRUCTORS; -use hurrycurry_client_lib::Game; use hurrycurry_protocol::{Message, PacketC, PacketS, PlayerID}; use log::{debug, trace}; -use std::{ - collections::{HashMap, HashSet, VecDeque}, - time::Duration, -}; -use tokio::sync::broadcast::Sender; - -pub struct State { - index: DataIndex, - packet_out: VecDeque<PacketC>, - tx: Sender<PacketC>, - connections: HashMap<ConnectionID, HashSet<PlayerID>>, - pub server: ServerState, - pub game: Game, -} +use std::time::Duration; #[derive(Parser)] #[clap(multicall = true)] @@ -85,44 +66,11 @@ enum DownloadType { Recipes, } -impl State { - pub async fn new(tx: Sender<PacketC>) -> Result<Self> { - let mut index = DataIndex::default(); - index.reload()?; - - let mut packet_out = VecDeque::new(); - let mut game = Game::default(); - let mut server = ServerState::default(); - - { - Server { - game: &mut game, - state: &mut server, - } - .load(index.generate("lobby").await?, None, &mut packet_out); - } - - Ok(Self { - game, - server, - index, - tx, - packet_out, - connections: HashMap::new(), - }) - } - - pub async fn tick(&mut self, dt: f32) -> anyhow::Result<()> { - let mut server = Server { - game: &mut self.game, - state: &mut self.server, - }; - if let Some((name, timer)) = server.tick(dt, &mut self.packet_out) { - server.load( - self.index.generate(&name).await?, - timer, - &mut self.packet_out, - ); +impl Server { + pub async fn tick_outer(&mut self, dt: f32) -> anyhow::Result<()> { + let r = self.tick(dt); + if let Some((name, timer)) = r { + self.load(self.index.generate(&name).await?, timer); } while let Some(p) = self.packet_out.pop_front() { if matches!(p, PacketC::UpdateMap { .. } | PacketC::Movement { .. }) { @@ -134,7 +82,11 @@ impl State { } Ok(()) } - pub async fn packet_in(&mut self, conn: ConnectionID, packet: PacketS) -> Result<Vec<PacketC>> { + pub async fn packet_in_outer( + &mut self, + conn: ConnectionID, + packet: PacketS, + ) -> Result<Vec<PacketC>> { if let Some(p) = get_packet_player(&packet) { if !self.connections.entry(conn).or_default().contains(&p) { bail!("Packet sent to player that is not owned by this connection."); @@ -166,11 +118,7 @@ impl State { } _ => (), } - let mut server = Server { - game: &mut self.game, - state: &mut self.server, - }; - server.packet_in(packet, &mut replies, &mut self.packet_out)?; + self.packet_in(packet, &mut replies)?; for p in &replies { match p { @@ -181,17 +129,13 @@ impl State { } } - if server.count_chefs() <= 0 && !server.game.lobby { + if self.count_chefs() <= 0 && !self.game.lobby { self.tx .send(PacketC::ServerMessage { text: "Game was aborted automatically due to a lack of players".to_string(), }) .ok(); - server.load( - self.index.generate("lobby").await?, - None, - &mut self.packet_out, - ); + self.load(self.index.generate("lobby").await?, None); } Ok(replies) } @@ -199,7 +143,7 @@ impl State { pub async fn disconnect(&mut self, conn: ConnectionID) { if let Some(players) = self.connections.get(&conn) { for player in players.to_owned() { - let _ = self.packet_in(conn, PacketS::Leave { player }).await; + let _ = self.packet_in_outer(conn, PacketS::Leave { player }).await; } } self.connections.remove(&conn); @@ -221,22 +165,17 @@ impl State { } async fn handle_command(&mut self, player: PlayerID, command: Command) -> Result<()> { - let mut server = Server { - game: &mut self.game, - state: &mut self.server, - }; match command { Command::Start { spec, timer } => { let data = self.index.generate(&spec).await?; - server.load(data, Some(Duration::from_secs(timer)), &mut self.packet_out); + self.load(data, Some(Duration::from_secs(timer))); } Command::End => { self.tx .send(PacketC::ServerMessage { text: format!( "Game was aborted by {}.", - server - .game + self.game .players .get(&player) .ok_or(anyhow!("player missing"))? @@ -244,20 +183,15 @@ impl State { ), }) .ok(); - server.load( - self.index.generate("lobby").await?, - None, - &mut self.packet_out, - ); + self.load(self.index.generate("lobby").await?, None); } Command::Reload => { - if server.count_chefs() > 1 { + if self.count_chefs() > 1 { bail!("must be at most one player to reload"); } - server.load( - self.index.generate(&server.game.data.current_map).await?, + self.load( + self.index.generate(&self.game.data.current_map).await?, None, - &mut self.packet_out, ); } Command::ReloadIndex => { @@ -287,7 +221,7 @@ impl State { .ok(); } Command::Item { name } => { - let item = server + let item = self .game .data .get_item_by_name(&name) @@ -306,7 +240,7 @@ impl State { .find(|(name, _)| *name == algo.as_str()) .ok_or(anyhow!("algo name unknown"))?; let algo = cons(); - self.server.entities.push(Box::new(BotDriver::new( + self.entities.push(Box::new(BotDriver::new( format!("{}-bot", name.unwrap_or((*aname).to_owned())), 51, algo, |