diff options
author | metamuffin <metamuffin@disroot.org> | 2024-09-02 00:37:45 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-09-02 00:37:54 +0200 |
commit | 5fec7c7daa4741189a2749d7531e64b1ba6be58b (patch) | |
tree | 7fa1bfe2791ded4493743c1a973926192e70d9b6 /server/src/server.rs | |
parent | 5b14aab4341f099c9f5b59ad6aec08c4a58827c3 (diff) | |
download | hurrycurry-5fec7c7daa4741189a2749d7531e64b1ba6be58b.tar hurrycurry-5fec7c7daa4741189a2749d7531e64b1ba6be58b.tar.bz2 hurrycurry-5fec7c7daa4741189a2749d7531e64b1ba6be58b.tar.zst |
merge ServerState and State
Diffstat (limited to 'server/src/server.rs')
-rw-r--r-- | server/src/server.rs | 145 |
1 files changed, 69 insertions, 76 deletions
diff --git a/server/src/server.rs b/server/src/server.rs index a5d1e1d8..12eca299 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -16,9 +16,10 @@ */ use crate::{ - data::Serverdata, + data::{DataIndex, Serverdata}, entity::{Entities, EntityContext}, interaction::{interact, tick_slot, InteractEffect, TickEffect}, + ConnectionID, }; use anyhow::{anyhow, bail, Result}; use hurrycurry_client_lib::{Game, Item, Player, Tile}; @@ -30,29 +31,25 @@ use hurrycurry_protocol::{ use log::{info, warn}; use rand::random; use std::{ - collections::{HashMap, VecDeque}, + collections::{HashMap, HashSet, VecDeque}, sync::Arc, time::{Duration, Instant}, }; +use tokio::sync::broadcast::Sender; + +pub struct Server { + pub game: Game, -pub struct ServerState { pub data: Arc<Serverdata>, pub entities: Entities, pub player_id_counter: PlayerID, pub score_changed: bool, pub packet_loopback: VecDeque<PacketS>, pub last_movement_update: HashMap<PlayerID, Instant>, -} - -pub struct Server<'a> { - pub game: &'a mut Game, - pub state: &'a mut ServerState, -} - -impl Default for ServerState { - fn default() -> Self { - Self::new() - } + pub index: DataIndex, + pub packet_out: VecDeque<PacketC>, + pub tx: Sender<PacketC>, + pub connections: HashMap<ConnectionID, HashSet<PlayerID>>, } pub trait GameServerExt { @@ -232,46 +229,48 @@ impl GameServerExt for Game { } } -impl ServerState { - pub fn new() -> Self { - Self { +impl Server { + pub async fn new(tx: Sender<PacketC>) -> Result<Self> { + let mut index = DataIndex::default(); + index.reload()?; + Ok(Self { + game: Game::default(), + index, + tx, + packet_out: VecDeque::new(), + connections: HashMap::new(), data: Serverdata::default().into(), entities: vec![], player_id_counter: PlayerID(1), score_changed: false, packet_loopback: VecDeque::new(), last_movement_update: HashMap::default(), - } + }) } } -impl Server<'_> { +impl Server { pub fn load( &mut self, (gamedata, serverdata, entities): (Gamedata, Serverdata, Entities), timer: Option<Duration>, - packet_out: &mut VecDeque<PacketC>, ) { - self.game.load(gamedata, &serverdata, timer, packet_out); - for mut e in self.state.entities.drain(..) { + self.game + .load(gamedata, &serverdata, timer, &mut self.packet_out); + for mut e in self.entities.drain(..) { e.destructor(EntityContext { - game: self.game, - packet_out, - packet_in: &mut self.state.packet_loopback, - score_changed: &mut self.state.score_changed, + game: &mut self.game, + packet_out: &mut self.packet_out, + packet_in: &mut self.packet_loopback, + score_changed: &mut self.score_changed, dt: 0., load_map: &mut None, }); } - self.state.data = serverdata.into(); - self.state.entities = entities; + self.data = serverdata.into(); + self.entities = entities; } - pub fn packet_in( - &mut self, - packet: PacketS, - replies: &mut Vec<PacketC>, - packet_out: &mut VecDeque<PacketC>, - ) -> Result<()> { + pub fn packet_in(&mut self, packet: PacketS, replies: &mut Vec<PacketC>) -> Result<()> { match packet { PacketS::Join { name, @@ -279,12 +278,12 @@ impl Server<'_> { id, } => { let id = id.unwrap_or_else(|| { - let id = self.state.player_id_counter; - self.state.player_id_counter.0 += 1; + let id = self.player_id_counter; + self.player_id_counter.0 += 1; id }); self.game - .join_player(id, name, character, &self.state.data, Some(packet_out)); + .join_player(id, name, character, &self.data, Some(&mut self.packet_out)); replies.push(PacketC::Joined { id }) } PacketS::Leave { player } => { @@ -300,7 +299,7 @@ impl Server<'_> { let pos = p.movement.position.floor().as_ivec2(); if let Some(tile) = self.game.tiles.get_mut(&pos) { if tile.item.is_none() { - packet_out.push_back(PacketC::SetItem { + self.packet_out.push_back(PacketC::SetItem { location: ItemLocation::Tile(pos), item: Some(item.kind), }); @@ -308,7 +307,8 @@ impl Server<'_> { } } } - packet_out.push_back(PacketC::RemovePlayer { id: player }) + self.packet_out + .push_back(PacketC::RemovePlayer { id: player }) } PacketS::Movement { pos, @@ -326,7 +326,6 @@ impl Server<'_> { if let Some(pos) = pos { let last_position_update = self - .state .last_movement_update .entry(player) .or_insert_with(|| Instant::now()); @@ -399,9 +398,9 @@ impl Server<'_> { &mut other.item, ItemLocation::Player(pid), None, - packet_out, + &mut self.packet_out, &mut self.game.score, - &mut self.state.score_changed, + &mut self.score_changed, false, ) } else { @@ -419,9 +418,9 @@ impl Server<'_> { &mut player.item, ItemLocation::Player(pid), Some(tile.kind), - packet_out, + &mut self.packet_out, &mut self.game.score, - &mut self.state.score_changed, + &mut self.score_changed, false, ) } @@ -445,7 +444,7 @@ impl Server<'_> { }); } } - packet_out.push_back(PacketC::Communicate { + self.packet_out.push_back(PacketC::Communicate { player, message, timeout: timeout.map(|t| MessageTimeout { @@ -464,7 +463,7 @@ impl Server<'_> { kind: i, active: None, }); - packet_out.push_back(PacketC::SetItem { + self.packet_out.push_back(PacketC::SetItem { location: ItemLocation::Player(player), item, }) @@ -473,7 +472,7 @@ impl Server<'_> { self.game.score.demands_completed += score.demands_completed; self.game.score.demands_failed += score.demands_failed; self.game.score.points += score.points; - self.state.score_changed = true; + self.score_changed = true; } PacketS::ReplayTick { .. } => bail!("packet not supported in this session"), } @@ -481,14 +480,11 @@ impl Server<'_> { } /// Returns true if the game should end - pub fn tick( - &mut self, - dt: f32, - packet_out: &mut VecDeque<PacketC>, - ) -> Option<(String, Option<Duration>)> { - if self.state.score_changed { - self.state.score_changed = false; - packet_out.push_back(PacketC::Score(self.game.score.clone())); + pub fn tick(&mut self, dt: f32) -> Option<(String, Option<Duration>)> { + if self.score_changed { + self.score_changed = false; + self.packet_out + .push_back(PacketC::Score(self.game.score.clone())); } for (&pos, tile) in &mut self.game.tiles { @@ -500,7 +496,7 @@ impl Server<'_> { &mut self.game.score, ) { match effect { - TickEffect::Progress(warn) => packet_out.push_back(PacketC::SetProgress { + TickEffect::Progress(warn) => self.packet_out.push_back(PacketC::SetProgress { warn, item: ItemLocation::Tile(pos), progress: tile @@ -512,12 +508,12 @@ impl Server<'_> { .map(|i| i.progress), }), TickEffect::Produce => { - packet_out.push_back(PacketC::SetProgress { + self.packet_out.push_back(PacketC::SetProgress { warn: false, item: ItemLocation::Tile(pos), progress: None, }); - packet_out.push_back(PacketC::SetItem { + self.packet_out.push_back(PacketC::SetItem { location: ItemLocation::Tile(pos), item: tile.item.as_ref().map(|i| i.kind), }); @@ -545,7 +541,7 @@ impl Server<'_> { }); for (&pid, player) in &mut self.game.players { - packet_out.push_back(PacketC::Movement { + self.packet_out.push_back(PacketC::Movement { player: pid, pos: player.movement.position, dir: player.movement.input_direction, @@ -561,7 +557,7 @@ impl Server<'_> { &mut self.game.score, ) { match effect { - TickEffect::Progress(warn) => packet_out.push_back(PacketC::SetProgress { + TickEffect::Progress(warn) => self.packet_out.push_back(PacketC::SetProgress { warn, item: ItemLocation::Player(pid), progress: player @@ -573,12 +569,12 @@ impl Server<'_> { .map(|i| i.progress), }), TickEffect::Produce => { - packet_out.push_back(PacketC::SetProgress { + self.packet_out.push_back(PacketC::SetProgress { warn: false, item: ItemLocation::Player(pid), progress: None, }); - packet_out.push_back(PacketC::SetItem { + self.packet_out.push_back(PacketC::SetItem { location: ItemLocation::Player(pid), item: player.item.as_ref().map(|i| i.kind), }); @@ -608,21 +604,17 @@ impl Server<'_> { } } for player in players_auto_release.drain(..) { - let _ = self.packet_in( - PacketS::Interact { pos: None, player }, - &mut vec![], - packet_out, - ); + let _ = self.packet_in(PacketS::Interact { pos: None, player }, &mut vec![]); } let mut load_map = None; - for entity in self.state.entities.iter_mut() { + for entity in self.entities.iter_mut() { if let Err(e) = entity.tick(EntityContext { - game: self.game, + game: &mut self.game, load_map: &mut load_map, - packet_out, - score_changed: &mut self.state.score_changed, - packet_in: &mut self.state.packet_loopback, + packet_out: &mut self.packet_out, + score_changed: &mut self.score_changed, + packet_in: &mut self.packet_loopback, dt, }) { warn!("entity tick failed: {e}") @@ -632,8 +624,8 @@ impl Server<'_> { return Some((map, Some(Duration::from_secs(300)))); } - while let Some(p) = self.state.packet_loopback.pop_front() { - if let Err(e) = self.packet_in(p, &mut vec![], packet_out) { + while let Some(p) = self.packet_loopback.pop_front() { + if let Err(e) = self.packet_in(p, &mut vec![]) { warn!("internal packet errored: {e}"); } } @@ -644,14 +636,15 @@ impl Server<'_> { self.game.score.time_remaining = (end - now).as_secs_f64(); if end < now { let relative_score = - (self.game.score.points * 100) / self.state.data.score_baseline.max(1); + (self.game.score.points * 100) / self.data.score_baseline.max(1); self.game.score.stars = match relative_score { 100.. => 3, 70.. => 2, 40.. => 1, _ => 0, }; - packet_out.push_back(PacketC::Menu(Menu::Score(self.game.score.clone()))); + self.packet_out + .push_back(PacketC::Menu(Menu::Score(self.game.score.clone()))); Some(("lobby".to_string(), None)) } else { None |