Add flags for mismatch type to client desync log
This commit is contained in:
@@ -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);
|
||||||
|
@@ -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();
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user