mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-04-03 22:36:14 +00:00
- reduce the amount of data required from the registry
- remove wxWidgets - general cleanup
This commit is contained in:
137
src/Config.cpp
137
src/Config.cpp
@@ -3,46 +3,39 @@
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
|
||||
#include <tomlplusplus/toml.hpp>
|
||||
#include "Launcher.h"
|
||||
#include "Logger.h"
|
||||
#include <shlguid.h>
|
||||
#include <shlobj_core.h>
|
||||
#include <shobjidl.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
void Launcher::LoadConfig() {
|
||||
if (fs::exists(UIData::ConfigPath)) {
|
||||
toml::parse_result config = toml::parse_file(UIData::ConfigPath);
|
||||
auto ui = config["UI"];
|
||||
void Launcher::LoadConfig(const fs::path& conf) { // check if json (issue)
|
||||
if (fs::is_regular_file(conf)) {
|
||||
if(fs::is_empty(conf)) {
|
||||
fs::remove(conf);
|
||||
LoadConfig(conf);
|
||||
}
|
||||
toml::parse_result config = toml::parse_file(conf.string());
|
||||
auto build = config["Build"];
|
||||
auto GamePath = config["GamePath"];
|
||||
auto ProfilePath = config["ProfilePath"];
|
||||
auto CachePath = config["CachePath"];
|
||||
|
||||
EnableUI = false;
|
||||
/*if (ui.is_boolean()) {
|
||||
EnableUI = ui.as_boolean()->get();
|
||||
} else LOG(ERROR) << "Failed to get 'UI' boolean from config";*/
|
||||
|
||||
// Default -1 / Release 1 / EA 2 / Dev 3 / Custom 3
|
||||
if (build.is_string()) {
|
||||
TargetBuild = build.as_string()->get();
|
||||
for (char& c : TargetBuild) c = char(tolower(c));
|
||||
} else LOG(ERROR) << "Failed to get 'Build' string from config";
|
||||
|
||||
if (GamePath.is_string()) {
|
||||
if (!GamePath.as_string()->get().empty()) {
|
||||
BeamRoot = GamePath.as_string()->get();
|
||||
} else throw ShutdownException("GamePath cannot be empty");
|
||||
} else LOG(ERROR) << "Failed to get 'GamePath' string from config";
|
||||
|
||||
if (ProfilePath.is_string()) {
|
||||
if (!UIData::GameVer.empty()) {
|
||||
auto GameVer = VersionParser(UIData::GameVer).split;
|
||||
|
||||
if (!ProfilePath.as_string()->get().empty()) {
|
||||
BeamUserPath = fs::path(ProfilePath.as_string()->get()) / (GameVer[0] + '.' + GameVer[1]);
|
||||
MPUserPath = BeamUserPath / "mods" / "multiplayer";
|
||||
} else throw ShutdownException("ProfilePath cannot be empty");
|
||||
} else throw ShutdownException ("Check game path in config");
|
||||
} else LOG(ERROR) << "Failed to get 'ProfilePath' string from config";
|
||||
if (ProfilePath.is_string() && !ProfilePath.as_string()->get().empty()) {
|
||||
BeamUserPath = fs::path(ProfilePath.as_string()->get());
|
||||
} else {
|
||||
LOG(ERROR) << "'ProfilePath' string from config is empty defaulting";
|
||||
BeamUserPath = GetBeamNGProfile();
|
||||
}
|
||||
MPUserPath = BeamUserPath / "mods" / "multiplayer";
|
||||
|
||||
if (CachePath.is_string()) {
|
||||
if (!CachePath.as_string()->get().empty()) {
|
||||
@@ -50,9 +43,95 @@ void Launcher::LoadConfig() {
|
||||
} else throw ShutdownException("CachePath cannot be empty");
|
||||
} else LOG(ERROR) << "Failed to get 'CachePath' string from config";
|
||||
|
||||
BeamVersion = UIData::GameVer;
|
||||
} else {
|
||||
LOG(FATAL) << "Failed to find config on disk!";
|
||||
throw ShutdownException("Fatal Error");
|
||||
auto GameProfile = GetBeamNGProfile();
|
||||
std::ofstream tml(conf);
|
||||
if (tml.is_open()) {
|
||||
tml << "Build = 'Default'\n"
|
||||
"CachePath = 'Resources'\n"
|
||||
"ProfilePath = '"
|
||||
<< GameProfile.string() << "'";
|
||||
|
||||
tml.close();
|
||||
LoadConfig(conf);
|
||||
} else LOG(ERROR) << "Failed to create config file";
|
||||
}
|
||||
}
|
||||
|
||||
fs::path Launcher::GetBeamNGProfile() {
|
||||
|
||||
HKEY BeamNG;
|
||||
fs::path ProfilePath;
|
||||
LONG RegRes =
|
||||
RegOpenKeyExA(HKEY_CURRENT_USER, R"(Software\BeamNG\BeamNG.drive)", 0,
|
||||
KEY_READ, &BeamNG);
|
||||
if (RegRes == ERROR_SUCCESS) {
|
||||
ProfilePath = QueryValue(BeamNG, "userpath_override");
|
||||
RegCloseKey(BeamNG);
|
||||
}
|
||||
|
||||
if (ProfilePath.empty()) {
|
||||
PWSTR folderPath = nullptr;
|
||||
HRESULT hr =
|
||||
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &folderPath);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
throw ShutdownException("Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive");
|
||||
} else {
|
||||
ProfilePath = fs::path(folderPath)/"BeamNG.drive";
|
||||
CoTaskMemFree(folderPath);
|
||||
}
|
||||
}
|
||||
|
||||
/////Load latest link
|
||||
|
||||
if (CoInitializeEx(nullptr, COINIT_MULTITHREADED) != S_OK) {
|
||||
throw ShutdownException("Failed to read link: CoInitializeEx");
|
||||
}
|
||||
|
||||
HRESULT rc;
|
||||
|
||||
IShellLink* iShellLink;
|
||||
rc = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_IShellLink, (LPVOID*)&iShellLink);
|
||||
|
||||
if (FAILED(rc)) {
|
||||
throw ShutdownException("Failed to read link: CoCreateInstance");
|
||||
}
|
||||
|
||||
IPersistFile* iPersistFile;
|
||||
|
||||
rc = iShellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&iPersistFile);
|
||||
|
||||
if (FAILED(rc)) {
|
||||
throw ShutdownException("Failed to read link: QueryInterface(IID_IPersistFile)");
|
||||
}
|
||||
|
||||
rc = iPersistFile->Load((ProfilePath/"latest.lnk").wstring().c_str(), STGM_READ);
|
||||
|
||||
if (FAILED(rc)) {
|
||||
throw ShutdownException("Failed to read link: iPersistFile->Load()");
|
||||
}
|
||||
|
||||
rc = iShellLink->Resolve(nullptr, 0);
|
||||
|
||||
if (FAILED(rc)) {
|
||||
throw ShutdownException("Failed to read link: IShellLink failed to resolve");
|
||||
}
|
||||
|
||||
std::wstring linkTarget(MAX_PATH, '\x00');
|
||||
rc = iShellLink->GetPath(&linkTarget[0], MAX_PATH, nullptr, SLGP_SHORTPATH);
|
||||
|
||||
if (FAILED(rc)) {
|
||||
throw ShutdownException("Failed to read link: IShellLink failed to get path");
|
||||
}
|
||||
|
||||
linkTarget.resize(linkTarget.find(L'\000'));
|
||||
|
||||
iPersistFile->Release();
|
||||
iShellLink->Release();
|
||||
|
||||
BeamVersion = std::filesystem::path(linkTarget).filename().string();
|
||||
LOG(INFO) << "Found BeamNG profile " << BeamVersion;
|
||||
return ProfilePath/BeamVersion;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user