aboutsummaryrefslogtreecommitdiff
path: root/server/src/server.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-09-02 00:37:45 +0200
committermetamuffin <metamuffin@disroot.org>2024-09-02 00:37:54 +0200
commit5fec7c7daa4741189a2749d7531e64b1ba6be58b (patch)
tree7fa1bfe2791ded4493743c1a973926192e70d9b6 /server/src/server.rs
parent5b14aab4341f099c9f5b59ad6aec08c4a58827c3 (diff)
downloadhurrycurry-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.rs145
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