diff --git a/doc/metaserver_protocol.txt b/doc/metaserver_protocol.txt deleted file mode 100644 index 5303d56e7..000000000 --- a/doc/metaserver_protocol.txt +++ /dev/null @@ -1,175 +0,0 @@ -This document describes the protocol used by Stratagus to communicate with -the metaserver. - - -(c) Copyright 2005 by Jimmy Salmon - -Distributed under the GNU General Public License - - ----------------------------------------------------------------------- -LOGIN ----------------------------------------------------------------------- - - -USER username password gamename gamever - -Immediately after connecting you must either log in as an existing user or -REGISTER a new account. - -Replies: -ERR_NOUSER The username does not exist -ERR_BADPASSWORD Incorrect password for the username -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -ERR_ALREADYLOGGEDIN Already logged in -USER_OK Login successful - - - -REGISTER username password gamename gamever - -Immediately after connecting you must either log in as an existing user or -REGISTER a new account. - -Replies: -ERR_USEREXISTS The username already exists -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -ERR_ALREADYLOGGEDIN Already logged in -REGISTER_OK Login successful - - ----------------------------------------------------------------------- -HOSTING GAMES ----------------------------------------------------------------------- - - -CREATEGAME description map players ip port [password] - -Create a new game. A user may only have one created game at a time. If the -description or map includes spaces it must be enclosed in quotation marks. -Players is the number of player slots (human or computer), ip is the user's -ip address, and port is the udp port number that the engine is listening on. -An optional password may be used. - -Replies: -ERR_GAMECREATED The user already has an open created game -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -CREATEGAME_OK The game was created - - - -CANCELGAME - -Cancel the created game. - -Replies: -ERR_NOGAMECREATED The user does not have a created game -ERR_GAMESTARTED The game has already started -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -CANCELGAME_OK The game was cancelled - - - -STARTGAME - -The game is starting. - -Replies: -ERR_NOGAMECREATED The user does not have a created game -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -STARTGAME_OK Received the start message - - ----------------------------------------------------------------------- -JOINING GAMES ----------------------------------------------------------------------- - - -LISTGAMES - -Get a list of all created games. The server will send a series of LISTGAMES -responses for all currently open games and as new games are created. The -LISTGAMES parameters are a unique game id used by JOINGAME, the game -description, map, number of open player slots, total number of players (human -and computer), game creator user name, ip address, and the udp port number the -engine is listening on. The server will continue sending LISTGAMES until -LISTGAMESEND is called or the user joins a game. - -Replies: -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -LISTGAMES id "description" "map" open_players players creator ip port - - -LISTGAMESEND - -Stop the server from sending LISTGAMES. - -Replies: -ERR_NOTLISTINGGAMES The server is not currently sending LISTGAMES -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -LISTGAMESEND_OK Message received - - -JOINGAME id [password] - -Join a game. The id is obtained from LISTGAMES. The password must be sent -when joining games created with a password. - -Replies: -ERR_GAMEFULL There are no empty player slots -ERR_ALREADYINGAME The user is already in a game -ERR_NEEDPASSWORD The game requires a password to join -ERR_BADPASSWORD The password is incorrect -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -JOINGAME_OK The player joined the game - - -PARTGAME - -Leave a game. - -Replies: -ERR_GAMESTARTED The game has already started -ERR_NOTINGAME The user is not currently in a game -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -PARTGAME_OK The player left the game - - ----------------------------------------------------------------------- -ENDING GAMES ----------------------------------------------------------------------- - - -ENDGAME result - -End a game with a result of win, lose, or draw. TODO: find a way to prevent -cheating. - -Replies: -ERR_NOTINGAME The user is not currently in a game -ERR_BADPARAMETER Too many parameters, not enough parameters, or a badly - formed parameter was sent -ENDGAME_OK Received the end game message - - ----------------------------------------------------------------------- -CHATTING ----------------------------------------------------------------------- - - -MSG message - -Send a message. - -Replies: -None - diff --git a/src/include/net_message.h b/src/include/net_message.h index da2059c8c..19e401817 100644 --- a/src/include/net_message.h +++ b/src/include/net_message.h @@ -241,10 +241,11 @@ public: const CInitMessage_Header &GetHeader() const { return header; } const unsigned char *Serialize() const; void Deserialize(const unsigned char *p); - static size_t Size() { return CInitMessage_Header::Size() + PlayerMax * CNetworkHost::Size(); } + static size_t Size() { return CInitMessage_Header::Size() + 1 + PlayerMax * CNetworkHost::Size(); } private: CInitMessage_Header header; public: + uint8_t clientIndex; /// index of the receiving client in the compacted host array CNetworkHost hosts[PlayerMax]; /// Participant information }; diff --git a/src/network/net_message.cpp b/src/network/net_message.cpp index 87641d164..fd9c75838 100644 --- a/src/network/net_message.cpp +++ b/src/network/net_message.cpp @@ -382,6 +382,7 @@ const unsigned char *CInitMessage_Config::Serialize() const unsigned char *p = buf; p += header.Serialize(p); + p += serialize8(p, clientIndex); for (int i = 0; i < PlayerMax; ++i) { p += this->hosts[i].Serialize(p); } @@ -391,6 +392,7 @@ const unsigned char *CInitMessage_Config::Serialize() const void CInitMessage_Config::Deserialize(const unsigned char *p) { p += header.Deserialize(p); + p += deserialize8(p, &clientIndex); for (int i = 0; i < PlayerMax; ++i) { p += this->hosts[i].Deserialize(p); } diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 099ccd8b1..72d41befc 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -653,6 +653,8 @@ bool CClient::Update(unsigned long tick) void CClient::SetConfig(const CInitMessage_Config &msg) { NetPlayers = 0; + // the local host slot may have changed due to Hosts array compaction on the server + NetLocalHostsSlot = msg.clientIndex; for (int i = 0; i < PlayerMax; ++i) { Hosts[i] = msg.hosts[i]; if (Hosts[i].IsValid()) { @@ -669,6 +671,9 @@ void CClient::SetConfig(const CInitMessage_Config &msg) // server is first, set our view of ip:port Hosts[0].Host = serverHost.getIp(); Hosts[0].Port = serverHost.getPort(); + // for ourselves we use the loopback ip:port + Hosts[NetLocalHostsSlot].Host = INADDR_LOOPBACK; // FIXME: use CNetworkParameter::Instance.localHost, but also in InitNetwork1 + Hosts[NetLocalHostsSlot].Port = CNetworkParameter::Instance.localPort; const std::string serverHostStr = serverHost.toString(); } @@ -908,6 +913,9 @@ void CClient::Parse_Welcome(const unsigned char *buf) // server is first, set ip:port from our perspective Hosts[0].Host = serverHost.getIp(); Hosts[0].Port = serverHost.getPort(); + // for ourselves we use the loopback ip:port + Hosts[NetLocalHostsSlot].Host = INADDR_LOOPBACK; // FIXME: use CNetworkParameter::Instance.localHost, but also in InitNetwork1 + Hosts[NetLocalHostsSlot].Port = CNetworkParameter::Instance.localPort; } void CClient::Parse_State(const unsigned char *buf) @@ -1797,14 +1805,21 @@ void NetworkServerStartGame() // Slot 0 is the server! NetLocalPlayerNumber = Hosts[0].PlyNr; - for (int i = 0; i < PlayerMax;) { - if (Hosts[i].IsValid()) { - i++; - } else { - for (int j = i; j < PlayerMax - 1; j++) { - Hosts[j] = Hosts[j + 1]; + // compact hosts array + for (int i = 0; i < PlayerMax; i++) { + if (!Hosts[i].IsValid()) { + bool any_more_hosts = false; + for (int j = i + 1; j < PlayerMax; j++) { + if (Hosts[j].IsValid()) { + Hosts[i] = Hosts[j]; + Hosts[j].Clear(); + any_more_hosts = true; + break; + } + } + if (!any_more_hosts) { + break; } - Hosts[PlayerMax - 1].Clear(); } } @@ -1843,6 +1858,7 @@ breakout: const CHost host(message.hosts[i].Host, message.hosts[i].Port); if (waitingForConfigAck[i]) { // not acknowledged yet DebugPrint("Sending InitConfig to %s\n" _C_ host.toString().c_str()); + message.clientIndex = i; NetworkSendICMessage_Log(NetworkFildes, host, message); } else if (waitingForInitAck[i]) { DebugPrint("Sending InitState to %s\n" _C_ host.toString().c_str());