diff --git a/src/debug_settings.h b/src/debug_settings.h index 9d770a6f11..5e29fe6db3 100644 --- a/src/debug_settings.h +++ b/src/debug_settings.h @@ -14,11 +14,12 @@ #include "core/bitmath_func.hpp" enum ChickenBitFlags { - DCBF_VEH_TICK_CACHE = 0, - DCBF_MP_NO_STATE_CSUM_CHECK = 1, - DCBF_DESYNC_CHECK_PERIODIC = 2, - DCBF_DESYNC_CHECK_POST_COMMAND = 3, - DCBF_DESYNC_CHECK_NO_GENERAL = 4, + DCBF_VEH_TICK_CACHE = 0, + DCBF_MP_NO_STATE_CSUM_CHECK = 1, + DCBF_DESYNC_CHECK_PERIODIC = 2, + DCBF_DESYNC_CHECK_POST_COMMAND = 3, + DCBF_DESYNC_CHECK_NO_GENERAL = 4, + DCBF_DESYNC_CHECK_PERIODIC_SIGNALS = 5, }; inline bool HasChickenBit(ChickenBitFlags flag) diff --git a/src/openttd.cpp b/src/openttd.cpp index 12763a5fdf..8e12068a66 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -82,6 +82,7 @@ #include "debug_settings.h" #include "debug_desync.h" #include "event_logs.h" +#include "tunnelbridge.h" #include "linkgraph/linkgraphschedule.h" #include "tracerestrict.h" @@ -1336,6 +1337,43 @@ void WriteVehicleInfo(char *&p, const char *last, const Vehicle *u, const Vehicl } } +static bool SignalInfraTotalMatches() +{ + std::array old_signal_totals = {}; + for (const Company *c : Company::Iterate()) { + old_signal_totals[c->index] = c->infrastructure.signal; + } + + std::array new_signal_totals = {}; + for (TileIndex tile = 0; tile < MapSize(); tile++) { + switch (GetTileType(tile)) { + case MP_RAILWAY: + if (HasSignals(tile)) { + const Company *c = Company::GetIfValid(GetTileOwner(tile)); + if (c != nullptr) new_signal_totals[c->index] += CountBits(GetPresentSignals(tile)); + } + break; + + case MP_TUNNELBRIDGE: { + /* Only count the tunnel/bridge if we're on the northern end tile. */ + DiagDirection dir = GetTunnelBridgeDirection(tile); + if (dir == DIAGDIR_NE || dir == DIAGDIR_NW) break; + + if (IsTunnelBridgeWithSignalSimulation(tile)) { + const Company *c = Company::GetIfValid(GetTileOwner(tile)); + if (c != nullptr) new_signal_totals[c->index] += GetTunnelBridgeSignalSimulationSignalCount(tile, GetOtherTunnelBridgeEnd(tile)); + } + break; + } + + default: + break; + } + } + + return old_signal_totals == new_signal_totals; +} + /** * Check the validity of some of the caches. * Especially in the sense of desyncs between @@ -1351,6 +1389,9 @@ void CheckCaches(bool force_check, std::function log, CheckC desync_level = 1; if (HasChickenBit(DCBF_DESYNC_CHECK_NO_GENERAL)) flags &= ~CHECK_CACHE_GENERAL; } + if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_PERIODIC_SIGNALS)) && desync_level < 2 && _scaled_date_ticks % 256 == 0) { + if (!SignalInfraTotalMatches()) desync_level = 2; + } /* Return here so it is easy to add checks that are run * always to aid testing of caches. */ @@ -1492,6 +1533,9 @@ void CheckCaches(bool force_check, std::function log, CheckC ProcessLineByLine(buffer, [&](const char *line) { CCLOG(" %s", line); }); + if (old_infrastructure[i].signal != c->infrastructure.signal && _network_server && !HasChickenBit(DCBF_DESYNC_CHECK_PERIODIC_SIGNALS)) { + DoCommandP(0, 0, _settings_game.debug.chicken_bits | (1 << DCBF_DESYNC_CHECK_PERIODIC_SIGNALS), CMD_CHANGE_SETTING, nullptr, "debug.chicken_bits"); + } } i++; }