author | alfadur |
Mon, 18 Jun 2018 09:22:53 -0400 | |
changeset 13416 | cdf69667593b |
parent 13119 | 1e39b8749072 |
child 13419 | 81e0ed105f5d |
permissions | -rw-r--r-- |
12127 | 1 |
use slab; |
12126 | 2 |
use utils; |
13416 | 3 |
use super::{ |
4 |
client::*, room::*, actions, handlers |
|
5 |
}; |
|
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
6 |
use protocol::messages::*; |
12126 | 7 |
|
12852 | 8 |
type Slab<T> = slab::Slab<T>; |
12127 | 9 |
|
13416 | 10 |
#[derive(Debug)] |
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
11 |
pub enum Destination { |
13416 | 12 |
ToAll, |
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
13 |
ToSelf(ClientId), |
13416 | 14 |
ToOthers(ClientId), |
15 |
ToSelected(Vec<ClientId>) |
|
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
16 |
} |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
17 |
|
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
18 |
pub struct PendingMessage(pub Destination, pub HWServerMessage); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
19 |
|
12126 | 20 |
pub struct HWServer { |
12143 | 21 |
pub clients: Slab<HWClient>, |
22 |
pub rooms: Slab<HWRoom>, |
|
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
23 |
pub lobby_id: RoomId, |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
24 |
pub output: Vec<PendingMessage>, |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
25 |
pub removed_clients: Vec<ClientId>, |
12126 | 26 |
} |
27 |
||
28 |
impl HWServer { |
|
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
29 |
pub fn new(clients_limit: usize, rooms_limit: usize) -> HWServer { |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
30 |
let rooms = Slab::with_capacity(rooms_limit); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
31 |
let clients = Slab::with_capacity(clients_limit); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
32 |
let mut server = HWServer { |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
33 |
clients, rooms, |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
34 |
lobby_id: 0, |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
35 |
output: vec![], |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
36 |
removed_clients: vec![] |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
37 |
}; |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
38 |
server.lobby_id = server.add_room(); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
39 |
server |
12126 | 40 |
} |
41 |
||
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
42 |
pub fn add_client(&mut self) -> ClientId { |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
43 |
let key: ClientId; |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
44 |
{ |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
45 |
let entry = self.clients.vacant_entry(); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
46 |
key = entry.key(); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
47 |
let client = HWClient::new(entry.key()); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
48 |
entry.insert(client); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
49 |
} |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
50 |
self.send_self(key, HWServerMessage::Connected(utils::PROTOCOL_VERSION)); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
51 |
key |
12126 | 52 |
} |
12127 | 53 |
|
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
54 |
pub fn client_lost(&mut self, client_id: ClientId) { |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
55 |
actions::run_action(self, client_id, |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
56 |
actions::Action::ByeClient("Connection reset".to_string())); |
12127 | 57 |
} |
58 |
||
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
59 |
pub fn add_room(&mut self) -> RoomId { |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
60 |
let entry = self.rooms.vacant_entry(); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
61 |
let key = entry.key(); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
62 |
let room = HWRoom::new(entry.key()); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
63 |
entry.insert(room); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
64 |
key |
12127 | 65 |
} |
12137
193dfdcb0620
- Use logging facilities instead of plain println!
unc0rr
parents:
12136
diff
changeset
|
66 |
|
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
67 |
pub fn handle_msg(&mut self, client_id: ClientId, msg: HWProtocolMessage) { |
13416 | 68 |
debug!("Handling message {:?} for client {}", msg, client_id); |
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
69 |
handlers::handle(self, client_id, msg); |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
70 |
} |
12139 | 71 |
|
13416 | 72 |
pub fn send_all(&mut self, msg: HWServerMessage) { |
73 |
self.output.push(PendingMessage( |
|
74 |
Destination::ToAll, msg)); |
|
75 |
} |
|
76 |
||
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
77 |
pub fn send_self(&mut self, client_id: ClientId, msg: HWServerMessage) { |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
78 |
self.output.push(PendingMessage( |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
79 |
Destination::ToSelf(client_id), msg)); |
12137
193dfdcb0620
- Use logging facilities instead of plain println!
unc0rr
parents:
12136
diff
changeset
|
80 |
} |
12138 | 81 |
|
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
82 |
pub fn send_others(&mut self, client_id: ClientId, msg: HWServerMessage) { |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
83 |
self.output.push(PendingMessage( |
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
84 |
Destination::ToOthers(client_id), msg)); |
12141 | 85 |
} |
86 |
||
13416 | 87 |
pub fn send_to_selected(&mut self, client_ids: Vec<ClientId>, msg: HWServerMessage) { |
88 |
self.output.push(PendingMessage( |
|
89 |
Destination::ToSelected(client_ids), msg)); |
|
90 |
} |
|
91 |
||
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
92 |
pub fn react(&mut self, client_id: ClientId, actions: Vec<actions::Action>) { |
12139 | 93 |
for action in actions { |
13119
1e39b8749072
separated the server logic from all the async io mess.
alfadur
parents:
12852
diff
changeset
|
94 |
actions::run_action(self, client_id, action); |
12138 | 95 |
} |
96 |
} |
|
13416 | 97 |
|
98 |
pub fn has_room(&self, name: &str) -> bool { |
|
99 |
self.rooms.iter().any(|(_, r)| r.name == name) |
|
100 |
} |
|
101 |
||
102 |
pub fn find_room(&self, name: &str) -> Option<&HWRoom> { |
|
103 |
self.rooms.iter().find(|(_, r)| r.name == name).map(|(_, r)| r) |
|
104 |
} |
|
105 |
||
106 |
pub fn find_room_mut(&mut self, name: &str) -> Option<&mut HWRoom> { |
|
107 |
self.rooms.iter_mut().find(|(_, r)| r.name == name).map(|(_, r)| r) |
|
108 |
} |
|
109 |
||
110 |
pub fn select_clients<F>(&self, f: F) -> Vec<ClientId> |
|
111 |
where F: Fn(&(usize, &HWClient)) -> bool { |
|
112 |
self.clients.iter().filter(f) |
|
113 |
.map(|(_, c)| c.id).collect() |
|
114 |
} |
|
115 |
||
116 |
pub fn room_clients(&self, room_id: RoomId) -> Vec<ClientId> { |
|
117 |
self.select_clients(|(_, c)| c.room_id == Some(room_id)) |
|
118 |
} |
|
119 |
||
120 |
pub fn protocol_clients(&self, protocol: u32) -> Vec<ClientId> { |
|
121 |
self.select_clients(|(_, c)| c.protocol_number == protocol) |
|
122 |
} |
|
123 |
||
124 |
pub fn other_clients_in_room(&self, self_id: ClientId) -> Vec<ClientId> { |
|
125 |
let room_id = self.clients[self_id].room_id; |
|
126 |
self.select_clients(|(id, c)| *id != self_id && c.room_id == room_id ) |
|
127 |
} |
|
128 |
||
129 |
pub fn client_and_room(&mut self, client_id: ClientId) -> (&mut HWClient, Option<&mut HWRoom>) { |
|
130 |
let c = &mut self.clients[client_id]; |
|
131 |
if let Some(room_id) = c.room_id { |
|
132 |
(c, Some(&mut self.rooms[room_id])) |
|
133 |
} else { |
|
134 |
(c, None) |
|
135 |
} |
|
136 |
} |
|
137 |
} |