(svn r14772) -Codechange: make the "dump log of game to reproduce" desync debug stuff a runtime configurable debug option instead of a compile time option.
This commit is contained in:
@@ -583,7 +583,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
|
||||
return true;
|
||||
}
|
||||
#endif /* ENABLE_NETWORK */
|
||||
DebugDumpCommands("ddc:cmd:%d;%d;%d;%d;%d;%d;%d;%s\n", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd, text);
|
||||
DEBUG(desync, 1, "cmd: %08x; %08x; %1x; %06x; %08x; %08x; %04x; %s\n", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text);
|
||||
|
||||
/* update last build coordinate of company. */
|
||||
if (tile != 0 && IsValidCompanyID(_current_company)) {
|
||||
|
14
src/date.cpp
14
src/date.cpp
@@ -15,9 +15,7 @@
|
||||
#include "vehicle_base.h"
|
||||
#include "debug.h"
|
||||
#include "rail_gui.h"
|
||||
#ifdef DEBUG_DUMP_COMMANDS
|
||||
#include "saveload.h"
|
||||
#endif
|
||||
|
||||
Year _cur_year;
|
||||
Month _cur_month;
|
||||
@@ -244,12 +242,12 @@ void IncreaseDate()
|
||||
|
||||
/* yes, call various monthly loops */
|
||||
if (_game_mode != GM_MENU) {
|
||||
#ifdef DEBUG_DUMP_COMMANDS
|
||||
char name[MAX_PATH];
|
||||
snprintf(name, lengthof(name), "dmp_cmds_%d.sav", _date);
|
||||
SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
|
||||
DebugDumpCommands("ddc:save:%s\n", name);
|
||||
#endif /* DUMP_COMMANDS */
|
||||
if (_debug_desync_level > 2) {
|
||||
char name[MAX_PATH];
|
||||
snprintf(name, lengthof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
|
||||
SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
|
||||
}
|
||||
|
||||
if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
|
||||
_do_autosave = true;
|
||||
RedrawAutosave();
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include "debug.h"
|
||||
#include "string_func.h"
|
||||
#include "network/core/core.h"
|
||||
#include "fileio_func.h"
|
||||
|
||||
#if defined(ENABLE_NETWORK)
|
||||
SOCKET _debug_socket = INVALID_SOCKET;
|
||||
@@ -31,6 +32,7 @@ int _debug_freetype_level;
|
||||
int _debug_sl_level;
|
||||
int _debug_station_level;
|
||||
int _debug_gamelog_level;
|
||||
int _debug_desync_level;
|
||||
|
||||
|
||||
struct DebugLevel {
|
||||
@@ -56,6 +58,7 @@ struct DebugLevel {
|
||||
DEBUG_LEVEL(sl),
|
||||
DEBUG_LEVEL(station),
|
||||
DEBUG_LEVEL(gamelog),
|
||||
DEBUG_LEVEL(desync),
|
||||
};
|
||||
#undef DEBUG_LEVEL
|
||||
|
||||
@@ -71,7 +74,7 @@ static void debug_print(const char *dbg, const char *buf)
|
||||
send(_debug_socket, buf2, (int)strlen(buf2), 0);
|
||||
} else
|
||||
#endif /* ENABLE_NETWORK */
|
||||
{
|
||||
if (strcmp(dbg, "desync") != 0) {
|
||||
#if defined(WINCE)
|
||||
/* We need to do OTTD2FS twice, but as it uses a static buffer, we need to store one temporary */
|
||||
TCHAR tbuf[512];
|
||||
@@ -81,6 +84,12 @@ static void debug_print(const char *dbg, const char *buf)
|
||||
fprintf(stderr, "dbg: [%s] %s\n", dbg, buf);
|
||||
#endif
|
||||
IConsoleDebug(dbg, buf);
|
||||
} else {
|
||||
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
|
||||
if (f == NULL) return;
|
||||
|
||||
fprintf(f, "%s", buf);
|
||||
fflush(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,20 +177,3 @@ const char *GetDebugString()
|
||||
|
||||
return dbgstr;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DUMP_COMMANDS
|
||||
#include "fileio_func.h"
|
||||
|
||||
void CDECL DebugDumpCommands(const char *s, ...)
|
||||
{
|
||||
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
|
||||
if (f == NULL) return;
|
||||
|
||||
va_list va;
|
||||
va_start(va, s);
|
||||
vfprintf(f, s, va);
|
||||
va_end(va);
|
||||
|
||||
fflush(f);
|
||||
}
|
||||
#endif /* DEBUG_DUMP_COMMANDS */
|
||||
|
13
src/debug.h
13
src/debug.h
@@ -48,6 +48,7 @@
|
||||
extern int _debug_sl_level;
|
||||
extern int _debug_station_level;
|
||||
extern int _debug_gamelog_level;
|
||||
extern int _debug_desync_level;
|
||||
|
||||
void CDECL debug(const char *dbg, ...);
|
||||
#endif /* NO_DEBUG_MESSAGES */
|
||||
@@ -101,16 +102,4 @@ const char *GetDebugString();
|
||||
void ShowInfo(const char *str);
|
||||
void CDECL ShowInfoF(const char *str, ...);
|
||||
|
||||
#ifdef DEBUG_DUMP_COMMANDS
|
||||
void CDECL DebugDumpCommands(const char *s, ...);
|
||||
#else /* DEBUG_DUMP_COMMANDS */
|
||||
/* when defined as an empty function with variable argument list,
|
||||
* it can't be inlined - so define it as an empty macro */
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
#define DebugDumpCommands(s, args...)
|
||||
#else
|
||||
#define DebugDumpCommands(s, ...)
|
||||
#endif
|
||||
#endif /* DEBUG_DUMP_COMMANDS */
|
||||
|
||||
#endif /* DEBUG_H */
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "newgrf_storage.h"
|
||||
#include "water.h"
|
||||
#include "tilehighlight_func.h"
|
||||
#include "saveload.h"
|
||||
|
||||
#include "table/sprites.h"
|
||||
|
||||
@@ -163,8 +164,14 @@ static void _GenerateWorld(void *arg)
|
||||
MarkWholeScreenDirty();
|
||||
|
||||
if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game");
|
||||
DEBUG(desync, 1, "new_map: %i\n", _settings_game.game_creation.generation_seed);
|
||||
|
||||
if (_settings_client.gui.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, 1, 0, CMD_PAUSE);
|
||||
if (_debug_desync_level > 0) {
|
||||
char name[MAX_PATH];
|
||||
snprintf(name, lengthof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
|
||||
SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
|
||||
}
|
||||
} catch (...) {
|
||||
_generating_world = false;
|
||||
throw;
|
||||
|
@@ -213,7 +213,7 @@ void NetworkTextMessage(NetworkAction action, ConsoleColour color, bool self_sen
|
||||
SetDParam(2, data);
|
||||
GetString(message, strid, lastof(message));
|
||||
|
||||
DebugDumpCommands("ddc:cmsg:%d;%d;%s\n", _date, _date_fract, message);
|
||||
DEBUG(desync, 1, "msg: %d; %d; %s\n", _date, _date_fract, message);
|
||||
IConsolePrintF(color, "%s", message);
|
||||
NetworkAddChatMessage(color, duration, "%s", message);
|
||||
}
|
||||
@@ -964,7 +964,7 @@ static bool NetworkDoClientLoop()
|
||||
if (_sync_seed_1 != _random.state[0]) {
|
||||
#endif
|
||||
NetworkError(STR_NETWORK_ERR_DESYNC);
|
||||
DebugDumpCommands("ddc:serr:%d;%d\n", _date, _date_fract);
|
||||
DEBUG(desync, 1, "sync_err: %d; %d\n", _date, _date_fract);
|
||||
DEBUG(net, 0, "Sync error detected!");
|
||||
NetworkClientError(NETWORK_RECV_STATUS_DESYNC, GetNetworkClientSocket(0));
|
||||
return false;
|
||||
@@ -1032,10 +1032,10 @@ void NetworkGameLoop()
|
||||
|
||||
char buff[4096];
|
||||
if (fgets(buff, lengthof(buff), f) == NULL) break;
|
||||
if (strncmp(buff, "ddc:cmd:", 8) != 0) continue;
|
||||
if (strncmp(buff, "cmd: ", 8) != 0) continue;
|
||||
cp = MallocT<CommandPacket>(1);
|
||||
int company;
|
||||
sscanf(&buff[8], "%d;%d;%d;%d;%d;%d;%d;%s", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cp->cmd, cp->text);
|
||||
sscanf(&buff[8], "%d; %d; %d; %d; %d; %d; %d; %s", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cp->cmd, cp->text);
|
||||
cp->company = (CompanyID)company;
|
||||
}
|
||||
#endif /* DEBUG_DUMP_COMMANDS */
|
||||
|
@@ -102,8 +102,6 @@ void NetworkExecuteCommand(CommandPacket *cp)
|
||||
cp->callback = 0;
|
||||
}
|
||||
|
||||
DebugDumpCommands("ddc:cmd:%d;%d;%d;%d;%d;%d;%d;%s\n", _date, _date_fract, (int)cp->company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text);
|
||||
|
||||
DoCommandP(cp->tile, cp->p1, cp->p2, cp->cmd | CMD_NETWORK_COMMAND, _callback_table[cp->callback], cp->text, cp->my_cmd);
|
||||
}
|
||||
|
||||
|
@@ -1029,53 +1029,53 @@ void StateGameLoop()
|
||||
CallWindowTickEvent();
|
||||
NewsLoop();
|
||||
} else {
|
||||
#ifdef DEBUG_DUMP_COMMANDS
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v != v->First()) continue;
|
||||
if (_debug_desync_level > 1) {
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v != v->First()) continue;
|
||||
|
||||
switch (v->type) {
|
||||
case VEH_ROAD: {
|
||||
extern byte GetRoadVehLength(const Vehicle *v);
|
||||
if (GetRoadVehLength(v) != v->u.road.cached_veh_length) {
|
||||
printf("cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
|
||||
}
|
||||
} break;
|
||||
|
||||
case VEH_TRAIN: {
|
||||
uint length = 0;
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) length++;
|
||||
|
||||
VehicleRail *wagons = MallocT<VehicleRail>(length);
|
||||
length = 0;
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) wagons[length++] = u->u.rail;
|
||||
|
||||
TrainConsistChanged(v, true);
|
||||
|
||||
length = 0;
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||
if (memcmp(&wagons[length], &u->u.rail, sizeof(VehicleRail)) != 0) {
|
||||
printf("cache mismatch: vehicle %i, company %i, unit number %i, wagon %i\n", v->index, (int)v->owner, v->unitnumber, length);
|
||||
switch (v->type) {
|
||||
case VEH_ROAD: {
|
||||
extern byte GetRoadVehLength(const Vehicle *v);
|
||||
if (GetRoadVehLength(v) != v->u.road.cached_veh_length) {
|
||||
DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
|
||||
}
|
||||
length++;
|
||||
}
|
||||
} break;
|
||||
|
||||
free(wagons);
|
||||
} break;
|
||||
case VEH_TRAIN: {
|
||||
uint length = 0;
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) length++;
|
||||
|
||||
case VEH_AIRCRAFT: {
|
||||
uint speed = v->u.air.cached_max_speed;
|
||||
UpdateAircraftCache(v);
|
||||
if (speed != v->u.air.cached_max_speed) {
|
||||
printf("cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
|
||||
}
|
||||
} break;
|
||||
VehicleRail *wagons = MallocT<VehicleRail>(length);
|
||||
length = 0;
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) wagons[length++] = u->u.rail;
|
||||
|
||||
default:
|
||||
break;
|
||||
TrainConsistChanged(v, true);
|
||||
|
||||
length = 0;
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||
if (memcmp(&wagons[length], &u->u.rail, sizeof(VehicleRail)) != 0) {
|
||||
DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i, wagon %i\n", v->index, (int)v->owner, v->unitnumber, length);
|
||||
}
|
||||
length++;
|
||||
}
|
||||
|
||||
free(wagons);
|
||||
} break;
|
||||
|
||||
case VEH_AIRCRAFT: {
|
||||
uint speed = v->u.air.cached_max_speed;
|
||||
UpdateAircraftCache(v);
|
||||
if (speed != v->u.air.cached_max_speed) {
|
||||
DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* All these actions has to be done from OWNER_NONE
|
||||
* for multiplayer compatibility */
|
||||
|
@@ -1687,6 +1687,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
|
||||
/* General tactic is to first save the game to memory, then use an available writer
|
||||
* to write it to file, either in threaded mode if possible, or single-threaded */
|
||||
if (mode == SL_SAVE) { /* SAVE game */
|
||||
DEBUG(desync, 1, "save: %s\n", filename);
|
||||
fmt = GetSavegameFormat("memory"); // write to memory
|
||||
|
||||
_sl.write_bytes = fmt->writer;
|
||||
@@ -1714,7 +1715,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
|
||||
}
|
||||
} else { /* LOAD game */
|
||||
assert(mode == SL_LOAD);
|
||||
DebugDumpCommands("ddc:load:%s\n", filename);
|
||||
DEBUG(desync, 1, "load: %s\n", filename);
|
||||
|
||||
if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
||||
|
||||
|
Reference in New Issue
Block a user