mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-06-19 23:20:57 +00:00
add path detection
add game path auto detection add profile path auto detection add cache path reset
This commit is contained in:
+6
-3
@@ -18,6 +18,8 @@ struct VersionParser {
|
|||||||
std::vector<std::string> split;
|
std::vector<std::string> split;
|
||||||
std::vector<size_t> data;
|
std::vector<size_t> data;
|
||||||
};
|
};
|
||||||
|
struct HKEY__;
|
||||||
|
typedef HKEY__ *HKEY;
|
||||||
|
|
||||||
class Launcher {
|
class Launcher {
|
||||||
public: // constructors
|
public: // constructors
|
||||||
@@ -35,6 +37,7 @@ class Launcher {
|
|||||||
void LaunchGame();
|
void LaunchGame();
|
||||||
void CheckKey();
|
void CheckKey();
|
||||||
void SetupMOD();
|
void SetupMOD();
|
||||||
|
static std::string QueryValue(HKEY& hKey, const char* Name);
|
||||||
|
|
||||||
public: // Getters and Setters
|
public: // Getters and Setters
|
||||||
void setDiscordMessage(const std::string& message);
|
void setDiscordMessage(const std::string& message);
|
||||||
@@ -82,9 +85,9 @@ class Launcher {
|
|||||||
std::string Version{"2.0"};
|
std::string Version{"2.0"};
|
||||||
Server ServerHandler{this};
|
Server ServerHandler{this};
|
||||||
std::string TargetBuild{"default"};
|
std::string TargetBuild{"default"};
|
||||||
std::string GameConfigPath{""};
|
std::string GameConfigPath{};
|
||||||
std::string ProfileConfigPath{""};
|
std::string ProfileConfigPath{};
|
||||||
std::string CacheConfigPath{""};
|
std::string CacheConfigPath{};
|
||||||
static inline std::atomic<bool> Shutdown{false}, Exit{false};
|
static inline std::atomic<bool> Shutdown{false}, Exit{false};
|
||||||
std::string FullVersion{Version + ".99"};
|
std::string FullVersion{Version + ".99"};
|
||||||
VersionParser SupportedVersion{"0.25.4.0"};
|
VersionParser SupportedVersion{"0.25.4.0"};
|
||||||
|
|||||||
+1
-1
@@ -176,7 +176,7 @@ void Launcher::SendIPC(const std::string& Data, bool core) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string QueryValue(HKEY& hKey, const char* Name) {
|
std::string Launcher::QueryValue(HKEY& hKey, const char* Name) {
|
||||||
DWORD keySize;
|
DWORD keySize;
|
||||||
BYTE buffer[16384];
|
BYTE buffer[16384];
|
||||||
if (RegQueryValueExA(hKey, Name, nullptr, nullptr, buffer, &keySize) ==
|
if (RegQueryValueExA(hKey, Name, nullptr, nullptr, buffer, &keySize) ==
|
||||||
|
|||||||
+87
-38
@@ -15,6 +15,8 @@
|
|||||||
#include <wx/wxhtml.h.>
|
#include <wx/wxhtml.h.>
|
||||||
#include <wx/filepicker.h>
|
#include <wx/filepicker.h>
|
||||||
#include <tomlplusplus/toml.hpp>
|
#include <tomlplusplus/toml.hpp>
|
||||||
|
#include <comutil.h>
|
||||||
|
#include <ShlObj.h>
|
||||||
#include "Launcher.h"
|
#include "Launcher.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -72,6 +74,9 @@ class MySettingsFrame : public wxFrame {
|
|||||||
void OnClickConsole(wxCommandEvent& event);
|
void OnClickConsole(wxCommandEvent& event);
|
||||||
void OnChangedGameDir (wxFileDirPickerEvent& event);
|
void OnChangedGameDir (wxFileDirPickerEvent& event);
|
||||||
void OnChangedBuild (wxCommandEvent& event);
|
void OnChangedBuild (wxCommandEvent& event);
|
||||||
|
void OnAutoDetectGame(wxCommandEvent& event);
|
||||||
|
void OnAutoDetectProfile(wxCommandEvent& event);
|
||||||
|
void OnResetCache(wxCommandEvent& event);
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,6 +111,9 @@ wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame)
|
|||||||
EVT_CHECKBOX(45, MySettingsFrame::OnClickConsole)
|
EVT_CHECKBOX(45, MySettingsFrame::OnClickConsole)
|
||||||
EVT_DIRPICKER_CHANGED(46, MySettingsFrame::OnChangedGameDir)
|
EVT_DIRPICKER_CHANGED(46, MySettingsFrame::OnChangedGameDir)
|
||||||
EVT_CHOICE(47, MySettingsFrame::OnChangedBuild)
|
EVT_CHOICE(47, MySettingsFrame::OnChangedBuild)
|
||||||
|
EVT_BUTTON(10, MySettingsFrame::OnAutoDetectGame)
|
||||||
|
EVT_BUTTON(11, MySettingsFrame::OnAutoDetectProfile)
|
||||||
|
EVT_BUTTON(12, MySettingsFrame::OnResetCache)
|
||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
/////////// OnInit function to show frame ///////////
|
/////////// OnInit function to show frame ///////////
|
||||||
@@ -152,7 +160,6 @@ bool isSignedIn () {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////// Load Config function ///////////
|
/////////// Load Config function ///////////
|
||||||
void MySettingsFrame:: LoadConfig() {
|
void MySettingsFrame:: LoadConfig() {
|
||||||
if (fs::exists("Launcher.toml")) {
|
if (fs::exists("Launcher.toml")) {
|
||||||
@@ -387,18 +394,17 @@ MySettingsFrame::MySettingsFrame() :
|
|||||||
ctrlGameDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Game Directory"), wxPoint(130, 100), wxSize(300,-1));
|
ctrlGameDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Game Directory"), wxPoint(130, 100), wxSize(300,-1));
|
||||||
ctrlGameDirectory->SetLabel("GamePath");
|
ctrlGameDirectory->SetLabel("GamePath");
|
||||||
MySettingsFrame::SetFocus();
|
MySettingsFrame::SetFocus();
|
||||||
auto btnDetectGameDirectory = new wxButton(panel, 40, wxT("Detect"), wxPoint(185,140), wxSize(90, 25));
|
auto btnDetectGameDirectory = new wxButton(panel, 10, wxT("Detect"), wxPoint(185,140), wxSize(90, 25));
|
||||||
|
|
||||||
auto* txtProfileDirectory = new wxStaticText(panel, wxID_ANY, wxT("Profile Directory: "), wxPoint(30, 200));
|
auto* txtProfileDirectory = new wxStaticText(panel, wxID_ANY, wxT("Profile Directory: "), wxPoint(30, 200));
|
||||||
ctrlProfileDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Profile Directory"), wxPoint(130, 200), wxSize(300,-1));
|
ctrlProfileDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Profile Directory"), wxPoint(130, 200), wxSize(300,-1));
|
||||||
ctrlProfileDirectory->SetLabel("ProfilePath");
|
ctrlProfileDirectory->SetLabel("ProfilePath");
|
||||||
auto btnDetectProfileDirectory = new wxButton(panel, 40, wxT("Detect"), wxPoint(185,240), wxSize(90, 25));
|
auto btnDetectProfileDirectory = new wxButton(panel, 11, wxT("Detect"), wxPoint(185,240), wxSize(90, 25));
|
||||||
|
|
||||||
auto* txtCacheDirectory = new wxStaticText(panel, wxID_ANY, wxT("Cache Directory: "), wxPoint(30, 300));
|
auto* txtCacheDirectory = new wxStaticText(panel, wxID_ANY, wxT("Cache Directory: "), wxPoint(30, 300));
|
||||||
ctrlCacheDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Cache Directory"), wxPoint(130, 300), wxSize(300,-1));
|
ctrlCacheDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Cache Directory"), wxPoint(130, 300), wxSize(300,-1));
|
||||||
ctrlCacheDirectory->SetLabel("CachePath");
|
ctrlCacheDirectory->SetLabel("CachePath");
|
||||||
auto btnCacheDirectory = new wxButton(panel, 40, wxT("Detect"), wxPoint(185,340), wxSize(90, 25));
|
auto btnCacheDirectory = new wxButton(panel, 12, wxT("Reset"), wxPoint(185,340), wxSize(90, 25));
|
||||||
|
|
||||||
|
|
||||||
auto* txtBuild = new wxStaticText(panel, wxID_ANY, wxT("Build: "), wxPoint(30, 400));
|
auto* txtBuild = new wxStaticText(panel, wxID_ANY, wxT("Build: "), wxPoint(30, 400));
|
||||||
wxArrayString BuildChoices;
|
wxArrayString BuildChoices;
|
||||||
@@ -427,6 +433,21 @@ MySettingsFrame::MySettingsFrame() :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////// UpdateConfig function ///////////
|
||||||
|
template <typename ValueType>
|
||||||
|
void UpdateConfig (const std::string& key, ValueType&& value) {
|
||||||
|
if (fs::exists("Launcher.toml")) {
|
||||||
|
toml::parse_result config = toml::parse_file("Launcher.toml");
|
||||||
|
config.insert_or_assign(key, value);
|
||||||
|
|
||||||
|
std::ofstream tml("Launcher.toml");
|
||||||
|
if (tml.is_open()) {
|
||||||
|
tml << config;
|
||||||
|
tml.close();
|
||||||
|
} else wxMessageBox("Failed to modify config file", "Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/////////// OnClick Account Event ///////////
|
/////////// OnClick Account Event ///////////
|
||||||
void MyMainFrame::OnClickAccount(wxCommandEvent& event WXUNUSED(event)) {
|
void MyMainFrame::OnClickAccount(wxCommandEvent& event WXUNUSED(event)) {
|
||||||
auto* AccountFrame = new MyAccountFrame();
|
auto* AccountFrame = new MyAccountFrame();
|
||||||
@@ -506,52 +527,80 @@ void MyMainFrame::OnClickLaunch(wxCommandEvent& event WXUNUSED(event)) {
|
|||||||
void MySettingsFrame::OnClickConsole(wxCommandEvent& event) {
|
void MySettingsFrame::OnClickConsole(wxCommandEvent& event) {
|
||||||
WindowsConsole(checkConsole->IsChecked());
|
WindowsConsole(checkConsole->IsChecked());
|
||||||
bool status = event.IsChecked();
|
bool status = event.IsChecked();
|
||||||
|
UpdateConfig("Console", status);
|
||||||
if (fs::exists("Launcher.toml")) {
|
|
||||||
toml::parse_result config = toml::parse_file("Launcher.toml");
|
|
||||||
config.insert_or_assign("Console", status);
|
|
||||||
|
|
||||||
std::ofstream tml("Launcher.toml");
|
|
||||||
if (tml.is_open()) {
|
|
||||||
tml << config;
|
|
||||||
tml.close();
|
|
||||||
} else wxMessageBox("Failed to modify config file", "Error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////// OnChanged Game Path Event ///////////
|
/////////// OnChanged Game Path Event ///////////
|
||||||
void MySettingsFrame::OnChangedGameDir(wxFileDirPickerEvent& event) {
|
void MySettingsFrame::OnChangedGameDir(wxFileDirPickerEvent& event) {
|
||||||
std::string NewPath = event.GetPath().utf8_string();
|
std::string NewPath = event.GetPath().utf8_string();
|
||||||
|
|
||||||
std::string key = reinterpret_cast<wxDirPickerCtrl*> (event.GetEventObject())->GetLabel();
|
std::string key = reinterpret_cast<wxDirPickerCtrl*> (event.GetEventObject())->GetLabel();
|
||||||
|
UpdateConfig(key, NewPath);
|
||||||
if (fs::exists("Launcher.toml")) {
|
|
||||||
toml::parse_result config = toml::parse_file("Launcher.toml");
|
|
||||||
config.insert_or_assign(key, NewPath);
|
|
||||||
|
|
||||||
std::ofstream tml("Launcher.toml");
|
|
||||||
if (tml.is_open()) {
|
|
||||||
tml << config;
|
|
||||||
tml.close();
|
|
||||||
} else wxMessageBox("Failed to modify config file", "Error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////// OnChanged Build Event ///////////
|
/////////// OnChanged Build Event ///////////
|
||||||
void MySettingsFrame::OnChangedBuild(wxCommandEvent& event) {
|
void MySettingsFrame::OnChangedBuild(wxCommandEvent& event) {
|
||||||
std::string key = reinterpret_cast<wxChoice*> (event.GetEventObject())->GetString(event.GetSelection());
|
std::string key = reinterpret_cast<wxChoice*> (event.GetEventObject())->GetString(event.GetSelection());
|
||||||
|
UpdateConfig("Build", key);
|
||||||
|
}
|
||||||
|
|
||||||
if (fs::exists("Launcher.toml")) {
|
/////////// AutoDetect Game Function ///////////
|
||||||
toml::parse_result config = toml::parse_file("Launcher.toml");
|
void MySettingsFrame::OnAutoDetectGame (wxCommandEvent& event) {
|
||||||
config.insert_or_assign("Build", key);
|
HKEY BeamNG;
|
||||||
|
std::string GamePath;
|
||||||
std::ofstream tml("Launcher.toml");
|
LONG RegRes =
|
||||||
if (tml.is_open()) {
|
RegOpenKeyExA(HKEY_CURRENT_USER, R"(Software\BeamNG\BeamNG.drive)", 0,
|
||||||
tml << config;
|
KEY_READ, &BeamNG);
|
||||||
tml.close();
|
if (RegRes == ERROR_SUCCESS) {
|
||||||
} else wxMessageBox("Failed to modify config file", "Error");
|
GamePath = Launcher::QueryValue(BeamNG, "rootpath");
|
||||||
|
RegCloseKey(BeamNG);
|
||||||
}
|
}
|
||||||
|
if (!GamePath.empty()) {
|
||||||
|
if (GamePath.ends_with('\\')) GamePath.pop_back();
|
||||||
|
UpdateConfig("GamePath", GamePath);
|
||||||
|
ctrlGameDirectory->SetPath(GamePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wxMessageBox("Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive", "Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////// AutoDetect Profile Function ///////////
|
||||||
|
void MySettingsFrame::OnAutoDetectProfile(wxCommandEvent& event){
|
||||||
|
HKEY BeamNG;
|
||||||
|
std::string ProfilePath;
|
||||||
|
LONG RegRes =
|
||||||
|
RegOpenKeyExA(HKEY_CURRENT_USER, R"(Software\BeamNG\BeamNG.drive)", 0,
|
||||||
|
KEY_READ, &BeamNG);
|
||||||
|
if (RegRes == ERROR_SUCCESS) {
|
||||||
|
ProfilePath = Launcher::QueryValue(BeamNG, "userpath_override");
|
||||||
|
RegCloseKey(BeamNG);
|
||||||
|
}
|
||||||
|
if (ProfilePath.empty()) {
|
||||||
|
PWSTR folderPath = nullptr;
|
||||||
|
HRESULT hr =
|
||||||
|
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &folderPath);
|
||||||
|
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
wxMessageBox(
|
||||||
|
"Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive",
|
||||||
|
"Error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_bstr_t bstrPath(folderPath);
|
||||||
|
std::string Path((char*)bstrPath);
|
||||||
|
CoTaskMemFree(folderPath);
|
||||||
|
ProfilePath = Path + "\\BeamNG.drive";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateConfig("ProfilePath", ProfilePath);
|
||||||
|
ctrlProfileDirectory->SetPath(ProfilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////// Reset Cache Function ///////////
|
||||||
|
void MySettingsFrame::OnResetCache(wxCommandEvent& event) {
|
||||||
|
std::string CachePath = fs::current_path().append("Resources").string();
|
||||||
|
UpdateConfig("CachePath", CachePath);
|
||||||
|
ctrlCacheDirectory->SetPath(CachePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////// MAIN FUNCTION ///////////
|
/////////// MAIN FUNCTION ///////////
|
||||||
|
|||||||
Reference in New Issue
Block a user