Skip to main content

manabrew_server/
state.rs

1use dashmap::DashMap;
2use std::time::Instant;
3use tokio::sync::mpsc;
4use tokio_tungstenite::tungstenite::Message;
5
6use crate::analytics::AnalyticsHandle;
7use crate::deck_play_events::DeckPlayEventHandle;
8use crate::room::Room;
9
10pub struct ConnectedPlayer {
11    pub player_id: String,
12    pub username: String,
13    pub room_id: Option<String>,
14    pub sender: mpsc::UnboundedSender<Message>,
15    pub connected: bool,
16    pub generation: u64,
17    pub last_seen: Instant,
18    pub disconnected_at: Option<Instant>,
19    pub is_service: bool,
20}
21
22pub struct ServerState {
23    pub players: DashMap<String, ConnectedPlayer>,
24    pub rooms: DashMap<String, Room>,
25    pub server_key: String,
26    pub max_rooms: usize,
27    pub official_key: Option<String>,
28    pub analytics: AnalyticsHandle,
29    pub deck_play_events: DeckPlayEventHandle,
30}
31
32impl ServerState {
33    pub fn new(
34        server_key: String,
35        max_rooms: usize,
36        official_key: Option<String>,
37        analytics: AnalyticsHandle,
38        deck_play_events: DeckPlayEventHandle,
39    ) -> Self {
40        ServerState {
41            players: DashMap::new(),
42            rooms: DashMap::new(),
43            server_key,
44            max_rooms,
45            official_key,
46            analytics,
47            deck_play_events,
48        }
49    }
50
51    pub fn username_taken_by_connected(&self, username: &str) -> bool {
52        self.players
53            .iter()
54            .any(|entry| entry.value().username == username && entry.value().connected)
55    }
56
57    pub fn find_disconnected_by_username(
58        &self,
59        username: &str,
60    ) -> Option<(String, Option<String>, u64)> {
61        self.players
62            .iter()
63            .find(|entry| entry.value().username == username && !entry.value().connected)
64            .map(|entry| {
65                (
66                    entry.value().player_id.clone(),
67                    entry.value().room_id.clone(),
68                    entry.value().generation,
69                )
70            })
71    }
72
73    pub fn find_connected_by_username(&self, username: &str) -> Option<(String, u64, bool)> {
74        self.players
75            .iter()
76            .find(|entry| entry.value().username == username && entry.value().connected)
77            .map(|entry| {
78                (
79                    entry.value().player_id.clone(),
80                    entry.value().generation,
81                    entry.value().sender.is_closed(),
82                )
83            })
84    }
85}