67 LoadRoom(String), |
67 LoadRoom(String), |
68 Malformed, |
68 Malformed, |
69 Empty, |
69 Empty, |
70 } |
70 } |
71 |
71 |
|
72 #[derive(Debug)] |
72 pub enum HWServerMessage { |
73 pub enum HWServerMessage { |
73 Ping, |
74 Ping, |
74 Pong, |
75 Pong, |
75 Bye(String), |
76 Bye(String), |
76 Nick(String), |
77 Nick(String), |
77 LobbyLeft(String), |
78 Proto(u32), |
|
79 LobbyLeft(String, String), |
78 LobbyJoined(Vec<String>), |
80 LobbyJoined(Vec<String>), |
79 ChatMsg(String, String), |
81 ChatMsg(String, String), |
80 ClientFlags(String, Vec<String>), |
82 ClientFlags(String, Vec<String>), |
|
83 Rooms(Vec<String>), |
|
84 RoomAdd(Vec<String>), |
|
85 RoomJoined(Vec<String>), |
|
86 RoomLeft(String, String), |
|
87 RoomRemove(String), |
|
88 RoomUpdated(String, Vec<String>), |
|
89 ServerMessage(String), |
81 |
90 |
82 Warning(String), |
91 Warning(String), |
|
92 Error(String), |
83 Connected(u32), |
93 Connected(u32), |
84 Unreachable, |
94 Unreachable, |
85 } |
|
86 |
|
87 fn construct_message(msg: & [&str]) -> String { |
|
88 let mut m = String::with_capacity(64); |
|
89 |
|
90 for s in msg { |
|
91 m.push_str(s); |
|
92 m.push('\n'); |
|
93 } |
|
94 m.push('\n'); |
|
95 |
|
96 m |
|
97 } |
95 } |
98 |
96 |
99 impl<'a> HWProtocolMessage { |
97 impl<'a> HWProtocolMessage { |
100 pub fn to_raw_protocol(&self) -> String { |
98 pub fn to_raw_protocol(&self) -> String { |
101 use self::HWProtocolMessage::*; |
99 use self::HWProtocolMessage::*; |
102 match *self { |
100 match self { |
103 Ping => "PING\n\n".to_string(), |
101 Ping => "PING\n\n".to_string(), |
104 Pong => "PONG\n\n".to_string(), |
102 Pong => "PONG\n\n".to_string(), |
105 Quit(None) => format!("QUIT\n\n"), |
103 Quit(None) => format!("QUIT\n\n"), |
106 Quit(Some(ref msg)) => format!("QUIT\n{}\n\n", msg), |
104 Quit(Some(msg)) => format!("QUIT\n{}\n\n", msg), |
107 Global(ref msg) => format!("CMD\nGLOBAL\n{}\n\n", msg), |
105 Global(msg) => format!("CMD\nGLOBAL\n{}\n\n", msg), |
108 Watch(ref name) => format!("CMD\nWATCH\n{}\n\n", name), |
106 Watch(name) => format!("CMD\nWATCH\n{}\n\n", name), |
109 ToggleServerRegisteredOnly => "CMD\nREGISTERED_ONLY\n\n".to_string(), |
107 ToggleServerRegisteredOnly => "CMD\nREGISTERED_ONLY\n\n".to_string(), |
110 SuperPower => "CMD\nSUPER_POWER\n\n".to_string(), |
108 SuperPower => "CMD\nSUPER_POWER\n\n".to_string(), |
111 Info(ref info) => format!("CMD\nINFO\n{}\n\n", info), |
109 Info(info) => format!("CMD\nINFO\n{}\n\n", info), |
112 Nick(ref nick) => format!("NICK\n{}\n\n", nick), |
110 Nick(nick) => format!("NICK\n{}\n\n", nick), |
113 Proto(version) => format!("PROTO\n{}\n\n", version), |
111 Proto(version) => format!("PROTO\n{}\n\n", version), |
114 Password(ref p, ref s) => format!("PASSWORD\n{}\n{}\n\n", p, s), //? |
112 Password(p, s) => format!("PASSWORD\n{}\n{}\n\n", p, s), //? |
115 Checker(i, ref n, ref p) => |
113 Checker(i, n, p) => |
116 format!("CHECKER\n{}\n{}\n{}\n\n", i, n, p), //?, |
114 format!("CHECKER\n{}\n{}\n{}\n\n", i, n, p), //?, |
117 List => "LIST\n\n".to_string(), |
115 List => "LIST\n\n".to_string(), |
118 Chat(ref msg) => format!("CHAT\n{}\n\n", msg), |
116 Chat(msg) => format!("CHAT\n{}\n\n", msg), |
119 CreateRoom(ref name, None) => |
117 CreateRoom(name, None) => |
120 format!("CREATE_ROOM\n{}\n\n", name), |
118 format!("CREATE_ROOM\n{}\n\n", name), |
121 CreateRoom(ref name, Some(ref password)) => |
119 CreateRoom(name, Some(password)) => |
122 format!("CREATE_ROOM\n{}\n{}\n\n", name, password), |
120 format!("CREATE_ROOM\n{}\n{}\n\n", name, password), |
123 Join(ref name, None) => |
121 JoinRoom(name, None) => |
124 format!("JOIN\n{}\n\n", name), |
122 format!("JOIN\n{}\n\n", name), |
125 Join(ref name, Some(ref arg)) => |
123 JoinRoom(name, Some(arg)) => |
126 format!("JOIN\n{}\n{}\n\n", name, arg), |
124 format!("JOIN\n{}\n{}\n\n", name, arg), |
127 Follow(ref name) => |
125 Follow(name) => |
128 format!("FOLLOW\n{}\n\n", name), |
126 format!("FOLLOW\n{}\n\n", name), |
129 //Rnd(Vec<String>), ??? |
127 //Rnd(Vec<String>), ??? |
130 Kick(ref name) => format!("KICK\n{}\n\n", name), |
128 Kick(name) => format!("KICK\n{}\n\n", name), |
131 Ban(ref name, ref reason, time) => |
129 Ban(name, reason, time) => |
132 format!("BAN\n{}\n{}\n{}\n\n", name, reason, time), |
130 format!("BAN\n{}\n{}\n{}\n\n", name, reason, time), |
133 BanIP(ref ip, ref reason, time) => |
131 BanIP(ip, reason, time) => |
134 format!("BAN_IP\n{}\n{}\n{}\n\n", ip, reason, time), |
132 format!("BAN_IP\n{}\n{}\n{}\n\n", ip, reason, time), |
135 BanNick(ref nick, ref reason, time) => |
133 BanNick(nick, reason, time) => |
136 format!("BAN_NICK\n{}\n{}\n{}\n\n", nick, reason, time), |
134 format!("BAN_NICK\n{}\n{}\n{}\n\n", nick, reason, time), |
137 BanList => "BANLIST\n\n".to_string(), |
135 BanList => "BANLIST\n\n".to_string(), |
138 Unban(ref name) => format!("UNBAN\n{}\n\n", name), |
136 Unban(name) => format!("UNBAN\n{}\n\n", name), |
139 //SetServerVar(ServerVar), ??? |
137 //SetServerVar(ServerVar), ??? |
140 GetServerVar => "GET_SERVER_VAR\n\n".to_string(), |
138 GetServerVar => "GET_SERVER_VAR\n\n".to_string(), |
141 RestartServer => "CMD\nRESTART_SERVER\nYES\n\n".to_string(), |
139 RestartServer => "CMD\nRESTART_SERVER\nYES\n\n".to_string(), |
142 Stats => "CMD\nSTATS\n\n".to_string(), |
140 Stats => "CMD\nSTATS\n\n".to_string(), |
143 Part(None) => "CMD\nPART\n\n".to_string(), |
141 Part(None) => "CMD\nPART\n\n".to_string(), |
144 Part(Some(ref msg)) => format!("CMD\nPART\n{}\n\n", msg), |
142 Part(Some(msg)) => format!("CMD\nPART\n{}\n\n", msg), |
145 //Cfg(GameCfg) ?? |
143 //Cfg(GameCfg) ?? |
146 //AddTeam(TeamInfo) ??, |
144 //AddTeam(TeamInfo) ??, |
147 RemoveTeam(ref name) => format!("REMOVE_TEAM\n{}\n\n", name), |
145 RemoveTeam(name) => format!("REMOVE_TEAM\n{}\n\n", name), |
148 //SetHedgehogsNumber(String, u8), ?? |
146 //SetHedgehogsNumber(String, u8), ?? |
149 //SetTeamColor(String, u8), ?? |
147 //SetTeamColor(String, u8), ?? |
150 ToggleReady => "TOGGLE_READY\n\n".to_string(), |
148 ToggleReady => "TOGGLE_READY\n\n".to_string(), |
151 StartGame => "START_GAME\n\n".to_string(), |
149 StartGame => "START_GAME\n\n".to_string(), |
152 EngineMessage(ref msg) => format!("EM\n{}\n\n", msg), |
150 EngineMessage(msg) => format!("EM\n{}\n\n", msg), |
153 RoundFinished => "ROUNDFINISHED\n\n".to_string(), |
151 RoundFinished => "ROUNDFINISHED\n\n".to_string(), |
154 ToggleRestrictJoin => "TOGGLE_RESTRICT_JOINS\n\n".to_string(), |
152 ToggleRestrictJoin => "TOGGLE_RESTRICT_JOINS\n\n".to_string(), |
155 ToggleRestrictTeams => "TOGGLE_RESTRICT_TEAMS\n\n".to_string(), |
153 ToggleRestrictTeams => "TOGGLE_RESTRICT_TEAMS\n\n".to_string(), |
156 ToggleRegisteredOnly => "TOGGLE_REGISTERED_ONLY\n\n".to_string(), |
154 ToggleRegisteredOnly => "TOGGLE_REGISTERED_ONLY\n\n".to_string(), |
157 RoomName(ref name) => format!("ROOM_NAME\n{}\n\n", name), |
155 RoomName(name) => format!("ROOM_NAME\n{}\n\n", name), |
158 Delegate(ref name) => format!("CMD\nDELEGATE\n{}\n\n", name), |
156 Delegate(name) => format!("CMD\nDELEGATE\n{}\n\n", name), |
159 TeamChat(ref msg) => format!("TEAMCHAT\n{}\n\n", msg), |
157 TeamChat(msg) => format!("TEAMCHAT\n{}\n\n", msg), |
160 MaxTeams(count) => format!("CMD\nMAXTEAMS\n{}\n\n", count) , |
158 MaxTeams(count) => format!("CMD\nMAXTEAMS\n{}\n\n", count) , |
161 Fix => "CMD\nFIX\n\n".to_string(), |
159 Fix => "CMD\nFIX\n\n".to_string(), |
162 Unfix => "CMD\nUNFIX\n\n".to_string(), |
160 Unfix => "CMD\nUNFIX\n\n".to_string(), |
163 Greeting(ref msg) => format!("CMD\nGREETING\n{}\n\n", msg), |
161 Greeting(msg) => format!("CMD\nGREETING\n{}\n\n", msg), |
164 //CallVote(Option<(String, Option<String>)>) =>, ?? |
162 //CallVote(Option<(String, Option<String>)>) =>, ?? |
165 Vote(ref msg) => format!("CMD\nVOTE\n{}\n\n", msg), |
163 Vote(msg) => format!("CMD\nVOTE\n{}\n\n", msg), |
166 ForceVote(ref msg) => format!("CMD\nFORCE\n{}\n\n", msg), |
164 ForceVote(msg) => format!("CMD\nFORCE\n{}\n\n", msg), |
167 //Save(String, String), ?? |
165 //Save(String, String), ?? |
168 Delete(ref room) => format!("CMD\nDELETE\n{}\n\n", room), |
166 Delete(room) => format!("CMD\nDELETE\n{}\n\n", room), |
169 SaveRoom(ref room) => format!("CMD\nSAVEROOM\n{}\n\n", room), |
167 SaveRoom(room) => format!("CMD\nSAVEROOM\n{}\n\n", room), |
170 LoadRoom(ref room) => format!("CMD\nLOADROOM\n{}\n\n", room), |
168 LoadRoom(room) => format!("CMD\nLOADROOM\n{}\n\n", room), |
171 Malformed => "A\nQUICK\nBROWN\nHOG\nJUMPS\nOVER\nTHE\nLAZY\nDOG\n\n".to_string(), |
169 Malformed => "A\nQUICK\nBROWN\nHOG\nJUMPS\nOVER\nTHE\nLAZY\nDOG\n\n".to_string(), |
172 Empty => "\n\n".to_string(), |
170 Empty => "\n\n".to_string(), |
173 _ => panic!("Protocol message not yet implemented") |
171 _ => panic!("Protocol message not yet implemented") |
174 } |
172 } |
175 } |
173 } |
176 } |
174 } |
177 |
175 |
|
176 macro_rules! const_braces { |
|
177 ($e: expr) => { "{}\n" } |
|
178 } |
|
179 |
|
180 macro_rules! msg { |
|
181 [$($part: expr),*] => { |
|
182 format!(concat!($(const_braces!($part)),*, "\n"), $($part),*); |
|
183 }; |
|
184 } |
|
185 |
|
186 fn construct_message(mut msg: Vec<&str>) -> String { |
|
187 msg.push("\n"); |
|
188 msg.join("\n") |
|
189 } |
|
190 |
178 impl HWServerMessage { |
191 impl HWServerMessage { |
179 pub fn to_raw_protocol(&self) -> String { |
192 pub fn to_raw_protocol(&self) -> String { |
180 use self::HWServerMessage::*; |
193 use self::HWServerMessage::*; |
181 match self { |
194 match self { |
182 &Ping => "PING\n\n".to_string(), |
195 Ping => msg!["PING"], |
183 &Pong => "PONG\n\n".to_string(), |
196 Pong => msg!["PONG"], |
184 &Connected(protocol_version) |
197 Connected(protocol_version) => msg![ |
185 => construct_message(&[ |
198 "CONNECTED", |
186 "CONNECTED", |
199 "Hedgewars server http://www.hedgewars.org/", |
187 "Hedgewars server http://www.hedgewars.org/", |
200 protocol_version], |
188 &protocol_version.to_string() |
201 Bye(msg) => msg!["BYE", msg], |
189 ]), |
202 Nick(nick) => msg!["NICK", nick], |
190 &Bye(ref msg) => construct_message(&["BYE", &msg]), |
203 Proto(proto) => msg!["PROTO", proto], |
191 &Nick(ref nick) => construct_message(&["NICK", &nick]), |
204 LobbyLeft(nick, msg) => msg!["LOBBY:LEFT", nick, msg], |
192 &LobbyLeft(ref nick) |
205 LobbyJoined(nicks) => { |
193 => construct_message(&["LOBBY_LEFT", &nick]), |
|
194 &LobbyJoined(ref nicks) |
|
195 => { |
|
196 let mut v = vec!["LOBBY:JOINED"]; |
206 let mut v = vec!["LOBBY:JOINED"]; |
197 v.extend(nicks.iter().map(|n| { &n[..] })); |
207 v.extend(nicks.iter().map(|n| { &n[..] })); |
198 construct_message(&v) |
208 construct_message(v) |
199 }, |
209 }, |
200 &ClientFlags(ref flags, ref nicks) |
210 ClientFlags(flags, nicks) |
201 => { |
211 => { |
202 let mut v = vec!["CLIENT_FLAGS"]; |
212 let mut v = vec!["CLIENT_FLAGS"]; |
203 v.push(&flags[..]); |
213 v.push(&flags[..]); |
204 v.extend(nicks.iter().map(|n| { &n[..] })); |
214 v.extend(nicks.iter().map(|n| { &n[..] })); |
205 construct_message(&v) |
215 construct_message(v) |
206 }, |
216 }, |
207 &ChatMsg(ref nick, ref msg) |
217 Rooms(info) => { |
208 => construct_message(&["CHAT", &nick, &msg]), |
218 let mut v = vec!["ROOMS"]; |
209 &Warning(ref msg) |
219 v.extend(info.iter().map(|n| { &n[..] })); |
210 => construct_message(&["WARNING", &msg]), |
220 construct_message(v) |
211 _ => construct_message(&["ERROR", "UNIMPLEMENTED"]), |
221 }, |
|
222 RoomAdd(info) => { |
|
223 let mut v = vec!["ROOM", "ADD"]; |
|
224 v.extend(info.iter().map(|n| { &n[..] })); |
|
225 construct_message(v) |
|
226 }, |
|
227 RoomJoined(nicks) => { |
|
228 let mut v = vec!["JOINED"]; |
|
229 v.extend(nicks.iter().map(|n| { &n[..] })); |
|
230 construct_message(v) |
|
231 }, |
|
232 RoomLeft(nick, msg) => msg!["LEFT", nick, msg], |
|
233 RoomRemove(name) => msg!["ROOM", "DEL", name], |
|
234 RoomUpdated(name, info) => { |
|
235 let mut v = vec!["ROOM", "UPD", name]; |
|
236 v.extend(info.iter().map(|n| { &n[..] })); |
|
237 construct_message(v) |
|
238 } |
|
239 ChatMsg(nick, msg) => msg!["CHAT", nick, msg], |
|
240 ServerMessage(msg) => msg!["SERVER_MESSAGE", msg], |
|
241 Warning(msg) => msg!["WARNING", msg], |
|
242 Error(msg) => msg!["ERROR", msg], |
|
243 _ => msg!["ERROR", "UNIMPLEMENTED"], |
212 } |
244 } |
213 } |
245 } |
214 } |
246 } |