diff --git a/application/scenarioloadermode.cpp b/application/scenarioloadermode.cpp index dbdce606..7afe0a44 100644 --- a/application/scenarioloadermode.cpp +++ b/application/scenarioloadermode.cpp @@ -41,11 +41,25 @@ bool scenarioloader_mode::update() { WriteLog("using simulation seed: " + std::to_string(Global.random_seed), logtype::generic); WriteLog("using simulation starting timestamp: " + std::to_string(Global.starting_timestamp), logtype::generic); + // the command line gives the name lowercased, the file may be named in another case, as a scenery made on Windows; + // the scenery is saved back to its own file then + if (auto const cased{FileCased(Global.asCurrentSceneryPath + Global.SceneryFile)}; cased.size() > Global.asCurrentSceneryPath.size()) + Global.SceneryFile = cased.substr(Global.asCurrentSceneryPath.size()); Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" ); WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." ); timestart = std::chrono::system_clock::now(); - state = simulation::State.deserialize_begin(Global.SceneryFile); + try { + state = simulation::State.deserialize_begin(Global.SceneryFile); + } + catch (std::exception const &e) { + ErrorLog("Bad init: scenario \"" + Global.SceneryFile + "\" couldn't be opened (" + e.what() + ")"); + state.reset(); + Global.SceneryFile.clear(); + Application.pop_mode(); + Application.push_mode(eu07_application::mode::launcher); + return true; + } } try { diff --git a/utilities/parser.cpp b/utilities/parser.cpp index b64aee39..ee5a9ce5 100644 --- a/utilities/parser.cpp +++ b/utilities/parser.cpp @@ -63,6 +63,15 @@ cParser::cParser(std::string const &Stream, buffertype const Type, std::string P // the file is read in one go, tokens are then extracted straight from the memory std::ifstream file(Path, std::ios_base::binary); if (file.fail()) + { + // named in another case than it's on the disk + if (auto const cased{FileCased(Path)}; false == cased.empty()) + { + file.clear(); + file.open(cased, std::ios_base::binary); + } + } + if (file.fail()) { mFailBit = true; } diff --git a/utilities/utilities.cpp b/utilities/utilities.cpp index 02608262..0c18e002 100644 --- a/utilities/utilities.cpp +++ b/utilities/utilities.cpp @@ -471,6 +471,20 @@ bool FileExists(std::string const &Filename) return std::filesystem::exists(Filename); } +std::string FileCased(std::string const &Filename) +{ + std::error_code error; + if (std::filesystem::exists(Filename, error)) + return Filename; + std::filesystem::path const path{Filename}; + auto const directory{path.has_parent_path() ? path.parent_path() : std::filesystem::path{"."}}; + auto const wanted{ToLower(path.filename().string())}; + for (std::filesystem::directory_iterator entry{directory, error}, end; entry != end; entry.increment(error)) + if (ToLower(entry->path().filename().string()) == wanted) + return path.has_parent_path() ? (directory / entry->path().filename()).string() : entry->path().filename().string(); + return {}; +} + std::pair FileExists(std::vector const &Names, std::vector const &Extensions) { diff --git a/utilities/utilities.h b/utilities/utilities.h index 5392ba6c..d98b7bc9 100644 --- a/utilities/utilities.h +++ b/utilities/utilities.h @@ -217,6 +217,9 @@ template bool extract_value(Type_ &Variable, std::string const template <> bool extract_value(bool &Variable, std::string const &Key, std::string const &Input, std::string const &Default); bool FileExists(std::string const &Filename); +// the file as it's named on the disk when only the case of its name differs, as in the sceneries made on Windows; empty when +// there's none +std::string FileCased(std::string const &Filename); std::pair FileExists(std::vector const &Names, std::vector const &Extensions);