--- a/rust/hedgewars-server/src/main.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/main.rs Wed Apr 10 18:12:30 2019 +0300
@@ -15,10 +15,7 @@
fn main() {
env_logger::init();
- info!(
- "Hedgewars game server, protocol {}",
- utils::PROTOCOL_VERSION
- );
+ info!("Hedgewars game server, protocol {}", utils::SERVER_VERSION);
let address = "0.0.0.0:46631".parse().unwrap();
let listener = TcpListener::bind(&address).unwrap();
--- a/rust/hedgewars-server/src/protocol/messages.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/protocol/messages.rs Wed Apr 10 18:12:30 2019 +0300
@@ -118,8 +118,8 @@
Nick(String),
Proto(u16),
AskPassword(String),
+ ServerAuth(String),
- ServerAuth(String),
LobbyLeft(String, String),
LobbyJoined(Vec<String>),
ChatMsg { nick: String, msg: String },
@@ -142,6 +142,7 @@
RoundFinished,
ServerMessage(String),
+ ServerVars(Vec<String>),
Notice(String),
Warning(String),
Error(String),
@@ -159,6 +160,16 @@
}
}
+impl ServerVar {
+ pub fn to_protocol(&self) -> Vec<String> {
+ match self {
+ ServerVar::MOTDNew(s) => vec!["MOTD_NEW".to_string(), s.clone()],
+ ServerVar::MOTDOld(s) => vec!["MOTD_OLD".to_string(), s.clone()],
+ ServerVar::LatestProto(n) => vec!["LATEST_PROTO".to_string(), n.to_string()],
+ }
+ }
+}
+
impl GameCfg {
pub fn to_protocol(&self) -> (String, Vec<String>) {
use crate::server::coretypes::GameCfg::*;
@@ -251,7 +262,7 @@
BanNick(nick, reason, time) => msg!("BAN_NICK", nick, reason, time),
BanList => msg!["BANLIST"],
Unban(name) => msg!["UNBAN", name],
- //SetServerVar(ServerVar), ???
+ SetServerVar(var) => construct_message(&["SET_SERVER_VAR"], &var.to_protocol()),
GetServerVar => msg!["GET_SERVER_VAR"],
RestartServer => msg!["CMD", "RESTART_SERVER YES"],
Stats => msg!["CMD", "STATS"],
@@ -351,6 +362,7 @@
RoundFinished => msg!["ROUND_FINISHED"],
ChatMsg { nick, msg } => msg!["CHAT", nick, msg],
ServerMessage(msg) => msg!["SERVER_MESSAGE", msg],
+ ServerVars(vars) => construct_message(&["SERVER_VARS"], &vars),
Notice(msg) => msg!["NOTICE", msg],
Warning(msg) => msg!["WARNING", msg],
Error(msg) => msg!["ERROR", msg],
--- a/rust/hedgewars-server/src/protocol/parser.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/protocol/parser.rs Wed Apr 10 18:12:30 2019 +0300
@@ -15,7 +15,9 @@
};
use super::messages::{HWProtocolMessage, HWProtocolMessage::*};
-use crate::server::coretypes::{GameCfg, HedgehogInfo, TeamInfo, VoteType, MAX_HEDGEHOGS_PER_TEAM};
+use crate::server::coretypes::{
+ GameCfg, HedgehogInfo, ServerVar, TeamInfo, VoteType, MAX_HEDGEHOGS_PER_TEAM,
+};
#[derive(Debug, PartialEq)]
pub struct HWProtocolError {}
@@ -369,6 +371,27 @@
Ok((i, Cfg(cfg)))
}
+fn server_var_message(input: &[u8]) -> HWResult<HWProtocolMessage> {
+ precededc(
+ input,
+ hw_tag("SET_SERVER_VAR\n"),
+ alt((
+ |i| {
+ precededc(i, hw_tag("MOTD_NEW\n"), a_line)
+ .map(|(i, s)| (i, SetServerVar(ServerVar::MOTDNew(s))))
+ },
+ |i| {
+ precededc(i, hw_tag("MOTD_OLD\n"), a_line)
+ .map(|(i, s)| (i, SetServerVar(ServerVar::MOTDOld(s))))
+ },
+ |i| {
+ precededc(i, hw_tag("LATEST_PROTO\n"), u16_line)
+ .map(|(i, n)| (i, SetServerVar(ServerVar::LatestProto(n))))
+ },
+ )),
+ )
+}
+
fn complex_message(input: &[u8]) -> HWResult<HWProtocolMessage> {
alt((
|i| {
@@ -527,6 +550,7 @@
single_arg_message,
cmd_message,
config_message,
+ server_var_message,
complex_message,
)),
end_of_message,
--- a/rust/hedgewars-server/src/protocol/test.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/protocol/test.rs Wed Apr 10 18:12:30 2019 +0300
@@ -4,7 +4,7 @@
test_runner::{Reason, TestRunner},
};
-use crate::server::coretypes::{GameCfg, HedgehogInfo, TeamInfo};
+use crate::server::coretypes::{GameCfg, HedgehogInfo, ServerVar, ServerVar::*, TeamInfo};
use super::messages::{HWProtocolMessage, HWProtocolMessage::*};
@@ -146,6 +146,25 @@
type Strategy = BoxedStrategy<TeamInfo>;
}
+impl Arbitrary for ServerVar {
+ type Parameters = ();
+
+ fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
+ (0..2)
+ .no_shrink()
+ .prop_flat_map(|i| {
+ proto_msg_match!(i, def = ServerVar::LatestProto(0),
+ 0 => MOTDNew(Ascii),
+ 1 => MOTDOld(Ascii),
+ 2 => LatestProto(u16)
+ )
+ })
+ .boxed()
+ }
+
+ type Strategy = BoxedStrategy<ServerVar>;
+}
+
pub fn gen_proto_msg() -> BoxedStrategy<HWProtocolMessage> where {
let res = (0..58).no_shrink().prop_flat_map(|i| {
proto_msg_match!(i, def = Malformed,
@@ -174,7 +193,7 @@
22 => BanNick(Ascii, Ascii, u32),
23 => BanList(),
24 => Unban(Ascii),
- //25 => SetServerVar(ServerVar),
+ 25 => SetServerVar(ServerVar),
26 => GetServerVar(),
27 => RestartServer(),
28 => Stats(),
--- a/rust/hedgewars-server/src/server/core.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/server/core.rs Wed Apr 10 18:12:30 2019 +0300
@@ -6,6 +6,7 @@
};
use crate::utils;
+use crate::protocol::messages::HWProtocolMessage::Greeting;
use log::*;
use slab;
use std::{borrow::BorrowMut, iter, num::NonZeroU16};
@@ -45,10 +46,26 @@
}
}
+pub struct ServerGreetings {
+ pub for_latest_protocol: String,
+ pub for_old_protocols: String,
+}
+
+impl ServerGreetings {
+ fn new() -> Self {
+ Self {
+ for_latest_protocol: "\u{1f994} is watching".to_string(),
+ for_old_protocols: "\u{1f994} is watching".to_string(),
+ }
+ }
+}
+
pub struct HWServer {
pub clients: IndexSlab<HWClient>,
pub rooms: Slab<HWRoom>,
pub anteroom: HWAnteroom,
+ pub latest_protocol: u16,
+ pub greetings: ServerGreetings,
}
impl HWServer {
@@ -59,6 +76,8 @@
clients,
rooms,
anteroom: HWAnteroom::new(clients_limit),
+ greetings: ServerGreetings::new(),
+ latest_protocol: 58,
}
}
@@ -74,6 +93,14 @@
self.clients.remove(client_id);
}
+ pub fn get_greetings(&self, client_id: ClientId) -> &str {
+ if self.clients[client_id].protocol_number < self.latest_protocol {
+ &self.greetings.for_old_protocols
+ } else {
+ &self.greetings.for_latest_protocol
+ }
+ }
+
#[inline]
pub fn create_room(
&mut self,
--- a/rust/hedgewars-server/src/server/coretypes.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/server/coretypes.rs Wed Apr 10 18:12:30 2019 +0300
@@ -7,7 +7,7 @@
pub enum ServerVar {
MOTDNew(String),
MOTDOld(String),
- LatestProto(u32),
+ LatestProto(u16),
}
#[derive(PartialEq, Eq, Clone, Debug)]
--- a/rust/hedgewars-server/src/server/handlers.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers.rs Wed Apr 10 18:12:30 2019 +0300
@@ -233,7 +233,7 @@
server.anteroom.add_client(client_id, encode(&salt));
- response.add(HWServerMessage::Connected(utils::PROTOCOL_VERSION).send_self());
+ response.add(HWServerMessage::Connected(utils::SERVER_VERSION).send_self());
}
pub fn handle_client_loss(server: &mut HWServer, client_id: ClientId, response: &mut Response) {
--- a/rust/hedgewars-server/src/server/handlers/common.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers/common.rs Wed Apr 10 18:12:30 2019 +0300
@@ -47,7 +47,7 @@
add_flags(&[Flags::InRoom]),
server.collect_nicks(|(_, c)| c.room_id.is_some()),
);
- let server_msg = ServerMessage("\u{1f994} is watching".to_string());
+ let server_msg = ServerMessage(server.get_greetings(client_id).to_string());
let rooms_msg = Rooms(
server
@@ -138,9 +138,12 @@
if client.is_master() && !room.is_fixed() {
client.set_is_master(false);
response.add(
- ClientFlags(remove_flags(&[Flags::RoomMaster]), vec![client.nick.clone()])
- .send_all()
- .in_room(room.id),
+ ClientFlags(
+ remove_flags(&[Flags::RoomMaster]),
+ vec![client.nick.clone()],
+ )
+ .send_all()
+ .in_room(room.id),
);
room.master_id = None;
}
--- a/rust/hedgewars-server/src/server/handlers/lobby.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers/lobby.rs Wed Apr 10 18:12:30 2019 +0300
@@ -5,7 +5,10 @@
protocol::messages::{
add_flags, remove_flags, HWProtocolMessage, HWServerMessage::*, ProtocolFlags as Flags,
},
- server::{core::HWServer, coretypes::ClientId},
+ server::{
+ core::HWServer,
+ coretypes::{ClientId, ServerVar},
+ },
utils::is_name_illegal,
};
use log::*;
@@ -108,6 +111,32 @@
response.add(Warning("No such room.".to_string()).send_self());
}
}
+ SetServerVar(var) => {
+ if !server.clients[client_id].is_admin() {
+ response.add(Warning("Access denied.".to_string()).send_self());
+ } else {
+ match var {
+ ServerVar::MOTDNew(msg) => server.greetings.for_latest_protocol = msg,
+ ServerVar::MOTDOld(msg) => server.greetings.for_old_protocols = msg,
+ ServerVar::LatestProto(n) => server.latest_protocol = n,
+ }
+ }
+ }
+ GetServerVar => {
+ if !server.clients[client_id].is_admin() {
+ response.add(Warning("Access denied.".to_string()).send_self());
+ } else {
+ let vars: Vec<_> = [
+ ServerVar::MOTDNew(server.greetings.for_latest_protocol.clone()),
+ ServerVar::MOTDOld(server.greetings.for_old_protocols.clone()),
+ ServerVar::LatestProto(server.latest_protocol),
+ ]
+ .iter()
+ .flat_map(|v| v.to_protocol())
+ .collect();
+ response.add(ServerVars(vars).send_self());
+ }
+ }
Rnd(v) => {
response.add(rnd_reply(&v).send_self());
}
--- a/rust/hedgewars-server/src/utils.rs Wed Apr 10 16:14:33 2019 +0300
+++ b/rust/hedgewars-server/src/utils.rs Wed Apr 10 18:12:30 2019 +0300
@@ -2,7 +2,7 @@
use mio;
use std::iter::Iterator;
-pub const PROTOCOL_VERSION: u32 = 3;
+pub const SERVER_VERSION: u32 = 3;
pub const SERVER_TOKEN: mio::Token = mio::Token(1_000_000_000);
pub const IO_TOKEN: mio::Token = mio::Token(1_000_000_001);