aboutsummaryrefslogtreecommitdiff
path: root/src/server.rs
blob: d8be64ee7b9549113efcb9f164582aeb88822858 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use crate::{
    map::Map,
    wire::{Match, MatchId, MatchUser, Response, User, UserId},
};
use async_std::sync::{Arc, Mutex};
use std::{collections::BTreeMap, path::Path};

/// A convenience result wrapper for server actions
pub type Result<T> = std::result::Result<T, ServerErr>;
pub enum ServerErr {
    /// The requested directory is corrupted
    NoSuchDir,
    /// Corrupted game state
    Corrupted,
    /// No such match found
    NoSuchMatch,
}

/// The game's server backend
pub struct Server {
    matches: BTreeMap<MatchId, Mutex<Match>>,
    users: BTreeMap<UserId, User>,
}

impl Server {
    /// Create a new game server
    fn new() -> Self {
        Self {
            matches: Default::default(),
            users: Default::default(),
        }
    }

    /// Open the state dir of a game server
    pub async fn open(self: Arc<Self>, path: &Path) -> Result<()> {
        Ok(())
    }

    /// Stop accepting new game connections and shutdown gracefully
    ///
    /// Returns the number of matches still going on.
    pub async fn shutdown(self: Arc<Self>) -> Result<u64> {
        Ok(0)
    }

    /// Save and close the statedir and kicking all players
    ///
    /// Returns the number of players that were kicked off the server
    /// prematurely.
    pub async fn kill(self: Arc<Self>) -> Result<u64> {
        Ok(0)
    }

    pub async fn update_map<F>(self: Arc<Self>, id: MatchId, cb: F) -> Result<Response>
    where
        F: Fn(&mut Map) -> Result<Response>,
    {
        match self.matches.get(&id) {
            Some(ref mut m) => m.lock().await.map.update(cb),
            None => Err(ServerErr::NoSuchMatch),
        }
    }

    pub async fn update_players<F>(self: Arc<Self>, id: MatchId, cb: F) -> Result<Response>
    where
        F: Fn(&mut Vec<MatchUser>) -> Result<Response>,
    {
        match self.matches.get(&id) {
            Some(ref mut m) => cb(&mut m.lock().await.players),
            None => Err(ServerErr::NoSuchMatch),
        }
    }
}