mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Merge pull request #17665 from janisozaur/more-info-on-save-failure
Collect more info in case of save failure
This commit is contained in:
@@ -640,6 +640,30 @@ public:
|
||||
_platformUiContext->ShowMessageBox(_window, message);
|
||||
}
|
||||
|
||||
int32_t ShowMessageBox(
|
||||
const std::string& title, const std::string& message, const std::vector<std::string>& options) override
|
||||
{
|
||||
auto message_box_button_data = std::make_unique<SDL_MessageBoxButtonData[]>(options.size());
|
||||
for (size_t i = 0; i < options.size(); i++)
|
||||
{
|
||||
message_box_button_data[i].buttonid = static_cast<int>(i);
|
||||
message_box_button_data[i].text = options[i].c_str();
|
||||
}
|
||||
|
||||
SDL_MessageBoxData message_box_data{};
|
||||
message_box_data.window = _window;
|
||||
message_box_data.title = title.c_str();
|
||||
message_box_data.message = message.c_str();
|
||||
message_box_data.numbuttons = static_cast<int>(options.size());
|
||||
message_box_data.buttons = message_box_button_data.get();
|
||||
|
||||
int buttonid{};
|
||||
|
||||
SDL_ShowMessageBox(&message_box_data, &buttonid);
|
||||
|
||||
return buttonid;
|
||||
}
|
||||
|
||||
bool HasMenuSupport() override
|
||||
{
|
||||
return _platformUiContext->HasMenuSupport();
|
||||
|
||||
@@ -541,6 +541,18 @@ namespace OpenRCT2
|
||||
const std::string& path, bool loadTitleScreenOnFail = false, bool asScenario = false) final override
|
||||
{
|
||||
log_verbose("Context::LoadParkFromFile(%s)", path.c_str());
|
||||
|
||||
// Register the file for crash upload if it asserts while loading.
|
||||
crash_register_additional_file("load_park", path);
|
||||
// Deregister park file in case it was processed without hitting an assert.
|
||||
struct foo
|
||||
{
|
||||
~foo()
|
||||
{
|
||||
crash_unregister_additional_file("load_park");
|
||||
}
|
||||
} f;
|
||||
|
||||
try
|
||||
{
|
||||
if (String::Equals(Path::GetExtension(path), ".sea", true))
|
||||
|
||||
@@ -184,9 +184,11 @@ namespace OpenRCT2
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (fwrite(buffer, static_cast<size_t>(length), 1, _file) != 1)
|
||||
if (auto count = fwrite(buffer, static_cast<size_t>(length), 1, _file); count != 1)
|
||||
{
|
||||
throw IOException("Unable to write to file.");
|
||||
std::string error = "Unable to write " + std::to_string(length) + " bytes to file. Count = " + std::to_string(count)
|
||||
+ ", errno = " + std::to_string(errno);
|
||||
throw IOException(error);
|
||||
}
|
||||
|
||||
uint64_t position = GetPosition();
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "../scenario/Scenario.h"
|
||||
#include "../scenario/ScenarioRepository.h"
|
||||
#include "../scripting/ScriptEngine.h"
|
||||
#include "../ui/UiContext.h"
|
||||
#include "../world/Climate.h"
|
||||
#include "../world/Entrance.h"
|
||||
#include "../world/Map.h"
|
||||
@@ -2312,6 +2313,31 @@ int32_t scenario_save(u8string_view path, int32_t flags)
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log_error(e.what());
|
||||
|
||||
Formatter ft;
|
||||
ft.Add<const char*>(e.what());
|
||||
context_show_error(STR_FILE_DIALOG_TITLE_SAVE_SCENARIO, STR_STRING, ft);
|
||||
gfx_invalidate_screen();
|
||||
|
||||
auto ctx = OpenRCT2::GetContext();
|
||||
auto uictx = ctx->GetUiContext();
|
||||
|
||||
std::string title = "Error while saving";
|
||||
std::string message
|
||||
= "There was an error while saving scenario.\nhttps://github.com/OpenRCT2/OpenRCT2/issues/17664\nWe would like to "
|
||||
"collect more information about this issue, if this did not happen due to missing permissions, lack of space, "
|
||||
"etc. please consider submitting a bug report. To collect information we would like to trigger an assert.";
|
||||
|
||||
std::string report_bug_button = "Report bug, trigger an assert, potentially terminating the game";
|
||||
std::string skip_button = "Skip reporting, let me continue";
|
||||
|
||||
std::vector<std::string> buttons{ std::move(report_bug_button), std::move(skip_button) };
|
||||
int choice = uictx->ShowMessageBox(title, message, buttons);
|
||||
|
||||
if (choice == 0)
|
||||
{
|
||||
Guard::Assert(false, "Error while saving: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
gfx_invalidate_screen();
|
||||
|
||||
@@ -47,13 +47,14 @@
|
||||
# define WSZ(x) L"" x
|
||||
|
||||
# ifdef OPENRCT2_COMMIT_SHA1_SHORT
|
||||
const wchar_t* _wszCommitSha1Short = WSZ(OPENRCT2_COMMIT_SHA1_SHORT);
|
||||
static const wchar_t* _wszCommitSha1Short = WSZ(OPENRCT2_COMMIT_SHA1_SHORT);
|
||||
# else
|
||||
const wchar_t* _wszCommitSha1Short = WSZ("");
|
||||
static const wchar_t* _wszCommitSha1Short = WSZ("");
|
||||
# endif
|
||||
|
||||
// OPENRCT2_ARCHITECTURE is required to be defined in version.h
|
||||
const wchar_t* _wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE);
|
||||
static const wchar_t* _wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE);
|
||||
static std::map<std::wstring, std::wstring> _uploadFiles;
|
||||
|
||||
# define BACKTRACE_TOKEN L"0ca992e20aca116b5e090fd2eaff6e7b5c8225f778fd8f4e77cb077d70329324"
|
||||
|
||||
@@ -114,8 +115,6 @@ static bool OnCrash(
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
std::map<std::wstring, std::wstring> uploadFiles;
|
||||
|
||||
// Get filenames
|
||||
wchar_t dumpFilePath[MAX_PATH];
|
||||
wchar_t saveFilePath[MAX_PATH];
|
||||
@@ -147,7 +146,7 @@ static bool OnCrash(
|
||||
// advertise it officially.
|
||||
|
||||
/*
|
||||
uploadFiles[L"upload_file_minidump"] = dumpFilePathGZIP;
|
||||
_uploadFiles[L"upload_file_minidump"] = dumpFilePathGZIP;
|
||||
*/
|
||||
}
|
||||
fclose(input);
|
||||
@@ -161,7 +160,7 @@ static bool OnCrash(
|
||||
{
|
||||
std::wcscpy(dumpFilePath, dumpFilePathNew);
|
||||
}
|
||||
uploadFiles[L"upload_file_minidump"] = dumpFilePath;
|
||||
_uploadFiles[L"upload_file_minidump"] = dumpFilePath;
|
||||
|
||||
// Compress to gzip-compatible stream
|
||||
|
||||
@@ -195,13 +194,13 @@ static bool OnCrash(
|
||||
// Compress the save
|
||||
if (savedGameDumped)
|
||||
{
|
||||
uploadFiles[L"attachment_park.park"] = saveFilePath;
|
||||
_uploadFiles[L"attachment_park.park"] = saveFilePath;
|
||||
}
|
||||
|
||||
auto configFilePathUTF8 = String::ToUtf8(configFilePath);
|
||||
if (config_save(configFilePathUTF8))
|
||||
{
|
||||
uploadFiles[L"attachment_config.ini"] = configFilePath;
|
||||
_uploadFiles[L"attachment_config.ini"] = configFilePath;
|
||||
}
|
||||
|
||||
// janisozaur: https://github.com/OpenRCT2/OpenRCT2/pull/17634
|
||||
@@ -219,7 +218,7 @@ static bool OnCrash(
|
||||
if (!screenshotPath.empty())
|
||||
{
|
||||
auto screenshotPathW = String::ToWideChar(screenshotPath.c_str());
|
||||
uploadFiles[L"attachment_screenshot.png"] = screenshotPathW;
|
||||
_uploadFiles[L"attachment_screenshot.png"] = screenshotPathW;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +228,7 @@ static bool OnCrash(
|
||||
bool record_copied = CopyFileW(parkReplayPathW.c_str(), recordFilePathNew, true);
|
||||
if (record_copied)
|
||||
{
|
||||
uploadFiles[L"attachment_replay.parkrep"] = recordFilePathNew;
|
||||
_uploadFiles[L"attachment_replay.parkrep"] = recordFilePathNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -242,7 +241,7 @@ static bool OnCrash(
|
||||
printf("Uploading minidump in silent mode...\n");
|
||||
int error;
|
||||
std::wstring response;
|
||||
UploadMinidump(uploadFiles, error, response);
|
||||
UploadMinidump(_uploadFiles, error, response);
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
@@ -260,7 +259,7 @@ static bool OnCrash(
|
||||
{
|
||||
int error;
|
||||
std::wstring response;
|
||||
bool ok = UploadMinidump(uploadFiles, error, response);
|
||||
bool ok = UploadMinidump(_uploadFiles, error, response);
|
||||
if (!ok)
|
||||
{
|
||||
const wchar_t* MessageFormat2 = L"There was a problem while uploading the dump. Please upload it manually to "
|
||||
@@ -340,3 +339,21 @@ CExceptionHandler crash_init()
|
||||
return nullptr;
|
||||
#endif // USE_BREAKPAD
|
||||
}
|
||||
|
||||
void crash_register_additional_file(const std::string& key, const std::string& path)
|
||||
{
|
||||
#ifdef USE_BREAKPAD
|
||||
_uploadFiles[String::ToWideChar(key.c_str())] = String::ToWideChar(path.c_str());
|
||||
#endif // USE_BREAKPAD
|
||||
}
|
||||
|
||||
void crash_unregister_additional_file(const std::string& key)
|
||||
{
|
||||
#ifdef USE_BREAKPAD
|
||||
auto it = _uploadFiles.find(String::ToWideChar(key.c_str()));
|
||||
if (it != _uploadFiles.end())
|
||||
{
|
||||
_uploadFiles.erase(it);
|
||||
}
|
||||
#endif // USE_BREAKPAD
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
using CExceptionHandler = void*;
|
||||
|
||||
extern bool gOpenRCT2SilentBreakpad;
|
||||
CExceptionHandler crash_init();
|
||||
void crash_register_additional_file(const std::string& key, const std::string& path);
|
||||
void crash_unregister_additional_file(const std::string& key);
|
||||
|
||||
@@ -90,6 +90,10 @@ namespace OpenRCT2::Ui
|
||||
void ShowMessageBox(const std::string& /*message*/) override
|
||||
{
|
||||
}
|
||||
int32_t ShowMessageBox(const std::string&, const std::string&, const std::vector<std::string>&) override
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
bool HasMenuSupport() override
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -120,6 +120,8 @@ namespace OpenRCT2
|
||||
virtual void TriggerResize() abstract;
|
||||
|
||||
virtual void ShowMessageBox(const std::string& message) abstract;
|
||||
virtual int32_t ShowMessageBox(
|
||||
const std::string& title, const std::string& message, const std::vector<std::string>& options) abstract;
|
||||
|
||||
virtual bool HasMenuSupport() abstract;
|
||||
// Creates a menu with a series of options, returns the index of the selected option
|
||||
|
||||
Reference in New Issue
Block a user