port some legacy protocol support
authoralfadur
Sun, 09 Sep 2018 01:20:35 +0300
changeset 13806 5fb40c8e5542
parent 13805 0118b7412570
child 13807 24fe56d3c6a2
port some legacy protocol support
gameServer2/src/protocol/messages.rs
gameServer2/src/protocol/parser.rs
gameServer2/src/protocol/test.rs
gameServer2/src/server/actions.rs
gameServer2/src/server/coretypes.rs
gameServer2/src/server/handlers/inroom.rs
gameServer2/src/server/room.rs
gameServer2/src/utils.rs
--- 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