author | alfadur <mail@none> |
Sat, 21 Dec 2019 00:26:17 +0300 | |
changeset 15518 | e705d30e0f10 |
parent 15516 | b907b9071ec5 |
child 15519 | b3157d218ae2 |
permissions | -rw-r--r-- |
15482 | 1 |
use super::{common::rnd_reply, strings::*}; |
13666 | 2 |
use crate::{ |
15074 | 3 |
core::{ |
15075 | 4 |
room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM}, |
15492 | 5 |
server::{ |
15518 | 6 |
ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, ModifyTeamError, |
7 |
StartGameError, |
|
15492 | 8 |
}, |
15074 | 9 |
types, |
10 |
types::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM}, |
|
15075 | 11 |
}, |
12 |
protocol::messages::{ |
|
13 |
add_flags, remove_flags, server_chat, HwProtocolMessage, HwServerMessage::*, |
|
14 |
ProtocolFlags as Flags, |
|
13666 | 15 |
}, |
15482 | 16 |
utils::{is_name_illegal, to_engine_msg}, |
13416 | 17 |
}; |
14457 | 18 |
use base64::{decode, encode}; |
13805 | 19 |
use log::*; |
15026 | 20 |
use std::{cmp::min, iter::once, mem::swap}; |
13423 | 21 |
|
22 |
#[derive(Clone)] |
|
23 |
struct ByMsg<'a> { |
|
14457 | 24 |
messages: &'a [u8], |
13423 | 25 |
} |
26 |
||
14457 | 27 |
impl<'a> Iterator for ByMsg<'a> { |
28 |
type Item = &'a [u8]; |
|
13423 | 29 |
|
30 |
fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
|
31 |
if let Some(size) = self.messages.get(0) { |
|
32 |
let (msg, next) = self.messages.split_at(*size as usize + 1); |
|
33 |
self.messages = next; |
|
34 |
Some(msg) |
|
35 |
} else { |
|
36 |
None |
|
37 |
} |
|
38 |
} |
|
39 |
} |
|
40 |
||
13524 | 41 |
fn by_msg(source: &[u8]) -> ByMsg { |
14457 | 42 |
ByMsg { messages: source } |
13423 | 43 |
} |
44 |
||
45 |
const VALID_MESSAGES: &[u8] = |
|
46 |
b"M#+LlRrUuDdZzAaSjJ,NpPwtgfhbc12345\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A"; |
|
47 |
const NON_TIMED_MESSAGES: &[u8] = b"M#hb"; |
|
48 |
||
15482 | 49 |
/*#[cfg(canhazslicepatterns)] |
13423 | 50 |
fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool { |
13424 | 51 |
match msg { |
15326 | 52 |
[size, typ, body..MAX] => { |
14457 | 53 |
VALID_MESSAGES.contains(typ) |
54 |
&& match body { |
|
15439 | 55 |
[1..=MAX_HEDGEHOGS_PER_TEAM, team, ..] if *typ == b'h' => { |
14457 | 56 |
team_indices.contains(team) |
57 |
} |
|
58 |
_ => *typ != b'h', |
|
59 |
} |
|
60 |
} |
|
61 |
_ => false, |
|
13423 | 62 |
} |
15482 | 63 |
}*/ |
13423 | 64 |
|
13666 | 65 |
fn is_msg_valid(msg: &[u8], _team_indices: &[u8]) -> bool { |
13429 | 66 |
if let Some(typ) = msg.get(1) { |
67 |
VALID_MESSAGES.contains(typ) |
|
68 |
} else { |
|
69 |
false |
|
70 |
} |
|
71 |
} |
|
72 |
||
13423 | 73 |
fn is_msg_empty(msg: &[u8]) -> bool { |
13429 | 74 |
msg.get(1).filter(|t| **t == b'+').is_some() |
13423 | 75 |
} |
12147 | 76 |
|
13443 | 77 |
fn is_msg_timed(msg: &[u8]) -> bool { |
14457 | 78 |
msg.get(1) |
79 |
.filter(|t| !NON_TIMED_MESSAGES.contains(t)) |
|
80 |
.is_some() |
|
13443 | 81 |
} |
82 |
||
13480 | 83 |
fn voting_description(kind: &VoteType) -> String { |
14457 | 84 |
format!( |
85 |
"New voting started: {}", |
|
86 |
match kind { |
|
87 |
VoteType::Kick(nick) => format!("kick {}", nick), |
|
88 |
VoteType::Map(name) => format!("map {}", name.as_ref().unwrap()), |
|
89 |
VoteType::Pause => "pause".to_string(), |
|
90 |
VoteType::NewSeed => "new seed".to_string(), |
|
91 |
VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number), |
|
92 |
} |
|
93 |
) |
|
13480 | 94 |
} |
95 |
||
15075 | 96 |
fn room_message_flag(msg: &HwProtocolMessage) -> RoomFlags { |
97 |
use crate::protocol::messages::HwProtocolMessage::*; |
|
13523 | 98 |
match msg { |
99 |
ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN, |
|
100 |
ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD, |
|
101 |
ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS, |
|
14457 | 102 |
_ => RoomFlags::empty(), |
13523 | 103 |
} |
104 |
} |
|
105 |
||
14457 | 106 |
pub fn handle( |
15075 | 107 |
server: &mut HwServer, |
14457 | 108 |
client_id: ClientId, |
14671
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14457
diff
changeset
|
109 |
response: &mut super::Response, |
14457 | 110 |
room_id: RoomId, |
15075 | 111 |
message: HwProtocolMessage, |
14457 | 112 |
) { |
15482 | 113 |
let (client, room) = server.client_and_room_mut(client_id, room_id); |
14697 | 114 |
|
15075 | 115 |
use crate::protocol::messages::HwProtocolMessage::*; |
12147 | 116 |
match message { |
14675
dfe652c53470
Server action refactoring part 6 of N
alfadur <mail@none>
parents:
14671
diff
changeset
|
117 |
Part(msg) => { |
14697 | 118 |
let msg = match msg { |
119 |
Some(s) => format!("part: {}", s), |
|
120 |
None => "part".to_string(), |
|
121 |
}; |
|
15482 | 122 |
|
15492 | 123 |
let result = server.leave_room(client_id); |
124 |
super::common::get_room_leave_data(server, room_id, &msg, result, response); |
|
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
125 |
} |
13416 | 126 |
Chat(msg) => { |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
127 |
response.add( |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
128 |
ChatMsg { |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
129 |
nick: client.nick.clone(), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
130 |
msg, |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
131 |
} |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
132 |
.send_all() |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
133 |
.in_room(room_id), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
134 |
); |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
135 |
} |
14788 | 136 |
TeamChat(msg) => { |
137 |
if let Some(ref info) = room.game_info { |
|
138 |
if let Some(clan_color) = room.find_team_color(client_id) { |
|
139 |
let engine_msg = |
|
140 |
to_engine_msg(format!("b{}]{}\x20\x20", client.nick, msg).bytes()); |
|
141 |
let team = room.clan_team_owners(clan_color).collect(); |
|
142 |
response.add(ForwardEngineMessage(vec![engine_msg]).send_many(team)) |
|
143 |
} |
|
144 |
} |
|
145 |
} |
|
13477 | 146 |
Fix => { |
14697 | 147 |
if client.is_admin() { |
148 |
room.set_is_fixed(true); |
|
149 |
room.set_join_restriction(false); |
|
150 |
room.set_team_add_restriction(false); |
|
151 |
room.set_unregistered_players_restriction(true); |
|
15492 | 152 |
} else { |
153 |
response.warn(ACCESS_DENIED) |
|
13477 | 154 |
} |
155 |
} |
|
156 |
Unfix => { |
|
14697 | 157 |
if client.is_admin() { |
158 |
room.set_is_fixed(false); |
|
15492 | 159 |
} else { |
160 |
response.warn(ACCESS_DENIED) |
|
13477 | 161 |
} |
162 |
} |
|
163 |
Greeting(text) => { |
|
14697 | 164 |
if client.is_admin() || client.is_master() && !room.is_fixed() { |
15111 | 165 |
room.greeting = text.unwrap_or(String::new()); |
13477 | 166 |
} |
167 |
} |
|
14788 | 168 |
MaxTeams(count) => { |
169 |
if !client.is_master() { |
|
15482 | 170 |
response.warn(NOT_MASTER); |
15026 | 171 |
} else if !(2..=MAX_TEAMS_IN_ROOM).contains(&count) { |
15482 | 172 |
response.warn("/maxteams: specify number from 2 to 8"); |
14788 | 173 |
} else { |
15482 | 174 |
room.max_teams = count; |
14788 | 175 |
} |
176 |
} |
|
13416 | 177 |
RoomName(new_name) => { |
15518 | 178 |
use crate::core::server::ModifyRoomNameError; |
179 |
match server.set_room_name(client_id, room_id, new_name) { |
|
180 |
Ok(old_name) => { |
|
181 |
let (client, room) = server.client_and_room(client_id, room_id); |
|
182 |
super::common::get_room_update(Some(old_name), room, Some(client), response) |
|
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
183 |
} |
15518 | 184 |
Err(ModifyRoomNameError::AccessDenied) => response.warn(ACCESS_DENIED), |
185 |
Err(ModifyRoomNameError::InvalidName) => response.warn(ILLEGAL_ROOM_NAME), |
|
186 |
Err(ModifyRoomNameError::DuplicateName) => response.warn(ROOM_EXISTS), |
|
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
187 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
188 |
} |
13419 | 189 |
ToggleReady => { |
15518 | 190 |
let flags = if server.toggle_ready(client_id) { |
191 |
add_flags(&[Flags::Ready]) |
|
14697 | 192 |
} else { |
15518 | 193 |
remove_flags(&[Flags::Ready]) |
14697 | 194 |
}; |
15518 | 195 |
let (client, room) = server.client_and_room(client_id, room_id); |
13801 | 196 |
|
14697 | 197 |
let msg = if client.protocol_number < 38 { |
198 |
LegacyReady(client.is_ready(), vec![client.nick.clone()]) |
|
199 |
} else { |
|
14782 | 200 |
ClientFlags(flags, vec![client.nick.clone()]) |
14697 | 201 |
}; |
15518 | 202 |
response.add(msg.send_all().in_room(room_id)); |
14691 | 203 |
|
14697 | 204 |
if room.is_fixed() && room.ready_players_number == room.players_number { |
15492 | 205 |
let result = server.start_game(room_id); |
206 |
super::common::get_start_game_data(server, room_id, result, response); |
|
13666 | 207 |
} |
13416 | 208 |
} |
14785
a1077e8d26f4
implement watch message apart from replay deserializing
alfadur
parents:
14784
diff
changeset
|
209 |
AddTeam(mut info) => { |
14788 | 210 |
if room.teams.len() >= room.max_teams as usize { |
15482 | 211 |
response.warn("Too many teams!"); |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
212 |
} else if room.addable_hedgehogs() == 0 { |
15482 | 213 |
response.warn("Too many hedgehogs!"); |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
214 |
} else if room.find_team(|t| t.name == info.name) != None { |
15482 | 215 |
response.warn("There's already a team with same name in the list."); |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
216 |
} else if room.game_info.is_some() { |
15482 | 217 |
response.warn("Joining not possible: Round is in progress."); |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
218 |
} else if room.is_team_add_restricted() { |
15482 | 219 |
response.warn("This room currently does not allow adding new teams."); |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
220 |
} else { |
14785
a1077e8d26f4
implement watch message apart from replay deserializing
alfadur
parents:
14784
diff
changeset
|
221 |
info.owner = client.nick.clone(); |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
222 |
let team = room.add_team(client.id, *info, client.protocol_number < 42); |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
223 |
client.teams_in_game += 1; |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
224 |
client.clan = Some(team.color); |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
225 |
response.add(TeamAccepted(team.name.clone()).send_self()); |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
226 |
response.add( |
14785
a1077e8d26f4
implement watch message apart from replay deserializing
alfadur
parents:
14784
diff
changeset
|
227 |
TeamAdd(team.to_protocol()) |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
228 |
.send_all() |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
229 |
.in_room(room_id) |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
230 |
.but_self(), |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
231 |
); |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
232 |
response.add( |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
233 |
TeamColor(team.name.clone(), team.color) |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
234 |
.send_all() |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
235 |
.in_room(room_id), |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
236 |
); |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
237 |
response.add( |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
238 |
HedgehogsNumber(team.name.clone(), team.hedgehogs_number) |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
239 |
.send_all() |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
240 |
.in_room(room_id), |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
241 |
); |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
242 |
|
15482 | 243 |
let room = server.room(room_id); |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
244 |
let room_master = if let Some(id) = room.master_id { |
15482 | 245 |
Some(server.client(id)) |
13419 | 246 |
} else { |
14688
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
247 |
None |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
248 |
}; |
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14687
diff
changeset
|
249 |
super::common::get_room_update(None, room, room_master, response); |
13419 | 250 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
251 |
} |
14697 | 252 |
RemoveTeam(name) => match room.find_team_owner(&name) { |
15482 | 253 |
None => response.warn("Error: The team you tried to remove does not exist."), |
254 |
Some((id, _)) if id != client_id => { |
|
255 |
response.warn("You can't remove a team you don't own.") |
|
256 |
} |
|
14697 | 257 |
Some((_, name)) => { |
15482 | 258 |
let name = name.to_string(); |
14697 | 259 |
client.teams_in_game -= 1; |
260 |
client.clan = room.find_team_color(client.id); |
|
15482 | 261 |
room.remove_team(&name); |
262 |
let removed_teams = vec![name]; |
|
263 |
super::common::get_remove_teams_data( |
|
264 |
room_id, |
|
265 |
client.is_in_game(), |
|
266 |
removed_teams, |
|
267 |
response, |
|
268 |
); |
|
14691 | 269 |
|
14697 | 270 |
match room.game_info { |
271 |
Some(ref info) if info.teams_in_game == 0 => { |
|
15516 | 272 |
let result = server.end_game(room_id); |
273 |
super::common::get_end_game_result(server, room_id, result, response); |
|
13419 | 274 |
} |
14697 | 275 |
_ => (), |
13419 | 276 |
} |
14675
dfe652c53470
Server action refactoring part 6 of N
alfadur <mail@none>
parents:
14671
diff
changeset
|
277 |
} |
14697 | 278 |
}, |
13419 | 279 |
SetHedgehogsNumber(team_name, number) => { |
14697 | 280 |
let addable_hedgehogs = room.addable_hedgehogs(); |
281 |
if let Some((_, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) { |
|
15026 | 282 |
let max_hedgehogs = min( |
283 |
MAX_HEDGEHOGS_PER_TEAM, |
|
284 |
addable_hedgehogs + team.hedgehogs_number, |
|
285 |
); |
|
14697 | 286 |
if !client.is_master() { |
15482 | 287 |
response.error(NOT_MASTER); |
15026 | 288 |
} else if !(1..=max_hedgehogs).contains(&number) { |
14697 | 289 |
response |
290 |
.add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send_self()); |
|
13419 | 291 |
} else { |
14697 | 292 |
team.hedgehogs_number = number; |
293 |
response.add( |
|
294 |
HedgehogsNumber(team.name.clone(), number) |
|
295 |
.send_all() |
|
296 |
.in_room(room_id) |
|
297 |
.but_self(), |
|
298 |
); |
|
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
299 |
} |
14697 | 300 |
} else { |
15482 | 301 |
response.warn(NO_TEAM); |
13666 | 302 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
303 |
} |
13419 | 304 |
SetTeamColor(team_name, color) => { |
15518 | 305 |
match server.set_team_color(client_id, room_id, &team_name, color) { |
306 |
Ok(()) => response.add( |
|
307 |
TeamColor(team_name, color) |
|
308 |
.send_all() |
|
309 |
.in_room(room_id) |
|
310 |
.but_self(), |
|
311 |
), |
|
312 |
Err(ModifyTeamError::NoTeam) => response.warn(NO_TEAM), |
|
313 |
Err(ModifyTeamError::NotMaster) => response.error(NOT_MASTER), |
|
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
314 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
315 |
} |
13422 | 316 |
Cfg(cfg) => { |
14697 | 317 |
if room.is_fixed() { |
15482 | 318 |
response.warn(ACCESS_DENIED); |
14697 | 319 |
} else if !client.is_master() { |
15482 | 320 |
response.error(NOT_MASTER); |
14697 | 321 |
} else { |
322 |
let cfg = match cfg { |
|
323 |
GameCfg::Scheme(name, mut values) => { |
|
324 |
if client.protocol_number == 49 && values.len() >= 2 { |
|
325 |
let mut s = "X".repeat(50); |
|
326 |
s.push_str(&values.pop().unwrap()); |
|
327 |
values.push(s); |
|
13801 | 328 |
} |
14697 | 329 |
GameCfg::Scheme(name, values) |
330 |
} |
|
331 |
cfg => cfg, |
|
332 |
}; |
|
13801 | 333 |
|
14697 | 334 |
response.add(cfg.to_server_msg().send_all().in_room(room.id).but_self()); |
335 |
room.set_config(cfg); |
|
13666 | 336 |
} |
13419 | 337 |
} |
13528 | 338 |
Save(name, location) => { |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
339 |
response.add( |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
340 |
server_chat(format!("Room config saved as {}", name)) |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
341 |
.send_all() |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
342 |
.in_room(room_id), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
343 |
); |
14697 | 344 |
room.save_config(name, location); |
13528 | 345 |
} |
14785
a1077e8d26f4
implement watch message apart from replay deserializing
alfadur
parents:
14784
diff
changeset
|
346 |
#[cfg(feature = "official-server")] |
13529 | 347 |
SaveRoom(filename) => { |
14697 | 348 |
if client.is_admin() { |
349 |
match room.get_saves() { |
|
14781 | 350 |
Ok(contents) => response.request_io(super::IoTask::SaveRoom { |
351 |
room_id, |
|
352 |
filename, |
|
353 |
contents, |
|
354 |
}), |
|
13529 | 355 |
Err(e) => { |
356 |
warn!("Error while serializing the room configs: {}", e); |
|
15482 | 357 |
response.warn("Unable to serialize the room configs.") |
13529 | 358 |
} |
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
359 |
} |
13666 | 360 |
} |
13529 | 361 |
} |
14785
a1077e8d26f4
implement watch message apart from replay deserializing
alfadur
parents:
14784
diff
changeset
|
362 |
#[cfg(feature = "official-server")] |
13529 | 363 |
LoadRoom(filename) => { |
14697 | 364 |
if client.is_admin() { |
14781 | 365 |
response.request_io(super::IoTask::LoadRoom { room_id, filename }); |
13666 | 366 |
} |
13529 | 367 |
} |
13528 | 368 |
Delete(name) => { |
14697 | 369 |
if !room.delete_config(&name) { |
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
370 |
response.add(Warning(format!("Save doesn't exist: {}", name)).send_self()); |
13528 | 371 |
} else { |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
372 |
response.add( |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
373 |
server_chat(format!("Room config {} has been deleted", name)) |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
374 |
.send_all() |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
375 |
.in_room(room_id), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
376 |
); |
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
377 |
} |
13528 | 378 |
} |
13478 | 379 |
CallVote(None) => { |
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
380 |
response.add(server_chat("Available callvote commands: kick <nickname>, map <name>, pause, newseed, hedgehogs <number>".to_string()) |
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
381 |
.send_self()); |
13478 | 382 |
} |
383 |
CallVote(Some(kind)) => { |
|
14697 | 384 |
let is_in_game = room.game_info.is_some(); |
13478 | 385 |
let error = match &kind { |
386 |
VoteType::Kick(nick) => { |
|
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
387 |
if server |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
388 |
.find_client(&nick) |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
389 |
.filter(|c| c.room_id == Some(room_id)) |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
390 |
.is_some() |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
391 |
{ |
13478 | 392 |
None |
393 |
} else { |
|
13527 | 394 |
Some("/callvote kick: No such user!".to_string()) |
13478 | 395 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
396 |
} |
13478 | 397 |
VoteType::Map(None) => { |
13527 | 398 |
let names: Vec<_> = server.rooms[room_id].saves.keys().cloned().collect(); |
399 |
if names.is_empty() { |
|
400 |
Some("/callvote map: No maps saved in this room!".to_string()) |
|
401 |
} else { |
|
402 |
Some(format!("Available maps: {}", names.join(", "))) |
|
403 |
} |
|
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
404 |
} |
13478 | 405 |
VoteType::Map(Some(name)) => { |
14697 | 406 |
if room.saves.get(&name[..]).is_some() { |
13530 | 407 |
None |
13527 | 408 |
} else { |
13530 | 409 |
Some("/callvote map: No such map!".to_string()) |
13527 | 410 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
411 |
} |
13478 | 412 |
VoteType::Pause => { |
413 |
if is_in_game { |
|
414 |
None |
|
415 |
} else { |
|
13527 | 416 |
Some("/callvote pause: No game in progress!".to_string()) |
13478 | 417 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
418 |
} |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
419 |
VoteType::NewSeed => None, |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
420 |
VoteType::HedgehogsPerTeam(number) => match number { |
15439 | 421 |
1..=MAX_HEDGEHOGS_PER_TEAM => None, |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
422 |
_ => Some("/callvote hedgehogs: Specify number from 1 to 8.".to_string()), |
13478 | 423 |
}, |
424 |
}; |
|
14697 | 425 |
|
13478 | 426 |
match error { |
427 |
None => { |
|
13480 | 428 |
let msg = voting_description(&kind); |
14789 | 429 |
let voting = Voting::new(kind, server.room_clients(client_id).collect()); |
14686
9f98086de1b6
Server action refactoring part 9 of N
alfadur <mail@none>
parents:
14683
diff
changeset
|
430 |
let room = &mut server.rooms[room_id]; |
9f98086de1b6
Server action refactoring part 9 of N
alfadur <mail@none>
parents:
14683
diff
changeset
|
431 |
room.voting = Some(voting); |
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
432 |
response.add(server_chat(msg).send_all().in_room(room_id)); |
14687
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
433 |
super::common::submit_vote( |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
434 |
server, |
15074 | 435 |
types::Vote { |
14687
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
436 |
is_pro: true, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
437 |
is_forced: false, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
438 |
}, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
439 |
response, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
440 |
); |
13478 | 441 |
} |
442 |
Some(msg) => { |
|
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
443 |
response.add(server_chat(msg).send_self()); |
13478 | 444 |
} |
445 |
} |
|
446 |
} |
|
447 |
Vote(vote) => { |
|
14687
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
448 |
super::common::submit_vote( |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
449 |
server, |
15074 | 450 |
types::Vote { |
14687
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
451 |
is_pro: vote, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
452 |
is_forced: false, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
453 |
}, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
454 |
response, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
455 |
); |
13478 | 456 |
} |
457 |
ForceVote(vote) => { |
|
14697 | 458 |
let is_forced = client.is_admin(); |
14687
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
459 |
super::common::submit_vote( |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
460 |
server, |
15074 | 461 |
types::Vote { |
14687
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
462 |
is_pro: vote, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
463 |
is_forced, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
464 |
}, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
465 |
response, |
5122c584804e
Server action refactoring part A of N
alfadur <mail@none>
parents:
14686
diff
changeset
|
466 |
); |
13478 | 467 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
468 |
ToggleRestrictJoin | ToggleRestrictTeams | ToggleRegisteredOnly => { |
14686
9f98086de1b6
Server action refactoring part 9 of N
alfadur <mail@none>
parents:
14683
diff
changeset
|
469 |
if client.is_master() { |
9f98086de1b6
Server action refactoring part 9 of N
alfadur <mail@none>
parents:
14683
diff
changeset
|
470 |
room.flags.toggle(room_message_flag(&message)); |
9f98086de1b6
Server action refactoring part 9 of N
alfadur <mail@none>
parents:
14683
diff
changeset
|
471 |
super::common::get_room_update(None, room, Some(&client), response); |
13523 | 472 |
} |
473 |
} |
|
13423 | 474 |
StartGame => { |
15492 | 475 |
let result = server.start_game(room_id); |
476 |
super::common::get_start_game_data(server, room_id, result, response); |
|
13423 | 477 |
} |
478 |
EngineMessage(em) => { |
|
14697 | 479 |
if client.teams_in_game > 0 { |
480 |
let decoding = decode(&em[..]).unwrap(); |
|
481 |
let messages = by_msg(&decoding); |
|
482 |
let valid = messages.filter(|m| is_msg_valid(m, &client.team_indices)); |
|
483 |
let non_empty = valid.clone().filter(|m| !is_msg_empty(m)); |
|
484 |
let sync_msg = valid.clone().filter(|m| is_msg_timed(m)).last().map(|m| { |
|
485 |
if is_msg_empty(m) { |
|
486 |
Some(encode(m)) |
|
487 |
} else { |
|
488 |
None |
|
489 |
} |
|
490 |
}); |
|
13423 | 491 |
|
14697 | 492 |
let em_response = encode(&valid.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
493 |
if !em_response.is_empty() { |
|
494 |
response.add( |
|
495 |
ForwardEngineMessage(vec![em_response]) |
|
496 |
.send_all() |
|
497 |
.in_room(room.id) |
|
498 |
.but_self(), |
|
499 |
); |
|
500 |
} |
|
501 |
let em_log = encode(&non_empty.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
|
502 |
if let Some(ref mut info) = room.game_info { |
|
503 |
if !em_log.is_empty() { |
|
504 |
info.msg_log.push(em_log); |
|
13423 | 505 |
} |
14697 | 506 |
if let Some(msg) = sync_msg { |
507 |
info.sync_msg = msg; |
|
13427 | 508 |
} |
13423 | 509 |
} |
510 |
} |
|
511 |
} |
|
512 |
RoundFinished => { |
|
14689
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
513 |
let mut game_ended = false; |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
514 |
if client.is_in_game() { |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
515 |
client.set_is_in_game(false); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
516 |
response.add( |
14782 | 517 |
ClientFlags(remove_flags(&[Flags::InGame]), vec![client.nick.clone()]) |
14689
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
518 |
.send_all() |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
519 |
.in_room(room.id), |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
520 |
); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
521 |
let team_names: Vec<_> = room |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
522 |
.client_teams(client_id) |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
523 |
.map(|t| t.name.clone()) |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
524 |
.collect(); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
525 |
|
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
526 |
if let Some(ref mut info) = room.game_info { |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
527 |
info.teams_in_game -= team_names.len() as u8; |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
528 |
if info.teams_in_game == 0 { |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
529 |
game_ended = true; |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
530 |
} |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
531 |
|
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
532 |
for team_name in team_names { |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
533 |
let msg = once(b'F').chain(team_name.bytes()); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
534 |
response.add( |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
535 |
ForwardEngineMessage(vec![to_engine_msg(msg)]) |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
536 |
.send_all() |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
537 |
.in_room(room_id) |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
538 |
.but_self(), |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
539 |
); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
540 |
|
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
541 |
let remove_msg = to_engine_msg(once(b'F').chain(team_name.bytes())); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
542 |
if let Some(m) = &info.sync_msg { |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
543 |
info.msg_log.push(m.clone()); |
13426 | 544 |
} |
14689
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
545 |
if info.sync_msg.is_some() { |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
546 |
info.sync_msg = None |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
547 |
} |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
548 |
info.msg_log.push(remove_msg.clone()); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
549 |
response.add( |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
550 |
ForwardEngineMessage(vec![remove_msg]) |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
551 |
.send_all() |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
552 |
.in_room(room_id) |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
553 |
.but_self(), |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
554 |
); |
13423 | 555 |
} |
556 |
} |
|
557 |
} |
|
14689
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
558 |
if game_ended { |
15516 | 559 |
let result = server.end_game(room_id); |
560 |
super::common::get_end_game_result(server, room_id, result, response); |
|
14689
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
561 |
} |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
562 |
} |
13445
d3c86ade3d4d
Send the rnd reply to the room only.
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
13444
diff
changeset
|
563 |
Rnd(v) => { |
13521 | 564 |
let result = rnd_reply(&v); |
565 |
let mut echo = vec!["/rnd".to_string()]; |
|
566 |
echo.extend(v.into_iter()); |
|
567 |
let chat_msg = ChatMsg { |
|
15487 | 568 |
nick: server.client(client_id).nick.clone(), |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
569 |
msg: echo.join(" "), |
13521 | 570 |
}; |
14676
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
571 |
response.add(chat_msg.send_all().in_room(room_id)); |
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14675
diff
changeset
|
572 |
response.add(result.send_all().in_room(room_id)); |
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
573 |
} |
15487 | 574 |
Delegate(nick) => match server.change_master(client_id, room_id, nick) { |
575 |
Ok(ChangeMasterResult { |
|
576 |
old_master_id, |
|
577 |
new_master_id, |
|
578 |
}) => { |
|
579 |
if let Some(master_id) = old_master_id { |
|
580 |
response.add( |
|
581 |
ClientFlags( |
|
582 |
remove_flags(&[Flags::RoomMaster]), |
|
583 |
vec![server.client(master_id).nick.clone()], |
|
584 |
) |
|
585 |
.send_all() |
|
586 |
.in_room(room_id), |
|
587 |
); |
|
588 |
} |
|
589 |
response.add( |
|
590 |
ClientFlags( |
|
591 |
add_flags(&[Flags::RoomMaster]), |
|
592 |
vec![server.client(new_master_id).nick.clone()], |
|
593 |
) |
|
594 |
.send_all() |
|
595 |
.in_room(room_id), |
|
596 |
); |
|
597 |
} |
|
598 |
Err(ChangeMasterError::NoAccess) => { |
|
15482 | 599 |
response.warn("You're not the room master or a server admin!") |
15487 | 600 |
} |
601 |
Err(ChangeMasterError::AlreadyMaster) => { |
|
602 |
response.warn("You're already the room master.") |
|
14784 | 603 |
} |
15487 | 604 |
Err(ChangeMasterError::NoClient) => response.warn("Player is not online."), |
605 |
Err(ChangeMasterError::ClientNotInRoom) => { |
|
606 |
response.warn("The player is not in your room.") |
|
607 |
} |
|
608 |
}, |
|
14683
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
609 |
_ => warn!("Unimplemented!"), |
12147 | 610 |
} |
611 |
} |