gameServer2/src/protocol/messages.rs
author nemo
Tue, 21 Aug 2018 15:11:28 -0400
branch0.9.24
changeset 13682 f60b3998ba56
parent 13119 1e39b8749072
child 13416 cdf69667593b
permissions -rw-r--r--
only-stats should never create visual gears. and lua should never rely on visual gears being created. critical is just to help ensure ones important to gameplay don't get lost in fast-forward

use server::coretypes::{ServerVar, GameCfg, TeamInfo, HedgehogInfo};
use std;
use std::ops;
use std::convert::From;

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum HWProtocolMessage {
    // core
    Ping,
    Pong,
    Quit(Option<String>),
    //Cmd(String, Vec<String>),
    Global(String),
    Watch(String),
    ToggleServerRegisteredOnly,
    SuperPower,
    Info(String),
    // not entered state
    Nick(String),
    Proto(u32),
    Password(String, String),
    Checker(u32, String, String),
    // lobby
    List,
    Chat(String),
    CreateRoom(String, Option<String>),
    Join(String, Option<String>),
    Follow(String),
    Rnd(Vec<String>),
    Kick(String),
    Ban(String, String, u32),
    BanIP(String, String, u32),
    BanNick(String, String, u32),
    BanList,
    Unban(String),
    SetServerVar(ServerVar),
    GetServerVar,
    RestartServer,
    Stats,
    // in room
    Part(Option<String>),
    Cfg(GameCfg),
    AddTeam(TeamInfo),
    RemoveTeam(String),
    SetHedgehogsNumber(String, u8),
    SetTeamColor(String, u8),
    ToggleReady,
    StartGame,
    EngineMessage(String),
    RoundFinished,
    ToggleRestrictJoin,
    ToggleRestrictTeams,
    ToggleRegisteredOnly,
    RoomName(String),
    Delegate(String),
    TeamChat(String),
    MaxTeams(u8),
    Fix,
    Unfix,
    Greeting(String),
    CallVote(Option<(String, Option<String>)>),
    Vote(String),
    ForceVote(String),
    Save(String, String),
    Delete(String),
    SaveRoom(String),
    LoadRoom(String),
    Malformed,
    Empty,
}

pub enum HWServerMessage {
    Ping,
    Pong,
    Bye(String),
    Nick(String),
    LobbyLeft(String),
    LobbyJoined(Vec<String>),
    ChatMsg(String, String),
    ClientFlags(String, Vec<String>),

    Warning(String),
    Connected(u32),
    Unreachable,
}

fn construct_message(msg: & [&str]) -> String {
    let mut m = String::with_capacity(64);

    for s in msg {
        m.push_str(s);
        m.push('\n');
    }
    m.push('\n');

    m
}

impl<'a> HWProtocolMessage {
    pub fn to_raw_protocol(&self) -> String {
        use self::HWProtocolMessage::*;
        match *self {
            Ping => "PING\n\n".to_string(),
            Pong => "PONG\n\n".to_string(),
            Quit(None) => format!("QUIT\n\n"),
            Quit(Some(ref msg)) => format!("QUIT\n{}\n\n", msg),
            Global(ref msg) => format!("CMD\nGLOBAL\n{}\n\n", msg),
            Watch(ref name) => format!("CMD\nWATCH\n{}\n\n", name),
            ToggleServerRegisteredOnly => "CMD\nREGISTERED_ONLY\n\n".to_string(),
            SuperPower => "CMD\nSUPER_POWER\n\n".to_string(),
            Info(ref info) => format!("CMD\nINFO\n{}\n\n", info),
            Nick(ref nick) => format!("NICK\n{}\n\n", nick),
            Proto(version) => format!("PROTO\n{}\n\n", version),
            Password(ref p, ref s) => format!("PASSWORD\n{}\n{}\n\n", p, s), //?
            Checker(i, ref n, ref p) =>
                format!("CHECKER\n{}\n{}\n{}\n\n", i, n, p), //?,
            List => "LIST\n\n".to_string(),
            Chat(ref msg) => format!("CHAT\n{}\n\n", msg),
            CreateRoom(ref name, None) =>
                format!("CREATE_ROOM\n{}\n\n", name),
            CreateRoom(ref name, Some(ref password)) =>
                format!("CREATE_ROOM\n{}\n{}\n\n", name, password),
            Join(ref name, None) =>
                format!("JOIN\n{}\n\n", name),
            Join(ref name, Some(ref arg)) =>
                format!("JOIN\n{}\n{}\n\n", name, arg),
            Follow(ref name) =>
                format!("FOLLOW\n{}\n\n", name),
            //Rnd(Vec<String>), ???
            Kick(ref name) => format!("KICK\n{}\n\n", name),
            Ban(ref name, ref reason, time) =>
                format!("BAN\n{}\n{}\n{}\n\n", name, reason, time),
            BanIP(ref ip, ref reason, time) =>
                format!("BAN_IP\n{}\n{}\n{}\n\n", ip, reason, time),
            BanNick(ref nick, ref reason, time) =>
                format!("BAN_NICK\n{}\n{}\n{}\n\n", nick, reason, time),
            BanList => "BANLIST\n\n".to_string(),
            Unban(ref name) => format!("UNBAN\n{}\n\n", name),
            //SetServerVar(ServerVar), ???
            GetServerVar => "GET_SERVER_VAR\n\n".to_string(),
            RestartServer => "CMD\nRESTART_SERVER\nYES\n\n".to_string(),
            Stats => "CMD\nSTATS\n\n".to_string(),
            Part(None) => "CMD\nPART\n\n".to_string(),
            Part(Some(ref msg)) => format!("CMD\nPART\n{}\n\n", msg),
            //Cfg(GameCfg) ??
            //AddTeam(TeamInfo) ??,
            RemoveTeam(ref name) => format!("REMOVE_TEAM\n{}\n\n", name),
            //SetHedgehogsNumber(String, u8), ??
            //SetTeamColor(String, u8), ??
            ToggleReady => "TOGGLE_READY\n\n".to_string(),
            StartGame => "START_GAME\n\n".to_string(),
            EngineMessage(ref msg) => format!("EM\n{}\n\n", msg),
            RoundFinished => "ROUNDFINISHED\n\n".to_string(),
            ToggleRestrictJoin => "TOGGLE_RESTRICT_JOINS\n\n".to_string(),
            ToggleRestrictTeams => "TOGGLE_RESTRICT_TEAMS\n\n".to_string(),
            ToggleRegisteredOnly => "TOGGLE_REGISTERED_ONLY\n\n".to_string(),
            RoomName(ref name) => format!("ROOM_NAME\n{}\n\n", name),
            Delegate(ref name) => format!("CMD\nDELEGATE\n{}\n\n", name),
            TeamChat(ref msg) => format!("TEAMCHAT\n{}\n\n", msg),
            MaxTeams(count) => format!("CMD\nMAXTEAMS\n{}\n\n", count) ,
            Fix => "CMD\nFIX\n\n".to_string(),
            Unfix => "CMD\nUNFIX\n\n".to_string(),
            Greeting(ref msg) => format!("CMD\nGREETING\n{}\n\n", msg),
            //CallVote(Option<(String, Option<String>)>) =>, ??
            Vote(ref msg) => format!("CMD\nVOTE\n{}\n\n", msg),
            ForceVote(ref msg) => format!("CMD\nFORCE\n{}\n\n", msg),
            //Save(String, String), ??
            Delete(ref room) => format!("CMD\nDELETE\n{}\n\n", room),
            SaveRoom(ref room) => format!("CMD\nSAVEROOM\n{}\n\n", room),
            LoadRoom(ref room) => format!("CMD\nLOADROOM\n{}\n\n", room),
            Malformed => "A\nQUICK\nBROWN\nHOG\nJUMPS\nOVER\nTHE\nLAZY\nDOG\n\n".to_string(),
            Empty => "\n\n".to_string(),
            _ => panic!("Protocol message not yet implemented")
        }
    }
}

impl HWServerMessage {
    pub fn to_raw_protocol(&self) -> String {
        use self::HWServerMessage::*;
        match self {
            &Ping => "PING\n\n".to_string(),
            &Pong => "PONG\n\n".to_string(),
            &Connected(protocol_version)
                => construct_message(&[
                    "CONNECTED",
                    "Hedgewars server http://www.hedgewars.org/",
                    &protocol_version.to_string()
                ]),
            &Bye(ref msg) => construct_message(&["BYE", &msg]),
            &Nick(ref nick) => construct_message(&["NICK", &nick]),
            &LobbyLeft(ref nick)
                => construct_message(&["LOBBY_LEFT", &nick]),
            &LobbyJoined(ref nicks)
                => {
                let mut v = vec!["LOBBY:JOINED"];
                v.extend(nicks.iter().map(|n| { &n[..] }));
                construct_message(&v)
            },
            &ClientFlags(ref flags, ref nicks)
                => {
                let mut v = vec!["CLIENT_FLAGS"];
                v.push(&flags[..]);
                v.extend(nicks.iter().map(|n| { &n[..] }));
                construct_message(&v)
            },
            &ChatMsg(ref nick, ref msg)
                => construct_message(&["CHAT", &nick, &msg]),
            &Warning(ref msg)
                => construct_message(&["WARNING", &msg]),
            _ => construct_message(&["ERROR", "UNIMPLEMENTED"]),
        }
    }
}