1 use mio; |
1 use mio; |
2 |
2 |
3 use protocol::messages::{ |
3 use crate::{ |
4 HWProtocolMessage, |
4 server::{ |
5 HWServerMessage::*, |
5 coretypes::{ClientId, RoomId, Voting, VoteType}, |
6 server_chat |
6 server::HWServer, |
|
7 room::{HWRoom, RoomFlags}, |
|
8 actions::{Action, Action::*} |
|
9 }, |
|
10 protocol::messages::{ |
|
11 HWProtocolMessage, |
|
12 HWServerMessage::*, |
|
13 server_chat |
|
14 }, |
|
15 utils::is_name_illegal |
7 }; |
16 }; |
8 use server::{ |
|
9 coretypes::{ClientId, RoomId, Voting, VoteType}, |
|
10 server::HWServer, |
|
11 room::{HWRoom, RoomFlags}, |
|
12 actions::{Action, Action::*} |
|
13 }; |
|
14 use utils::is_name_illegal; |
|
15 use std::{ |
17 use std::{ |
16 mem::swap, fs::{File, OpenOptions}, |
18 mem::swap, fs::{File, OpenOptions}, |
17 io::{Read, Write, Result, Error, ErrorKind} |
19 io::{Read, Write, Result, Error, ErrorKind} |
18 }; |
20 }; |
19 use base64::{encode, decode}; |
21 use base64::{encode, decode}; |
83 VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number) |
85 VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number) |
84 }) |
86 }) |
85 } |
87 } |
86 |
88 |
87 fn room_message_flag(msg: &HWProtocolMessage) -> RoomFlags { |
89 fn room_message_flag(msg: &HWProtocolMessage) -> RoomFlags { |
88 use protocol::messages::HWProtocolMessage::*; |
90 use crate::protocol::messages::HWProtocolMessage::*; |
89 match msg { |
91 match msg { |
90 ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN, |
92 ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN, |
91 ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD, |
93 ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD, |
92 ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS, |
94 ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS, |
93 _ => RoomFlags::empty() |
95 _ => RoomFlags::empty() |
105 let mut writer = OpenOptions::new().create(true).write(true).open(filename)?; |
107 let mut writer = OpenOptions::new().create(true).write(true).open(filename)?; |
106 writer.write_all(content.as_bytes()) |
108 writer.write_all(content.as_bytes()) |
107 } |
109 } |
108 |
110 |
109 pub fn handle(server: &mut HWServer, client_id: ClientId, room_id: RoomId, message: HWProtocolMessage) { |
111 pub fn handle(server: &mut HWServer, client_id: ClientId, room_id: RoomId, message: HWProtocolMessage) { |
110 use protocol::messages::HWProtocolMessage::*; |
112 use crate::protocol::messages::HWProtocolMessage::*; |
111 match message { |
113 match message { |
112 Part(None) => server.react(client_id, vec![ |
114 Part(None) => server.react(client_id, vec![ |
113 MoveToLobby("part".to_string())]), |
115 MoveToLobby("part".to_string())]), |
114 Part(Some(msg)) => server.react(client_id, vec![ |
116 Part(Some(msg)) => server.react(client_id, vec![ |
115 MoveToLobby(format!("part: {}", msg))]), |
117 MoveToLobby(format!("part: {}", msg))]), |
152 vec![SendRoomUpdate(Some(old_name))] |
154 vec![SendRoomUpdate(Some(old_name))] |
153 }; |
155 }; |
154 server.react(client_id, actions); |
156 server.react(client_id, actions); |
155 }, |
157 }, |
156 ToggleReady => { |
158 ToggleReady => { |
157 let actions = if let (c, Some(r)) = server.client_and_room(client_id) { |
159 if let (c, Some(r)) = server.client_and_room(client_id) { |
158 let flags = if c.is_ready() { |
160 let flags = if c.is_ready() { |
159 r.ready_players_number -= 1; |
161 r.ready_players_number -= 1; |
160 "-r" |
162 "-r" |
161 } else { |
163 } else { |
162 r.ready_players_number += 1; |
164 r.ready_players_number += 1; |
163 "+r" |
165 "+r" |
164 }; |
166 }; |
165 let is_ready = !c.is_ready(); |
167 c.set_is_ready(!c.is_ready()); |
166 c.set_is_ready(is_ready); |
|
167 let mut v = |
168 let mut v = |
168 vec![ClientFlags(flags.to_string(), vec![c.nick.clone()]) |
169 vec![ClientFlags(flags.to_string(), vec![c.nick.clone()]) |
169 .send_all().in_room(r.id).action()]; |
170 .send_all().in_room(r.id).action()]; |
170 if r.is_fixed() && r.ready_players_number == r.players_number { |
171 if r.is_fixed() && r.ready_players_number == r.players_number { |
171 v.push(StartRoomGame(r.id)) |
172 v.push(StartRoomGame(r.id)) |
172 } |
173 } |
173 v |
174 server.react(client_id, v); |
174 } else { |
175 } |
175 Vec::new() |
|
176 }; |
|
177 server.react(client_id, actions); |
|
178 } |
176 } |
179 AddTeam(info) => { |
177 AddTeam(info) => { |
180 let mut actions = Vec::new(); |
178 let mut actions = Vec::new(); |
181 if let (c, Some(r)) = server.client_and_room(client_id) { |
179 if let (c, Some(r)) = server.client_and_room(client_id) { |
182 if r.teams.len() >= r.team_limit as usize { |
180 if r.teams.len() >= r.team_limit as usize { |
222 } |
220 } |
223 }; |
221 }; |
224 server.react(client_id, actions); |
222 server.react(client_id, actions); |
225 }, |
223 }, |
226 SetHedgehogsNumber(team_name, number) => { |
224 SetHedgehogsNumber(team_name, number) => { |
227 let actions = if let (c, Some(r)) = server.client_and_room(client_id) { |
225 if let (c, Some(r)) = server.client_and_room(client_id) { |
228 let addable_hedgehogs = r.addable_hedgehogs(); |
226 let addable_hedgehogs = r.addable_hedgehogs(); |
229 if let Some((_, mut team)) = r.find_team_and_owner_mut(|t| t.name == team_name) { |
227 let actions = if let Some((_, team)) = r.find_team_and_owner_mut(|t| t.name == team_name) { |
230 if !c.is_master() { |
228 if !c.is_master() { |
231 vec![ProtocolError("You're not the room master!".to_string())] |
229 vec![ProtocolError("You're not the room master!".to_string())] |
232 } else if number < 1 || number > 8 |
230 } else if number < 1 || number > 8 |
233 || number > addable_hedgehogs + team.hedgehogs_number { |
231 || number > addable_hedgehogs + team.hedgehogs_number { |
234 vec![HedgehogsNumber(team.name.clone(), team.hedgehogs_number) |
232 vec![HedgehogsNumber(team.name.clone(), team.hedgehogs_number) |
238 vec![HedgehogsNumber(team.name.clone(), number) |
236 vec![HedgehogsNumber(team.name.clone(), number) |
239 .send_all().in_room(room_id).but_self().action()] |
237 .send_all().in_room(room_id).but_self().action()] |
240 } |
238 } |
241 } else { |
239 } else { |
242 vec![(Warn("No such team.".to_string()))] |
240 vec![(Warn("No such team.".to_string()))] |
243 } |
241 }; |
244 } else { |
242 server.react(client_id, actions); |
245 Vec::new() |
243 } |
246 }; |
|
247 server.react(client_id, actions); |
|
248 }, |
244 }, |
249 SetTeamColor(team_name, color) => { |
245 SetTeamColor(team_name, color) => { |
250 let mut owner_id = None; |
246 if let (c, Some(r)) = server.client_and_room(client_id) { |
251 let actions = if let (c, Some(r)) = server.client_and_room(client_id) { |
247 let mut owner_id = None; |
252 if let Some((owner, mut team)) = r.find_team_and_owner_mut(|t| t.name == team_name) { |
248 let actions = if let Some((owner, team)) = r.find_team_and_owner_mut(|t| t.name == team_name) { |
253 if !c.is_master() { |
249 if !c.is_master() { |
254 vec![ProtocolError("You're not the room master!".to_string())] |
250 vec![ProtocolError("You're not the room master!".to_string())] |
255 } else if false { |
251 } else if false { |
256 Vec::new() |
252 Vec::new() |
257 } else { |
253 } else { |
260 vec![TeamColor(team.name.clone(), color) |
256 vec![TeamColor(team.name.clone(), color) |
261 .send_all().in_room(room_id).but_self().action()] |
257 .send_all().in_room(room_id).but_self().action()] |
262 } |
258 } |
263 } else { |
259 } else { |
264 vec![(Warn("No such team.".to_string()))] |
260 vec![(Warn("No such team.".to_string()))] |
265 } |
261 }; |
266 } else { |
262 |
267 Vec::new() |
263 if let Some(id) = owner_id { |
268 }; |
264 server.clients[id].clan = Some(color); |
269 |
265 } |
270 if let Some(id) = owner_id { |
266 |
271 server.clients[id].clan = Some(color); |
267 server.react(client_id, actions); |
272 } |
268 }; |
273 |
|
274 server.react(client_id, actions); |
|
275 }, |
269 }, |
276 Cfg(cfg) => { |
270 Cfg(cfg) => { |
277 let actions = if let (c, Some(r)) = server.client_and_room(client_id) { |
271 if let (c, Some(r)) = server.client_and_room(client_id) { |
278 if r.is_fixed() { |
272 let actions = if r.is_fixed() { |
279 vec![Warn("Access denied.".to_string())] |
273 vec![Warn("Access denied.".to_string())] |
280 } else if !c.is_master() { |
274 } else if !c.is_master() { |
281 vec![ProtocolError("You're not the room master!".to_string())] |
275 vec![ProtocolError("You're not the room master!".to_string())] |
282 } else { |
276 } else { |
283 let v = vec![cfg.to_server_msg() |
277 let v = vec![cfg.to_server_msg() |
284 .send_all().in_room(r.id).but_self().action()]; |
278 .send_all().in_room(r.id).but_self().action()]; |
285 r.set_config(cfg); |
279 r.set_config(cfg); |
286 v |
280 v |
287 } |
281 }; |
288 } else { |
282 server.react(client_id, actions); |
289 Vec::new() |
283 } |
290 }; |
|
291 server.react(client_id, actions); |
|
292 } |
284 } |
293 Save(name, location) => { |
285 Save(name, location) => { |
294 let actions = vec![server_chat(format!("Room config saved as {}", name)) |
286 let actions = vec![server_chat(format!("Room config saved as {}", name)) |
295 .send_all().in_room(room_id).action()]; |
287 .send_all().in_room(room_id).action()]; |
296 server.rooms[room_id].save_config(name, location); |
288 server.rooms[room_id].save_config(name, location); |
297 server.react(client_id, actions); |
289 server.react(client_id, actions); |
298 } |
290 } |
299 SaveRoom(filename) => { |
291 SaveRoom(filename) => { |
300 let actions = if server.clients[client_id].is_admin() { |
292 if server.clients[client_id].is_admin() { |
301 match server.rooms[room_id].get_saves() { |
293 let actions = match server.rooms[room_id].get_saves() { |
302 Ok(text) => match write_file(&filename, &text) { |
294 Ok(text) => match write_file(&filename, &text) { |
303 Ok(_) => vec![server_chat("Room configs saved successfully.".to_string()) |
295 Ok(_) => vec![server_chat("Room configs saved successfully.".to_string()) |
304 .send_self().action()], |
296 .send_self().action()], |
305 Err(e) => { |
297 Err(e) => { |
306 warn!("Error while writing the config file \"{}\": {}", filename, e); |
298 warn!("Error while writing the config file \"{}\": {}", filename, e); |
309 } |
301 } |
310 Err(e) => { |
302 Err(e) => { |
311 warn!("Error while serializing the room configs: {}", e); |
303 warn!("Error while serializing the room configs: {}", e); |
312 vec![Warn("Unable to serialize the room configs.".to_string())] |
304 vec![Warn("Unable to serialize the room configs.".to_string())] |
313 } |
305 } |
314 } |
306 }; |
315 } else { |
307 server.react(client_id, actions); |
316 Vec::new() |
308 } |
317 }; |
|
318 server.react(client_id, actions); |
|
319 } |
309 } |
320 LoadRoom(filename) => { |
310 LoadRoom(filename) => { |
321 let actions = if server.clients[client_id].is_admin() { |
311 if server.clients[client_id].is_admin() { |
322 match read_file(&filename) { |
312 let actions = match read_file(&filename) { |
323 Ok(text) => match server.rooms[room_id].set_saves(&text) { |
313 Ok(text) => match server.rooms[room_id].set_saves(&text) { |
324 Ok(_) => vec![server_chat("Room configs loaded successfully.".to_string()) |
314 Ok(_) => vec![server_chat("Room configs loaded successfully.".to_string()) |
325 .send_self().action()], |
315 .send_self().action()], |
326 Err(e) => { |
316 Err(e) => { |
327 warn!("Error while deserializing the room configs: {}", e); |
317 warn!("Error while deserializing the room configs: {}", e); |
330 } |
320 } |
331 Err(e) => { |
321 Err(e) => { |
332 warn!("Error while reading the config file \"{}\": {}", filename, e); |
322 warn!("Error while reading the config file \"{}\": {}", filename, e); |
333 vec![Warn("Unable to load the room configs.".to_string())] |
323 vec![Warn("Unable to load the room configs.".to_string())] |
334 } |
324 } |
335 } |
325 }; |
336 } else { |
326 server.react(client_id, actions); |
337 Vec::new() |
327 } |
338 }; |
|
339 server.react(client_id, actions); |
|
340 } |
328 } |
341 Delete(name) => { |
329 Delete(name) => { |
342 let actions = if !server.rooms[room_id].delete_config(&name) { |
330 let actions = if !server.rooms[room_id].delete_config(&name) { |
343 vec![Warn(format!("Save doesn't exist: {}", name))] |
331 vec![Warn(format!("Save doesn't exist: {}", name))] |
344 } else { |
332 } else { |