@ -65,11 +65,13 @@
# include "viewport_sprite_sorter.h"
# include "framerate_type.h"
# include "industry.h"
# include "string_func.h"
# include "linkgraph/linkgraphschedule.h"
# include <stdarg.h>
# include <system_error>
# include <functional>
# include "safeguards.h"
@ -1136,7 +1138,7 @@ void SwitchToMode(SwitchMode new_mode)
* the cached value and what the value would
* be when calculated from the ' base ' data .
*/
void CheckCaches ( bool force_check )
void CheckCaches ( bool force_check , std : : function < void ( const char * ) > log )
{
if ( ! force_check ) {
/* Return here so it is easy to add checks that are run
@ -1146,6 +1148,13 @@ void CheckCaches(bool force_check)
if ( _debug_desync_level = = 1 & & _tick_counter % 500 ! = 0 ) return ;
}
char cclog_buffer [ 1024 ] ;
# define CCLOG(...) { \
seprintf ( cclog_buffer , lastof ( cclog_buffer ) , __VA_ARGS__ ) ; \
DEBUG ( desync , 0 , " %s " , cclog_buffer ) ; \
if ( log ) log ( cclog_buffer ) ; \
}
/* Check the town caches. */
std : : vector < TownCache > old_town_caches ;
for ( const Town * t : Town : : Iterate ( ) ) {
@ -1159,7 +1168,7 @@ void CheckCaches(bool force_check)
uint i = 0 ;
for ( Town * t : Town : : Iterate ( ) ) {
if ( MemCmpT ( old_town_caches . data ( ) + i , & t - > cache ) ! = 0 ) {
DEBUG( desync , 0 , " town cache mismatch: town %i " , ( int ) t - > index ) ;
CCLOG( " town cache mismatch: town %i " , ( int ) t - > index ) ;
}
i + + ;
}
@ -1174,12 +1183,18 @@ void CheckCaches(bool force_check)
i = 0 ;
for ( const Company * c : Company : : Iterate ( ) ) {
if ( MemCmpT ( old_infrastructure . data ( ) + i , & c - > infrastructure ) ! = 0 ) {
DEBUG( desync , 0 , " infrastructure cache mismatch: company %i " , ( int ) c - > index ) ;
CCLOG( " infrastructure cache mismatch: company %i " , ( int ) c - > index ) ;
char buffer [ 4096 ] ;
old_infrastructure . Get ( i ) - > Dump ( buffer , lastof ( buffer ) ) ;
DEBUG ( desync , 0 , " Previous: \n %s " , buffer ) ;
old_infrastructure [ i ] . Dump ( buffer , lastof ( buffer ) ) ;
CCLOG ( " Previous: " ) ;
ProcessLineByLine ( buffer , [ & ] ( const char * line ) {
CCLOG ( " %s " , line ) ;
} ) ;
c - > infrastructure . Dump ( buffer , lastof ( buffer ) ) ;
DEBUG ( desync , 0 , " Recalculated: \n %s " , buffer ) ;
CCLOG ( " Recalculated: " ) ;
ProcessLineByLine ( buffer , [ & ] ( const char * line ) {
CCLOG ( " %s " , line ) ;
} ) ;
}
i + + ;
}
@ -1249,49 +1264,49 @@ void CheckCaches(bool force_check)
for ( const Vehicle * u = v ; u ! = nullptr ; u = u - > Next ( ) ) {
FillNewGRFVehicleCache ( u ) ;
if ( memcmp ( & grf_cache [ length ] , & u - > grf_cache , sizeof ( NewGRFCache ) ) ! = 0 ) {
DEBUG( desync , 0 , " newgrf cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i " , ( int ) v - > type , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " newgrf cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i " , ( int ) v - > type , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( memcmp ( & veh_cache [ length ] , & u - > vcache , sizeof ( VehicleCache ) ) ! = 0 ) {
DEBUG ( desync , 0 , " vehicle cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i " , ( int ) v - > type , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( veh_old [ length ] - > acceleration ! = u - > acceleration ) {
DEBUG( desync , 0 , " acceleration mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " acceleration mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( veh_old [ length ] - > breakdown_chance ! = u - > breakdown_chance ) {
DEBUG( desync , 0 , " breakdown_chance mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " breakdown_chance mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( veh_old [ length ] - > breakdowns_since_last_service ! = u - > breakdowns_since_last_service ) {
DEBUG( desync , 0 , " breakdowns_since_last_service mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " breakdowns_since_last_service mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( veh_old [ length ] - > vehicle_flags ! = u - > vehicle_flags ) {
DEBUG( desync , 0 , " vehicle_flags mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " vehicle_flags mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
switch ( u - > type ) {
case VEH_TRAIN :
if ( memcmp ( & gro_cache [ length ] , & Train : : From ( u ) - > gcache , sizeof ( GroundVehicleCache ) ) ! = 0 ) {
DEBUG( desync , 0 , " train ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " train ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( memcmp ( & tra_cache [ length ] , & Train : : From ( u ) - > tcache , sizeof ( TrainCache ) ) ! = 0 ) {
DEBUG( desync , 0 , " train cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " train cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( Train : : From ( veh_old [ length ] ) - > railtype ! = Train : : From ( u ) - > railtype ) {
DEBUG( desync , 0 , " railtype mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " railtype mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( Train : : From ( veh_old [ length ] ) - > compatible_railtypes ! = Train : : From ( u ) - > compatible_railtypes ) {
DEBUG( desync , 0 , " compatible_railtypes mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " compatible_railtypes mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( Train : : From ( veh_old [ length ] ) - > flags ! = Train : : From ( u ) - > flags ) {
DEBUG( desync , 0 , " flags mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " flags mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
break ;
case VEH_ROAD :
if ( memcmp ( & gro_cache [ length ] , & RoadVehicle : : From ( u ) - > gcache , sizeof ( GroundVehicleCache ) ) ! = 0 ) {
DEBUG( desync , 0 , " road vehicle ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " road vehicle ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
break ;
case VEH_AIRCRAFT :
if ( memcmp ( & air_cache [ length ] , & Aircraft : : From ( u ) - > acache , sizeof ( AircraftCache ) ) ! = 0 ) {
DEBUG( desync , 0 , " Aircraft vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " Aircraft vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
break ;
default :
@ -1372,6 +1387,8 @@ void CheckCaches(bool force_check)
}
i + + ;
}
# undef CCLOG
}
/**
@ -1386,7 +1403,7 @@ void CheckCaches(bool force_check)
CommandCost CmdDesyncCheck ( TileIndex tile , DoCommandFlag flags , uint32 p1 , uint32 p2 , const char * text )
{
if ( flags & DC_EXEC ) {
CheckCaches ( true );
CheckCaches ( true , nullptr );
}
return CommandCost ( ) ;
@ -1440,7 +1457,7 @@ void StateGameLoop()
SaveOrLoad ( name , SLO_SAVE , DFT_GAME_FILE , AUTOSAVE_DIR , false ) ;
}
CheckCaches ( false );
CheckCaches ( false , nullptr );
/* All these actions has to be done from OWNER_NONE
* for multiplayer compatibility */