diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 5f29f23d87..9bf4fb64d5 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -30,15 +30,10 @@ jobs: fail-fast: false matrix: include: - - name: Clang - Debug + - name: Clang compiler: clang-15 cxxcompiler: clang++-15 libraries: libsdl2-dev - - name: Clang - Release - compiler: clang-15 - cxxcompiler: clang++-15 - libraries: libsdl2-dev - extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF - name: GCC - SDL2 compiler: gcc cxxcompiler: g++ @@ -66,10 +61,16 @@ jobs: fail-fast: false matrix: include: - - arch: arm64 + - name: arm64 - Debug + arch: arm64 full_arch: arm64 + extra-cmake-parameters: -DCMAKE_BUILD_TYPE=Debug + - name: arm64 - Release + arch: arm64 + full_arch: arm64 + extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF - name: Mac OS (${{ matrix.arch }}) + name: Mac OS (${{ matrix.name }}) uses: ./.github/workflows/ci-macos.yml secrets: inherit @@ -77,6 +78,7 @@ jobs: with: arch: ${{ matrix.arch }} full_arch: ${{ matrix.full_arch }} + extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }} windows: strategy: diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml index 803dfbeece..704ddf3b57 100644 --- a/.github/workflows/ci-macos.yml +++ b/.github/workflows/ci-macos.yml @@ -9,6 +9,10 @@ on: full_arch: required: true type: string + extra-cmake-parameters: + required: false + type: string + default: "" env: CTEST_OUTPUT_ON_FAILURE: 1 @@ -78,6 +82,7 @@ jobs: -DCMAKE_OSX_ARCHITECTURES=${{ inputs.full_arch }} \ -DVCPKG_TARGET_TRIPLET=${{ inputs.arch }}-osx \ -DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ + ${{ inputs.extra-cmake-parameters }} \ # EOF echo "::endgroup::" diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 97ab31955b..bfbe13cacc 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -7,6 +7,7 @@ on: - synchronize branches: - master + - release/** concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} diff --git a/cmake/scripts/GenerateWidget.cmake b/cmake/scripts/GenerateWidget.cmake index b6748422f5..ffa5e6edea 100644 --- a/cmake/scripts/GenerateWidget.cmake +++ b/cmake/scripts/GenerateWidget.cmake @@ -56,11 +56,14 @@ foreach(ENUM IN LISTS ENUM_LINES) endif() # Check for enum match - if("${LINE}" MATCHES "^ *enum *${ENUM_PATTERN} *\{") + if("${LINE}" MATCHES "^ *enum *${ENUM_PATTERN}( *: *[^ ]*)? *\{") # REGEX REPLACE does a REGEX MATCHALL and fails if an empty string is matched string(REGEX MATCH "[^ ]*" RESULT "${LINE}") string(REPLACE "${RESULT}" "" RM_INDENT "${LINE}") + string(REGEX MATCH " *: *[^ ]*" RESULT "${LINE}") + string(REPLACE "${RESULT}" "" LINE "${LINE}") + set(ACTIVE 1) if(ACTIVE_COMMENT GREATER 0) string(APPEND ${PLACE_HOLDER} "\n${COMMENT}") diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 8f14867e36..f14342c353 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -118,21 +118,20 @@ struct PacketWriter : SaveFilter { /** * Transfer all packets from here to the network's queue while holding * the lock on our mutex. - * @param socket The network socket to write to. * @return True iff the last packet of the map has been sent. */ - bool TransferToNetworkQueue(ServerNetworkGameSocketHandler *socket) + bool TransferToNetworkQueue() { std::lock_guard lock(this->mutex); if (this->map_size_packet) { /* Don't queue the PACKET_SERVER_MAP_SIZE before the corresponding PACKET_SERVER_MAP_BEGIN */ - socket->SendPrependPacket(std::move(this->map_size_packet), PACKET_SERVER_MAP_BEGIN); + this->cs->SendPrependPacket(std::move(this->map_size_packet), PACKET_SERVER_MAP_BEGIN); } bool last_packet = false; for (auto &p : this->packets) { if (p->GetPacketType() == PACKET_SERVER_MAP_DONE) last_packet = true; - socket->SendPacket(std::move(p)); + this->cs->SendPacket(std::move(p)); } this->packets.clear(); @@ -142,13 +141,13 @@ struct PacketWriter : SaveFilter { void Write(byte *buf, size_t size) override { + std::lock_guard lock(this->mutex); + /* We want to abort the saving when the socket is closed. */ if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION); if (this->current == nullptr) this->current = std::make_unique(PACKET_SERVER_MAP_DATA, TCP_MTU); - std::lock_guard lock(this->mutex); - byte *bufe = buf + size; while (buf != bufe) { size_t written = this->current->Send_binary_until_full(buf, bufe); @@ -165,11 +164,11 @@ struct PacketWriter : SaveFilter { void Finish() override { + std::lock_guard lock(this->mutex); + /* We want to abort the saving when the socket is closed. */ if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION); - std::lock_guard lock(this->mutex); - /* Make sure the last packet is flushed. */ if (this->current != nullptr) this->packets.push_back(std::move(this->current)); @@ -489,6 +488,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendDesyncLog(const std::strin NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() { auto p = std::make_unique(PACKET_SERVER_CHECK_NEWGRFS, TCP_MTU); + + /* Invalid packet when status is anything but STATUS_INACTIVE. */ + if (this->status != STATUS_INACTIVE) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + + this->status = STATUS_NEWGRFS_CHECK; + + if (_grfconfig == nullptr) { + /* There are no NewGRFs, continue with the game password. */ + return this->SendNeedGamePassword(); + } + const GRFConfig *c; uint grf_count = 0; @@ -508,15 +518,16 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() /** Request the game password. */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword() { + /* Invalid packet when status is anything but STATUS_NEWGRFS_CHECK. */ + if (this->status != STATUS_NEWGRFS_CHECK) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + + this->status = STATUS_AUTH_GAME; + if (_settings_client.network.server_password.empty()) { /* Do not actually need a game password, continue with the company password. */ return this->SendNeedCompanyPassword(); } - /* Invalid packet when status is STATUS_AUTH_GAME or higher */ - if (this->status >= STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); - - this->status = STATUS_AUTH_GAME; /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; @@ -533,15 +544,16 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword() /** Request the company password. */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword() { + /* Invalid packet when status is anything but STATUS_AUTH_GAME. */ + if (this->status != STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + + this->status = STATUS_AUTH_COMPANY; + NetworkClientInfo *ci = this->GetInfo(); if (!Company::IsValidID(ci->client_playas) || _network_company_states[ci->client_playas].password.empty()) { return this->SendWelcome(); } - /* Invalid packet when status is STATUS_AUTH_COMPANY or higher */ - if (this->status >= STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); - - this->status = STATUS_AUTH_COMPANY; /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; @@ -555,10 +567,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword() /** Send the client a welcome message with some basic information. */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome() { - /* Invalid packet when status is AUTH or higher */ - if (this->status >= STATUS_AUTHORIZED) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); + /* Invalid packet when status is anything but STATUS_AUTH_COMPANY. */ + if (this->status != STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); this->status = STATUS_AUTHORIZED; + /* Reset 'lag' counters */ this->last_frame = this->last_frame_server = _frame_counter; @@ -659,7 +672,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() } if (this->status == STATUS_MAP) { - bool last_packet = this->savegame->TransferToNetworkQueue(this); + bool last_packet = this->savegame->TransferToNetworkQueue(); if (last_packet) { /* Done reading, make sure saving is done as well */ this->savegame->Destroy(); @@ -1015,13 +1028,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet &p) /* Make sure companies to which people try to join are not autocleaned */ if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0; - this->status = STATUS_NEWGRFS_CHECK; - - if (_grfconfig == nullptr) { - /* Continue asking for the game password. */ - return this->SendNeedGamePassword(); - } - return this->SendNewGRFCheck(); } diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index e33235205b..d638f441af 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -180,7 +180,7 @@ public: TrackdirBits dirs = follower.m_new_td_bits; const TrackdirBits dirs_without_90_degree = dirs & ~TrackdirCrossesTrackdirs(dir); if (dirs_without_90_degree != TRACKDIR_BIT_NONE) dirs = dirs_without_90_degree; - const int strip_amount = _random.Next(CountBits(dirs)); + const int strip_amount = RandomRange(CountBits(dirs)); for (int s = 0; s < strip_amount; ++s) RemoveFirstTrackdir(&dirs); return { follower.m_new_tile, FindFirstTrackdir(dirs) }; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 1ea5ebf110..b9af66cb48 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -303,8 +303,8 @@ protected: this->stations_per_cargo_type_no_rating = 0; for (const Station *st : Station::Iterate()) { - if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { - if (this->filter.facilities & st->facilities) { // only stations with selected facilities + if ((this->filter.facilities & st->facilities) != 0) { // only stations with selected facilities + if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { bool has_rating = false; /* Add to the station/cargo counts. */ for (CargoID j = 0; j < NUM_CARGO; j++) { diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini index 91b666d410..45237fa889 100644 --- a/src/table/settings/gui_settings.ini +++ b/src/table/settings/gui_settings.ini @@ -526,9 +526,9 @@ cat = SC_BASIC var = gui.liveries type = SLE_UINT8 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 2 +def = LIT_ALL +min = LIT_NONE +max = LIT_ALL str = STR_CONFIG_SETTING_LIVERIES strhelp = STR_CONFIG_SETTING_LIVERIES_HELPTEXT strval = STR_CONFIG_SETTING_LIVERIES_NONE