author | alfadur |
Wed, 11 Mar 2020 23:20:15 +0300 | |
changeset 15570 | e1c2ca38e511 |
parent 15563 | d122b65bdf6f |
child 15573 | 7478568cffbe |
permissions | -rw-r--r-- |
15504 | 1 |
use super::{common::rnd_reply, strings::*}; |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
2 |
use crate::core::room::GameInfo; |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
3 |
use crate::core::server::{AddTeamError, SetTeamCountError}; |
13666 | 4 |
use crate::{ |
15095 | 5 |
core::{ |
15096 | 6 |
room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM}, |
15514 | 7 |
server::{ |
15547 | 8 |
ChangeMasterError, ChangeMasterResult, HwRoomControl, HwServer, LeaveRoomResult, |
9 |
ModifyTeamError, StartGameError, |
|
15514 | 10 |
}, |
15095 | 11 |
types, |
12 |
types::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM}, |
|
15096 | 13 |
}, |
14 |
protocol::messages::{ |
|
15 |
add_flags, remove_flags, server_chat, HwProtocolMessage, HwServerMessage::*, |
|
16 |
ProtocolFlags as Flags, |
|
13666 | 17 |
}, |
15504 | 18 |
utils::{is_name_illegal, to_engine_msg}, |
13416 | 19 |
}; |
14478 | 20 |
use base64::{decode, encode}; |
13810 | 21 |
use log::*; |
15047 | 22 |
use std::{cmp::min, iter::once, mem::swap}; |
13423 | 23 |
|
24 |
#[derive(Clone)] |
|
25 |
struct ByMsg<'a> { |
|
14478 | 26 |
messages: &'a [u8], |
13423 | 27 |
} |
28 |
||
14478 | 29 |
impl<'a> Iterator for ByMsg<'a> { |
30 |
type Item = &'a [u8]; |
|
13423 | 31 |
|
32 |
fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
|
33 |
if let Some(size) = self.messages.get(0) { |
|
34 |
let (msg, next) = self.messages.split_at(*size as usize + 1); |
|
35 |
self.messages = next; |
|
36 |
Some(msg) |
|
37 |
} else { |
|
38 |
None |
|
39 |
} |
|
40 |
} |
|
41 |
} |
|
42 |
||
13500 | 43 |
fn by_msg(source: &[u8]) -> ByMsg { |
14478 | 44 |
ByMsg { messages: source } |
13423 | 45 |
} |
46 |
||
47 |
const VALID_MESSAGES: &[u8] = |
|
48 |
b"M#+LlRrUuDdZzAaSjJ,NpPwtgfhbc12345\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A"; |
|
49 |
const NON_TIMED_MESSAGES: &[u8] = b"M#hb"; |
|
50 |
||
51 |
fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool { |
|
13424 | 52 |
match msg { |
15552 | 53 |
[size, typ, body @ ..] => { |
14478 | 54 |
VALID_MESSAGES.contains(typ) |
55 |
&& match body { |
|
15463 | 56 |
[1..=MAX_HEDGEHOGS_PER_TEAM, team, ..] if *typ == b'h' => { |
14478 | 57 |
team_indices.contains(team) |
58 |
} |
|
59 |
_ => *typ != b'h', |
|
60 |
} |
|
61 |
} |
|
62 |
_ => false, |
|
13423 | 63 |
} |
15550
17ad5d43e820
update subslice pattern to the new syntax
alfadur <mail@none>
parents:
15549
diff
changeset
|
64 |
} |
13423 | 65 |
|
66 |
fn is_msg_empty(msg: &[u8]) -> bool { |
|
13429 | 67 |
msg.get(1).filter(|t| **t == b'+').is_some() |
13423 | 68 |
} |
12147 | 69 |
|
13443 | 70 |
fn is_msg_timed(msg: &[u8]) -> bool { |
14478 | 71 |
msg.get(1) |
72 |
.filter(|t| !NON_TIMED_MESSAGES.contains(t)) |
|
73 |
.is_some() |
|
13443 | 74 |
} |
75 |
||
13460 | 76 |
fn voting_description(kind: &VoteType) -> String { |
14478 | 77 |
format!( |
78 |
"New voting started: {}", |
|
79 |
match kind { |
|
80 |
VoteType::Kick(nick) => format!("kick {}", nick), |
|
81 |
VoteType::Map(name) => format!("map {}", name.as_ref().unwrap()), |
|
82 |
VoteType::Pause => "pause".to_string(), |
|
83 |
VoteType::NewSeed => "new seed".to_string(), |
|
84 |
VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number), |
|
85 |
} |
|
86 |
) |
|
13460 | 87 |
} |
88 |
||
15096 | 89 |
fn room_message_flag(msg: &HwProtocolMessage) -> RoomFlags { |
90 |
use crate::protocol::messages::HwProtocolMessage::*; |
|
13494 | 91 |
match msg { |
92 |
ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN, |
|
93 |
ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD, |
|
15556 | 94 |
ToggleRegisteredOnly => RoomFlags::REGISTRATION_REQUIRED, |
14478 | 95 |
_ => RoomFlags::empty(), |
13494 | 96 |
} |
97 |
} |
|
98 |
||
14478 | 99 |
pub fn handle( |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
100 |
mut room_control: HwRoomControl, |
14692
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14478
diff
changeset
|
101 |
response: &mut super::Response, |
15096 | 102 |
message: HwProtocolMessage, |
14478 | 103 |
) { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
104 |
let (client, room) = room_control.get(); |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
105 |
let (client_id, room_id) = (client.id, room.id); |
14718 | 106 |
|
15096 | 107 |
use crate::protocol::messages::HwProtocolMessage::*; |
12147 | 108 |
match message { |
14696
dfe652c53470
Server action refactoring part 6 of N
alfadur <mail@none>
parents:
14692
diff
changeset
|
109 |
Part(msg) => { |
14718 | 110 |
let msg = match msg { |
111 |
Some(s) => format!("part: {}", s), |
|
112 |
None => "part".to_string(), |
|
113 |
}; |
|
15504 | 114 |
|
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
115 |
let result = room_control.leave_room(); |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
116 |
super::common::get_room_leave_result( |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
117 |
room_control.server(), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
118 |
room_control.room(), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
119 |
&msg, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
120 |
result, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
121 |
response, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
122 |
); |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
123 |
} |
13416 | 124 |
Chat(msg) => { |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
125 |
response.add( |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
126 |
ChatMsg { |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
127 |
nick: client.nick.clone(), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
128 |
msg, |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
129 |
} |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
130 |
.send_all() |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
131 |
.in_room(room_id), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
132 |
); |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
133 |
} |
14809 | 134 |
TeamChat(msg) => { |
15553 | 135 |
if room.game_info.is_some() { |
14809 | 136 |
if let Some(clan_color) = room.find_team_color(client_id) { |
137 |
let engine_msg = |
|
138 |
to_engine_msg(format!("b{}]{}\x20\x20", client.nick, msg).bytes()); |
|
139 |
let team = room.clan_team_owners(clan_color).collect(); |
|
140 |
response.add(ForwardEngineMessage(vec![engine_msg]).send_many(team)) |
|
141 |
} |
|
142 |
} |
|
143 |
} |
|
13447 | 144 |
Fix => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
145 |
if let Err(_) = room_control.fix_room() { |
15514 | 146 |
response.warn(ACCESS_DENIED) |
13447 | 147 |
} |
148 |
} |
|
149 |
Unfix => { |
|
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
150 |
if let Err(_) = room_control.unfix_room() { |
15514 | 151 |
response.warn(ACCESS_DENIED) |
13447 | 152 |
} |
153 |
} |
|
154 |
Greeting(text) => { |
|
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
155 |
if let Err(_) = room_control.set_room_greeting(text) { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
156 |
response.warn(ACCESS_DENIED) |
13447 | 157 |
} |
158 |
} |
|
14809 | 159 |
MaxTeams(count) => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
160 |
use crate::core::server::SetTeamCountError; |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
161 |
match room_control.set_room_max_teams(count) { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
162 |
Ok(()) => {} |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
163 |
Err(SetTeamCountError::NotMaster) => response.warn(NOT_MASTER), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
164 |
Err(SetTeamCountError::InvalidNumber) => { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
165 |
response.warn("/maxteams: specify number from 2 to 8") |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
166 |
} |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
167 |
}; |
14809 | 168 |
} |
13416 | 169 |
RoomName(new_name) => { |
15540 | 170 |
use crate::core::server::ModifyRoomNameError; |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
171 |
match room_control.set_room_name(new_name) { |
15540 | 172 |
Ok(old_name) => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
173 |
let (client, room) = room_control.get(); |
15540 | 174 |
super::common::get_room_update(Some(old_name), room, Some(client), response) |
14709
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14708
diff
changeset
|
175 |
} |
15540 | 176 |
Err(ModifyRoomNameError::AccessDenied) => response.warn(ACCESS_DENIED), |
177 |
Err(ModifyRoomNameError::InvalidName) => response.warn(ILLEGAL_ROOM_NAME), |
|
178 |
Err(ModifyRoomNameError::DuplicateName) => response.warn(ROOM_EXISTS), |
|
14709
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14708
diff
changeset
|
179 |
} |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
180 |
} |
13419 | 181 |
ToggleReady => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
182 |
let flags = if room_control.toggle_ready() { |
15540 | 183 |
add_flags(&[Flags::Ready]) |
14718 | 184 |
} else { |
15540 | 185 |
remove_flags(&[Flags::Ready]) |
14718 | 186 |
}; |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
187 |
let (client, room) = room_control.get(); |
13775 | 188 |
|
14718 | 189 |
let msg = if client.protocol_number < 38 { |
190 |
LegacyReady(client.is_ready(), vec![client.nick.clone()]) |
|
191 |
} else { |
|
14803 | 192 |
ClientFlags(flags, vec![client.nick.clone()]) |
14718 | 193 |
}; |
15540 | 194 |
response.add(msg.send_all().in_room(room_id)); |
14712 | 195 |
|
14718 | 196 |
if room.is_fixed() && room.ready_players_number == room.players_number { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
197 |
let result = room_control.start_game(); |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
198 |
super::common::get_start_game_data( |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
199 |
room_control.server(), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
200 |
room_id, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
201 |
result, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
202 |
response, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
203 |
); |
13666 | 204 |
} |
13416 | 205 |
} |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
206 |
AddTeam(info) => { |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
207 |
use crate::core::server::AddTeamError; |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
208 |
match room_control.add_team(info) { |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
209 |
Ok(team) => { |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
210 |
response.add(TeamAccepted(team.name.clone()).send_self()); |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
211 |
response.add( |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
212 |
TeamAdd(team.to_protocol()) |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
213 |
.send_all() |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
214 |
.in_room(room_id) |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
215 |
.but_self(), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
216 |
); |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
217 |
response.add( |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
218 |
TeamColor(team.name.clone(), team.color) |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
219 |
.send_all() |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
220 |
.in_room(room_id), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
221 |
); |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
222 |
response.add( |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
223 |
HedgehogsNumber(team.name.clone(), team.hedgehogs_number) |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
224 |
.send_all() |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
225 |
.in_room(room_id), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
226 |
); |
14709
4569d8d50286
Server action refactoring part B of N
alfadur <mail@none>
parents:
14708
diff
changeset
|
227 |
|
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
228 |
let room = room_control.room(); |
15547 | 229 |
let room_master = room.master_id.map(|id| room_control.server().client(id)); |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
230 |
super::common::get_room_update(None, room, room_master, response); |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
231 |
} |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
232 |
Err(AddTeamError::TooManyTeams) => response.warn(TOO_MANY_TEAMS), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
233 |
Err(AddTeamError::TooManyHedgehogs) => response.warn(TOO_MANY_HEDGEHOGS), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
234 |
Err(AddTeamError::TeamAlreadyExists) => response.warn(TEAM_EXISTS), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
235 |
Err(AddTeamError::GameInProgress) => response.warn(ROUND_IN_PROGRESS), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
236 |
Err(AddTeamError::Restricted) => response.warn(TEAM_ADD_RESTRICTED), |
13419 | 237 |
} |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
238 |
} |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
239 |
RemoveTeam(name) => { |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
240 |
use crate::core::server::RemoveTeamError; |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
241 |
match room_control.remove_team(&name) { |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
242 |
Ok(()) => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
243 |
let (client, room) = room_control.get(); |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
244 |
|
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
245 |
let removed_teams = vec![name]; |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
246 |
super::common::get_remove_teams_data( |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
247 |
room_id, |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
248 |
client.is_in_game(), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
249 |
removed_teams, |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
250 |
response, |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
251 |
); |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
252 |
|
15563 | 253 |
if let Some(0) = room.teams_in_game() { |
254 |
if let Some(result) = room_control.end_game() { |
|
255 |
super::common::get_end_game_result( |
|
256 |
room_control.server(), |
|
257 |
room_id, |
|
258 |
result, |
|
259 |
response, |
|
260 |
); |
|
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
261 |
} |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
262 |
} |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
263 |
} |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
264 |
Err(RemoveTeamError::NoTeam) => response.warn(NO_TEAM_TO_REMOVE), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
265 |
Err(RemoveTeamError::TeamNotOwned) => response.warn(TEAM_NOT_OWNED), |
15504 | 266 |
} |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
267 |
} |
13419 | 268 |
SetHedgehogsNumber(team_name, number) => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
269 |
use crate::core::server::SetHedgehogsError; |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
270 |
match room_control.set_team_hedgehogs_number(&team_name, number) { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
271 |
Ok(()) => { |
14718 | 272 |
response.add( |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
273 |
HedgehogsNumber(team_name.clone(), number) |
14718 | 274 |
.send_all() |
275 |
.in_room(room_id) |
|
276 |
.but_self(), |
|
277 |
); |
|
14697
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
278 |
} |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
279 |
Err(SetHedgehogsError::NotMaster) => response.error(NOT_MASTER), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
280 |
Err(SetHedgehogsError::NoTeam) => response.warn(NO_TEAM), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
281 |
Err(SetHedgehogsError::InvalidNumber(previous_number)) => { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
282 |
response.add(HedgehogsNumber(team_name.clone(), previous_number).send_self()) |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
283 |
} |
14697
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
284 |
} |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
285 |
} |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
286 |
SetTeamColor(team_name, color) => match room_control.set_team_color(&team_name, color) { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
287 |
Ok(()) => response.add( |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
288 |
TeamColor(team_name, color) |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
289 |
.send_all() |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
290 |
.in_room(room_id) |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
291 |
.but_self(), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
292 |
), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
293 |
Err(ModifyTeamError::NoTeam) => response.warn(NO_TEAM), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
294 |
Err(ModifyTeamError::NotMaster) => response.error(NOT_MASTER), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
295 |
}, |
13422 | 296 |
Cfg(cfg) => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
297 |
use crate::core::server::SetConfigError; |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
298 |
let msg = cfg.to_server_msg(); |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
299 |
match room_control.set_config(cfg) { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
300 |
Ok(()) => { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
301 |
response.add(msg.send_all().in_room(room_control.room().id).but_self()); |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
302 |
} |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
303 |
Err(SetConfigError::NotMaster) => response.error(NOT_MASTER), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
304 |
Err(SetConfigError::RoomFixed) => response.warn(ACCESS_DENIED), |
13666 | 305 |
} |
13419 | 306 |
} |
13528 | 307 |
Save(name, location) => { |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
308 |
response.add( |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
309 |
server_chat(format!("Room config saved as {}", name)) |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
310 |
.send_all() |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
311 |
.in_room(room_id), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
312 |
); |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
313 |
room_control.save_config(name, location); |
13528 | 314 |
} |
14806
a1077e8d26f4
implement watch message apart from replay deserializing
alfadur
parents:
14805
diff
changeset
|
315 |
#[cfg(feature = "official-server")] |
13529 | 316 |
SaveRoom(filename) => { |
14718 | 317 |
if client.is_admin() { |
318 |
match room.get_saves() { |
|
14802 | 319 |
Ok(contents) => response.request_io(super::IoTask::SaveRoom { |
320 |
room_id, |
|
321 |
filename, |
|
322 |
contents, |
|
323 |
}), |
|
13529 | 324 |
Err(e) => { |
325 |
warn!("Error while serializing the room configs: {}", e); |
|
15504 | 326 |
response.warn("Unable to serialize the room configs.") |
13529 | 327 |
} |
14697
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
328 |
} |
13666 | 329 |
} |
13529 | 330 |
} |
14806
a1077e8d26f4
implement watch message apart from replay deserializing
alfadur
parents:
14805
diff
changeset
|
331 |
#[cfg(feature = "official-server")] |
13529 | 332 |
LoadRoom(filename) => { |
14718 | 333 |
if client.is_admin() { |
14802 | 334 |
response.request_io(super::IoTask::LoadRoom { room_id, filename }); |
13666 | 335 |
} |
13529 | 336 |
} |
13528 | 337 |
Delete(name) => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
338 |
if !room_control.delete_config(&name) { |
14697
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
339 |
response.add(Warning(format!("Save doesn't exist: {}", name)).send_self()); |
13528 | 340 |
} else { |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
341 |
response.add( |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
342 |
server_chat(format!("Room config {} has been deleted", name)) |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
343 |
.send_all() |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
344 |
.in_room(room_id), |
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
345 |
); |
14697
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
346 |
} |
13528 | 347 |
} |
13450 | 348 |
CallVote(None) => { |
14697
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
349 |
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:
14696
diff
changeset
|
350 |
.send_self()); |
13450 | 351 |
} |
15547 | 352 |
CallVote(Some(kind)) => { |
353 |
use crate::core::server::StartVoteError; |
|
354 |
let room_id = room_control.room().id; |
|
355 |
if super::common::check_vote( |
|
356 |
room_control.server(), |
|
357 |
room_control.room(), |
|
358 |
&kind, |
|
359 |
response, |
|
360 |
) { |
|
361 |
match room_control.start_vote(kind.clone()) { |
|
362 |
Ok(()) => { |
|
363 |
let msg = voting_description(&kind); |
|
364 |
response.add(server_chat(msg).send_all().in_room(room_id)); |
|
365 |
let vote_result = room_control.vote(types::Vote { |
|
366 |
is_pro: true, |
|
367 |
is_forced: false, |
|
368 |
}); |
|
369 |
super::common::handle_vote(room_control, vote_result, response); |
|
13450 | 370 |
} |
15547 | 371 |
Err(StartVoteError::VotingInProgress) => { |
372 |
response.add( |
|
373 |
server_chat("There is already voting in progress".to_string()) |
|
374 |
.send_self(), |
|
375 |
); |
|
13450 | 376 |
} |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
377 |
} |
13450 | 378 |
} |
15547 | 379 |
} |
380 |
Vote(vote) => { |
|
381 |
let vote_result = room_control.vote(types::Vote { |
|
382 |
is_pro: vote, |
|
383 |
is_forced: false, |
|
384 |
}); |
|
385 |
super::common::handle_vote(room_control, vote_result, response); |
|
386 |
} |
|
387 |
ForceVote(vote) => { |
|
14718 | 388 |
let is_forced = client.is_admin(); |
15547 | 389 |
let vote_result = room_control.vote(types::Vote { |
390 |
is_pro: vote, |
|
391 |
is_forced, |
|
392 |
}); |
|
393 |
super::common::handle_vote(room_control, vote_result, response); |
|
394 |
} |
|
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
395 |
ToggleRestrictJoin | ToggleRestrictTeams | ToggleRegisteredOnly => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
396 |
if room_control.toggle_flag(room_message_flag(&message)) { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
397 |
let (client, room) = room_control.get(); |
14707
9f98086de1b6
Server action refactoring part 9 of N
alfadur <mail@none>
parents:
14704
diff
changeset
|
398 |
super::common::get_room_update(None, room, Some(&client), response); |
13494 | 399 |
} |
400 |
} |
|
13423 | 401 |
StartGame => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
402 |
let result = room_control.start_game(); |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
403 |
super::common::get_start_game_data(room_control.server(), room_id, result, response); |
13423 | 404 |
} |
15549 | 405 |
EngineMessage(em) => { |
14718 | 406 |
if client.teams_in_game > 0 { |
407 |
let decoding = decode(&em[..]).unwrap(); |
|
408 |
let messages = by_msg(&decoding); |
|
409 |
let valid = messages.filter(|m| is_msg_valid(m, &client.team_indices)); |
|
410 |
let non_empty = valid.clone().filter(|m| !is_msg_empty(m)); |
|
411 |
let sync_msg = valid.clone().filter(|m| is_msg_timed(m)).last().map(|m| { |
|
412 |
if is_msg_empty(m) { |
|
413 |
Some(encode(m)) |
|
414 |
} else { |
|
415 |
None |
|
416 |
} |
|
417 |
}); |
|
13423 | 418 |
|
14718 | 419 |
let em_response = encode(&valid.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
420 |
if !em_response.is_empty() { |
|
421 |
response.add( |
|
422 |
ForwardEngineMessage(vec![em_response]) |
|
423 |
.send_all() |
|
424 |
.in_room(room.id) |
|
425 |
.but_self(), |
|
426 |
); |
|
427 |
} |
|
428 |
let em_log = encode(&non_empty.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
|
15549 | 429 |
|
430 |
room_control.log_engine_msg(em_log, sync_msg); |
|
13423 | 431 |
} |
15549 | 432 |
} |
13423 | 433 |
RoundFinished => { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
434 |
if let Some(team_names) = room_control.leave_game() { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
435 |
let (client, room) = room_control.get(); |
14710
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14709
diff
changeset
|
436 |
response.add( |
14803 | 437 |
ClientFlags(remove_flags(&[Flags::InGame]), vec![client.nick.clone()]) |
14710
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14709
diff
changeset
|
438 |
.send_all() |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14709
diff
changeset
|
439 |
.in_room(room.id), |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14709
diff
changeset
|
440 |
); |
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14709
diff
changeset
|
441 |
|
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
442 |
for team_name in team_names { |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
443 |
let msg = once(b'F').chain(team_name.bytes()); |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
444 |
response.add( |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
445 |
ForwardEngineMessage(vec![to_engine_msg(msg)]) |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
446 |
.send_all() |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
447 |
.in_room(room_id) |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
448 |
.but_self(), |
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
449 |
); |
13423 | 450 |
} |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
451 |
|
15563 | 452 |
if let Some(0) = room.teams_in_game() { |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
453 |
if let Some(result) = room_control.end_game() { |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
454 |
super::common::get_end_game_result( |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
455 |
room_control.server(), |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
456 |
room_id, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
457 |
result, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
458 |
response, |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
459 |
); |
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
460 |
} |
15541
b3157d218ae2
disallow mutable clients to leave the server
alfadur <mail@none>
parents:
15540
diff
changeset
|
461 |
} |
14710
aae29ba56aec
Server action refactoring part C of N
alfadur <mail@none>
parents:
14709
diff
changeset
|
462 |
} |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
463 |
} |
13445
d3c86ade3d4d
Send the rnd reply to the room only.
Marcin Mielniczuk <marmistrz.dev@zoho.eu>
parents:
13444
diff
changeset
|
464 |
Rnd(v) => { |
13492 | 465 |
let result = rnd_reply(&v); |
466 |
let mut echo = vec!["/rnd".to_string()]; |
|
467 |
echo.extend(v.into_iter()); |
|
468 |
let chat_msg = ChatMsg { |
|
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
469 |
nick: client.nick.clone(), |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
470 |
msg: echo.join(" "), |
13492 | 471 |
}; |
14697
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
472 |
response.add(chat_msg.send_all().in_room(room_id)); |
9377ee00f1f1
Server action refactoring part 7 of N
alfadur <mail@none>
parents:
14696
diff
changeset
|
473 |
response.add(result.send_all().in_room(room_id)); |
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
474 |
} |
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
475 |
Delegate(nick) => match room_control.change_master(nick) { |
15509 | 476 |
Ok(ChangeMasterResult { |
477 |
old_master_id, |
|
478 |
new_master_id, |
|
479 |
}) => { |
|
480 |
if let Some(master_id) = old_master_id { |
|
481 |
response.add( |
|
482 |
ClientFlags( |
|
483 |
remove_flags(&[Flags::RoomMaster]), |
|
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
484 |
vec![room_control.server().client(master_id).nick.clone()], |
15509 | 485 |
) |
486 |
.send_all() |
|
487 |
.in_room(room_id), |
|
488 |
); |
|
489 |
} |
|
490 |
response.add( |
|
491 |
ClientFlags( |
|
492 |
add_flags(&[Flags::RoomMaster]), |
|
15545
f4f6060b536c
add a separate interface for modifying room state
alfadur <mail@none>
parents:
15544
diff
changeset
|
493 |
vec![room_control.server().client(new_master_id).nick.clone()], |
15509 | 494 |
) |
495 |
.send_all() |
|
496 |
.in_room(room_id), |
|
497 |
); |
|
498 |
} |
|
499 |
Err(ChangeMasterError::NoAccess) => { |
|
15504 | 500 |
response.warn("You're not the room master or a server admin!") |
15509 | 501 |
} |
502 |
Err(ChangeMasterError::AlreadyMaster) => { |
|
503 |
response.warn("You're already the room master.") |
|
14805 | 504 |
} |
15509 | 505 |
Err(ChangeMasterError::NoClient) => response.warn("Player is not online."), |
506 |
Err(ChangeMasterError::ClientNotInRoom) => { |
|
507 |
response.warn("The player is not in your room.") |
|
508 |
} |
|
509 |
}, |
|
14704
932ff7683653
Server action refactoring part 8 of N
alfadur <mail@none>
parents:
14697
diff
changeset
|
510 |
_ => warn!("Unimplemented!"), |
12147 | 511 |
} |
512 |
} |