1 use crate::protocol::messages::server_chat; |
1 use crate::protocol::messages::server_chat; |
2 use crate::server::client::HWClient; |
2 use crate::server::client::HWClient; |
3 use crate::server::coretypes::ClientId; |
3 use crate::server::coretypes::ClientId; |
|
4 use crate::server::coretypes::GameCfg; |
|
5 use crate::server::coretypes::RoomId; |
|
6 use crate::server::coretypes::Vote; |
|
7 use crate::server::coretypes::VoteType; |
4 use crate::server::room::HWRoom; |
8 use crate::server::room::HWRoom; |
5 use crate::utils::to_engine_msg; |
9 use crate::utils::to_engine_msg; |
6 use crate::{ |
10 use crate::{ |
7 protocol::messages::{ |
11 protocol::messages::{ |
8 HWProtocolMessage::{self, Rnd}, |
12 HWProtocolMessage::{self, Rnd}, |
9 HWServerMessage::{ |
13 HWServerMessage::{ |
10 self, Bye, ChatMsg, ClientFlags, ForwardEngineMessage, LobbyJoined, LobbyLeft, Notice, |
14 self, Bye, ChatMsg, ClientFlags, ForwardEngineMessage, HedgehogsNumber, Kicked, |
11 RoomLeft, RoomRemove, RoomUpdated, Rooms, ServerMessage, TeamRemove, |
15 LobbyJoined, LobbyLeft, Notice, RoomLeft, RoomRemove, RoomUpdated, Rooms, |
|
16 ServerMessage, TeamRemove, |
12 }, |
17 }, |
13 }, |
18 }, |
14 server::{actions::Action, core::HWServer}, |
19 server::{actions::Action, core::HWServer}, |
15 }; |
20 }; |
16 use rand::{self, thread_rng, Rng}; |
21 use rand::{self, thread_rng, Rng}; |
189 } |
194 } |
190 |
195 |
191 pub fn get_room_update( |
196 pub fn get_room_update( |
192 room_name: Option<String>, |
197 room_name: Option<String>, |
193 room: &HWRoom, |
198 room: &HWRoom, |
194 client: Option<&HWClient>, |
199 master: Option<&HWClient>, |
195 response: &mut super::Response, |
200 response: &mut super::Response, |
196 ) { |
201 ) { |
197 let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(client)); |
202 let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master)); |
198 response.add(update_msg.send_all().with_protocol(room.protocol_number)); |
203 response.add(update_msg.send_all().with_protocol(room.protocol_number)); |
199 } |
204 } |
200 |
205 |
201 pub fn add_vote(room: &mut HWRoom, response: &mut super::Response, vote: bool, is_forced: bool) { |
206 pub fn apply_voting_result( |
|
207 server: &mut HWServer, |
|
208 room_id: RoomId, |
|
209 response: &mut super::Response, |
|
210 kind: VoteType, |
|
211 ) { |
|
212 let client_id = response.client_id; |
|
213 |
|
214 match kind { |
|
215 VoteType::Kick(nick) => { |
|
216 if let Some(client) = server.find_client(&nick) { |
|
217 if client.room_id == Some(room_id) { |
|
218 let id = client.id; |
|
219 response.add(Kicked.send_self()); |
|
220 exit_room( |
|
221 &mut server.clients[client_id], |
|
222 &mut server.rooms[room_id], |
|
223 response, |
|
224 "kicked", |
|
225 ); |
|
226 } |
|
227 } |
|
228 } |
|
229 VoteType::Map(None) => (), |
|
230 VoteType::Map(Some(name)) => { |
|
231 if let Some(location) = server.rooms[room_id].load_config(&name) { |
|
232 response.add( |
|
233 server_chat(location.to_string()) |
|
234 .send_all() |
|
235 .in_room(room_id), |
|
236 ); |
|
237 get_room_update( |
|
238 None, |
|
239 &server.rooms[room_id], |
|
240 Some(&server.clients[client_id]), |
|
241 response, |
|
242 ); |
|
243 |
|
244 for (_, c) in server.clients.iter() { |
|
245 if c.room_id == Some(room_id) { |
|
246 /*SendRoomData { |
|
247 to: c.id, |
|
248 teams: false, |
|
249 config: true, |
|
250 flags: false, |
|
251 }*/ |
|
252 } |
|
253 } |
|
254 } |
|
255 } |
|
256 VoteType::Pause => { |
|
257 if let Some(ref mut info) = server.rooms[room_id].game_info { |
|
258 info.is_paused = !info.is_paused; |
|
259 response.add( |
|
260 server_chat("Pause toggled.".to_string()) |
|
261 .send_all() |
|
262 .in_room(room_id), |
|
263 ); |
|
264 response.add( |
|
265 ForwardEngineMessage(vec![to_engine_msg(once(b'I'))]) |
|
266 .send_all() |
|
267 .in_room(room_id), |
|
268 ); |
|
269 } |
|
270 } |
|
271 VoteType::NewSeed => { |
|
272 let seed = thread_rng().gen_range(0, 1_000_000_000).to_string(); |
|
273 let cfg = GameCfg::Seed(seed); |
|
274 response.add(cfg.to_server_msg().send_all().in_room(room_id)); |
|
275 server.rooms[room_id].set_config(cfg); |
|
276 } |
|
277 VoteType::HedgehogsPerTeam(number) => { |
|
278 let r = &mut server.rooms[room_id]; |
|
279 let nicks = r.set_hedgehogs_number(number); |
|
280 |
|
281 response.extend( |
|
282 nicks |
|
283 .into_iter() |
|
284 .map(|n| HedgehogsNumber(n, number).send_all().in_room(room_id)), |
|
285 ); |
|
286 } |
|
287 } |
|
288 } |
|
289 |
|
290 fn add_vote(room: &mut HWRoom, response: &mut super::Response, vote: Vote) -> Option<bool> { |
202 let client_id = response.client_id; |
291 let client_id = response.client_id; |
203 let mut result = None; |
292 let mut result = None; |
|
293 |
204 if let Some(ref mut voting) = room.voting { |
294 if let Some(ref mut voting) = room.voting { |
205 if is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) { |
295 if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) { |
206 response.add(server_chat("Your vote has been counted.".to_string()).send_self()); |
296 response.add(server_chat("Your vote has been counted.".to_string()).send_self()); |
207 voting.votes.push((client_id, vote)); |
297 voting.votes.push((client_id, vote.is_pro)); |
208 let i = voting.votes.iter(); |
298 let i = voting.votes.iter(); |
209 let pro = i.clone().filter(|(_, v)| *v).count(); |
299 let pro = i.clone().filter(|(_, v)| *v).count(); |
210 let contra = i.filter(|(_, v)| !*v).count(); |
300 let contra = i.filter(|(_, v)| !*v).count(); |
211 let success_quota = voting.voters.len() / 2 + 1; |
301 let success_quota = voting.voters.len() / 2 + 1; |
212 if is_forced && vote || pro >= success_quota { |
302 if vote.is_forced && vote.is_pro || pro >= success_quota { |
213 result = Some(true); |
303 result = Some(true); |
214 } else if is_forced && !vote || contra > voting.voters.len() - success_quota { |
304 } else if vote.is_forced && !vote.is_pro || contra > voting.voters.len() - success_quota |
|
305 { |
215 result = Some(false); |
306 result = Some(false); |
216 } |
307 } |
217 } else { |
308 } else { |
218 response.add(server_chat("You already have voted.".to_string()).send_self()); |
309 response.add(server_chat("You already have voted.".to_string()).send_self()); |
219 } |
310 } |
220 } else { |
311 } else { |
221 response.add(server_chat("There's no voting going on.".to_string()).send_self()); |
312 response.add(server_chat("There's no voting going on.".to_string()).send_self()); |
222 } |
313 } |
223 |
314 |
224 if let Some(res) = result { |
315 result |
225 response.add( |
316 } |
226 server_chat("Voting closed.".to_string()) |
317 |
227 .send_all() |
318 pub fn submit_vote(server: &mut HWServer, vote: Vote, response: &mut super::Response) { |
228 .in_room(room.id), |
319 let client_id = response.client_id; |
229 ); |
320 let client = &server.clients[client_id]; |
230 let voting = replace(&mut room.voting, None).unwrap(); |
321 |
231 if res { |
322 if let Some(room_id) = client.room_id { |
232 //ApplyVoting(voting.kind, room.id)); |
323 let room = &mut server.rooms[room_id]; |
|
324 |
|
325 if let Some(res) = add_vote(room, response, vote) { |
|
326 response.add( |
|
327 server_chat("Voting closed.".to_string()) |
|
328 .send_all() |
|
329 .in_room(room.id), |
|
330 ); |
|
331 let voting = replace(&mut room.voting, None).unwrap(); |
|
332 if res { |
|
333 apply_voting_result(server, room_id, response, voting.kind); |
|
334 } |
233 } |
335 } |
234 } |
336 } |
235 } |
337 } |
236 |
338 |
237 #[cfg(test)] |
339 #[cfg(test)] |