added ShutdownException and registry queries

This commit is contained in:
Anonymous275
2022-01-18 21:44:20 +02:00
parent e8d25beac0
commit 2e4db92640
6 changed files with 114 additions and 52 deletions
+17 -1
View File
@@ -10,14 +10,21 @@
namespace fs = std::filesystem; 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<size_t> data;
};
class Launcher { class Launcher {
public: //constructors public: //constructors
Launcher(int argc, char* argv[]); Launcher(int argc, char* argv[]);
~Launcher(); ~Launcher();
public: //available functions public: //available functions
std::string Login(const std::string& fields); std::string Login(const std::string& fields);
bool Terminate() const;
void RunDiscordRPC(); void RunDiscordRPC();
void QueryRegistry();
void LoadConfig(); void LoadConfig();
void LaunchGame(); void LaunchGame();
void CheckKey(); void CheckKey();
@@ -36,11 +43,20 @@ private: //variables
bool Shutdown = false; bool Shutdown = false;
bool LoginAuth = false; bool LoginAuth = false;
fs::path CurrentPath{}; fs::path CurrentPath{};
std::string BeamRoot{};
std::string UserRole{}; std::string UserRole{};
std::string PublicKey{}; std::string PublicKey{};
std::thread DiscordRPC{}; std::thread DiscordRPC{};
std::string BeamVersion{};
std::string BeamUserPath{};
std::string DiscordMessage{}; std::string DiscordMessage{};
std::string Version{"3.0"}; std::string Version{"3.0"};
std::string TargetBuild{"default"}; std::string TargetBuild{"default"};
std::string FullVersion{Version + ".0"}; 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){};
}; };
+2 -1
View File
@@ -33,6 +33,7 @@ Build = "Default"
cfg.close(); cfg.close();
}else{ }else{
LOG(FATAL) << "Failed to write config on disk!"; LOG(FATAL) << "Failed to write config on disk!";
throw ShutdownException("Fatal Error");
} }
} }
} }
+52 -20
View File
@@ -9,7 +9,6 @@
#include <windows.h> #include <windows.h>
#include <shellapi.h> #include <shellapi.h>
Launcher::Launcher(int argc, char* argv[]) : CurrentPath(std::filesystem::path(argv[0])), DiscordMessage("Just launched") { Launcher::Launcher(int argc, char* argv[]) : CurrentPath(std::filesystem::path(argv[0])), DiscordMessage("Just launched") {
Log::Init(); Log::Init();
WindowsInit(); WindowsInit();
@@ -19,17 +18,25 @@ Launcher::Launcher(int argc, char* argv[]) : CurrentPath(std::filesystem::path(a
Launcher::~Launcher() { Launcher::~Launcher() {
Shutdown = true; Shutdown = true;
LOG(INFO) << "Shutting down";
if(DiscordRPC.joinable()) { if(DiscordRPC.joinable()) {
DiscordRPC.join(); DiscordRPC.join();
} }
} }
bool Launcher::Terminate() const {
return Shutdown;
}
void Launcher::LaunchGame() { 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); ShellExecuteA(nullptr, nullptr, "steam://rungameid/284160", nullptr, nullptr, SW_SHOWNORMAL);
//ShowWindow(GetConsoleWindow(), HIDE_WINDOW); //ShowWindow(GetConsoleWindow(), HIDE_WINDOW);
} }
@@ -39,6 +46,45 @@ void Launcher::WindowsInit() {
SetConsoleTitleA(("BeamMP Launcher v" + FullVersion).c_str()); 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() { const std::string& Launcher::getFullVersion() {
return FullVersion; return FullVersion;
} }
@@ -51,17 +97,3 @@ const std::string& Launcher::getUserRole() {
return UserRole; 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;
}
+6 -2
View File
@@ -15,7 +15,10 @@ void UpdateKey(const char* newKey){
if(Key.is_open()){ if(Key.is_open()){
Key << newKey; Key << newKey;
Key.close(); 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")){ }else if(fs::exists("key")){
remove("key"); remove("key");
} }
@@ -88,8 +91,9 @@ void Launcher::CheckKey() {
Json::Document d; Json::Document d;
d.Parse(Buffer.c_str()); d.Parse(Buffer.c_str());
if (Buffer == "-1" || Buffer.at(0) != '{' || d.HasParseError()) { 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!"; LOG(FATAL) << "Invalid answer from authentication servers, please try again later!";
throw ShutdownException("Fatal Error");
} }
if(d["success"].GetBool()){ if(d["success"].GetBool()){
LoginAuth = true; LoginAuth = true;
+25 -26
View File
@@ -6,32 +6,30 @@
#include "Launcher.h" #include "Launcher.h"
#include "Logger.h" #include "Logger.h"
#include "Http.h" #include "Http.h"
#include <sstream>
struct Ver {
std::vector<size_t> 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() { void Launcher::UpdateCheck() {
std::string link; std::string link;
@@ -42,6 +40,7 @@ void Launcher::UpdateCheck() {
fallback = true; fallback = true;
if(HTTP.find_first_of("0123456789") == std::string::npos) { if(HTTP.find_first_of("0123456789") == std::string::npos) {
LOG(FATAL) << "Primary Servers Offline! sorry for the inconvenience!"; LOG(FATAL) << "Primary Servers Offline! sorry for the inconvenience!";
throw ShutdownException("Fatal Error");
} }
} }
if(fallback){ if(fallback){
@@ -58,7 +57,7 @@ void Launcher::UpdateCheck() {
} }
} }
if(Ver(RemoteVer) > Ver(FullVersion)){ if(VersionParser(RemoteVer) > VersionParser(FullVersion)){
system("cls"); system("cls");
LOG(INFO) << "Update found! Downloading..."; LOG(INFO) << "Update found! Downloading...";
if(std::rename(EP.c_str(), Back.c_str())){ if(std::rename(EP.c_str(), Back.c_str())){
+12 -2
View File
@@ -4,14 +4,24 @@
/// ///
#include "Launcher.h" #include "Launcher.h"
#include "Logger.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
Launcher launcher(argc, argv); try {
if(!launcher.Terminate()) { Launcher launcher(argc, argv);
launcher.RunDiscordRPC(); launcher.RunDiscordRPC();
launcher.LoadConfig(); launcher.LoadConfig();
launcher.CheckKey(); launcher.CheckKey();
launcher.LaunchGame();
//launcher.WaitForGame();
launcher.QueryRegistry();
//UI call //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; return 0;
} }