rust/hedgewars-server/src/server/handlers/inroom.rs
changeset 14457 98ef2913ec73
parent 14415 06672690d71b
child 14671 455865ccd36c
equal deleted inserted replaced
14456:a077aac9df01 14457:98ef2913ec73
     1 use mio;
     1 use mio;
     2 
     2 
       
     3 use super::common::rnd_reply;
     3 use crate::{
     4 use crate::{
       
     5     protocol::messages::{server_chat, HWProtocolMessage, HWServerMessage::*},
     4     server::{
     6     server::{
     5         coretypes::{
     7         actions::{Action, Action::*},
     6             ClientId, RoomId, Voting, VoteType, GameCfg,
       
     7             MAX_HEDGEHOGS_PER_TEAM
       
     8         },
       
     9         core::HWServer,
     8         core::HWServer,
       
     9         coretypes::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM},
    10         room::{HWRoom, RoomFlags},
    10         room::{HWRoom, RoomFlags},
    11         actions::{Action, Action::*}
       
    12     },
    11     },
    13     protocol::messages::{
    12     utils::is_name_illegal,
    14         HWProtocolMessage,
       
    15         HWServerMessage::*,
       
    16         server_chat
       
    17     },
       
    18     utils::is_name_illegal
       
    19 };
    13 };
    20 use std::{
    14 use base64::{decode, encode};
    21     mem::swap
       
    22 };
       
    23 use base64::{encode, decode};
       
    24 use super::common::rnd_reply;
       
    25 use log::*;
    15 use log::*;
       
    16 use std::mem::swap;
    26 
    17 
    27 #[derive(Clone)]
    18 #[derive(Clone)]
    28 struct ByMsg<'a> {
    19 struct ByMsg<'a> {
    29     messages: &'a[u8]
    20     messages: &'a [u8],
    30 }
    21 }
    31 
    22 
    32 impl <'a> Iterator for ByMsg<'a> {
    23 impl<'a> Iterator for ByMsg<'a> {
    33     type Item = &'a[u8];
    24     type Item = &'a [u8];
    34 
    25 
    35     fn next(&mut self) -> Option<<Self as Iterator>::Item> {
    26     fn next(&mut self) -> Option<<Self as Iterator>::Item> {
    36         if let Some(size) = self.messages.get(0) {
    27         if let Some(size) = self.messages.get(0) {
    37             let (msg, next) = self.messages.split_at(*size as usize + 1);
    28             let (msg, next) = self.messages.split_at(*size as usize + 1);
    38             self.messages = next;
    29             self.messages = next;
    42         }
    33         }
    43     }
    34     }
    44 }
    35 }
    45 
    36 
    46 fn by_msg(source: &[u8]) -> ByMsg {
    37 fn by_msg(source: &[u8]) -> ByMsg {
    47     ByMsg {messages: source}
    38     ByMsg { messages: source }
    48 }
    39 }
    49 
    40 
    50 const VALID_MESSAGES: &[u8] =
    41 const VALID_MESSAGES: &[u8] =
    51     b"M#+LlRrUuDdZzAaSjJ,NpPwtgfhbc12345\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A";
    42     b"M#+LlRrUuDdZzAaSjJ,NpPwtgfhbc12345\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A";
    52 const NON_TIMED_MESSAGES: &[u8] = b"M#hb";
    43 const NON_TIMED_MESSAGES: &[u8] = b"M#hb";
    53 
    44 
    54 #[cfg(canhazslicepatterns)]
    45 #[cfg(canhazslicepatterns)]
    55 fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool {
    46 fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool {
    56     match msg {
    47     match msg {
    57         [size, typ, body..] => VALID_MESSAGES.contains(typ)
    48         [size, typ, body..] => {
    58             && match body {
    49             VALID_MESSAGES.contains(typ)
    59                 [1...MAX_HEDGEHOGS_PER_TEAM, team, ..] if *typ == b'h' =>
    50                 && match body {
    60                     team_indices.contains(team),
    51                     [1...MAX_HEDGEHOGS_PER_TEAM, team, ..] if *typ == b'h' => {
    61                 _ => *typ != b'h'
    52                         team_indices.contains(team)
    62             },
    53                     }
    63         _ => false
    54                     _ => *typ != b'h',
       
    55                 }
       
    56         }
       
    57         _ => false,
    64     }
    58     }
    65 }
    59 }
    66 
    60 
    67 fn is_msg_valid(msg: &[u8], _team_indices: &[u8]) -> bool {
    61 fn is_msg_valid(msg: &[u8], _team_indices: &[u8]) -> bool {
    68     if let Some(typ) = msg.get(1) {
    62     if let Some(typ) = msg.get(1) {
    75 fn is_msg_empty(msg: &[u8]) -> bool {
    69 fn is_msg_empty(msg: &[u8]) -> bool {
    76     msg.get(1).filter(|t| **t == b'+').is_some()
    70     msg.get(1).filter(|t| **t == b'+').is_some()
    77 }
    71 }
    78 
    72 
    79 fn is_msg_timed(msg: &[u8]) -> bool {
    73 fn is_msg_timed(msg: &[u8]) -> bool {
    80     msg.get(1).filter(|t| !NON_TIMED_MESSAGES.contains(t)).is_some()
    74     msg.get(1)
       
    75         .filter(|t| !NON_TIMED_MESSAGES.contains(t))
       
    76         .is_some()
    81 }
    77 }
    82 
    78 
    83 fn voting_description(kind: &VoteType) -> String {
    79 fn voting_description(kind: &VoteType) -> String {
    84     format!("New voting started: {}", match kind {
    80     format!(
    85         VoteType::Kick(nick) => format!("kick {}", nick),
    81         "New voting started: {}",
    86         VoteType::Map(name) => format!("map {}", name.as_ref().unwrap()),
    82         match kind {
    87         VoteType::Pause => "pause".to_string(),
    83             VoteType::Kick(nick) => format!("kick {}", nick),
    88         VoteType::NewSeed => "new seed".to_string(),
    84             VoteType::Map(name) => format!("map {}", name.as_ref().unwrap()),
    89         VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number)
    85             VoteType::Pause => "pause".to_string(),
    90     })
    86             VoteType::NewSeed => "new seed".to_string(),
       
    87             VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number),
       
    88         }
       
    89     )
    91 }
    90 }
    92 
    91 
    93 fn room_message_flag(msg: &HWProtocolMessage) -> RoomFlags {
    92 fn room_message_flag(msg: &HWProtocolMessage) -> RoomFlags {
    94     use crate::protocol::messages::HWProtocolMessage::*;
    93     use crate::protocol::messages::HWProtocolMessage::*;
    95     match msg {
    94     match msg {
    96         ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN,
    95         ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN,
    97         ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD,
    96         ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD,
    98         ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS,
    97         ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS,
    99         _ => RoomFlags::empty()
    98         _ => RoomFlags::empty(),
   100     }
    99     }
   101 }
   100 }
   102 
   101 
   103 pub fn handle(server: &mut HWServer, client_id: ClientId, room_id: RoomId, message: HWProtocolMessage) {
   102 pub fn handle(
       
   103     server: &mut HWServer,
       
   104     client_id: ClientId,
       
   105     room_id: RoomId,
       
   106     message: HWProtocolMessage,
       
   107 ) {
   104     use crate::protocol::messages::HWProtocolMessage::*;
   108     use crate::protocol::messages::HWProtocolMessage::*;
   105     match message {
   109     match message {
   106         Part(None) => server.react(client_id, vec![
   110         Part(None) => server.react(client_id, vec![
   107             MoveToLobby("part".to_string())]),
   111             MoveToLobby("part".to_string())]),
   108         Part(Some(msg)) => server.react(client_id, vec![
   112         Part(Some(msg)) => server.react(client_id, vec![