--- a/rust/hedgewars-server/src/core/server.rs Thu Dec 19 23:13:58 2019 +0300
+++ b/rust/hedgewars-server/src/core/server.rs Sat Dec 21 00:26:17 2019 +0300
@@ -26,6 +26,7 @@
Restricted,
}
+#[derive(Debug)]
pub enum LeaveRoomResult {
RoomRemoved,
RoomRemains {
@@ -57,6 +58,19 @@
}
#[derive(Debug)]
+pub enum ModifyTeamError {
+ NoTeam,
+ NotMaster,
+}
+
+#[derive(Debug)]
+pub enum ModifyRoomNameError {
+ AccessDenied,
+ InvalidName,
+ DuplicateName,
+}
+
+#[derive(Debug)]
pub enum StartGameError {
NotEnoughClans,
NotEnoughTeams,
@@ -210,7 +224,7 @@
}
#[inline]
- pub fn client_mut(&mut self, client_id: ClientId) -> &mut HwClient {
+ fn client_mut(&mut self, client_id: ClientId) -> &mut HwClient {
&mut self.clients[client_id]
}
@@ -530,6 +544,73 @@
}
}
+ pub fn enable_super_power(&mut self, client_id: ClientId) -> bool {
+ let client = &mut self.clients[client_id];
+ if client.is_admin() {
+ client.set_has_super_power(true);
+ }
+ client.is_admin()
+ }
+
+ pub fn set_room_name(
+ &mut self,
+ client_id: ClientId,
+ room_id: RoomId,
+ mut name: String,
+ ) -> Result<String, ModifyRoomNameError> {
+ let room_exists = self.has_room(&name);
+ let room = &mut self.rooms[room_id];
+ if room.is_fixed() || room.master_id != Some(client_id) {
+ Err(ModifyRoomNameError::AccessDenied)
+ } else if utils::is_name_illegal(&name) {
+ Err(ModifyRoomNameError::InvalidName)
+ } else if room_exists {
+ Err(ModifyRoomNameError::DuplicateName)
+ } else {
+ std::mem::swap(&mut room.name, &mut name);
+ Ok(name)
+ }
+ }
+
+ pub fn add_team(&mut self, client_id: ClientId) {}
+
+ pub fn set_team_color(
+ &mut self,
+ client_id: ClientId,
+ room_id: RoomId,
+ team_name: &str,
+ color: u8,
+ ) -> Result<(), ModifyTeamError> {
+ let client = &self.clients[client_id];
+ let room = &mut self.rooms[room_id];
+ if let Some((owner, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) {
+ if !client.is_master() {
+ Err(ModifyTeamError::NotMaster)
+ } else {
+ team.color = color;
+ self.clients[owner].clan = Some(color);
+ Ok(())
+ }
+ } else {
+ Err(ModifyTeamError::NoTeam)
+ }
+ }
+
+ pub fn toggle_ready(&mut self, client_id: ClientId) -> bool {
+ let client = &mut self.clients[client_id];
+ if let Some(room_id) = client.room_id {
+ let room = &mut self.rooms[room_id];
+
+ client.set_is_ready(!client.is_ready());
+ if client.is_ready() {
+ room.ready_players_number += 1;
+ } else {
+ room.ready_players_number -= 1;
+ }
+ }
+ client.is_ready()
+ }
+
#[inline]
pub fn set_var(&mut self, client_id: ClientId, var: ServerVar) -> Result<(), AccessError> {
if self.clients[client_id].is_admin() {
--- a/rust/hedgewars-server/src/handlers.rs Thu Dec 19 23:13:58 2019 +0300
+++ b/rust/hedgewars-server/src/handlers.rs Sat Dec 21 00:26:17 2019 +0300
@@ -319,12 +319,10 @@
}
}
HwProtocolMessage::SuperPower => {
- let client = server.client_mut(client_id);
- if !client.is_admin() {
+ if server.enable_super_power(client_id) {
+ response.add(server_chat(SUPER_POWER.to_string()).send_self())
+ } else {
response.warn(ACCESS_DENIED);
- } else {
- client.set_has_super_power(true);
- response.add(server_chat(SUPER_POWER.to_string()).send_self())
}
}
HwProtocolMessage::Watch(id) => {
--- a/rust/hedgewars-server/src/handlers/inroom.rs Thu Dec 19 23:13:58 2019 +0300
+++ b/rust/hedgewars-server/src/handlers/inroom.rs Sat Dec 21 00:26:17 2019 +0300
@@ -3,7 +3,8 @@
core::{
room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM},
server::{
- ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, StartGameError,
+ ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, ModifyTeamError,
+ StartGameError,
},
types,
types::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM},
@@ -174,37 +175,31 @@
}
}
RoomName(new_name) => {
- if is_name_illegal(&new_name) {
- response.warn("Illegal room name! A room name must be between 1-40 characters long, must not have a trailing or leading space and must not have any of these characters: $()*+?[]^{|}");
- } else if server.has_room(&new_name) {
- response.warn("A room with the same name already exists.");
- } else {
- let (client, room) = server.client_and_room_mut(client_id, room_id);
- if room.is_fixed() || room.master_id != Some(client_id) {
- response.warn(ACCESS_DENIED);
- } else {
- let mut old_name = new_name.clone();
- swap(&mut room.name, &mut old_name);
- super::common::get_room_update(Some(old_name), room, Some(&client), response);
+ use crate::core::server::ModifyRoomNameError;
+ match server.set_room_name(client_id, room_id, new_name) {
+ Ok(old_name) => {
+ let (client, room) = server.client_and_room(client_id, room_id);
+ super::common::get_room_update(Some(old_name), room, Some(client), response)
}
+ Err(ModifyRoomNameError::AccessDenied) => response.warn(ACCESS_DENIED),
+ Err(ModifyRoomNameError::InvalidName) => response.warn(ILLEGAL_ROOM_NAME),
+ Err(ModifyRoomNameError::DuplicateName) => response.warn(ROOM_EXISTS),
}
}
ToggleReady => {
- let flags = if client.is_ready() {
- room.ready_players_number -= 1;
- remove_flags(&[Flags::Ready])
+ let flags = if server.toggle_ready(client_id) {
+ add_flags(&[Flags::Ready])
} else {
- room.ready_players_number += 1;
- add_flags(&[Flags::Ready])
+ remove_flags(&[Flags::Ready])
};
+ let (client, room) = server.client_and_room(client_id, room_id);
let msg = if client.protocol_number < 38 {
LegacyReady(client.is_ready(), vec![client.nick.clone()])
} else {
ClientFlags(flags, vec![client.nick.clone()])
};
- response.add(msg.send_all().in_room(room.id));
- client.set_is_ready(!client.is_ready());
+ 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);
@@ -307,21 +302,15 @@
}
}
SetTeamColor(team_name, color) => {
- if let Some((owner, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) {
- if !client.is_master() {
- response.error(NOT_MASTER);
- } else {
- team.color = color;
- response.add(
- TeamColor(team.name.clone(), color)
- .send_all()
- .in_room(room_id)
- .but_self(),
- );
- server.client_mut(owner).clan = Some(color);
- }
- } else {
- response.warn(NO_TEAM);
+ 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),
}
}
Cfg(cfg) => {