--- 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<String>),
RoundFinished,
+ Info(Vec<String>),
ServerMessage(String),
ServerVars(Vec<String>),
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],
--- 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)
+ }
}
--- 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<HWClient>,
pub rooms: Slab<HWRoom>,
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<HWRoom>) -> &mut HWRoom {
--- 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) => {