From af91b9f4b4c4aaf133e40548fd75c59e4c55e99a Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 3 Jun 2017 22:13:20 +0100 Subject: [PATCH] Fix #5521: Infinite loop on first run if neither Zenity nor kdialog are installed (#5526) --- src/openrct2-ui/UiContext.Linux.cpp | 10 ++++-- src/openrct2/Context.cpp | 49 ++++++++++++++++++++--------- src/openrct2/config/Config.cpp | 44 ++++++++++++++++---------- 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index 4a2ab96aa1..d9697749ea 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -160,7 +161,7 @@ namespace OpenRCT2 { namespace Ui break; } default: - log_error("KDialog or Zenity not installed."); + ThrowMissingDialogApp(); break; } @@ -211,7 +212,7 @@ namespace OpenRCT2 { namespace Ui break; } default: - log_error("KDialog or Zenity not installed."); + ThrowMissingDialogApp(); break; } return result; @@ -337,6 +338,11 @@ namespace OpenRCT2 { namespace Ui } return filtersb.str(); } + + static void ThrowMissingDialogApp() + { + throw std::runtime_error("KDialog or Zenity not installed."); + } }; IPlatformUiContext * CreatePlatformUiContext() diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 3e248768bf..11c92ccc74 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -124,8 +124,10 @@ namespace OpenRCT2 sint32 RunOpenRCT2(int argc, char * * argv) override { - Initialise(); - Launch(); + if (Initialise()) + { + Launch(); + } return gExitCode; } @@ -677,26 +679,43 @@ extern "C" bool platform_open_common_file_dialog(utf8 * outFilename, file_dialog_desc * desc, size_t outSize) { - FileDialogDesc desc2; - desc2.Type = (FILE_DIALOG_TYPE)desc->type; - desc2.Title = String::ToStd(desc->title); - desc2.InitialDirectory = String::ToStd(desc->initial_directory); - desc2.DefaultFilename = String::ToStd(desc->default_filename); - for (const auto &filter : desc->filters) + try { - if (filter.name != nullptr) + FileDialogDesc desc2; + desc2.Type = (FILE_DIALOG_TYPE)desc->type; + desc2.Title = String::ToStd(desc->title); + desc2.InitialDirectory = String::ToStd(desc->initial_directory); + desc2.DefaultFilename = String::ToStd(desc->default_filename); + for (const auto &filter : desc->filters) { - desc2.Filters.push_back({ String::ToStd(filter.name), String::ToStd(filter.pattern) }); + if (filter.name != nullptr) + { + desc2.Filters.push_back({ String::ToStd(filter.name), String::ToStd(filter.pattern) }); + } } + std::string result = GetContext()->GetUiContext()->ShowFileDialog(desc2); + String::Set(outFilename, outSize, result.c_str()); + return !result.empty(); + } + catch (const std::exception &ex) + { + log_error(ex.what()); + outFilename[0] = '\0'; + return false; } - std::string result = GetContext()->GetUiContext()->ShowFileDialog(desc2); - String::Set(outFilename, outSize, result.c_str()); - return !result.empty(); } utf8 * platform_open_directory_browser(const utf8 * title) { - std::string result = GetContext()->GetUiContext()->ShowDirectoryDialog(title); - return String::Duplicate(result.c_str()); + try + { + std::string result = GetContext()->GetUiContext()->ShowDirectoryDialog(title); + return String::Duplicate(result.c_str()); + } + catch (const std::exception &ex) + { + log_error(ex.what()); + return nullptr; + } } } diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index b846ebaa46..eaa2f540d6 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -693,26 +693,36 @@ extern "C" { return false; } - while (1) + + try { - IUiContext * uiContext = GetContext()->GetUiContext(); - uiContext->ShowMessageBox("OpenRCT2 needs files from the original RollerCoaster Tycoon 2 in order to work. Please select the directory where you installed RollerCoaster Tycoon 2."); - utf8 * installPath = platform_open_directory_browser("Please select your RCT2 directory"); - if (installPath == nullptr) + while (true) { - return false; + IUiContext * uiContext = GetContext()->GetUiContext(); + uiContext->ShowMessageBox("OpenRCT2 needs files from the original RollerCoaster Tycoon 2 in order to work. Please select the directory where you installed RollerCoaster Tycoon 2."); + + std::string installPath = uiContext->ShowDirectoryDialog("Please select your RCT2 directory"); + if (installPath.empty()) + { + return false; + } + + Memory::Free(gConfigGeneral.rct2_path); + gConfigGeneral.rct2_path = String::Duplicate(installPath.c_str()); + + if (platform_original_game_data_exists(installPath.c_str())) + { + return true; + } + + std::string message = String::StdFormat("Could not find %s" PATH_SEPARATOR "Data" PATH_SEPARATOR "g1.dat at this path", installPath.c_str()); + uiContext->ShowMessageBox(message); } - - Memory::Free(gConfigGeneral.rct2_path); - gConfigGeneral.rct2_path = installPath; - - if (platform_original_game_data_exists(installPath)) - { - return true; - } - - std::string message = String::StdFormat("Could not find %s" PATH_SEPARATOR "Data" PATH_SEPARATOR "g1.dat at this path", installPath); - uiContext->ShowMessageBox(message); + } + catch (const std::exception &ex) + { + Console::Error::WriteLine(ex.what()); + return false; } } return true;