# HG changeset patch # User alfadur # Date 1554934409 -10800 # Node ID 8ecdb5c6bb2ae6ca223706546596af713455c061 # Parent a1077e8d26f4571d6e49f09cc64623144cf529a2 implement info, registered only & super power messages diff -r a1077e8d26f4 -r 8ecdb5c6bb2a rust/hedgewars-server/src/protocol/messages.rs --- a/rust/hedgewars-server/src/protocol/messages.rs Wed Apr 10 23:56:53 2019 +0300 +++ b/rust/hedgewars-server/src/protocol/messages.rs Thu Apr 11 01:13:29 2019 +0300 @@ -141,6 +141,7 @@ ForwardEngineMessage(Vec), RoundFinished, + Info(Vec), ServerMessage(String), ServerVars(Vec), Notice(String), @@ -389,6 +390,7 @@ ForwardEngineMessage(em) => construct_message(&["EM"], &em), RoundFinished => msg!["ROUND_FINISHED"], ChatMsg { nick, msg } => msg!["CHAT", nick, msg], + Info(info) => construct_message(&["INFO"], &info), ServerMessage(msg) => msg!["SERVER_MESSAGE", msg], ServerVars(vars) => construct_message(&["SERVER_VARS"], &vars), Notice(msg) => msg!["NOTICE", msg], diff -r a1077e8d26f4 -r 8ecdb5c6bb2a rust/hedgewars-server/src/server/client.rs --- a/rust/hedgewars-server/src/server/client.rs Wed Apr 10 23:56:53 2019 +0300 +++ b/rust/hedgewars-server/src/server/client.rs Thu Apr 11 01:13:29 2019 +0300 @@ -10,6 +10,7 @@ const IS_JOINED_MID_GAME = 0b0001_0000; const IS_CHECKER = 0b0010_0000; const IS_CONTRIBUTOR = 0b0100_0000; + const HAS_SUPER_POWER = 0b1000_0000; const NONE = 0b0000_0000; const DEFAULT = Self::NONE.bits; @@ -70,6 +71,9 @@ pub fn is_contributor(&self) -> bool { self.contains(ClientFlags::IS_CONTRIBUTOR) } + pub fn has_super_power(&self) -> bool { + self.contains(ClientFlags::HAS_SUPER_POWER) + } pub fn set_is_admin(&mut self, value: bool) { self.set(ClientFlags::IS_ADMIN, value) @@ -92,4 +96,7 @@ pub fn set_is_contributor(&mut self, value: bool) { self.set(ClientFlags::IS_CONTRIBUTOR, value) } + pub fn set_has_super_power(&mut self, value: bool) { + self.set(ClientFlags::HAS_SUPER_POWER, value) + } } diff -r a1077e8d26f4 -r 8ecdb5c6bb2a rust/hedgewars-server/src/server/core.rs --- a/rust/hedgewars-server/src/server/core.rs Wed Apr 10 23:56:53 2019 +0300 +++ b/rust/hedgewars-server/src/server/core.rs Thu Apr 11 01:13:29 2019 +0300 @@ -7,6 +7,7 @@ use crate::utils; use crate::protocol::messages::HWProtocolMessage::Greeting; +use bitflags::*; use log::*; use slab; use std::{borrow::BorrowMut, iter, num::NonZeroU16}; @@ -60,11 +61,18 @@ } } +bitflags! { + pub struct ServerFlags: u8 { + const REGISTERED_ONLY = 0b0000_1000; + } +} + pub struct HWServer { pub clients: IndexSlab, pub rooms: Slab, pub anteroom: HWAnteroom, pub latest_protocol: u16, + pub flags: ServerFlags, pub greetings: ServerGreetings, } @@ -78,6 +86,7 @@ anteroom: HWAnteroom::new(clients_limit), greetings: ServerGreetings::new(), latest_protocol: 58, + flags: ServerFlags::empty(), } } @@ -183,6 +192,14 @@ let room_id = self.clients[self_id].room_id; self.collect_clients(|(id, c)| *id != self_id && c.room_id == room_id) } + + pub fn is_registered_only(&self) -> bool { + self.flags.contains(ServerFlags::REGISTERED_ONLY) + } + + pub fn set_is_registered_only(&mut self, value: bool) { + self.flags.set(ServerFlags::REGISTERED_ONLY, value) + } } fn allocate_room(rooms: &mut Slab) -> &mut HWRoom { diff -r a1077e8d26f4 -r 8ecdb5c6bb2a rust/hedgewars-server/src/server/handlers.rs --- a/rust/hedgewars-server/src/server/handlers.rs Wed Apr 10 23:56:53 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers.rs Thu Apr 11 01:13:29 2019 +0300 @@ -222,6 +222,50 @@ HWProtocolMessage::Quit(None) => { common::remove_client(server, response, "User quit".to_string()); } + HWProtocolMessage::Info(nick) => { + if let Some(client) = server.find_client(&nick) { + let admin_sign = if client.is_admin() { "@" } else { "" }; + let master_sign = if client.is_master() { "+" } else { "" }; + let room_info = match client.room_id { + Some(room_id) => { + let room = &server.rooms[room_id]; + let status = match room.game_info { + Some(_) if client.teams_in_game == 0 => "(spectating)", + Some(_) => "(playing)", + None => "", + }; + format!( + "[{}{}room {}]{}", + admin_sign, master_sign, room.name, status + ) + } + None => format!("[{}lobby]", admin_sign), + }; + + let info = vec![ + client.nick.clone(), + utils::protocol_version_string(client.protocol_number).to_string(), + room_info, + ]; + Info(info); + } else { + response + .add(server_chat("Player is not online.".to_string()).send_self()) + } + } + HWProtocolMessage::ToggleServerRegisteredOnly => { + if !server.clients[client_id].is_admin() { + response.add(Warning("Access denied.".to_string()).send_self()); + } else { + server.set_is_registered_only(server.is_registered_only()); + let msg = if server.is_registered_only() { + "This server no longer allows unregistered players to join." + } else { + "This server now allows unregistered players to join." + }; + response.add(server_chat(msg.to_string()).send_all()); + } + } HWProtocolMessage::Global(msg) => { if !server.clients[client_id].is_admin() { response.add(Warning("Access denied.".to_string()).send_self()); @@ -229,6 +273,15 @@ response.add(global_chat(msg).send_all()) } } + HWProtocolMessage::SuperPower => { + if !server.clients[client_id].is_admin() { + response.add(Warning("Access denied.".to_string()).send_self()); + } else { + server.clients[client_id].set_has_super_power(true); + response + .add(server_chat("Super power activated.".to_string()).send_self()) + } + } HWProtocolMessage::Watch(id) => { #[cfg(feature = "official-server")] { @@ -278,12 +331,20 @@ ) { match io_result { IoResult::Account(Some(info)) => { - response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self()); - if let Some(client) = server.anteroom.remove_client(client_id) { - server.add_client(client_id, client); - let client = &mut server.clients[client_id]; - client.set_is_admin(info.is_admin); - client.set_is_contributor(info.is_admin) + if !info.is_registered && server.is_registered_only() { + response.add( + Bye("This server only allows registered users to join.".to_string()) + .send_self(), + ); + response.remove_client(client_id); + } else { + response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self()); + if let Some(client) = server.anteroom.remove_client(client_id) { + server.add_client(client_id, client); + let client = &mut server.clients[client_id]; + client.set_is_admin(info.is_admin); + client.set_is_contributor(info.is_admin) + } } } IoResult::Account(None) => {