--- a/gameServer2/src/protocol/messages.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/protocol/messages.rs Sun Sep 09 01:20:35 2018 +0300
@@ -100,10 +100,14 @@
RoundFinished,
ServerMessage(String),
+ Notice(String),
Warning(String),
Error(String),
Connected(u32),
Unreachable,
+
+ //Deprecated messages
+ LegacyReady(bool, Vec<String>)
}
pub fn server_chat(msg: String) -> HWServerMessage {
@@ -123,8 +127,8 @@
Ammo(n, None) => ("AMMO".to_string(), vec![n.to_string()]),
Ammo(n, Some(s)) => ("AMMO".to_string(), vec![n.to_string(), s.to_string()]),
- Scheme(n, None) => ("SCHEME".to_string(), vec![n.to_string()]),
- Scheme(n, Some(s)) => ("SCHEME".to_string(), {
+ Scheme(n, s) if s.is_empty() => ("SCHEME".to_string(), vec![n.to_string()]),
+ Scheme(n, s) => ("SCHEME".to_string(), {
let mut v = vec![n.to_string()];
v.extend(s.clone().into_iter());
v
@@ -299,8 +303,13 @@
RoundFinished => msg!["ROUND_FINISHED"],
ChatMsg {nick, msg} => msg!["CHAT", nick, msg],
ServerMessage(msg) => msg!["SERVER_MESSAGE", msg],
+ Notice(msg) => msg!["NOTICE", msg],
Warning(msg) => msg!["WARNING", msg],
Error(msg) => msg!["ERROR", msg],
+
+ LegacyReady(is_ready, nicks) =>
+ construct_message(&[if *is_ready {"READY"} else {"NOT_READY"}], &nicks),
+
_ => msg!["ERROR", "UNIMPLEMENTED"],
}
}
--- a/gameServer2/src/protocol/parser.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/protocol/parser.rs Sun Sep 09 01:20:35 2018 +0300
@@ -197,7 +197,7 @@
| do_parse!(tag!("SCHEME") >> eol >>
name: a_line >>
values: opt!(preceded!(eol, separated_list!(eol, a_line))) >>
- (GameCfg::Scheme(name, values)))
+ (GameCfg::Scheme(name, values.unwrap_or(Vec::new()))))
| do_parse!(tag!("FEATURE_SIZE") >> eol >>
value: u32_line >>
(GameCfg::FeatureSize(value)))
--- a/gameServer2/src/protocol/test.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/protocol/test.rs Sun Sep 09 01:20:35 2018 +0300
@@ -22,9 +22,6 @@
impl Into2<Option<String>> for Option<Ascii>{
fn into2(self) -> Option<String> { self.map(|x| {x.0}) }
}
-impl Into2<Option<Vec<String>>> for Option<Vec<Ascii>>{
- fn into2(self) -> Option<Vec<String>> { self.map(|x| {x.into2()}) }
-}
macro_rules! proto_msg_case {
($val: ident()) =>
@@ -74,7 +71,7 @@
4 => Seed(Ascii),
5 => Template(u32),
6 => Ammo(Ascii, Option<Ascii>),
- 7 => Scheme(Ascii, Option<Vec<Ascii>>),
+ 7 => Scheme(Ascii, Vec<Ascii>),
8 => Script(Ascii),
9 => Theme(Ascii),
10 => DrawnMap(Ascii))
--- a/gameServer2/src/server/actions.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/server/actions.rs Sun Sep 09 01:20:35 2018 +0300
@@ -143,12 +143,25 @@
},
ReactProtocolMessage(msg) =>
handlers::handle(server, client_id, msg),
- CheckRegistered =>
- if server.clients[client_id].protocol_number > 0 && server.clients[client_id].nick != "" {
- server.react(client_id, vec![
- JoinLobby,
- ]);
- },
+ CheckRegistered => {
+ let client = &server.clients[client_id];
+ if client.protocol_number > 0 && client.nick != "" {
+ let has_nick_clash = server.clients.iter().any(
+ |(id, c)| id != client_id && c.nick == client.nick);
+
+ let actions = if !client.is_checker() && has_nick_clash {
+ if client.protocol_number < 38 {
+ vec![ByeClient("Nickname is already in use".to_string())]
+ } else {
+ server.clients[client_id].nick.clear();
+ vec![Notice("NickAlreadyInUse".to_string()).send_self().action()]
+ }
+ } else {
+ vec![JoinLobby]
+ };
+ server.react(client_id, actions);
+ }
+ },
JoinLobby => {
server.clients[client_id].room_id = Some(server.lobby_id);
@@ -466,6 +479,9 @@
None => {}
}
r.master_id = new_id;
+ if !r.is_fixed() && c.protocol_number < 42 {
+ r.name.replace_range(.., new_nick.as_ref().map_or("[]", String::as_str));
+ }
r.set_join_restriction(false);
r.set_team_add_restriction(false);
let is_fixed = r.is_fixed();
@@ -517,6 +533,8 @@
if !room.has_multiple_clans() {
vec![Warn("The game can't be started with less than two clans!".to_string())]
+ } else if room.protocol_number <= 43 && room.players_number != room.ready_players_number {
+ vec![Warn("Not all players are ready".to_string())]
} else if room.game_info.is_some() {
vec![Warn("The game is already in progress".to_string())]
} else {
@@ -561,17 +579,13 @@
}
FinishRoomGame(room_id) => {
let mut actions = Vec::new();
- let old_info;
- {
- let r = &mut server.rooms[room_id];
- old_info = replace(&mut r.game_info, None);
- r.game_info = None;
- r.ready_players_number = 1;
- actions.push(SendRoomUpdate(None));
- actions.push(RoundFinished.send_all().in_room(r.id).action());
- }
- if let Some(info) = old_info {
+ let r = &mut server.rooms[room_id];
+ r.ready_players_number = 1;
+ actions.push(SendRoomUpdate(None));
+ actions.push(RoundFinished.send_all().in_room(r.id).action());
+
+ if let Some(info) = replace(&mut r.game_info, None) {
for (_, c) in server.clients.iter() {
if c.room_id == Some(room_id) && c.is_joined_mid_game() {
actions.push(SendRoomData{
@@ -596,9 +610,14 @@
} else {
None
}).collect();
+
if !nicks.is_empty() {
- actions.push(ClientFlags("-r".to_string(), nicks)
- .send_all().in_room(room_id).action());
+ let msg = if r.protocol_number < 38 {
+ LegacyReady(false, nicks)
+ } else {
+ ClientFlags("-r".to_string(), nicks)
+ };
+ actions.push(msg.send_all().in_room(room_id).action());
}
server.react(client_id, actions);
}
--- a/gameServer2/src/server/coretypes.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/server/coretypes.rs Sun Sep 09 01:20:35 2018 +0300
@@ -20,7 +20,7 @@
Template(u32),
Ammo(String, Option<String>),
- Scheme(String, Option<Vec<String>>),
+ Scheme(String, Vec<String>),
Script(String),
Theme(String),
DrawnMap(String)
--- a/gameServer2/src/server/handlers/inroom.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/server/handlers/inroom.rs Sun Sep 09 01:20:35 2018 +0300
@@ -3,7 +3,7 @@
use crate::{
server::{
coretypes::{
- ClientId, RoomId, Voting, VoteType,
+ ClientId, RoomId, Voting, VoteType, GameCfg,
MAX_HEDGEHOGS_PER_TEAM
},
server::HWServer,
@@ -168,13 +168,20 @@
r.ready_players_number += 1;
"+r"
};
- c.set_is_ready(!c.is_ready());
- let mut v =
- vec![ClientFlags(flags.to_string(), vec![c.nick.clone()])
- .send_all().in_room(r.id).action()];
+
+ let msg = if c.protocol_number < 38 {
+ LegacyReady(c.is_ready(), vec![c.nick.clone()])
+ } else {
+ ClientFlags(flags.to_string(), vec![c.nick.clone()])
+ };
+
+ let mut v = vec![msg.send_all().in_room(r.id).action()];
+
if r.is_fixed() && r.ready_players_number == r.players_number {
v.push(StartRoomGame(r.id))
}
+
+ c.set_is_ready(!c.is_ready());
server.react(client_id, v);
}
}
@@ -192,7 +199,7 @@
} else if r.is_team_add_restricted() {
actions.push(Warn("This room currently does not allow adding new teams.".to_string()));
} else {
- let team = r.add_team(c.id, *info);
+ let team = r.add_team(c.id, *info, c.protocol_number < 42);
c.teams_in_game += 1;
c.clan = Some(team.color);
actions.push(TeamAccepted(team.name.clone())
@@ -278,6 +285,18 @@
} else if !c.is_master() {
vec![ProtocolError("You're not the room master!".to_string())]
} else {
+ let cfg = match cfg {
+ GameCfg::Scheme(name, mut values) => {
+ if c.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
+ };
+
let v = vec![cfg.to_server_msg()
.send_all().in_room(r.id).but_self().action()];
r.set_config(cfg);
--- a/gameServer2/src/server/room.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/server/room.rs Sun Sep 09 01:20:35 2018 +0300
@@ -24,7 +24,7 @@
#[derive(Clone, Serialize, Deserialize)]
struct Scheme {
name: String,
- settings: Option<Vec<String>>
+ settings: Vec<String>
}
#[derive(Clone, Serialize, Deserialize)]
@@ -54,7 +54,7 @@
template: 0,
ammo: Ammo {name: "Default".to_string(), settings: None },
- scheme: Scheme {name: "Default".to_string(), settings: None },
+ scheme: Scheme {name: "Default".to_string(), settings: Vec::new() },
script: "Normal".to_string(),
theme: "\u{1f994}".to_string(),
drawn_map: None
@@ -180,11 +180,13 @@
MAX_HEDGEHOGS_IN_ROOM - self.hedgehogs_number()
}
- pub fn add_team(&mut self, owner_id: ClientId, mut team: TeamInfo) -> &TeamInfo {
- team.color = iter::repeat(()).enumerate()
- .map(|(i, _)| i as u8).take(u8::max_value() as usize + 1)
- .find(|i| self.teams.iter().all(|(_, t)| t.color != *i ))
- .unwrap_or(0u8);
+ pub fn add_team(&mut self, owner_id: ClientId, mut team: TeamInfo, preserve_color: bool) -> &TeamInfo {
+ if !preserve_color {
+ team.color = iter::repeat(()).enumerate()
+ .map(|(i, _)| i as u8).take(u8::max_value() as usize + 1)
+ .find(|i| self.teams.iter().all(|(_, t)| t.color != *i))
+ .unwrap_or(0u8)
+ };
team.hedgehogs_number = if self.teams.is_empty() {
self.default_hedgehog_number
} else {
--- a/gameServer2/src/utils.rs Fri Sep 07 04:16:05 2018 +0300
+++ b/gameServer2/src/utils.rs Sun Sep 09 01:20:35 2018 +0300
@@ -20,4 +20,48 @@
tmp.push(msg.clone().count() as u8);
tmp.extend(msg);
encode(&tmp)
+}
+
+pub fn protocol_version_string(protocol_number: u16) -> &'static str {
+ match protocol_number {
+ 17 => "0.9.7-dev",
+ 19 => "0.9.7",
+ 20 => "0.9.8-dev",
+ 21 => "0.9.8",
+ 22 => "0.9.9-dev",
+ 23 => "0.9.9",
+ 24 => "0.9.10-dev",
+ 25 => "0.9.10",
+ 26 => "0.9.11-dev",
+ 27 => "0.9.11",
+ 28 => "0.9.12-dev",
+ 29 => "0.9.12",
+ 30 => "0.9.13-dev",
+ 31 => "0.9.13",
+ 32 => "0.9.14-dev",
+ 33 => "0.9.14",
+ 34 => "0.9.15-dev",
+ 35 => "0.9.14.1",
+ 37 => "0.9.15",
+ 38 => "0.9.16-dev",
+ 39 => "0.9.16",
+ 40 => "0.9.17-dev",
+ 41 => "0.9.17",
+ 42 => "0.9.18-dev",
+ 43 => "0.9.18",
+ 44 => "0.9.19-dev",
+ 45 => "0.9.19",
+ 46 => "0.9.20-dev",
+ 47 => "0.9.20",
+ 48 => "0.9.21-dev",
+ 49 => "0.9.21",
+ 50 => "0.9.22-dev",
+ 51 => "0.9.22",
+ 52 => "0.9.23-dev",
+ 53 => "0.9.23",
+ 54 => "0.9.24-dev",
+ 55 => "0.9.24",
+ 56 => "0.9.25-dev",
+ _ => "Unknown"
+ }
}
\ No newline at end of file