234 } |
249 } |
235 } |
250 } |
236 } |
251 } |
237 |
252 |
238 pub fn handle( |
253 pub fn handle( |
239 server: &mut HwServer, |
254 state: &mut ServerState, |
240 client_id: ClientId, |
255 client_id: ClientId, |
241 response: &mut Response, |
256 response: &mut Response, |
242 message: HwProtocolMessage, |
257 message: HwProtocolMessage, |
243 ) { |
258 ) { |
244 match message { |
259 match message { |
245 HwProtocolMessage::Ping => response.add(Pong.send_self()), |
260 HwProtocolMessage::Ping => response.add(Pong.send_self()), |
246 HwProtocolMessage::Pong => (), |
261 HwProtocolMessage::Pong => (), |
247 _ => { |
262 _ => { |
248 if server.anteroom.clients.contains(client_id) { |
263 if state.anteroom.clients.contains(client_id) { |
249 match inanteroom::handle(server, client_id, response, message) { |
264 match inanteroom::handle(state, client_id, response, message) { |
250 LoginResult::Unchanged => (), |
265 LoginResult::Unchanged => (), |
251 LoginResult::Complete => { |
266 LoginResult::Complete => { |
252 if let Some(client) = server.anteroom.remove_client(client_id) { |
267 if let Some(client) = state.anteroom.remove_client(client_id) { |
253 server.add_client(client_id, client); |
268 state.server.add_client(client_id, client); |
254 common::get_lobby_join_data(server, response); |
269 common::get_lobby_join_data(&state.server, response); |
255 } |
270 } |
256 } |
271 } |
257 LoginResult::Exit => { |
272 LoginResult::Exit => { |
258 server.anteroom.remove_client(client_id); |
273 state.anteroom.remove_client(client_id); |
259 response.remove_client(client_id); |
274 response.remove_client(client_id); |
260 } |
275 } |
261 } |
276 } |
262 } else if server.has_client(client_id) { |
277 } else if state.server.has_client(client_id) { |
263 match message { |
278 match message { |
264 HwProtocolMessage::Quit(Some(msg)) => { |
279 HwProtocolMessage::Quit(Some(msg)) => { |
265 common::remove_client(server, response, "User quit: ".to_string() + &msg); |
280 common::remove_client( |
|
281 &mut state.server, |
|
282 response, |
|
283 "User quit: ".to_string() + &msg, |
|
284 ); |
266 } |
285 } |
267 HwProtocolMessage::Quit(None) => { |
286 HwProtocolMessage::Quit(None) => { |
268 common::remove_client(server, response, "User quit".to_string()); |
287 common::remove_client(&mut state.server, response, "User quit".to_string()); |
269 } |
288 } |
270 HwProtocolMessage::Info(nick) => { |
289 HwProtocolMessage::Info(nick) => { |
271 if let Some(client) = server.find_client(&nick) { |
290 if let Some(client) = state.server.find_client(&nick) { |
272 let admin_sign = if client.is_admin() { "@" } else { "" }; |
291 let admin_sign = if client.is_admin() { "@" } else { "" }; |
273 let master_sign = if client.is_master() { "+" } else { "" }; |
292 let master_sign = if client.is_master() { "+" } else { "" }; |
274 let room_info = match client.room_id { |
293 let room_info = match client.room_id { |
275 Some(room_id) => { |
294 Some(room_id) => { |
276 let room = server.room(room_id); |
295 let room = state.server.room(room_id); |
277 let status = match room.game_info { |
296 let status = match room.game_info { |
278 Some(_) if client.teams_in_game == 0 => "(spectating)", |
297 Some(_) if client.teams_in_game == 0 => "(spectating)", |
279 Some(_) => "(playing)", |
298 Some(_) => "(playing)", |
280 None => "", |
299 None => "", |
281 }; |
300 }; |
297 } else { |
316 } else { |
298 response.add(server_chat(USER_OFFLINE.to_string()).send_self()) |
317 response.add(server_chat(USER_OFFLINE.to_string()).send_self()) |
299 } |
318 } |
300 } |
319 } |
301 HwProtocolMessage::ToggleServerRegisteredOnly => { |
320 HwProtocolMessage::ToggleServerRegisteredOnly => { |
302 if !server.is_admin(client_id) { |
321 if !state.server.is_admin(client_id) { |
303 response.warn(ACCESS_DENIED); |
322 response.warn(ACCESS_DENIED); |
304 } else { |
323 } else { |
305 server.set_is_registered_only(!server.is_registered_only()); |
324 state |
306 let msg = if server.is_registered_only() { |
325 .server |
|
326 .set_is_registered_only(!state.server.is_registered_only()); |
|
327 let msg = if state.server.is_registered_only() { |
307 REGISTERED_ONLY_ENABLED |
328 REGISTERED_ONLY_ENABLED |
308 } else { |
329 } else { |
309 REGISTERED_ONLY_DISABLED |
330 REGISTERED_ONLY_DISABLED |
310 }; |
331 }; |
311 response.add(server_chat(msg.to_string()).send_all()); |
332 response.add(server_chat(msg.to_string()).send_all()); |
312 } |
333 } |
313 } |
334 } |
314 HwProtocolMessage::Global(msg) => { |
335 HwProtocolMessage::Global(msg) => { |
315 if !server.is_admin(client_id) { |
336 if !state.server.is_admin(client_id) { |
316 response.warn(ACCESS_DENIED); |
337 response.warn(ACCESS_DENIED); |
317 } else { |
338 } else { |
318 response.add(global_chat(msg).send_all()) |
339 response.add(global_chat(msg).send_all()) |
319 } |
340 } |
320 } |
341 } |
321 HwProtocolMessage::SuperPower => { |
342 HwProtocolMessage::SuperPower => { |
322 if server.enable_super_power(client_id) { |
343 if state.server.enable_super_power(client_id) { |
323 response.add(server_chat(SUPER_POWER.to_string()).send_self()) |
344 response.add(server_chat(SUPER_POWER.to_string()).send_self()) |
324 } else { |
345 } else { |
325 response.warn(ACCESS_DENIED); |
346 response.warn(ACCESS_DENIED); |
326 } |
347 } |
327 } |
348 } |
334 #[cfg(not(feature = "official-server"))] |
355 #[cfg(not(feature = "official-server"))] |
335 { |
356 { |
336 response.warn(REPLAY_NOT_SUPPORTED); |
357 response.warn(REPLAY_NOT_SUPPORTED); |
337 } |
358 } |
338 } |
359 } |
339 _ => match server.client(client_id).room_id { |
360 _ => match state.server.client(client_id).room_id { |
340 None => inlobby::handle(server, client_id, response, message), |
361 None => inlobby::handle(&mut state.server, client_id, response, message), |
341 Some(room_id) => { |
362 Some(room_id) => { |
342 inroom::handle(server, client_id, response, room_id, message) |
363 inroom::handle(&mut state.server, client_id, response, room_id, message) |
343 } |
364 } |
344 }, |
365 }, |
345 } |
366 } |
346 } |
367 } |
347 } |
368 } |
348 } |
369 } |
349 } |
370 } |
350 |
371 |
351 pub fn handle_client_accept( |
372 pub fn handle_client_accept( |
352 server: &mut HwServer, |
373 state: &mut ServerState, |
353 client_id: ClientId, |
374 client_id: ClientId, |
354 response: &mut Response, |
375 response: &mut Response, |
355 addr: [u8; 4], |
376 addr: [u8; 4], |
356 is_local: bool, |
377 is_local: bool, |
357 ) { |
378 ) { |
358 let ban_reason = Some(addr) |
379 let ban_reason = Some(addr) |
359 .filter(|_| !is_local) |
380 .filter(|_| !is_local) |
360 .and_then(|a| server.anteroom.find_ip_ban(a)); |
381 .and_then(|a| state.anteroom.find_ip_ban(a)); |
361 if let Some(reason) = ban_reason { |
382 if let Some(reason) = ban_reason { |
362 response.add(HwServerMessage::Bye(reason).send_self()); |
383 response.add(HwServerMessage::Bye(reason).send_self()); |
363 response.remove_client(client_id); |
384 response.remove_client(client_id); |
364 } else { |
385 } else { |
365 let mut salt = [0u8; 18]; |
386 let mut salt = [0u8; 18]; |
366 thread_rng().fill_bytes(&mut salt); |
387 thread_rng().fill_bytes(&mut salt); |
367 |
388 |
368 server |
389 state |
369 .anteroom |
390 .anteroom |
370 .add_client(client_id, encode(&salt), is_local); |
391 .add_client(client_id, encode(&salt), is_local); |
371 |
392 |
372 response.add(HwServerMessage::Connected(utils::SERVER_VERSION).send_self()); |
393 response.add(HwServerMessage::Connected(utils::SERVER_VERSION).send_self()); |
373 } |
394 } |
374 } |
395 } |
375 |
396 |
376 pub fn handle_client_loss(server: &mut HwServer, client_id: ClientId, response: &mut Response) { |
397 pub fn handle_client_loss(state: &mut ServerState, client_id: ClientId, response: &mut Response) { |
377 if server.anteroom.remove_client(client_id).is_none() { |
398 if state.anteroom.remove_client(client_id).is_none() { |
378 common::remove_client(server, response, "Connection reset".to_string()); |
399 common::remove_client(&mut state.server, response, "Connection reset".to_string()); |
379 } |
400 } |
380 } |
401 } |
381 |
402 |
382 pub fn handle_io_result( |
403 pub fn handle_io_result( |
383 server: &mut HwServer, |
404 state: &mut ServerState, |
384 client_id: ClientId, |
405 client_id: ClientId, |
385 response: &mut Response, |
406 response: &mut Response, |
386 io_result: IoResult, |
407 io_result: IoResult, |
387 ) { |
408 ) { |
388 match io_result { |
409 match io_result { |
389 IoResult::AccountRegistered(is_registered) => { |
410 IoResult::AccountRegistered(is_registered) => { |
390 if !is_registered && server.is_registered_only() { |
411 if !is_registered && state.server.is_registered_only() { |
391 response.add(Bye(REGISTRATION_REQUIRED.to_string()).send_self()); |
412 response.add(Bye(REGISTRATION_REQUIRED.to_string()).send_self()); |
392 response.remove_client(client_id); |
413 response.remove_client(client_id); |
393 } else if is_registered { |
414 } else if is_registered { |
394 let salt = server.anteroom.clients[client_id].server_salt.clone(); |
415 let salt = state.anteroom.clients[client_id].server_salt.clone(); |
395 response.add(AskPassword(salt).send_self()); |
416 response.add(AskPassword(salt).send_self()); |
396 } else if let Some(client) = server.anteroom.remove_client(client_id) { |
417 } else if let Some(client) = state.anteroom.remove_client(client_id) { |
397 server.add_client(client_id, client); |
418 state.server.add_client(client_id, client); |
398 common::get_lobby_join_data(server, response); |
419 common::get_lobby_join_data(&state.server, response); |
399 } |
420 } |
400 } |
421 } |
401 IoResult::Account(Some(info)) => { |
422 IoResult::Account(Some(info)) => { |
402 response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self()); |
423 response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self()); |
403 if let Some(mut client) = server.anteroom.remove_client(client_id) { |
424 if let Some(mut client) = state.anteroom.remove_client(client_id) { |
404 client.is_registered = info.is_registered; |
425 client.is_registered = info.is_registered; |
405 client.is_admin = info.is_admin; |
426 client.is_admin = info.is_admin; |
406 client.is_contributor = info.is_contributor; |
427 client.is_contributor = info.is_contributor; |
407 server.add_client(client_id, client); |
428 state.server.add_client(client_id, client); |
408 common::get_lobby_join_data(server, response); |
429 common::get_lobby_join_data(&state.server, response); |
409 } |
430 } |
410 } |
431 } |
411 IoResult::Account(None) => { |
432 IoResult::Account(None) => { |
412 response.error(AUTHENTICATION_FAILED); |
433 response.error(AUTHENTICATION_FAILED); |
413 response.remove_client(client_id); |
434 response.remove_client(client_id); |
414 } |
435 } |
415 IoResult::Replay(Some(replay)) => { |
436 IoResult::Replay(Some(replay)) => { |
416 let client = server.client(client_id); |
437 let client = state.server.client(client_id); |
417 let protocol = client.protocol_number; |
438 let protocol = client.protocol_number; |
418 let start_msg = if protocol < 58 { |
439 let start_msg = if protocol < 58 { |
419 RoomJoined(vec![client.nick.clone()]) |
440 RoomJoined(vec![client.nick.clone()]) |
420 } else { |
441 } else { |
421 ReplayStart |
442 ReplayStart |