2 use mio::net::*; |
2 use mio::net::*; |
3 use mio::*; |
3 use mio::*; |
4 use std::io; |
4 use std::io; |
5 |
5 |
6 use utils; |
6 use utils; |
7 use super::client::HWClient; |
7 use super::client::*; |
|
8 use super::room::*; |
8 use super::actions; |
9 use super::actions; |
|
10 use protocol::messages::*; |
|
11 use super::handlers; |
9 |
12 |
10 type Slab<T> = slab::Slab<T>; |
13 type Slab<T> = slab::Slab<T>; |
11 |
14 |
|
15 pub enum Destination { |
|
16 ToSelf(ClientId), |
|
17 ToOthers(ClientId) |
|
18 } |
|
19 |
|
20 pub struct PendingMessage(pub Destination, pub HWServerMessage); |
|
21 |
12 pub struct HWServer { |
22 pub struct HWServer { |
13 listener: TcpListener, |
|
14 pub clients: Slab<HWClient>, |
23 pub clients: Slab<HWClient>, |
15 pub rooms: Slab<HWRoom>, |
24 pub rooms: Slab<HWRoom>, |
16 pub lobby_id: usize, |
25 pub lobby_id: RoomId, |
|
26 pub output: Vec<PendingMessage>, |
|
27 pub removed_clients: Vec<ClientId>, |
17 } |
28 } |
18 |
29 |
19 impl HWServer { |
30 impl HWServer { |
20 pub fn new(listener: TcpListener, clients_limit: usize, rooms_limit: usize) -> HWServer { |
31 pub fn new(clients_limit: usize, rooms_limit: usize) -> HWServer { |
21 let mut rooms = Slab::with_capacity(rooms_limit); |
32 let rooms = Slab::with_capacity(rooms_limit); |
22 let token = rooms.insert(HWRoom::new()); |
33 let clients = Slab::with_capacity(clients_limit); |
23 HWServer { |
34 let mut server = HWServer { |
24 listener: listener, |
35 clients, rooms, |
25 clients: Slab::with_capacity(clients_limit), |
36 lobby_id: 0, |
26 rooms: rooms, |
37 output: vec![], |
27 lobby_id: token, |
38 removed_clients: vec![] |
28 } |
39 }; |
|
40 server.lobby_id = server.add_room(); |
|
41 server |
29 } |
42 } |
30 |
43 |
31 pub fn register(&self, poll: &Poll) -> io::Result<()> { |
44 pub fn add_client(&mut self) -> ClientId { |
32 poll.register(&self.listener, utils::SERVER, Ready::readable(), |
45 let key: ClientId; |
33 PollOpt::edge()) |
46 { |
|
47 let entry = self.clients.vacant_entry(); |
|
48 key = entry.key(); |
|
49 let client = HWClient::new(entry.key()); |
|
50 entry.insert(client); |
|
51 } |
|
52 self.send_self(key, HWServerMessage::Connected(utils::PROTOCOL_VERSION)); |
|
53 key |
34 } |
54 } |
35 |
55 |
36 pub fn accept(&mut self, poll: &Poll) -> io::Result<()> { |
56 pub fn client_lost(&mut self, client_id: ClientId) { |
37 let (sock, addr) = self.listener.accept()?; |
57 actions::run_action(self, client_id, |
38 info!("Connected: {}", addr); |
58 actions::Action::ByeClient("Connection reset".to_string())); |
39 |
|
40 let client = HWClient::new(sock); |
|
41 let token = self.clients.insert(client); |
|
42 |
|
43 self.clients[token].id = token; |
|
44 self.clients[token].register(poll, Token(token)); |
|
45 |
|
46 Ok(()) |
|
47 } |
59 } |
48 |
60 |
49 pub fn client_readable(&mut self, poll: &Poll, |
61 pub fn add_room(&mut self) -> RoomId { |
50 token: usize) -> io::Result<()> { |
62 let entry = self.rooms.vacant_entry(); |
51 let actions; |
63 let key = entry.key(); |
52 { |
64 let room = HWRoom::new(entry.key()); |
53 actions = self.clients[token].readable(poll); |
65 entry.insert(room); |
54 } |
66 key |
55 |
|
56 self.react(token, poll, actions); |
|
57 |
|
58 Ok(()) |
|
59 } |
67 } |
60 |
68 |
61 pub fn client_writable(&mut self, poll: &Poll, |
69 pub fn handle_msg(&mut self, client_id: ClientId, msg: HWProtocolMessage) { |
62 token: usize) -> io::Result<()> { |
70 handlers::handle(self, client_id, msg); |
63 self.clients[token].writable(poll)?; |
|
64 |
|
65 Ok(()) |
|
66 } |
71 } |
67 |
72 |
68 pub fn client_error(&mut self, poll: &Poll, |
73 pub fn send_self(&mut self, client_id: ClientId, msg: HWServerMessage) { |
69 token: usize) -> io::Result<()> { |
74 self.output.push(PendingMessage( |
70 let actions; |
75 Destination::ToSelf(client_id), msg)); |
71 { |
|
72 actions = self.clients[token].error(poll); |
|
73 } |
|
74 |
|
75 self.react(token, poll, actions); |
|
76 |
|
77 Ok(()) |
|
78 } |
76 } |
79 |
77 |
80 pub fn send(&mut self, token: usize, msg: &String) { |
78 pub fn send_others(&mut self, client_id: ClientId, msg: HWServerMessage) { |
81 self.clients[token].send_string(msg); |
79 self.output.push(PendingMessage( |
|
80 Destination::ToOthers(client_id), msg)); |
82 } |
81 } |
83 |
82 |
84 pub fn react(&mut self, token: usize, poll: &Poll, actions: Vec<actions::Action>) { |
83 pub fn react(&mut self, client_id: ClientId, actions: Vec<actions::Action>) { |
85 for action in actions { |
84 for action in actions { |
86 actions::run_action(self, token, poll, action); |
85 actions::run_action(self, client_id, action); |
87 } |
86 } |
88 } |
87 } |
89 } |
88 } |
90 |
|
91 |
|
92 pub struct HWRoom { |
|
93 pub id: usize, |
|
94 pub name: String, |
|
95 pub password: Option<String>, |
|
96 pub protocol_number: u32, |
|
97 pub ready_players_number: u8, |
|
98 } |
|
99 |
|
100 impl HWRoom { |
|
101 pub fn new() -> HWRoom { |
|
102 HWRoom { |
|
103 id: 0, |
|
104 name: String::new(), |
|
105 password: None, |
|
106 protocol_number: 0, |
|
107 ready_players_number: 0, |
|
108 } |
|
109 } |
|
110 } |
|