@ -73,6 +73,7 @@
# include "zoning.h"
# include "cargopacket.h"
# include "tbtr_template_vehicle.h"
# include "string_func_extra.h"
# include "linkgraph/linkgraphschedule.h"
# include "tracerestrict.h"
@ -1287,7 +1288,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
@ -1297,6 +1298,13 @@ void CheckCaches(bool force_check)
if ( _debug_desync_level = = 1 & & _scaled_date_ticks % 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 ;
Town * t ;
@ -1311,7 +1319,7 @@ void CheckCaches(bool force_check)
uint i = 0 ;
FOR_ALL_TOWNS ( t ) {
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 + + ;
}
@ -1327,12 +1335,18 @@ void CheckCaches(bool force_check)
i = 0 ;
FOR_ALL_COMPANIES ( c ) {
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 [ i ] . Dump ( buffer , lastof ( buffer ) ) ;
DEBUG ( desync , 0 , " Previous: \n %s " , 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 + + ;
}
@ -1404,65 +1418,65 @@ 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 ( veh_cache [ length ] . cached_max_speed ! = u - > vcache . cached_max_speed | | veh_cache [ length ] . cached_cargo_age_period ! = u - > vcache . cached_cargo_age_period | |
veh_cache [ length ] . cached_vis_effect ! = u - > vcache . cached_vis_effect | | HasBit ( veh_cache [ length ] . cached_veh_flags ^ u - > vcache . cached_veh_flags , VCF_LAST_VISUAL_EFFECT ) ) {
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 ) ;
CCLOG( " 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 ( u - > IsGroundVehicle ( ) & & ( HasBit ( u - > GetGroundVehicleFlags ( ) , GVF_GOINGUP_BIT ) | | HasBit ( u - > GetGroundVehicleFlags ( ) , GVF_GOINGDOWN_BIT ) ) & & u - > GetGroundVehicleCache ( ) - > cached_slope_resistance & & HasBit ( v - > vcache . cached_veh_flags , VCF_GV_ZERO_SLOPE_RESIST ) ) {
DEBUG( desync , 0 , " VCF_GV_ZERO_SLOPE_RESIST set incorrectly: type %i, vehicle %i, company %i, unit number %i, wagon %i " , ( int ) v - > type , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " VCF_GV_ZERO_SLOPE_RESIST set incorrectly: 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 ] - > breakdown_ctr ! = u - > breakdown_ctr ) {
DEBUG( desync , 0 , " breakdown_ctr mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " breakdown_ctr mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( veh_old [ length ] - > breakdown_delay ! = u - > breakdown_delay ) {
DEBUG( desync , 0 , " breakdown_delay mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " breakdown_delay 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 ] - > breakdown_severity ! = u - > breakdown_severity ) {
DEBUG( desync , 0 , " breakdown_severity mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " breakdown_severity mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
}
if ( veh_old [ length ] - > breakdown_type ! = u - > breakdown_type ) {
DEBUG( desync , 0 , " breakdown_type mismatch: vehicle %i, company %i, unit number %i, wagon %i " , v - > index , ( int ) v - > owner , v - > unitnumber , length ) ;
CCLOG( " breakdown_type 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 :
@ -1515,6 +1529,8 @@ void CheckCaches(bool force_check)
if ( tv - > Prev ( ) ) assert_msg ( tv - > Prev ( ) - > Next ( ) = = tv , " %u " , tv - > index ) ;
if ( tv - > Next ( ) ) assert_msg ( tv - > Next ( ) - > Prev ( ) = = tv , " %u " , tv - > index ) ;
}
# undef CCLOG
}
/**
@ -1529,7 +1545,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 ( ) ;
@ -1588,7 +1604,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 */