Add flags for mismatch type to client desync log

pull/104/head
Jonathan G Rennison 5 years ago
parent ec892879f4
commit 459a49cb24

@ -449,12 +449,22 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const
* @param last The last position in the buffer to write to.
* @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);
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)));
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;
ConvertDateToYMD(_date, &ymd);
@ -627,7 +637,7 @@ bool CrashLog::MakeCrashLog() const
* information like paths to the console.
* @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 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));
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()) {
b = strecpy(b, "\n", lastof(buffer), true);

@ -12,8 +12,22 @@
#ifndef CRASHLOG_H
#define CRASHLOG_H
#include "core/enum_type.hpp"
#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.
*/
@ -113,7 +127,7 @@ public:
virtual ~CrashLog() {}
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;
/**
@ -130,7 +144,7 @@ public:
bool WriteScreenshot(char *filename, const char *filename_last, const char *name = "crash") 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;
/**
@ -140,7 +154,7 @@ public:
*/
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 AfterCrashLogCleanup();

@ -288,13 +288,21 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
#else
if (_sync_seed_1 != _random.state[0] || _sync_state_checksum != _state_checksum.state) {
#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);
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);
DEBUG(net, 0, "Sync error detected!");
std::string desync_log;
CrashLog::DesyncCrashLog(nullptr, &desync_log);
CrashLog::DesyncCrashLog(nullptr, &desync_log, info);
my_client->SendDesyncLog(desync_log);
my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
return false;

@ -1214,7 +1214,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
NetworkAdminClientError(this->client_id, errorno);
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
_settings_client.network.sync_freq = min<uint16>(_settings_client.network.sync_freq, 16);

@ -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{});
log.MakeDesyncCrashLog(log_in, log_out);
log.MakeDesyncCrashLog(log_in, log_out, info);
}

@ -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{});
log.MakeDesyncCrashLog(log_in, log_out);
log.MakeDesyncCrashLog(log_in, log_out, info);
}

@ -612,10 +612,10 @@ static void CDECL CustomAbort(int signal)
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);
log.MakeDesyncCrashLog(log_in, log_out);
log.MakeDesyncCrashLog(log_in, log_out, info);
}
/* The crash log GUI */

Loading…
Cancel
Save