diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index 9fefc3667f..5fb58aa655 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -85,6 +85,7 @@ enum ClientStatus { STATUS_DONE_MAP, ///< The client has downloaded the map STATUS_PRE_ACTIVE, ///< The client is catching up the delayed frames STATUS_ACTIVE, ///< The client is active within in the game + STATUS_END ///< Must ALWAYS be on the end of this list!! (period) }; class NetworkClientSocket; diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index fc280ed972..286b940285 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -453,8 +453,6 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO) if (MY_CLIENT->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST; - if (!Company::IsValidID(playas)) playas = COMPANY_SPECTATOR; - ci = NetworkFindClientInfoFromClientID(client_id); if (ci != NULL) { if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) { @@ -467,7 +465,7 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO) /* Make sure we're in the company the server tells us to be in, * for the rare case that we get moved while joining. */ - if (client_id == _network_own_client_id) SetLocalCompany(playas); + if (client_id == _network_own_client_id) SetLocalCompany(!Company::IsValidID(playas) ? COMPANY_SPECTATOR : playas); ci->client_playas = playas; strecpy(ci->client_name, name, lastof(ci->client_name)); diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index e9c6103edf..06e30f736b 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -373,19 +373,38 @@ static bool GunzipFile(const ContentInfo *ci) if (fin == NULL || fout == NULL) { ret = false; - goto exit; - } - - byte buff[8192]; - while (!gzeof(fin)) { - int read = gzread(fin, buff, sizeof(buff)); - if (read < 0 || (size_t)read != fwrite(buff, 1, read, fout)) { - ret = false; - break; + } else { + byte buff[8192]; + while (1) { + int read = gzread(fin, buff, sizeof(buff)); + if (read == 0) { + /* If gzread() returns 0, either the end-of-file has been + * reached or an underlying read error has occurred. + * + * gzeof() can't be used, because: + * 1.2.5 - it is safe, 1 means 'everything was OK' + * 1.2.3.5, 1.2.4 - 0 or 1 is returned 'randomly' + * 1.2.3.3 - 1 is returned for truncated archive + * + * So we use gzerror(). When proper end of archive + * has been reached, then: + * errnum == Z_STREAM_END in 1.2.3.3, + * errnum == 0 in 1.2.4 and 1.2.5 */ + int errnum; + gzerror(fin, &errnum); + if (errnum != 0 && errnum != Z_STREAM_END) ret = false; + break; + } + if (read < 0 || (size_t)read != fwrite(buff, 1, read, fout)) { + /* If gzread() returns -1, there was an error in archive */ + ret = false; + break; + } + /* DO NOT DO THIS! It will fail to detect broken archive with 1.2.3.3! + * if (read < sizeof(buff)) break; */ } } -exit: if (fin != NULL) { /* Closes ftmp too! */ gzclose(fin); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 697a6630b0..6fdcf9ff8f 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1703,7 +1703,8 @@ void NetworkServerShowStatusToConsole() { static const char * const stat_str[] = { "inactive", - "authorizing", + "authorizing (server password)", + "authorizing (company password)", "authorized", "waiting", "loading map", @@ -1711,6 +1712,7 @@ void NetworkServerShowStatusToConsole() "ready", "active" }; + assert_compile(lengthof(stat_str) == STATUS_END); NetworkClientSocket *cs; FOR_ALL_CLIENT_SOCKETS(cs) { diff --git a/src/openttd.cpp b/src/openttd.cpp index e87ced87f9..fad7c91d7a 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1208,8 +1208,6 @@ void StateGameLoop() CallWindowTickEvent(); NewsLoop(); } else { - CheckCaches(); - if (_debug_desync_level > 2 && _date_fract == 0 && (_date & 0x1F) == 0) { /* Save the desync savegame if needed. */ char name[MAX_PATH]; @@ -1217,6 +1215,8 @@ void StateGameLoop() SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR); } + CheckCaches(); + /* All these actions has to be done from OWNER_NONE * for multiplayer compatibility */ CompanyID old_company = _current_company; diff --git a/src/road_type.h b/src/road_type.h index 2c58b31499..61775d0507 100644 --- a/src/road_type.h +++ b/src/road_type.h @@ -66,9 +66,11 @@ enum RoadBits { ROAD_S = ROAD_SE | ROAD_SW, ///< Road at the two southern edges ROAD_W = ROAD_NW | ROAD_SW, ///< Road at the two western edges - ROAD_ALL = ROAD_X | ROAD_Y ///< Full 4-way crossing + ROAD_ALL = ROAD_X | ROAD_Y, ///< Full 4-way crossing + + ROAD_END = ROAD_ALL + 1 ///< Out-of-range roadbits, used for iterations }; DECLARE_ENUM_AS_BIT_SET(RoadBits); -template <> struct EnumPropsT : MakeEnumPropsT {}; +template <> struct EnumPropsT : MakeEnumPropsT {}; #endif /* ROAD_TYPE_H */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 80b4db2531..b1e6578beb 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -481,7 +481,7 @@ int Train::GetCurrentMaxSpeed() const int st_max_speed = 120; int delta_v = this->cur_speed / (distance_to_go + 1); - if (this->max_speed > (this->cur_speed - delta_v)) { + if (max_speed > (this->cur_speed - delta_v)) { st_max_speed = this->cur_speed - (delta_v / 10); }