--- a/rust/hedgewars-server/src/handlers/inroom.rs Mon Dec 23 18:55:25 2019 +0300
+++ b/rust/hedgewars-server/src/handlers/inroom.rs Mon Dec 23 23:47:06 2019 +0300
@@ -1,11 +1,11 @@
use super::{common::rnd_reply, strings::*};
use crate::core::room::GameInfo;
-use crate::core::server::AddTeamError;
+use crate::core::server::{AddTeamError, SetTeamCountError};
use crate::{
core::{
room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM},
server::{
- ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, ModifyTeamError,
+ ChangeMasterError, ChangeMasterResult, HwRoomControl, LeaveRoomResult, ModifyTeamError,
StartGameError,
},
types,
@@ -106,13 +106,12 @@
}
pub fn handle(
- server: &mut HwServer,
- client_id: ClientId,
+ mut room_control: HwRoomControl,
response: &mut super::Response,
- room_id: RoomId,
message: HwProtocolMessage,
) {
- let (client, room) = server.client_and_room_mut(client_id, room_id);
+ let (client, room) = room_control.get();
+ let (client_id, room_id) = (client.id, room.id);
use crate::protocol::messages::HwProtocolMessage::*;
match message {
@@ -122,8 +121,14 @@
None => "part".to_string(),
};
- let result = server.leave_room(client_id);
- super::common::get_room_leave_data(server, room_id, &msg, result, response);
+ let result = room_control.leave_room();
+ super::common::get_room_leave_result(
+ room_control.server(),
+ room_control.room(),
+ &msg,
+ result,
+ response,
+ );
}
Chat(msg) => {
response.add(
@@ -146,41 +151,35 @@
}
}
Fix => {
- if client.is_admin() {
- room.set_is_fixed(true);
- room.set_join_restriction(false);
- room.set_team_add_restriction(false);
- room.set_unregistered_players_restriction(true);
- } else {
+ if let Err(_) = room_control.fix_room() {
response.warn(ACCESS_DENIED)
}
}
Unfix => {
- if client.is_admin() {
- room.set_is_fixed(false);
- } else {
+ if let Err(_) = room_control.unfix_room() {
response.warn(ACCESS_DENIED)
}
}
Greeting(text) => {
- if client.is_admin() || client.is_master() && !room.is_fixed() {
- room.greeting = text.unwrap_or(String::new());
+ if let Err(_) = room_control.set_room_greeting(text) {
+ response.warn(ACCESS_DENIED)
}
}
MaxTeams(count) => {
- if !client.is_master() {
- response.warn(NOT_MASTER);
- } else if !(2..=MAX_TEAMS_IN_ROOM).contains(&count) {
- response.warn("/maxteams: specify number from 2 to 8");
- } else {
- room.max_teams = count;
- }
+ use crate::core::server::SetTeamCountError;
+ match room_control.set_room_max_teams(count) {
+ Ok(()) => {}
+ Err(SetTeamCountError::NotMaster) => response.warn(NOT_MASTER),
+ Err(SetTeamCountError::InvalidNumber) => {
+ response.warn("/maxteams: specify number from 2 to 8")
+ }
+ };
}
RoomName(new_name) => {
use crate::core::server::ModifyRoomNameError;
- match server.set_room_name(client_id, room_id, new_name) {
+ match room_control.set_room_name(new_name) {
Ok(old_name) => {
- let (client, room) = server.client_and_room(client_id, room_id);
+ let (client, room) = room_control.get();
super::common::get_room_update(Some(old_name), room, Some(client), response)
}
Err(ModifyRoomNameError::AccessDenied) => response.warn(ACCESS_DENIED),
@@ -189,12 +188,12 @@
}
}
ToggleReady => {
- let flags = if server.toggle_ready(client_id) {
+ let flags = if room_control.toggle_ready() {
add_flags(&[Flags::Ready])
} else {
remove_flags(&[Flags::Ready])
};
- let (client, room) = server.client_and_room(client_id, room_id);
+ let (client, room) = room_control.get();
let msg = if client.protocol_number < 38 {
LegacyReady(client.is_ready(), vec![client.nick.clone()])
@@ -204,13 +203,18 @@
response.add(msg.send_all().in_room(room_id));
if room.is_fixed() && room.ready_players_number == room.players_number {
- let result = server.start_game(room_id);
- super::common::get_start_game_data(server, room_id, result, response);
+ let result = room_control.start_game();
+ super::common::get_start_game_data(
+ room_control.server(),
+ room_id,
+ result,
+ response,
+ );
}
}
AddTeam(info) => {
use crate::core::server::AddTeamError;
- match server.add_team(client_id, info) {
+ match room_control.add_team(info) {
Ok(team) => {
response.add(TeamAccepted(team.name.clone()).send_self());
response.add(
@@ -230,9 +234,9 @@
.in_room(room_id),
);
- let room = server.room(room_id);
+ let room = room_control.room();
let room_master = if let Some(id) = room.master_id {
- Some(server.client(id))
+ Some(room_control.server().client(id))
} else {
None
};
@@ -247,9 +251,9 @@
}
RemoveTeam(name) => {
use crate::core::server::RemoveTeamError;
- match server.remove_team(client_id, &name) {
+ match room_control.remove_team(&name) {
Ok(()) => {
- let (client, room) = server.client_and_room(client_id, room_id);
+ let (client, room) = room_control.get();
let removed_teams = vec![name];
super::common::get_remove_teams_data(
@@ -261,8 +265,14 @@
match room.game_info {
Some(ref info) if info.teams_in_game == 0 => {
- let result = server.end_game(room_id);
- super::common::get_end_game_result(server, room_id, result, response);
+ if let Some(result) = room_control.end_game() {
+ super::common::get_end_game_result(
+ room_control.server(),
+ room_id,
+ result,
+ response,
+ );
+ }
}
_ => (),
}
@@ -272,62 +282,42 @@
}
}
SetHedgehogsNumber(team_name, number) => {
- let addable_hedgehogs = room.addable_hedgehogs();
- if let Some((_, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) {
- let max_hedgehogs = min(
- MAX_HEDGEHOGS_PER_TEAM,
- addable_hedgehogs + team.hedgehogs_number,
- );
- if !client.is_master() {
- response.error(NOT_MASTER);
- } else if !(1..=max_hedgehogs).contains(&number) {
- response
- .add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send_self());
- } else {
- team.hedgehogs_number = number;
+ use crate::core::server::SetHedgehogsError;
+ match room_control.set_team_hedgehogs_number(&team_name, number) {
+ Ok(()) => {
response.add(
- HedgehogsNumber(team.name.clone(), number)
+ HedgehogsNumber(team_name.clone(), number)
.send_all()
.in_room(room_id)
.but_self(),
);
}
- } else {
- response.warn(NO_TEAM);
- }
- }
- SetTeamColor(team_name, color) => {
- match server.set_team_color(client_id, room_id, &team_name, color) {
- Ok(()) => response.add(
- TeamColor(team_name, color)
- .send_all()
- .in_room(room_id)
- .but_self(),
- ),
- Err(ModifyTeamError::NoTeam) => response.warn(NO_TEAM),
- Err(ModifyTeamError::NotMaster) => response.error(NOT_MASTER),
+ Err(SetHedgehogsError::NotMaster) => response.error(NOT_MASTER),
+ Err(SetHedgehogsError::NoTeam) => response.warn(NO_TEAM),
+ Err(SetHedgehogsError::InvalidNumber(previous_number)) => {
+ response.add(HedgehogsNumber(team_name.clone(), previous_number).send_self())
+ }
}
}
+ SetTeamColor(team_name, color) => match room_control.set_team_color(&team_name, color) {
+ Ok(()) => response.add(
+ TeamColor(team_name, color)
+ .send_all()
+ .in_room(room_id)
+ .but_self(),
+ ),
+ Err(ModifyTeamError::NoTeam) => response.warn(NO_TEAM),
+ Err(ModifyTeamError::NotMaster) => response.error(NOT_MASTER),
+ },
Cfg(cfg) => {
- if room.is_fixed() {
- response.warn(ACCESS_DENIED);
- } else if !client.is_master() {
- response.error(NOT_MASTER);
- } else {
- let cfg = match cfg {
- GameCfg::Scheme(name, mut values) => {
- if client.protocol_number == 49 && values.len() >= 2 {
- let mut s = "X".repeat(50);
- s.push_str(&values.pop().unwrap());
- values.push(s);
- }
- GameCfg::Scheme(name, values)
- }
- cfg => cfg,
- };
-
- response.add(cfg.to_server_msg().send_all().in_room(room.id).but_self());
- room.set_config(cfg);
+ use crate::core::server::SetConfigError;
+ let msg = cfg.to_server_msg();
+ match room_control.set_config(cfg) {
+ Ok(()) => {
+ response.add(msg.send_all().in_room(room_control.room().id).but_self());
+ }
+ Err(SetConfigError::NotMaster) => response.error(NOT_MASTER),
+ Err(SetConfigError::RoomFixed) => response.warn(ACCESS_DENIED),
}
}
Save(name, location) => {
@@ -336,7 +326,7 @@
.send_all()
.in_room(room_id),
);
- room.save_config(name, location);
+ room_control.save_config(name, location);
}
#[cfg(feature = "official-server")]
SaveRoom(filename) => {
@@ -361,7 +351,7 @@
}
}
Delete(name) => {
- if !room.delete_config(&name) {
+ if !room_control.delete_config(&name) {
response.add(Warning(format!("Save doesn't exist: {}", name)).send_self());
} else {
response.add(
@@ -375,11 +365,11 @@
response.add(server_chat("Available callvote commands: kick <nickname>, map <name>, pause, newseed, hedgehogs <number>".to_string())
.send_self());
}
- CallVote(Some(kind)) => {
+ /*CallVote(Some(kind)) => {
let is_in_game = room.game_info.is_some();
let error = match &kind {
VoteType::Kick(nick) => {
- if server
+ if room_control.server()
.find_client(&nick)
.filter(|c| c.room_id == Some(room_id))
.is_some()
@@ -390,7 +380,7 @@
}
}
VoteType::Map(None) => {
- let names: Vec<_> = server.room(room_id).saves.keys().cloned().collect();
+ let names: Vec<_> = room.saves.keys().cloned().collect();
if names.is_empty() {
Some("/callvote map: No maps saved in this room!".to_string())
} else {
@@ -421,12 +411,12 @@
match error {
None => {
let msg = voting_description(&kind);
- let voting = Voting::new(kind, server.room_clients(client_id).collect());
- let room = server.room_mut(room_id);
+ let voting = Voting::new(kind, room_control.server().room_clients(client_id).collect());
+ let room = room_control.server().room_mut(room_id);
room.voting = Some(voting);
response.add(server_chat(msg).send_all().in_room(room_id));
super::common::submit_vote(
- server,
+ room_control.server(),
types::Vote {
is_pro: true,
is_forced: false,
@@ -438,39 +428,39 @@
response.add(server_chat(msg).send_self());
}
}
- }
- Vote(vote) => {
+ }*/
+ /*Vote(vote) => {
super::common::submit_vote(
- server,
+ room_control.server(),
types::Vote {
is_pro: vote,
is_forced: false,
},
response,
);
- }
- ForceVote(vote) => {
+ }*/
+ /*ForceVote(vote) => {
let is_forced = client.is_admin();
super::common::submit_vote(
- server,
+ room_control.server(),
types::Vote {
is_pro: vote,
is_forced,
},
response,
);
- }
+ }*/
ToggleRestrictJoin | ToggleRestrictTeams | ToggleRegisteredOnly => {
- if client.is_master() {
- room.flags.toggle(room_message_flag(&message));
+ if room_control.toggle_flag(room_message_flag(&message)) {
+ let (client, room) = room_control.get();
super::common::get_room_update(None, room, Some(&client), response);
}
}
StartGame => {
- let result = server.start_game(room_id);
- super::common::get_start_game_data(server, room_id, result, response);
+ let result = room_control.start_game();
+ super::common::get_start_game_data(room_control.server(), room_id, result, response);
}
- EngineMessage(em) => {
+ /*EngineMessage(em) => {
if client.teams_in_game > 0 {
let decoding = decode(&em[..]).unwrap();
let messages = by_msg(&decoding);
@@ -503,10 +493,10 @@
}
}
}
- }
+ }*/
RoundFinished => {
- if let Some(team_names) = server.leave_game(client_id) {
- let (client, room) = server.client_and_room(client_id, room_id);
+ if let Some(team_names) = room_control.leave_game() {
+ let (client, room) = room_control.get();
response.add(
ClientFlags(remove_flags(&[Flags::InGame]), vec![client.nick.clone()])
.send_all()
@@ -527,8 +517,14 @@
teams_in_game: 0, ..
}) = room.game_info
{
- let result = server.end_game(room_id);
- super::common::get_end_game_result(server, room_id, result, response);
+ if let Some(result) = room_control.end_game() {
+ super::common::get_end_game_result(
+ room_control.server(),
+ room_id,
+ result,
+ response,
+ );
+ }
}
}
}
@@ -537,13 +533,13 @@
let mut echo = vec!["/rnd".to_string()];
echo.extend(v.into_iter());
let chat_msg = ChatMsg {
- nick: server.client(client_id).nick.clone(),
+ nick: client.nick.clone(),
msg: echo.join(" "),
};
response.add(chat_msg.send_all().in_room(room_id));
response.add(result.send_all().in_room(room_id));
}
- Delegate(nick) => match server.change_master(client_id, room_id, nick) {
+ Delegate(nick) => match room_control.change_master(nick) {
Ok(ChangeMasterResult {
old_master_id,
new_master_id,
@@ -552,7 +548,7 @@
response.add(
ClientFlags(
remove_flags(&[Flags::RoomMaster]),
- vec![server.client(master_id).nick.clone()],
+ vec![room_control.server().client(master_id).nick.clone()],
)
.send_all()
.in_room(room_id),
@@ -561,7 +557,7 @@
response.add(
ClientFlags(
add_flags(&[Flags::RoomMaster]),
- vec![server.client(new_master_id).nick.clone()],
+ vec![room_control.server().client(new_master_id).nick.clone()],
)
.send_all()
.in_room(room_id),