rust/hedgewars-server/src/protocol/messages.rs
changeset 14457 98ef2913ec73
parent 14415 06672690d71b
child 14697 f64e21f164a5
equal deleted inserted replaced
14456:a077aac9df01 14457:98ef2913ec73
     1 use crate::server::coretypes::{
     1 use crate::server::coretypes::{GameCfg, HedgehogInfo, ServerVar, TeamInfo, VoteType};
     2     ServerVar, GameCfg, TeamInfo,
     2 use std::{convert::From, iter::once, ops};
     3     HedgehogInfo, VoteType
       
     4 };
       
     5 use std::{ops, convert::From, iter::once};
       
     6 
     3 
     7 #[derive(PartialEq, Eq, Clone, Debug)]
     4 #[derive(PartialEq, Eq, Clone, Debug)]
     8 pub enum HWProtocolMessage {
     5 pub enum HWProtocolMessage {
     9     // core
     6     // core
    10     Ping,
     7     Ping,
    78     Nick(String),
    75     Nick(String),
    79     Proto(u16),
    76     Proto(u16),
    80     ServerAuth(String),
    77     ServerAuth(String),
    81     LobbyLeft(String, String),
    78     LobbyLeft(String, String),
    82     LobbyJoined(Vec<String>),
    79     LobbyJoined(Vec<String>),
    83     ChatMsg {nick: String, msg: String},
    80     ChatMsg { nick: String, msg: String },
    84     ClientFlags(String, Vec<String>),
    81     ClientFlags(String, Vec<String>),
    85     Rooms(Vec<String>),
    82     Rooms(Vec<String>),
    86     RoomAdd(Vec<String>),
    83     RoomAdd(Vec<String>),
    87     RoomJoined(Vec<String>),
    84     RoomJoined(Vec<String>),
    88     RoomLeft(String, String),
    85     RoomLeft(String, String),
   105     Error(String),
   102     Error(String),
   106     Connected(u32),
   103     Connected(u32),
   107     Unreachable,
   104     Unreachable,
   108 
   105 
   109     //Deprecated messages
   106     //Deprecated messages
   110     LegacyReady(bool, Vec<String>)
   107     LegacyReady(bool, Vec<String>),
   111 }
   108 }
   112 
   109 
   113 pub fn server_chat(msg: String) -> HWServerMessage  {
   110 pub fn server_chat(msg: String) -> HWServerMessage {
   114     HWServerMessage::ChatMsg{ nick: "[server]".to_string(), msg }
   111     HWServerMessage::ChatMsg {
       
   112         nick: "[server]".to_string(),
       
   113         msg,
       
   114     }
   115 }
   115 }
   116 
   116 
   117 impl GameCfg {
   117 impl GameCfg {
   118     pub fn to_protocol(&self) -> (String, Vec<String>) {
   118     pub fn to_protocol(&self) -> (String, Vec<String>) {
   119         use crate::server::coretypes::GameCfg::*;
   119         use crate::server::coretypes::GameCfg::*;
   133                 v.extend(s.clone().into_iter());
   133                 v.extend(s.clone().into_iter());
   134                 v
   134                 v
   135             }),
   135             }),
   136             Script(s) => ("SCRIPT".to_string(), vec![s.to_string()]),
   136             Script(s) => ("SCRIPT".to_string(), vec![s.to_string()]),
   137             Theme(t) => ("THEME".to_string(), vec![t.to_string()]),
   137             Theme(t) => ("THEME".to_string(), vec![t.to_string()]),
   138             DrawnMap(m) => ("DRAWNMAP".to_string(), vec![m.to_string()])
   138             DrawnMap(m) => ("DRAWNMAP".to_string(), vec![m.to_string()]),
   139         }
   139         }
   140     }
   140     }
   141 
   141 
   142     pub fn to_server_msg(&self) -> HWServerMessage {
   142     pub fn to_server_msg(&self) -> HWServerMessage {
   143         use self::HWServerMessage::ConfigEntry;
   143         use self::HWServerMessage::ConfigEntry;
   145         HWServerMessage::ConfigEntry(name, args)
   145         HWServerMessage::ConfigEntry(name, args)
   146     }
   146     }
   147 }
   147 }
   148 
   148 
   149 macro_rules! const_braces {
   149 macro_rules! const_braces {
   150     ($e: expr) => { "{}\n" }
   150     ($e: expr) => {
       
   151         "{}\n"
       
   152     };
   151 }
   153 }
   152 
   154 
   153 macro_rules! msg {
   155 macro_rules! msg {
   154     [$($part: expr),*] => {
   156     [$($part: expr),*] => {
   155         format!(concat!($(const_braces!($part)),*, "\n"), $($part),*);
   157         format!(concat!($(const_braces!($part)),*, "\n"), $($part),*);
   176             Quit(None) => msg!["QUIT"],
   178             Quit(None) => msg!["QUIT"],
   177             Quit(Some(msg)) => msg!["QUIT", msg],
   179             Quit(Some(msg)) => msg!["QUIT", msg],
   178             Global(msg) => msg!["CMD", format!("GLOBAL {}", msg)],
   180             Global(msg) => msg!["CMD", format!("GLOBAL {}", msg)],
   179             Watch(name) => msg!["CMD", format!("WATCH {}", name)],
   181             Watch(name) => msg!["CMD", format!("WATCH {}", name)],
   180             ToggleServerRegisteredOnly => msg!["CMD", "REGISTERED_ONLY"],
   182             ToggleServerRegisteredOnly => msg!["CMD", "REGISTERED_ONLY"],
   181             SuperPower =>  msg!["CMD", "SUPER_POWER"],
   183             SuperPower => msg!["CMD", "SUPER_POWER"],
   182             Info(info) => msg!["CMD", format!("INFO {}", info)],
   184             Info(info) => msg!["CMD", format!("INFO {}", info)],
   183             Nick(nick) => msg!("NICK", nick),
   185             Nick(nick) => msg!("NICK", nick),
   184             Proto(version) => msg!["PROTO", version],
   186             Proto(version) => msg!["PROTO", version],
   185             Password(p, s) => msg!["PASSWORD", p, s],
   187             Password(p, s) => msg!["PASSWORD", p, s],
   186             Checker(i, n, p) => msg!["CHECKER", i, n, p],
   188             Checker(i, n, p) => msg!["CHECKER", i, n, p],
   187             List => msg!["LIST"],
   189             List => msg!["LIST"],
   188             Chat(msg) => msg!["CHAT", msg],
   190             Chat(msg) => msg!["CHAT", msg],
   189             CreateRoom(name, None) => msg!["CREATE_ROOM", name],
   191             CreateRoom(name, None) => msg!["CREATE_ROOM", name],
   190             CreateRoom(name, Some(password)) =>
   192             CreateRoom(name, Some(password)) => msg!["CREATE_ROOM", name, password],
   191                 msg!["CREATE_ROOM", name, password],
       
   192             JoinRoom(name, None) => msg!["JOIN_ROOM", name],
   193             JoinRoom(name, None) => msg!["JOIN_ROOM", name],
   193             JoinRoom(name, Some(password)) =>
   194             JoinRoom(name, Some(password)) => msg!["JOIN_ROOM", name, password],
   194                 msg!["JOIN_ROOM", name, password],
       
   195             Follow(name) => msg!["FOLLOW", name],
   195             Follow(name) => msg!["FOLLOW", name],
   196             Rnd(args) => if args.is_empty() {
   196             Rnd(args) => {
   197                 msg!["CMD", "RND"]
   197                 if args.is_empty() {
   198             } else {
   198                     msg!["CMD", "RND"]
   199                 msg!["CMD", format!("RND {}", args.join(" "))]
   199                 } else {
   200             },
   200                     msg!["CMD", format!("RND {}", args.join(" "))]
       
   201                 }
       
   202             }
   201             Kick(name) => msg!["KICK", name],
   203             Kick(name) => msg!["KICK", name],
   202             Ban(name, reason, time) => msg!["BAN", name, reason, time],
   204             Ban(name, reason, time) => msg!["BAN", name, reason, time],
   203             BanIP(ip, reason, time) => msg!["BAN_IP", ip, reason, time],
   205             BanIP(ip, reason, time) => msg!["BAN_IP", ip, reason, time],
   204             BanNick(nick, reason, time) =>
   206             BanNick(nick, reason, time) => msg!("BAN_NICK", nick, reason, time),
   205                 msg!("BAN_NICK", nick, reason, time),
       
   206             BanList => msg!["BANLIST"],
   207             BanList => msg!["BANLIST"],
   207             Unban(name) => msg!["UNBAN", name],
   208             Unban(name) => msg!["UNBAN", name],
   208             //SetServerVar(ServerVar), ???
   209             //SetServerVar(ServerVar), ???
   209             GetServerVar => msg!["GET_SERVER_VAR"],
   210             GetServerVar => msg!["GET_SERVER_VAR"],
   210             RestartServer => msg!["CMD", "RESTART_SERVER YES"],
   211             RestartServer => msg!["CMD", "RESTART_SERVER YES"],
   212             Part(None) => msg!["PART"],
   213             Part(None) => msg!["PART"],
   213             Part(Some(msg)) => msg!["PART", msg],
   214             Part(Some(msg)) => msg!["PART", msg],
   214             Cfg(config) => {
   215             Cfg(config) => {
   215                 let (name, args) = config.to_protocol();
   216                 let (name, args) = config.to_protocol();
   216                 msg!["CFG", name, args.join("\n")]
   217                 msg!["CFG", name, args.join("\n")]
   217             },
   218             }
   218             AddTeam(info) =>
   219             AddTeam(info) => msg![
   219                 msg!["ADD_TEAM", info.name, info.color, info.grave, info.fort,
   220                 "ADD_TEAM",
   220                      info.voice_pack, info.flag, info.difficulty,
   221                 info.name,
   221                      info.hedgehogs.iter()
   222                 info.color,
   222                         .flat_map(|h| several![&h.name[..], &h.hat[..]])
   223                 info.grave,
   223                         .collect::<Vec<_>>().join("\n")],
   224                 info.fort,
       
   225                 info.voice_pack,
       
   226                 info.flag,
       
   227                 info.difficulty,
       
   228                 info.hedgehogs
       
   229                     .iter()
       
   230                     .flat_map(|h| several![&h.name[..], &h.hat[..]])
       
   231                     .collect::<Vec<_>>()
       
   232                     .join("\n")
       
   233             ],
   224             RemoveTeam(name) => msg!["REMOVE_TEAM", name],
   234             RemoveTeam(name) => msg!["REMOVE_TEAM", name],
   225             SetHedgehogsNumber(team, number) => msg!["HH_NUM", team, number],
   235             SetHedgehogsNumber(team, number) => msg!["HH_NUM", team, number],
   226             SetTeamColor(team, color) => msg!["TEAM_COLOR", team, color],
   236             SetTeamColor(team, color) => msg!["TEAM_COLOR", team, color],
   227             ToggleReady => msg!["TOGGLE_READY"],
   237             ToggleReady => msg!["TOGGLE_READY"],
   228             StartGame => msg!["START_GAME"],
   238             StartGame => msg!["START_GAME"],
   232             ToggleRestrictTeams => msg!["TOGGLE_RESTRICT_TEAMS"],
   242             ToggleRestrictTeams => msg!["TOGGLE_RESTRICT_TEAMS"],
   233             ToggleRegisteredOnly => msg!["TOGGLE_REGISTERED_ONLY"],
   243             ToggleRegisteredOnly => msg!["TOGGLE_REGISTERED_ONLY"],
   234             RoomName(name) => msg!["ROOM_NAME", name],
   244             RoomName(name) => msg!["ROOM_NAME", name],
   235             Delegate(name) => msg!["CMD", format!("DELEGATE {}", name)],
   245             Delegate(name) => msg!["CMD", format!("DELEGATE {}", name)],
   236             TeamChat(msg) => msg!["TEAMCHAT", msg],
   246             TeamChat(msg) => msg!["TEAMCHAT", msg],
   237             MaxTeams(count) => msg!["CMD", format!("MAXTEAMS {}", count)] ,
   247             MaxTeams(count) => msg!["CMD", format!("MAXTEAMS {}", count)],
   238             Fix => msg!["CMD", "FIX"],
   248             Fix => msg!["CMD", "FIX"],
   239             Unfix => msg!["CMD", "UNFIX"],
   249             Unfix => msg!["CMD", "UNFIX"],
   240             Greeting(msg) => msg!["CMD", format!("GREETING {}", msg)],
   250             Greeting(msg) => msg!["CMD", format!("GREETING {}", msg)],
   241             //CallVote(Option<(String, Option<String>)>) =>, ??
   251             //CallVote(Option<(String, Option<String>)>) =>, ??
   242             Vote(msg) => msg!["CMD", format!("VOTE {}", if *msg {"YES"} else {"NO"})],
   252             Vote(msg) => msg!["CMD", format!("VOTE {}", if *msg { "YES" } else { "NO" })],
   243             ForceVote(msg) => msg!["CMD", format!("FORCE {}", if *msg {"YES"} else {"NO"})],
   253             ForceVote(msg) => msg!["CMD", format!("FORCE {}", if *msg { "YES" } else { "NO" })],
   244             Save(name, location) => msg!["CMD", format!("SAVE {} {}", name, location)],
   254             Save(name, location) => msg!["CMD", format!("SAVE {} {}", name, location)],
   245             Delete(name) => msg!["CMD", format!("DELETE {}", name)],
   255             Delete(name) => msg!["CMD", format!("DELETE {}", name)],
   246             SaveRoom(name) => msg!["CMD", format!("SAVEROOM {}", name)],
   256             SaveRoom(name) => msg!["CMD", format!("SAVEROOM {}", name)],
   247             LoadRoom(name) => msg!["CMD", format!("LOADROOM {}", name)],
   257             LoadRoom(name) => msg!["CMD", format!("LOADROOM {}", name)],
   248             Malformed => msg!["A", "QUICK", "BROWN", "HOG", "JUMPS", "OVER", "THE", "LAZY", "DOG"],
   258             Malformed => msg!["A", "QUICK", "BROWN", "HOG", "JUMPS", "OVER", "THE", "LAZY", "DOG"],
   249             Empty => msg![""],
   259             Empty => msg![""],
   250             _ => panic!("Protocol message not yet implemented")
   260             _ => panic!("Protocol message not yet implemented"),
   251         }
   261         }
   252     }
   262     }
   253 }
   263 }
   254 
   264 
   255 fn construct_message(header: &[&str], msg: &[String]) -> String {
   265 fn construct_message(header: &[&str], msg: &[String]) -> String {
   266             Ping => msg!["PING"],
   276             Ping => msg!["PING"],
   267             Pong => msg!["PONG"],
   277             Pong => msg!["PONG"],
   268             Connected(protocol_version) => msg![
   278             Connected(protocol_version) => msg![
   269                 "CONNECTED",
   279                 "CONNECTED",
   270                 "Hedgewars server https://www.hedgewars.org/",
   280                 "Hedgewars server https://www.hedgewars.org/",
   271                 protocol_version],
   281                 protocol_version
       
   282             ],
   272             Bye(msg) => msg!["BYE", msg],
   283             Bye(msg) => msg!["BYE", msg],
   273             Nick(nick) => msg!["NICK", nick],
   284             Nick(nick) => msg!["NICK", nick],
   274             Proto(proto) => msg!["PROTO", proto],
   285             Proto(proto) => msg!["PROTO", proto],
   275             ServerAuth(hash) => msg!["SERVER_AUTH", hash],
   286             ServerAuth(hash) => msg!["SERVER_AUTH", hash],
   276             LobbyLeft(nick, msg) => msg!["LOBBY:LEFT", nick, msg],
   287             LobbyLeft(nick, msg) => msg!["LOBBY:LEFT", nick, msg],
   277             LobbyJoined(nicks) =>
   288             LobbyJoined(nicks) => construct_message(&["LOBBY:JOINED"], &nicks),
   278                 construct_message(&["LOBBY:JOINED"], &nicks),
   289             ClientFlags(flags, nicks) => construct_message(&["CLIENT_FLAGS", flags], &nicks),
   279             ClientFlags(flags, nicks) =>
   290             Rooms(info) => construct_message(&["ROOMS"], &info),
   280                 construct_message(&["CLIENT_FLAGS", flags], &nicks),
   291             RoomAdd(info) => construct_message(&["ROOM", "ADD"], &info),
   281             Rooms(info) =>
   292             RoomJoined(nicks) => construct_message(&["JOINED"], &nicks),
   282                 construct_message(&["ROOMS"], &info),
       
   283             RoomAdd(info) =>
       
   284                 construct_message(&["ROOM", "ADD"], &info),
       
   285             RoomJoined(nicks) =>
       
   286                 construct_message(&["JOINED"], &nicks),
       
   287             RoomLeft(nick, msg) => msg!["LEFT", nick, msg],
   293             RoomLeft(nick, msg) => msg!["LEFT", nick, msg],
   288             RoomRemove(name) => msg!["ROOM", "DEL", name],
   294             RoomRemove(name) => msg!["ROOM", "DEL", name],
   289             RoomUpdated(name, info) =>
   295             RoomUpdated(name, info) => construct_message(&["ROOM", "UPD", name], &info),
   290                 construct_message(&["ROOM", "UPD", name], &info),
   296             TeamAdd(info) => construct_message(&["ADD_TEAM"], &info),
   291             TeamAdd(info) =>
       
   292                 construct_message(&["ADD_TEAM"], &info),
       
   293             TeamRemove(name) => msg!["REMOVE_TEAM", name],
   297             TeamRemove(name) => msg!["REMOVE_TEAM", name],
   294             TeamAccepted(name) => msg!["TEAM_ACCEPTED", name],
   298             TeamAccepted(name) => msg!["TEAM_ACCEPTED", name],
   295             TeamColor(name, color) => msg!["TEAM_COLOR", name, color],
   299             TeamColor(name, color) => msg!["TEAM_COLOR", name, color],
   296             HedgehogsNumber(name, number) => msg!["HH_NUM", name, number],
   300             HedgehogsNumber(name, number) => msg!["HH_NUM", name, number],
   297             ConfigEntry(name, values) =>
   301             ConfigEntry(name, values) => construct_message(&["CFG", name], &values),
   298                 construct_message(&["CFG", name], &values),
       
   299             Kicked => msg!["KICKED"],
   302             Kicked => msg!["KICKED"],
   300             RunGame => msg!["RUN_GAME"],
   303             RunGame => msg!["RUN_GAME"],
   301             ForwardEngineMessage(em) =>
   304             ForwardEngineMessage(em) => construct_message(&["EM"], &em),
   302                 construct_message(&["EM"], &em),
       
   303             RoundFinished => msg!["ROUND_FINISHED"],
   305             RoundFinished => msg!["ROUND_FINISHED"],
   304             ChatMsg {nick, msg} => msg!["CHAT", nick, msg],
   306             ChatMsg { nick, msg } => msg!["CHAT", nick, msg],
   305             ServerMessage(msg) => msg!["SERVER_MESSAGE", msg],
   307             ServerMessage(msg) => msg!["SERVER_MESSAGE", msg],
   306             Notice(msg) => msg!["NOTICE", msg],
   308             Notice(msg) => msg!["NOTICE", msg],
   307             Warning(msg) => msg!["WARNING", msg],
   309             Warning(msg) => msg!["WARNING", msg],
   308             Error(msg) => msg!["ERROR", msg],
   310             Error(msg) => msg!["ERROR", msg],
   309 
   311 
   310             LegacyReady(is_ready, nicks) =>
   312             LegacyReady(is_ready, nicks) => {
   311                 construct_message(&[if *is_ready {"READY"} else {"NOT_READY"}], &nicks),
   313                 construct_message(&[if *is_ready { "READY" } else { "NOT_READY" }], &nicks)
       
   314             }
   312 
   315 
   313             _ => msg!["ERROR", "UNIMPLEMENTED"],
   316             _ => msg!["ERROR", "UNIMPLEMENTED"],
   314         }
   317         }
   315     }
   318     }
   316 }
   319 }