From 2e4db92640714ffbebd5934eb886d22c3dc68ad7 Mon Sep 17 00:00:00 2001 From: Anonymous275 <36374260+Anonymous-275@users.noreply.github.com> Date: Tue, 18 Jan 2022 21:44:20 +0200 Subject: [PATCH] added ShutdownException and registry queries --- include/Launcher.h | 18 ++++++++++- src/Config.cpp | 3 +- src/Launcher.cpp | 72 ++++++++++++++++++++++++++++++------------ src/Network/Login.cpp | 8 +++-- src/Network/Update.cpp | 51 +++++++++++++++--------------- src/main.cpp | 14 ++++++-- 6 files changed, 114 insertions(+), 52 deletions(-) diff --git a/include/Launcher.h b/include/Launcher.h index 18c419c..cdf4329 100644 --- a/include/Launcher.h +++ b/include/Launcher.h @@ -10,14 +10,21 @@ namespace fs = std::filesystem; +struct VersionParser { + explicit VersionParser(const std::string& from_string); + std::strong_ordering operator<=>(VersionParser const& rhs) const noexcept; + bool operator==(VersionParser const& rhs) const noexcept; + std::vector data; +}; + class Launcher { public: //constructors Launcher(int argc, char* argv[]); ~Launcher(); public: //available functions std::string Login(const std::string& fields); - bool Terminate() const; void RunDiscordRPC(); + void QueryRegistry(); void LoadConfig(); void LaunchGame(); void CheckKey(); @@ -36,11 +43,20 @@ private: //variables bool Shutdown = false; bool LoginAuth = false; fs::path CurrentPath{}; + std::string BeamRoot{}; std::string UserRole{}; std::string PublicKey{}; std::thread DiscordRPC{}; + std::string BeamVersion{}; + std::string BeamUserPath{}; std::string DiscordMessage{}; std::string Version{"3.0"}; std::string TargetBuild{"default"}; std::string FullVersion{Version + ".0"}; + VersionParser SupportedVersion{"0.24.1.1"}; +}; + +class ShutdownException : public std::runtime_error { +public: + explicit ShutdownException(const std::string& message): runtime_error(message){}; }; diff --git a/src/Config.cpp b/src/Config.cpp index 732d57d..c596515 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -33,6 +33,7 @@ Build = "Default" cfg.close(); }else{ LOG(FATAL) << "Failed to write config on disk!"; + throw ShutdownException("Fatal Error"); } } -} \ No newline at end of file +} diff --git a/src/Launcher.cpp b/src/Launcher.cpp index 7d93917..e246812 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -9,7 +9,6 @@ #include #include - Launcher::Launcher(int argc, char* argv[]) : CurrentPath(std::filesystem::path(argv[0])), DiscordMessage("Just launched") { Log::Init(); WindowsInit(); @@ -19,17 +18,25 @@ Launcher::Launcher(int argc, char* argv[]) : CurrentPath(std::filesystem::path(a Launcher::~Launcher() { Shutdown = true; - LOG(INFO) << "Shutting down"; if(DiscordRPC.joinable()) { DiscordRPC.join(); } } -bool Launcher::Terminate() const { - return Shutdown; -} - void Launcher::LaunchGame() { + VersionParser GameVersion(BeamVersion); + if(GameVersion.data[0] > SupportedVersion.data[0]) { + LOG(FATAL) << "BeamNG V" << BeamVersion << " not yet supported, please wait until we update BeamMP!"; + throw ShutdownException("Fatal Error"); + } else if(GameVersion.data[0] < SupportedVersion.data[0]) { + LOG(FATAL) << "BeamNG V" << BeamVersion << " not supported, please update and launch the new update!"; + throw ShutdownException("Fatal Error"); + } else if(GameVersion > SupportedVersion) { + LOG(WARNING) << "BeamNG V" << BeamVersion << " is slightly newer than recommended, this might cause issues!"; + } else if(GameVersion < SupportedVersion) { + LOG(WARNING) << "BeamNG V" << BeamVersion << " is slightly older than recommended, this might cause issues!"; + } + ShellExecuteA(nullptr, nullptr, "steam://rungameid/284160", nullptr, nullptr, SW_SHOWNORMAL); //ShowWindow(GetConsoleWindow(), HIDE_WINDOW); } @@ -39,6 +46,45 @@ void Launcher::WindowsInit() { SetConsoleTitleA(("BeamMP Launcher v" + FullVersion).c_str()); } +std::string QueryValue(HKEY& BeamNG, const char* Name) { + DWORD keySize; + BYTE buffer[1024]; + ZeroMemory(buffer, 1024); + if(RegQueryValueExA(BeamNG, Name, nullptr, nullptr, buffer, &keySize) == ERROR_SUCCESS) { + return {(char*)buffer, keySize}; + } + return {}; +} + +void Launcher::QueryRegistry() { + HKEY BeamNG; + LONG RegRes = RegOpenKeyExA(HKEY_CURRENT_USER, R"(Software\BeamNG\BeamNG.drive)", 0, KEY_READ, &BeamNG); + if(RegRes == ERROR_SUCCESS) { + BeamRoot = QueryValue(BeamNG, "rootpath"); + BeamVersion = QueryValue(BeamNG, "version"); + BeamUserPath = QueryValue(BeamNG, "userpath_override"); + //get shell folders for appdata dir + RegCloseKey(BeamNG); + if(!BeamRoot.empty() && !BeamVersion.empty())return; + } + LOG(FATAL) << "Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive"; + throw ShutdownException("Fatal Error"); +} + +void Launcher::AdminRelaunch() { + system("cls"); + ShellExecuteA(nullptr, "runas", CurrentPath.string().c_str(), nullptr, nullptr, SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(),0); + throw ShutdownException("Relaunching"); +} + +void Launcher::Relaunch() { + ShellExecuteA(nullptr, "open", CurrentPath.string().c_str(), nullptr, nullptr, SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(),0); + std::this_thread::sleep_for(std::chrono::seconds(1)); + throw ShutdownException("Relaunching"); +} + const std::string& Launcher::getFullVersion() { return FullVersion; } @@ -51,17 +97,3 @@ const std::string& Launcher::getUserRole() { return UserRole; } -void Launcher::AdminRelaunch() { - system("cls"); - ShellExecuteA(nullptr, "runas", CurrentPath.string().c_str(), nullptr, nullptr, SW_SHOWNORMAL); - ShowWindow(GetConsoleWindow(),0); - Shutdown = true; -} - -void Launcher::Relaunch() { - ShellExecuteA(nullptr, "open", CurrentPath.string().c_str(), nullptr, nullptr, SW_SHOWNORMAL); - ShowWindow(GetConsoleWindow(),0); - std::this_thread::sleep_for(std::chrono::seconds(1)); - Shutdown = true; -} - diff --git a/src/Network/Login.cpp b/src/Network/Login.cpp index 98f78c8..964d1c9 100644 --- a/src/Network/Login.cpp +++ b/src/Network/Login.cpp @@ -15,7 +15,10 @@ void UpdateKey(const char* newKey){ if(Key.is_open()){ Key << newKey; Key.close(); - }else LOG(FATAL) << "Cannot write to disk!"; + } else { + LOG(FATAL) << "Cannot write to disk!"; + throw ShutdownException("Fatal Error"); + } }else if(fs::exists("key")){ remove("key"); } @@ -88,8 +91,9 @@ void Launcher::CheckKey() { Json::Document d; d.Parse(Buffer.c_str()); if (Buffer == "-1" || Buffer.at(0) != '{' || d.HasParseError()) { - LOG(ERROR) << Buffer; + LOG(DEBUG) << Buffer; LOG(FATAL) << "Invalid answer from authentication servers, please try again later!"; + throw ShutdownException("Fatal Error"); } if(d["success"].GetBool()){ LoginAuth = true; diff --git a/src/Network/Update.cpp b/src/Network/Update.cpp index 14a9871..eaf2734 100644 --- a/src/Network/Update.cpp +++ b/src/Network/Update.cpp @@ -6,32 +6,30 @@ #include "Launcher.h" #include "Logger.h" #include "Http.h" -#include -struct Ver { - std::vector data; - explicit Ver(const std::string& from_string) { - std::string token; - std::istringstream tokenStream(from_string); - while (std::getline(tokenStream, token, '.')) { - data.emplace_back(std::stol(token)); - } - } - std::strong_ordering operator<=>(Ver const& rhs) const noexcept { - size_t const fields = std::min(data.size(), rhs.data.size()); - for(size_t i = 0; i != fields; ++i) { - if(data[i] == rhs.data[i]) continue; - else if(data[i] < rhs.data[i]) return std::strong_ordering::less; - else return std::strong_ordering::greater; - } - if(data.size() == rhs.data.size()) return std::strong_ordering::equal; - else if(data.size() > rhs.data.size()) return std::strong_ordering::greater; - else return std::strong_ordering::less; - } - bool operator==(Ver const& rhs) const noexcept { - return std::is_eq(*this <=> rhs); - } -}; +VersionParser::VersionParser(const std::string &from_string) { + std::string token; + std::istringstream tokenStream(from_string); + while (std::getline(tokenStream, token, '.')) { + data.emplace_back(std::stol(token)); + } +} + +std::strong_ordering VersionParser::operator<=>(const VersionParser &rhs) const noexcept { + size_t const fields = std::min(data.size(), rhs.data.size()); + for(size_t i = 0; i != fields; ++i) { + if(data[i] == rhs.data[i]) continue; + else if(data[i] < rhs.data[i]) return std::strong_ordering::less; + else return std::strong_ordering::greater; + } + if(data.size() == rhs.data.size()) return std::strong_ordering::equal; + else if(data.size() > rhs.data.size()) return std::strong_ordering::greater; + else return std::strong_ordering::less; +} + +bool VersionParser::operator==(const VersionParser &rhs) const noexcept { + return std::is_eq(*this <=> rhs); +} void Launcher::UpdateCheck() { std::string link; @@ -42,6 +40,7 @@ void Launcher::UpdateCheck() { fallback = true; if(HTTP.find_first_of("0123456789") == std::string::npos) { LOG(FATAL) << "Primary Servers Offline! sorry for the inconvenience!"; + throw ShutdownException("Fatal Error"); } } if(fallback){ @@ -58,7 +57,7 @@ void Launcher::UpdateCheck() { } } - if(Ver(RemoteVer) > Ver(FullVersion)){ + if(VersionParser(RemoteVer) > VersionParser(FullVersion)){ system("cls"); LOG(INFO) << "Update found! Downloading..."; if(std::rename(EP.c_str(), Back.c_str())){ diff --git a/src/main.cpp b/src/main.cpp index 1763a86..99ed201 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,14 +4,24 @@ /// #include "Launcher.h" +#include "Logger.h" int main(int argc, char* argv[]) { - Launcher launcher(argc, argv); - if(!launcher.Terminate()) { + try { + Launcher launcher(argc, argv); launcher.RunDiscordRPC(); launcher.LoadConfig(); launcher.CheckKey(); + launcher.LaunchGame(); + //launcher.WaitForGame(); + launcher.QueryRegistry(); //UI call + + + } catch (const ShutdownException& e) { + LOG(INFO) << "Launcher shutting down, reason: " << e.what(); + } catch (const std::exception& e) { + LOG(FATAL) << e.what(); } return 0; }