Add flags for mismatch type to client desync log

This commit is contained in:
Jonathan G Rennison
2019-08-20 20:47:17 +01:00
parent ec892879f4
commit 459a49cb24
7 changed files with 46 additions and 14 deletions

View File

@@ -449,12 +449,22 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const
* @param last The last position in the buffer to write to. * @param last The last position in the buffer to write to.
* @return the position of the \c '\0' character after the buffer. * @return the position of the \c '\0' character after the buffer.
*/ */
char *CrashLog::FillDesyncCrashLog(char *buffer, const char *last) const char *CrashLog::FillDesyncCrashLog(char *buffer, const char *last, const DesyncExtraInfo &info) const
{ {
time_t cur_time = time(nullptr); time_t cur_time = time(nullptr);
buffer += seprintf(buffer, last, "*** OpenTTD Multiplayer %s Desync Report ***\n\n", _network_server ? "Server" : "Client"); buffer += seprintf(buffer, last, "*** OpenTTD Multiplayer %s Desync Report ***\n\n", _network_server ? "Server" : "Client");
buffer += seprintf(buffer, last, "Desync at: %s", asctime(gmtime(&cur_time))); buffer += seprintf(buffer, last, "Desync at: %s", asctime(gmtime(&cur_time)));
if (!_network_server && info.flags) {
auto flag_check = [&](DesyncExtraInfo::Flags flag, const char *str) {
return info.flags & flag ? str : "";
};
buffer += seprintf(buffer, last, "Flags: %s%s%s%s\n",
flag_check(DesyncExtraInfo::DEIF_RAND1, "R"),
flag_check(DesyncExtraInfo::DEIF_RAND2, "Z"),
flag_check(DesyncExtraInfo::DEIF_STATE, "S"),
flag_check(DesyncExtraInfo::DEIF_DBL_RAND, "D"));
}
YearMonthDay ymd; YearMonthDay ymd;
ConvertDateToYMD(_date, &ymd); ConvertDateToYMD(_date, &ymd);
@@ -627,7 +637,7 @@ bool CrashLog::MakeCrashLog() const
* information like paths to the console. * information like paths to the console.
* @return true when everything is made successfully. * @return true when everything is made successfully.
*/ */
bool CrashLog::MakeDesyncCrashLog(const std::string *log_in, std::string *log_out) const bool CrashLog::MakeDesyncCrashLog(const std::string *log_in, std::string *log_out, const DesyncExtraInfo &info) const
{ {
char filename[MAX_PATH]; char filename[MAX_PATH];
char buffer[65536 * 2]; char buffer[65536 * 2];
@@ -641,7 +651,7 @@ bool CrashLog::MakeDesyncCrashLog(const std::string *log_in, std::string *log_ou
strftime(name_buffer_date, lastof(name_buffer) - name_buffer_date, "%Y%m%dT%H%M%SZ", gmtime(&cur_time)); strftime(name_buffer_date, lastof(name_buffer) - name_buffer_date, "%Y%m%dT%H%M%SZ", gmtime(&cur_time));
printf("Desync encountered (%s), generating desync log...\n", mode); printf("Desync encountered (%s), generating desync log...\n", mode);
char *b = this->FillDesyncCrashLog(buffer, lastof(buffer)); char *b = this->FillDesyncCrashLog(buffer, lastof(buffer), info);
if (log_in && !log_in->empty()) { if (log_in && !log_in->empty()) {
b = strecpy(b, "\n", lastof(buffer), true); b = strecpy(b, "\n", lastof(buffer), true);

View File

@@ -12,8 +12,22 @@
#ifndef CRASHLOG_H #ifndef CRASHLOG_H
#define CRASHLOG_H #define CRASHLOG_H
#include "core/enum_type.hpp"
#include <string> #include <string>
struct DesyncExtraInfo {
enum Flags {
DEIF_NONE = 0, ///< no flags
DEIF_RAND1 = 1 << 0, ///< random 1 mismatch
DEIF_RAND2 = 1 << 1, ///< random 2 mismatch
DEIF_STATE = 1 << 2, ///< state mismatch
DEIF_DBL_RAND = 1 << 3, ///< double-seed sent
};
Flags flags = DEIF_NONE;
};
DECLARE_ENUM_AS_BIT_SET(DesyncExtraInfo::Flags)
/** /**
* Helper class for creating crash logs. * Helper class for creating crash logs.
*/ */
@@ -113,7 +127,7 @@ public:
virtual ~CrashLog() {} virtual ~CrashLog() {}
char *FillCrashLog(char *buffer, const char *last) const; char *FillCrashLog(char *buffer, const char *last) const;
char *FillDesyncCrashLog(char *buffer, const char *last) const; char *FillDesyncCrashLog(char *buffer, const char *last, const DesyncExtraInfo &info) const;
bool WriteCrashLog(const char *buffer, char *filename, const char *filename_last, const char *name = "crash") const; bool WriteCrashLog(const char *buffer, char *filename, const char *filename_last, const char *name = "crash") const;
/** /**
@@ -130,7 +144,7 @@ public:
bool WriteScreenshot(char *filename, const char *filename_last, const char *name = "crash") const; bool WriteScreenshot(char *filename, const char *filename_last, const char *name = "crash") const;
bool MakeCrashLog() const; bool MakeCrashLog() const;
bool MakeDesyncCrashLog(const std::string *log_in, std::string *log_out) const; bool MakeDesyncCrashLog(const std::string *log_in, std::string *log_out, const DesyncExtraInfo &info) const;
bool MakeCrashSavegameAndScreenshot() const; bool MakeCrashSavegameAndScreenshot() const;
/** /**
@@ -140,7 +154,7 @@ public:
*/ */
static void InitialiseCrashLog(); static void InitialiseCrashLog();
static void DesyncCrashLog(const std::string *log_in, std::string *log_out); static void DesyncCrashLog(const std::string *log_in, std::string *log_out, const DesyncExtraInfo &info);
static void SetErrorMessage(const char *message); static void SetErrorMessage(const char *message);
static void AfterCrashLogCleanup(); static void AfterCrashLogCleanup();

View File

@@ -288,13 +288,21 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
#else #else
if (_sync_seed_1 != _random.state[0] || _sync_state_checksum != _state_checksum.state) { if (_sync_seed_1 != _random.state[0] || _sync_state_checksum != _state_checksum.state) {
#endif #endif
DesyncExtraInfo info;
if (_sync_seed_1 != _random.state[0]) info.flags |= DesyncExtraInfo::DEIF_RAND1;
#ifdef NETWORK_SEND_DOUBLE_SEED
if (_sync_seed_2 != _random.state[1]) info.flags |= DesyncExtraInfo::DEIF_RAND2;
info.flags |= DesyncExtraInfo::DEIF_DBL_RAND;
#endif
if (_sync_state_checksum != _state_checksum.state) info.flags |= DesyncExtraInfo::DEIF_STATE;
NetworkError(STR_NETWORK_ERROR_DESYNC); NetworkError(STR_NETWORK_ERROR_DESYNC);
DEBUG(desync, 1, "sync_err: date{%08x; %02x; %02x} {%x, " OTTD_PRINTFHEX64 "} != {%x, " OTTD_PRINTFHEX64 "}" DEBUG(desync, 1, "sync_err: date{%08x; %02x; %02x} {%x, " OTTD_PRINTFHEX64 "} != {%x, " OTTD_PRINTFHEX64 "}"
, _date, _date_fract, _tick_skip_counter, _sync_seed_1, _sync_state_checksum, _random.state[0], _state_checksum.state); , _date, _date_fract, _tick_skip_counter, _sync_seed_1, _sync_state_checksum, _random.state[0], _state_checksum.state);
DEBUG(net, 0, "Sync error detected!"); DEBUG(net, 0, "Sync error detected!");
std::string desync_log; std::string desync_log;
CrashLog::DesyncCrashLog(nullptr, &desync_log); CrashLog::DesyncCrashLog(nullptr, &desync_log, info);
my_client->SendDesyncLog(desync_log); my_client->SendDesyncLog(desync_log);
my_client->ClientError(NETWORK_RECV_STATUS_DESYNC); my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
return false; return false;

View File

@@ -1214,7 +1214,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
NetworkAdminClientError(this->client_id, errorno); NetworkAdminClientError(this->client_id, errorno);
if (errorno == NETWORK_ERROR_DESYNC) { if (errorno == NETWORK_ERROR_DESYNC) {
CrashLog::DesyncCrashLog(&(this->desync_log), nullptr); CrashLog::DesyncCrashLog(&(this->desync_log), nullptr, DesyncExtraInfo{});
// decrease the sync frequency for this point onwards // decrease the sync frequency for this point onwards
_settings_client.network.sync_freq = min<uint16>(_settings_client.network.sync_freq, 16); _settings_client.network.sync_freq = min<uint16>(_settings_client.network.sync_freq, 16);

View File

@@ -516,8 +516,8 @@ void CDECL HandleCrash(int signum, siginfo_t *si, void *context)
} }
} }
/* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out) /* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out, const DesyncExtraInfo &info)
{ {
CrashLogOSX log(CrashLogOSX::DesyncTag{}); CrashLogOSX log(CrashLogOSX::DesyncTag{});
log.MakeDesyncCrashLog(log_in, log_out); log.MakeDesyncCrashLog(log_in, log_out, info);
} }

View File

@@ -620,8 +620,8 @@ static void CDECL HandleCrash(int signum)
} }
} }
/* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out) /* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out, const DesyncExtraInfo &info)
{ {
CrashLogUnix log(CrashLogUnix::DesyncTag{}); CrashLogUnix log(CrashLogUnix::DesyncTag{});
log.MakeDesyncCrashLog(log_in, log_out); log.MakeDesyncCrashLog(log_in, log_out, info);
} }

View File

@@ -612,10 +612,10 @@ static void CDECL CustomAbort(int signal)
SetUnhandledExceptionFilter(ExceptionHandler); SetUnhandledExceptionFilter(ExceptionHandler);
} }
/* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out) /* static */ void CrashLog::DesyncCrashLog(const std::string *log_in, std::string *log_out, const DesyncExtraInfo &info)
{ {
CrashLogWindows log(nullptr); CrashLogWindows log(nullptr);
log.MakeDesyncCrashLog(log_in, log_out); log.MakeDesyncCrashLog(log_in, log_out, info);
} }
/* The crash log GUI */ /* The crash log GUI */