From 2cd67a51acc71b08e52c94fefa44fe665977396f Mon Sep 17 00:00:00 2001 From: rubidium Date: Sun, 24 Oct 2010 20:03:33 +0000 Subject: [PATCH] (svn r21029) -Codechange: split the map downloading packet + 3-state enum into 3 separate packets --- src/network/core/tcp_game.cpp | 8 +- src/network/core/tcp_game.h | 29 ++++--- src/network/network_client.cpp | 149 ++++++++++++++++----------------- src/network/network_client.h | 4 +- src/network/network_internal.h | 6 -- src/network/network_server.cpp | 9 +- 6 files changed, 103 insertions(+), 102 deletions(-) diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index dc3be15fe8..4f4baeb6b1 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.cpp @@ -85,7 +85,9 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p) GAME_COMMAND(PACKET_SERVER_WELCOME) GAME_COMMAND(PACKET_CLIENT_GETMAP) GAME_COMMAND(PACKET_SERVER_WAIT) - GAME_COMMAND(PACKET_SERVER_MAP) + GAME_COMMAND(PACKET_SERVER_MAP_BEGIN) + GAME_COMMAND(PACKET_SERVER_MAP_DATA) + GAME_COMMAND(PACKET_SERVER_MAP_DONE) GAME_COMMAND(PACKET_CLIENT_MAP_OK) GAME_COMMAND(PACKET_SERVER_JOIN) GAME_COMMAND(PACKET_SERVER_FRAME) @@ -170,7 +172,9 @@ DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_PASSWORD) DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_WELCOME) DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP) DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_WAIT) -DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP) +DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_BEGIN) +DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_DATA) +DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_DONE) DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK) DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_JOIN) DEFINE_UNAVAILABLE_GAME_RECEIVE_COMMAND(PACKET_SERVER_FRAME) diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index b312a447ca..6fd5649c13 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -72,7 +72,9 @@ enum PacketGameType { /* Getting the savegame/map. */ PACKET_CLIENT_GETMAP, ///< Client requests the actual map. PACKET_SERVER_WAIT, ///< Server tells the client there are some people waiting for the map as well. - PACKET_SERVER_MAP, ///< Server sends bits of the map to the client. + PACKET_SERVER_MAP_BEGIN, ///< Server tells the client that it is beginning to send the map. + PACKET_SERVER_MAP_DATA, ///< Server sends bits of the map to the client. + PACKET_SERVER_MAP_DONE, ///< Server tells it has just sent the last bits of the map to the client. PACKET_CLIENT_MAP_OK, ///< Client tells the server that it received the whole map. PACKET_SERVER_JOIN, ///< Tells clients that a new client has joined. @@ -283,17 +285,22 @@ protected: DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_WAIT); /** - * Sends parts of the map to the client: - * uint8 packet type (MAP_PACKET_START, MAP_PACKET_NORMAL, MAP_PACKET_END). - * If MAP_PACKET_START: - * uint32 Current frame. - * uint32 Size of the map (in bytes). - * If MAP_PACKET_NORMAL: - * Part of the map (until max size of packet). - * If MAP_PACKET_END: - * No further data sent. + * Sends that the server will begin with sending the map to the client: + * uint32 Current frame. + * uint32 Size of the map (in bytes). */ - DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP); + DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_BEGIN); + + /** + * Sends the data of the map to the client: + * Contains a part of the map (until max size of packet). + */ + DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_DATA); + + /** + * Sends that all data of the map are sent to the client: + */ + DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_DONE); /** * Tell the server that we are done receiving/loading the map. diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 17ea3cdbb7..84fa325cda 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -661,94 +661,91 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WAIT) return NETWORK_RECV_STATUS_OKAY; } -DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP) +DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP_BEGIN) { - byte maptype; - - maptype = p->Recv_uint8(); - if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST; + if (this->download_file != NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - /* First packet, init some stuff */ - if (maptype == MAP_PACKET_START) { - if (this->download_file != NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - this->download_file = FioFOpenFile("network_client.tmp", "wb", AUTOSAVE_DIR); - if (this->download_file == NULL) { - _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; - return NETWORK_RECV_STATUS_SAVEGAME; - } - - _frame_counter = _frame_counter_server = _frame_counter_max = p->Recv_uint32(); - - _network_join_bytes = 0; - _network_join_bytes_total = p->Recv_uint32(); - - /* If the network connection has been closed due to loss of connection - * or when _network_join_kbytes_total is 0, the join status window will - * do a division by zero. When the connection is lost, we just return - * that. If kbytes_total is 0, the packet must be malformed as a - * savegame less than 1 kilobyte is practically impossible. */ - if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST; - if (_network_join_bytes_total == 0) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - - _network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING; - SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); - - /* The first packet does not contain any more data */ - return NETWORK_RECV_STATUS_OKAY; + this->download_file = FioFOpenFile("network_client.tmp", "wb", AUTOSAVE_DIR); + if (this->download_file == NULL) { + _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; + return NETWORK_RECV_STATUS_SAVEGAME; } + _frame_counter = _frame_counter_server = _frame_counter_max = p->Recv_uint32(); + + _network_join_bytes = 0; + _network_join_bytes_total = p->Recv_uint32(); + + /* If the network connection has been closed due to loss of connection + * or when _network_join_kbytes_total is 0, the join status window will + * do a division by zero. When the connection is lost, we just return + * that. If kbytes_total is 0, the packet must be malformed as a + * savegame less than 1 kilobyte is practically impossible. */ + if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST; + if (_network_join_bytes_total == 0) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + + _network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING; + SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); + + return NETWORK_RECV_STATUS_OKAY; +} + +DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP_DATA) +{ if (this->download_file == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - if (maptype == MAP_PACKET_NORMAL) { - /* We are still receiving data, put it to the file */ - if (fwrite(p->buffer + p->pos, 1, p->size - p->pos, this->download_file) != (size_t)(p->size - p->pos)) { - _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; - fclose(this->download_file); - this->download_file = NULL; - return NETWORK_RECV_STATUS_SAVEGAME; - } - - _network_join_bytes = ftell(this->download_file); - SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); - } - - /* Check if this was the last packet */ - if (maptype == MAP_PACKET_END) { + /* We are still receiving data, put it to the file */ + if (fwrite(p->buffer + p->pos, 1, p->size - p->pos, this->download_file) != (size_t)(p->size - p->pos)) { + _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; fclose(this->download_file); this->download_file = NULL; + return NETWORK_RECV_STATUS_SAVEGAME; + } - _network_join_status = NETWORK_JOIN_STATUS_PROCESSING; - SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); + _network_join_bytes = ftell(this->download_file); + SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); - /* The map is done downloading, load it */ - if (!SafeSaveOrLoad("network_client.tmp", SL_LOAD, GM_NORMAL, AUTOSAVE_DIR)) { - DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); - _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; - return NETWORK_RECV_STATUS_SAVEGAME; - } - /* If the savegame has successfully loaded, ALL windows have been removed, - * only toolbar/statusbar and gamefield are visible */ - - /* Say we received the map and loaded it correctly! */ - SendMapOk(); - - /* New company/spectator (invalid company) or company we want to join is not active - * Switch local company to spectator and await the server's judgement */ - if (_network_join_as == COMPANY_NEW_COMPANY || !Company::IsValidID(_network_join_as)) { - SetLocalCompany(COMPANY_SPECTATOR); - - if (_network_join_as != COMPANY_SPECTATOR) { - /* We have arrived and ready to start playing; send a command to make a new company; - * the server will give us a client-id and let us in */ - _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; - ShowJoinStatusWindow(); - NetworkSend_Command(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company); - } - } else { - /* take control over an existing company */ - SetLocalCompany(_network_join_as); + return NETWORK_RECV_STATUS_OKAY; +} + +DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_MAP_DONE) +{ + if (this->download_file == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + + fclose(this->download_file); + this->download_file = NULL; + + _network_join_status = NETWORK_JOIN_STATUS_PROCESSING; + SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); + + /* The map is done downloading, load it */ + if (!SafeSaveOrLoad("network_client.tmp", SL_LOAD, GM_NORMAL, AUTOSAVE_DIR)) { + DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); + _switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR; + return NETWORK_RECV_STATUS_SAVEGAME; + } + /* If the savegame has successfully loaded, ALL windows have been removed, + * only toolbar/statusbar and gamefield are visible */ + + /* Say we received the map and loaded it correctly! */ + SendMapOk(); + + /* New company/spectator (invalid company) or company we want to join is not active + * Switch local company to spectator and await the server's judgement */ + if (_network_join_as == COMPANY_NEW_COMPANY || !Company::IsValidID(_network_join_as)) { + SetLocalCompany(COMPANY_SPECTATOR); + + if (_network_join_as != COMPANY_SPECTATOR) { + /* We have arrived and ready to start playing; send a command to make a new company; + * the server will give us a client-id and let us in */ + _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; + ShowJoinStatusWindow(); + NetworkSend_Command(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company); } + } else { + /* take control over an existing company */ + SetLocalCompany(_network_join_as); } return NETWORK_RECV_STATUS_OKAY; diff --git a/src/network/network_client.h b/src/network/network_client.h index 578b8026b3..90e37d2780 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -35,7 +35,9 @@ protected: DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_NEED_COMPANY_PASSWORD); DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_WELCOME); DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_WAIT); - DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP); + DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_BEGIN); + DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_DATA); + DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_MAP_DONE); DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_JOIN); DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_FRAME); DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_SYNC); diff --git a/src/network/network_internal.h b/src/network/network_internal.h index 5c0e664ede..5373e4422b 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -52,12 +52,6 @@ extern bool _ddc_fastforward; typedef class ServerNetworkGameSocketHandler NetworkClientSocket; -enum MapPacket { - MAP_PACKET_START, - MAP_PACKET_NORMAL, - MAP_PACKET_END, -}; - enum NetworkJoinStatus { NETWORK_JOIN_STATUS_CONNECTING, diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 4c6355b815..a7dc9daed2 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -388,8 +388,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() if (ftell(file_pointer) == 0) usererror("network savedump failed - zero sized savegame?"); /* Now send the _frame_counter and how many packets are coming */ - p = new Packet(PACKET_SERVER_MAP); - p->Send_uint8 (MAP_PACKET_START); + p = new Packet(PACKET_SERVER_MAP_BEGIN); p->Send_uint32(_frame_counter); p->Send_uint32(ftell(file_pointer)); this->Send_Packet(p); @@ -409,8 +408,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() uint i; int res; for (i = 0; i < sent_packets; i++) { - Packet *p = new Packet(PACKET_SERVER_MAP); - p->Send_uint8(MAP_PACKET_NORMAL); + Packet *p = new Packet(PACKET_SERVER_MAP_DATA); res = (int)fread(p->buffer + p->size, 1, SEND_MTU - p->size, file_pointer); if (ferror(file_pointer)) usererror("Error reading temporary network savegame!"); @@ -419,8 +417,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() this->Send_Packet(p); if (feof(file_pointer)) { /* Done reading! */ - Packet *p = new Packet(PACKET_SERVER_MAP); - p->Send_uint8(MAP_PACKET_END); + Packet *p = new Packet(PACKET_SERVER_MAP_DONE); this->Send_Packet(p); /* Set the status to DONE_MAP, no we will wait for the client