From 310b2094c5d4c52487bddfcd4bda6356e6d3c917 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Fri, 12 Aug 2022 14:45:46 +0300 Subject: [PATCH 01/10] add path detection add game path auto detection add profile path auto detection add cache path reset --- include/Launcher.h | 9 ++-- src/Launcher.cpp | 2 +- src/gui/Gui.cpp | 125 +++++++++++++++++++++++++++++++-------------- 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/include/Launcher.h b/include/Launcher.h index aaef043..a79dadd 100644 --- a/include/Launcher.h +++ b/include/Launcher.h @@ -18,6 +18,8 @@ struct VersionParser { std::vector split; std::vector data; }; +struct HKEY__; +typedef HKEY__ *HKEY; class Launcher { public: // constructors @@ -35,6 +37,7 @@ class Launcher { void LaunchGame(); void CheckKey(); void SetupMOD(); + static std::string QueryValue(HKEY& hKey, const char* Name); public: // Getters and Setters void setDiscordMessage(const std::string& message); @@ -82,9 +85,9 @@ class Launcher { std::string Version{"2.0"}; Server ServerHandler{this}; std::string TargetBuild{"default"}; - std::string GameConfigPath{""}; - std::string ProfileConfigPath{""}; - std::string CacheConfigPath{""}; + std::string GameConfigPath{}; + std::string ProfileConfigPath{}; + std::string CacheConfigPath{}; static inline std::atomic Shutdown{false}, Exit{false}; std::string FullVersion{Version + ".99"}; VersionParser SupportedVersion{"0.25.4.0"}; diff --git a/src/Launcher.cpp b/src/Launcher.cpp index f53f3fc..467f416 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -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; BYTE buffer[16384]; if (RegQueryValueExA(hKey, Name, nullptr, nullptr, buffer, &keySize) == diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index 4b95b86..8bdb1fc 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "Launcher.h" #include "Logger.h" #include @@ -72,6 +74,9 @@ class MySettingsFrame : public wxFrame { void OnClickConsole(wxCommandEvent& event); void OnChangedGameDir (wxFileDirPickerEvent& event); void OnChangedBuild (wxCommandEvent& event); + void OnAutoDetectGame(wxCommandEvent& event); + void OnAutoDetectProfile(wxCommandEvent& event); + void OnResetCache(wxCommandEvent& event); wxDECLARE_EVENT_TABLE(); }; @@ -106,6 +111,9 @@ wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame) EVT_CHECKBOX(45, MySettingsFrame::OnClickConsole) EVT_DIRPICKER_CHANGED(46, MySettingsFrame::OnChangedGameDir) EVT_CHOICE(47, MySettingsFrame::OnChangedBuild) + EVT_BUTTON(10, MySettingsFrame::OnAutoDetectGame) + EVT_BUTTON(11, MySettingsFrame::OnAutoDetectProfile) + EVT_BUTTON(12, MySettingsFrame::OnResetCache) wxEND_EVENT_TABLE() /////////// OnInit function to show frame /////////// @@ -152,7 +160,6 @@ bool isSignedIn () { return false; } - /////////// Load Config function /////////// void MySettingsFrame:: LoadConfig() { 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->SetLabel("GamePath"); 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)); ctrlProfileDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Profile Directory"), wxPoint(130, 200), wxSize(300,-1)); 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)); ctrlCacheDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Cache Directory"), wxPoint(130, 300), wxSize(300,-1)); 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)); wxArrayString BuildChoices; @@ -427,6 +433,21 @@ MySettingsFrame::MySettingsFrame() : } } +/////////// UpdateConfig function /////////// +template +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 /////////// void MyMainFrame::OnClickAccount(wxCommandEvent& event WXUNUSED(event)) { auto* AccountFrame = new MyAccountFrame(); @@ -506,52 +527,80 @@ void MyMainFrame::OnClickLaunch(wxCommandEvent& event WXUNUSED(event)) { void MySettingsFrame::OnClickConsole(wxCommandEvent& event) { WindowsConsole(checkConsole->IsChecked()); bool status = event.IsChecked(); - - 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"); - } + UpdateConfig("Console", status); } - /////////// OnChanged Game Path Event /////////// void MySettingsFrame::OnChangedGameDir(wxFileDirPickerEvent& event) { std::string NewPath = event.GetPath().utf8_string(); - std::string key = reinterpret_cast (event.GetEventObject())->GetLabel(); - - 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"); - } + UpdateConfig(key, NewPath); } /////////// OnChanged Build Event /////////// void MySettingsFrame::OnChangedBuild(wxCommandEvent& event) { std::string key = reinterpret_cast (event.GetEventObject())->GetString(event.GetSelection()); + UpdateConfig("Build", key); +} - if (fs::exists("Launcher.toml")) { - toml::parse_result config = toml::parse_file("Launcher.toml"); - config.insert_or_assign("Build", key); - - std::ofstream tml("Launcher.toml"); - if (tml.is_open()) { - tml << config; - tml.close(); - } else wxMessageBox("Failed to modify config file", "Error"); +/////////// AutoDetect Game Function /////////// +void MySettingsFrame::OnAutoDetectGame (wxCommandEvent& event) { + HKEY BeamNG; + std::string GamePath; + LONG RegRes = + RegOpenKeyExA(HKEY_CURRENT_USER, R"(Software\BeamNG\BeamNG.drive)", 0, + KEY_READ, &BeamNG); + if (RegRes == ERROR_SUCCESS) { + 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 /////////// From 51212dece24f0601f8430208d12efbabe048b8e1 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Fri, 12 Aug 2022 16:56:02 +0300 Subject: [PATCH 02/10] add read game version from json statically --- src/gui/Gui.cpp | 51 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index 8bdb1fc..a4531f3 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -17,15 +17,28 @@ #include #include #include +#include +#include #include "Launcher.h" #include "Logger.h" #include #endif +/*/////////// TestFrame class /////////// +class MyTestFrame : public wxFrame { + public: + MyTestFrame(); + + private: + // Here you put the frame functions: + bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); +};*/ + /////////// Inherit App class /////////// class MyApp : public wxApp { public: bool OnInit() override; + //static inline MyTestFrame* TestFrame; }; /////////// MainFrame class /////////// @@ -80,15 +93,7 @@ class MySettingsFrame : public wxFrame { wxDECLARE_EVENT_TABLE(); }; -/////////// TestFrame class /////////// -class MyTestFrame : public wxFrame { - public: - MyTestFrame(); - private: - // Here you put the frame functions: - bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); -}; enum { ID_Hello = 1 }; @@ -137,7 +142,8 @@ bool MyApp::OnInit() { MainFrame->Show(true); //Test Frame Properties: -/* auto* TestFrame = new MyTestFrame(); + /*TestFrame = new MyTestFrame(); + TestFrame->SetIcon(wxIcon("icons/BeamMP_black.png",wxBITMAP_TYPE_PNG)); TestFrame->SetSize(1000, 650); TestFrame->Center(); @@ -150,8 +156,7 @@ bool MyApp::OnInit() { else { TestFrame->SetBackgroundColour(wxColour("white")); TestFrame->SetForegroundColour(wxColour("white")); - } - TestFrame->Show(true);*/ + }*/ return true; } @@ -237,6 +242,15 @@ void WindowsConsole (bool isChecked) { file->SetForegroundColour("white"); }*/ +/////////// Read json function /////////// +std::string jsonRead () { + + std::ifstream ifs(R"(D:\BeamNG.Drive.v0.25.4.0.14071\Game\integrity.json)"); + nlohmann::json jf = nlohmann::json::parse(ifs); + if (!jf.empty()) return jf["version"]; + else return "Game Version: NA"; +} + /////////// MainFrame Function /////////// MyMainFrame::MyMainFrame() : wxFrame(nullptr, wxID_ANY, "BeamMP Launcher V3", wxDefaultPosition,wxDefaultSize, @@ -281,7 +295,8 @@ MyMainFrame::MyMainFrame() : } //Information: - auto* txtGameVersion = new wxStaticText(panel, wxID_ANY, wxT("Game Version: NA"), wxPoint(160, 490)); + auto* txtGameVersionTitle = new wxStaticText(panel, wxID_ANY, wxT("Game Version: "), wxPoint(160, 490)); + auto* txtGameVersion = new wxStaticText(panel, wxID_ANY, jsonRead(), wxPoint(240, 490)); auto* txtPlayers = new wxStaticText(panel, wxID_ANY, wxT("Currently Playing: NA"), wxPoint(300, 490)); auto* txtPatreon = new wxStaticText(panel, wxID_ANY, wxT("Special thanks to our Patreon Members!"), wxPoint(570, 490)); @@ -315,7 +330,15 @@ MyMainFrame::MyMainFrame() : //Texts: txtNews->SetForegroundColour("white"); txtUpdate->SetForegroundColour("white"); - txtGameVersion->SetForegroundColour("white"); + txtGameVersionTitle->SetForegroundColour("white"); + + if (jsonRead() > "0.25.4.0") + txtGameVersion->SetForegroundColour("orange"); + else if (jsonRead() < "0.25.4.0") + txtGameVersion->SetForegroundColour("red"); + else + txtGameVersion->SetForegroundColour("green"); + txtPlayers->SetForegroundColour("white"); txtModVersion->SetForegroundColour("white"); txtServers->SetForegroundColour("white"); @@ -463,7 +486,7 @@ void MyMainFrame::OnClickAccount(wxCommandEvent& event WXUNUSED(event)) { AccountFrame->SetBackgroundColour(wxColour("white")); AccountFrame->SetForegroundColour(wxColour("white")); } - AccountFrame->Show(true); + AccountFrame->Show(); } /////////// OnClick Settings Event /////////// From 44a6eac95af3579fecb68a18af05413dc4056bd0 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Mon, 15 Aug 2022 12:28:50 +0300 Subject: [PATCH 03/10] add link to player, servers, game version --- include/Launcher.h | 9 ++- src/gui/Gui.cpp | 174 ++++++++++++++++++++++++++++++--------------- 2 files changed, 125 insertions(+), 58 deletions(-) diff --git a/include/Launcher.h b/include/Launcher.h index a79dadd..c85fddf 100644 --- a/include/Launcher.h +++ b/include/Launcher.h @@ -66,6 +66,7 @@ class Launcher { public: // variables static inline std::thread EntryThread{}; + static inline VersionParser SupportedVersion{"0.25.4.0"}; private: // variables uint32_t GamePID{0}; @@ -90,7 +91,6 @@ class Launcher { std::string CacheConfigPath{}; static inline std::atomic Shutdown{false}, Exit{false}; std::string FullVersion{Version + ".99"}; - VersionParser SupportedVersion{"0.25.4.0"}; std::unique_ptr IPCToGame{}; std::unique_ptr IPCFromGame{}; }; @@ -100,4 +100,11 @@ class ShutdownException : public std::runtime_error { explicit ShutdownException(const std::string& message) : runtime_error(message){}; }; + +struct UIData { + static inline std::string GamePath, ProfilePath, CachePath; + + +}; + void entry(); diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index a4531f3..3f60edd 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -21,6 +21,7 @@ #include #include "Launcher.h" #include "Logger.h" +#include "HttpAPI.h" #include #endif @@ -45,12 +46,15 @@ class MyApp : public wxApp { class MyMainFrame : public wxFrame { public: MyMainFrame(); + static void GameVersionLabel(); private: // Here you put the frame functions: wxStaticText* txtStatusResult; + static inline wxStaticText* txtGameVersion, *txtPlayers, *txtModVersion, *txtServers; wxButton* btnLaunch; bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); + void GetStats(); void OnClickAccount(wxCommandEvent& event); void OnClickSettings(wxCommandEvent& event); void OnClickLaunch(wxCommandEvent& event); @@ -76,7 +80,8 @@ class MyAccountFrame : public wxFrame { class MySettingsFrame : public wxFrame { public: MySettingsFrame(); - void LoadConfig(); + void UpdateInfo(); + void UpdateGameDirectory(const std::string& path); private: // Here you put the frame functions: @@ -93,9 +98,63 @@ class MySettingsFrame : public wxFrame { wxDECLARE_EVENT_TABLE(); }; +void MyMainFrame::GetStats () { + std::string results = HTTP::Get("https://backend.beammp.com/stats_raw"); + nlohmann::json jf = nlohmann::json::parse(results); + if (!jf.empty()) { + txtPlayers->SetLabel(to_string(jf["Players"])); + txtServers->SetLabel(to_string(jf["PublicServers"])); + } else { + txtPlayers->SetLabel("NA"); + txtServers->SetLabel("NA"); + wxMessageBox("Couldn't get game stats", "Error"); + } +} -enum { ID_Hello = 1 }; +/////////// Update Info Function /////////// +void MySettingsFrame::UpdateInfo() { + ctrlGameDirectory->SetPath(UIData::GamePath); + ctrlProfileDirectory->SetPath(UIData::ProfilePath); + ctrlCacheDirectory->SetPath(UIData::CachePath); +} + +/////////// Load Config function /////////// +void LoadConfig() { + if (fs::exists("Launcher.toml")) { + toml::parse_result config = toml::parse_file("Launcher.toml"); + auto ui = config["UI"]; + auto build = config["Build"]; + auto GamePath = config["GamePath"]; + auto ProfilePath = config["ProfilePath"]; + auto CachePath = config["CachePath"]; + + if (GamePath.is_string()) { + UIData::GamePath = GamePath.as_string()->get(); + } else wxMessageBox("Game path not found!", "Error"); + + if (ProfilePath.is_string()) { + UIData::ProfilePath = ProfilePath.as_string()->get(); + } else wxMessageBox("Profile path not found!", "Error"); + + if (CachePath.is_string()) { + UIData::CachePath = CachePath.as_string()->get(); + } else wxMessageBox("Cache path not found!", "Error"); + + } else { + std::ofstream tml("Launcher.toml"); + if (tml.is_open()) { + tml << "UI = true\n" + "Build = 'Default'\n" + "GamePath = 'C:\\Program Files'\n" + "ProfilePath = 'C:\\Program Files'\n" + "CachePath = 'Resources'\n" + "Console = false"; + tml.close(); + LoadConfig(); + } else wxMessageBox("Failed to create config file", "Error"); + } +} /////////// MainFrame Event Table /////////// wxBEGIN_EVENT_TABLE(MyMainFrame, wxFrame) @@ -123,6 +182,7 @@ wxEND_EVENT_TABLE() /////////// OnInit function to show frame /////////// bool MyApp::OnInit() { + LoadConfig(); auto* MainFrame = new MyMainFrame(); MainFrame->SetIcon(wxIcon("icons/BeamMP_black.png",wxBITMAP_TYPE_PNG)); @@ -165,43 +225,6 @@ bool isSignedIn () { return false; } -/////////// Load Config function /////////// -void MySettingsFrame:: LoadConfig() { - if (fs::exists("Launcher.toml")) { - toml::parse_result config = toml::parse_file("Launcher.toml"); - auto ui = config["UI"]; - auto build = config["Build"]; - auto GamePath = config["GamePath"]; - auto ProfilePath = config["ProfilePath"]; - auto CachePath = config["CachePath"]; - - if (GamePath.is_string()) { - ctrlGameDirectory->SetPath(GamePath.as_string()->get()); - } else wxMessageBox("Game path not found!", "Error"); - - if (ProfilePath.is_string()) { - ctrlProfileDirectory->SetPath(ProfilePath.as_string()->get()); - } else wxMessageBox("Profile path not found!", "Error"); - - if (CachePath.is_string()) { - ctrlCacheDirectory->SetPath(CachePath.as_string()->get()); - } else wxMessageBox("Cache path not found!", "Error"); - - } else { - std::ofstream tml("Launcher.toml"); - if (tml.is_open()) { - tml << "UI = true\n" - "Build = 'Default'\n" - "GamePath = 'C:\\Program Files'\n" - "ProfilePath = 'C:\\Program Files'\n" - "CachePath = 'Resources'\n" - "Console = false"; - tml.close(); - LoadConfig(); - } else wxMessageBox("Failed to create config file", "Error"); - } -} - /////////// Windows Console Function /////////// void WindowsConsole (bool isChecked) { if (isChecked) { @@ -244,11 +267,15 @@ void WindowsConsole (bool isChecked) { /////////// Read json function /////////// std::string jsonRead () { + fs::path path = fs::path (UIData::GamePath).append("integrity.json"); + if (fs::exists(path)) { + std::ifstream ifs(path); + nlohmann::json jf = nlohmann::json::parse(ifs); + if (!jf.empty()) return jf["version"]; + } - std::ifstream ifs(R"(D:\BeamNG.Drive.v0.25.4.0.14071\Game\integrity.json)"); - nlohmann::json jf = nlohmann::json::parse(ifs); - if (!jf.empty()) return jf["version"]; - else return "Game Version: NA"; + else wxMessageBox("Couldn't read game version, check game path in settings", "Error"); + return ""; } /////////// MainFrame Function /////////// @@ -296,12 +323,19 @@ MyMainFrame::MyMainFrame() : //Information: auto* txtGameVersionTitle = new wxStaticText(panel, wxID_ANY, wxT("Game Version: "), wxPoint(160, 490)); - auto* txtGameVersion = new wxStaticText(panel, wxID_ANY, jsonRead(), wxPoint(240, 490)); - auto* txtPlayers = new wxStaticText(panel, wxID_ANY, wxT("Currently Playing: NA"), wxPoint(300, 490)); + txtGameVersion = new wxStaticText(panel, wxID_ANY, "NA", wxPoint(240, 490)); + + auto* txtPlayersTitle = new wxStaticText(panel, wxID_ANY, wxT("Currently Playing:"), wxPoint(300, 490)); + txtPlayers = new wxStaticText(panel, wxID_ANY, wxT("NA"), wxPoint(400, 490)); + auto* txtPatreon = new wxStaticText(panel, wxID_ANY, wxT("Special thanks to our Patreon Members!"), wxPoint(570, 490)); - auto* txtModVersion = new wxStaticText(panel, wxID_ANY, wxT("Mod Version: NA"), wxPoint(160, 520)); - auto* txtServers = new wxStaticText(panel, wxID_ANY, wxT("Available Servers: NA"), wxPoint(300, 520)); + auto* txtModVersionTitle = new wxStaticText(panel, wxID_ANY, wxT("Mod Version:"), wxPoint(160, 520)); + txtModVersion = new wxStaticText(panel, wxID_ANY, wxT("NA"), wxPoint(235, 520)); + + auto* txtServersTitle = new wxStaticText(panel, wxID_ANY, wxT("Available Servers:"), wxPoint(300, 520)); + txtServers = new wxStaticText(panel, wxID_ANY, wxT("NA"), wxPoint(395, 520)); + auto* txtStatus = new wxStaticText(panel, wxID_ANY, wxT("Status: "), wxPoint(880, 520)); txtStatusResult = new wxStaticText(panel, wxID_ANY, wxT("Online"), wxPoint(920, 520)); @@ -319,7 +353,10 @@ MyMainFrame::MyMainFrame() : auto btnSettings = new wxButton(panel, 40, wxT("Settings"), wxPoint(730,570), wxSize(110, 25)); btnLaunch = new wxButton(panel, 41, wxT("Launch"), wxPoint(850,570), wxSize(110, 25)); + GetStats(); + //UI Colors: + GameVersionLabel(); if (DarkMode) { //Text Separators: txtSeparator1->SetForegroundColour("white"); @@ -331,16 +368,12 @@ MyMainFrame::MyMainFrame() : txtNews->SetForegroundColour("white"); txtUpdate->SetForegroundColour("white"); txtGameVersionTitle->SetForegroundColour("white"); - - if (jsonRead() > "0.25.4.0") - txtGameVersion->SetForegroundColour("orange"); - else if (jsonRead() < "0.25.4.0") - txtGameVersion->SetForegroundColour("red"); - else - txtGameVersion->SetForegroundColour("green"); - + txtGameVersion->SetForegroundColour("white"); + txtPlayersTitle->SetForegroundColour("white"); txtPlayers->SetForegroundColour("white"); + txtModVersionTitle->SetForegroundColour("white"); txtModVersion->SetForegroundColour("white"); + txtServersTitle->SetForegroundColour("white"); txtServers->SetForegroundColour("white"); txtPatreon->SetForegroundColour("white"); txtStatus->SetForegroundColour("white"); @@ -362,6 +395,23 @@ MyMainFrame::MyMainFrame() : txtStatusResult->SetForegroundColour("green"); } +/////////// Game Version Label function /////////// +void MyMainFrame::GameVersionLabel() { + std::string read = jsonRead(); + if (!read.empty()) { + txtGameVersion->SetLabel(read); + VersionParser CurrentVersion(read); + if (CurrentVersion > Launcher::SupportedVersion) + txtGameVersion->SetForegroundColour("orange"); + else if (CurrentVersion < Launcher::SupportedVersion) + txtGameVersion->SetForegroundColour("red"); + else txtGameVersion->SetForegroundColour("green"); + } else { + txtGameVersion->SetLabel(wxT("NA")); + txtGameVersion->SetForegroundColour("red"); + } +} + /////////// Account Frame Content /////////// MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", wxDefaultPosition,wxDefaultSize, wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX) { @@ -504,8 +554,8 @@ void MyMainFrame::OnClickSettings(wxCommandEvent& event WXUNUSED(event)) { SettingsFrame->SetBackgroundColour(wxColour("white")); SettingsFrame->SetForegroundColour(wxColour("white")); } + SettingsFrame->UpdateInfo(); SettingsFrame->Show(true); - SettingsFrame->LoadConfig(); } /////////// OnClick Logo Event /////////// @@ -553,11 +603,19 @@ void MySettingsFrame::OnClickConsole(wxCommandEvent& event) { UpdateConfig("Console", status); } +/////////// Update Game Directory Function /////////// +void MySettingsFrame::UpdateGameDirectory(const std::string& path) { + ctrlGameDirectory->SetPath(path); + UIData::GamePath = path; + MyMainFrame::GameVersionLabel(); +} + /////////// OnChanged Game Path Event /////////// void MySettingsFrame::OnChangedGameDir(wxFileDirPickerEvent& event) { std::string NewPath = event.GetPath().utf8_string(); std::string key = reinterpret_cast (event.GetEventObject())->GetLabel(); UpdateConfig(key, NewPath); + UpdateGameDirectory(NewPath); } /////////// OnChanged Build Event /////////// @@ -566,6 +624,8 @@ void MySettingsFrame::OnChangedBuild(wxCommandEvent& event) { UpdateConfig("Build", key); } + + /////////// AutoDetect Game Function /////////// void MySettingsFrame::OnAutoDetectGame (wxCommandEvent& event) { HKEY BeamNG; @@ -580,7 +640,7 @@ void MySettingsFrame::OnAutoDetectGame (wxCommandEvent& event) { if (!GamePath.empty()) { if (GamePath.ends_with('\\')) GamePath.pop_back(); UpdateConfig("GamePath", GamePath); - ctrlGameDirectory->SetPath(GamePath); + UpdateGameDirectory(GamePath); } else wxMessageBox("Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive", "Error"); From 81208afb2a4fd3405ebfa0db63f3a17391900fb2 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Mon, 15 Aug 2022 15:33:36 +0300 Subject: [PATCH 04/10] add players and servers colors fix color bug with game version --- src/gui/Gui.cpp | 102 ++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index 3f60edd..bb5c142 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -49,12 +49,13 @@ class MyMainFrame : public wxFrame { static void GameVersionLabel(); private: - // Here you put the frame functions: wxStaticText* txtStatusResult; static inline wxStaticText* txtGameVersion, *txtPlayers, *txtModVersion, *txtServers; wxButton* btnLaunch; + bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); void GetStats(); + void OnClickAccount(wxCommandEvent& event); void OnClickSettings(wxCommandEvent& event); void OnClickLaunch(wxCommandEvent& event); @@ -68,8 +69,6 @@ class MyAccountFrame : public wxFrame { MyAccountFrame(); private: - // Here you put the frame functions: - bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); void OnClickRegister(wxCommandEvent& event); void OnClickLogout(wxCommandEvent& event); @@ -84,11 +83,12 @@ class MySettingsFrame : public wxFrame { void UpdateGameDirectory(const std::string& path); private: - // Here you put the frame functions: wxDirPickerCtrl* ctrlGameDirectory, *ctrlProfileDirectory, *ctrlCacheDirectory; wxCheckBox* checkConsole; wxChoice* choiceController; + bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); + void OnClickConsole(wxCommandEvent& event); void OnChangedGameDir (wxFileDirPickerEvent& event); void OnChangedBuild (wxCommandEvent& event); @@ -98,17 +98,30 @@ class MySettingsFrame : public wxFrame { wxDECLARE_EVENT_TABLE(); }; +/////////// Get Stats Function /////////// void MyMainFrame::GetStats () { std::string results = HTTP::Get("https://backend.beammp.com/stats_raw"); - nlohmann::json jf = nlohmann::json::parse(results); - if (!jf.empty()) { + nlohmann::json jf = nlohmann::json::parse(results, nullptr, false); + if (!jf.is_discarded() && !jf.empty()) { txtPlayers->SetLabel(to_string(jf["Players"])); txtServers->SetLabel(to_string(jf["PublicServers"])); + + if (jf["Players"].get() < 699) + txtPlayers->SetForegroundColour("green"); + else + txtPlayers->SetForegroundColour(wxColour(255,173,0)); + + if (jf["PublicServers"].get() < 749) + txtServers->SetForegroundColour("green"); + else + txtServers->SetForegroundColour(wxColour(255,173,0)); + } else { txtPlayers->SetLabel("NA"); + txtPlayers->SetForegroundColour("red"); txtServers->SetLabel("NA"); - wxMessageBox("Couldn't get game stats", "Error"); + txtServers->SetForegroundColour("red"); } } @@ -119,7 +132,7 @@ void MySettingsFrame::UpdateInfo() { ctrlCacheDirectory->SetPath(UIData::CachePath); } -/////////// Load Config function /////////// +/////////// Load Config Function /////////// void LoadConfig() { if (fs::exists("Launcher.toml")) { toml::parse_result config = toml::parse_file("Launcher.toml"); @@ -156,7 +169,8 @@ void LoadConfig() { } } -/////////// MainFrame Event Table /////////// +/////////// Event Tables /////////// +//MainFrame: wxBEGIN_EVENT_TABLE(MyMainFrame, wxFrame) EVT_BUTTON(39, MyMainFrame::OnClickAccount) EVT_BUTTON(40, MyMainFrame::OnClickSettings) @@ -164,13 +178,13 @@ wxBEGIN_EVENT_TABLE(MyMainFrame, wxFrame) EVT_BUTTON(42, MyMainFrame::OnClickLogo) wxEND_EVENT_TABLE() -/////////// AccountFrame Event Table /////////// +//AccountFrame: wxBEGIN_EVENT_TABLE(MyAccountFrame, wxFrame) EVT_BUTTON(43, MyAccountFrame::OnClickRegister) EVT_BUTTON(44, MyAccountFrame::OnClickLogout) wxEND_EVENT_TABLE() - /////////// SettingsFrame Event Table /////////// +//SettingsFrame: wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame) EVT_CHECKBOX(45, MySettingsFrame::OnClickConsole) EVT_DIRPICKER_CHANGED(46, MySettingsFrame::OnChangedGameDir) @@ -180,7 +194,7 @@ wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame) EVT_BUTTON(12, MySettingsFrame::OnResetCache) wxEND_EVENT_TABLE() -/////////// OnInit function to show frame /////////// +/////////// OnInit Function /////////// bool MyApp::OnInit() { LoadConfig(); auto* MainFrame = new MyMainFrame(); @@ -243,7 +257,7 @@ void WindowsConsole (bool isChecked) { ::fclose(stderr); ::fclose(stdin); } - // Clear the error state for all of the C++ standard streams. Attempting to accessing the streams before they refer + // Clear the error state for all the C++ standard streams. Attempting to accessing the streams before they refer // to a valid target causes the stream to enter an error state. Clearing the error state will fix this problem, // which seems to occur in newer version of Visual Studio even when the console has not been read from or written // to yet. @@ -265,15 +279,14 @@ void WindowsConsole (bool isChecked) { file->SetForegroundColour("white"); }*/ -/////////// Read json function /////////// +/////////// Read json Function /////////// std::string jsonRead () { fs::path path = fs::path (UIData::GamePath).append("integrity.json"); if (fs::exists(path)) { std::ifstream ifs(path); - nlohmann::json jf = nlohmann::json::parse(ifs); - if (!jf.empty()) return jf["version"]; + nlohmann::json jf = nlohmann::json::parse(ifs, nullptr, false); + if (!jf.is_discarded() && !jf.empty()) return jf["version"]; } - else wxMessageBox("Couldn't read game version, check game path in settings", "Error"); return ""; } @@ -368,13 +381,10 @@ MyMainFrame::MyMainFrame() : txtNews->SetForegroundColour("white"); txtUpdate->SetForegroundColour("white"); txtGameVersionTitle->SetForegroundColour("white"); - txtGameVersion->SetForegroundColour("white"); txtPlayersTitle->SetForegroundColour("white"); - txtPlayers->SetForegroundColour("white"); txtModVersionTitle->SetForegroundColour("white"); txtModVersion->SetForegroundColour("white"); txtServersTitle->SetForegroundColour("white"); - txtServers->SetForegroundColour("white"); txtPatreon->SetForegroundColour("white"); txtStatus->SetForegroundColour("white"); @@ -395,23 +405,6 @@ MyMainFrame::MyMainFrame() : txtStatusResult->SetForegroundColour("green"); } -/////////// Game Version Label function /////////// -void MyMainFrame::GameVersionLabel() { - std::string read = jsonRead(); - if (!read.empty()) { - txtGameVersion->SetLabel(read); - VersionParser CurrentVersion(read); - if (CurrentVersion > Launcher::SupportedVersion) - txtGameVersion->SetForegroundColour("orange"); - else if (CurrentVersion < Launcher::SupportedVersion) - txtGameVersion->SetForegroundColour("red"); - else txtGameVersion->SetForegroundColour("green"); - } else { - txtGameVersion->SetLabel(wxT("NA")); - txtGameVersion->SetForegroundColour("red"); - } -} - /////////// Account Frame Content /////////// MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", wxDefaultPosition,wxDefaultSize, wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX) { @@ -506,7 +499,7 @@ MySettingsFrame::MySettingsFrame() : } } -/////////// UpdateConfig function /////////// +/////////// UpdateConfig Function /////////// template void UpdateConfig (const std::string& key, ValueType&& value) { if (fs::exists("Launcher.toml")) { @@ -521,6 +514,30 @@ void UpdateConfig (const std::string& key, ValueType&& value) { } } +/////////// Game Version Label Function /////////// +void MyMainFrame::GameVersionLabel() { + std::string read = jsonRead(); + if (!read.empty()) { + txtGameVersion->SetLabel(read); + VersionParser CurrentVersion(read); + if (CurrentVersion > Launcher::SupportedVersion) + txtGameVersion->SetForegroundColour(wxColour(255,173,0)); + else if (CurrentVersion < Launcher::SupportedVersion) + txtGameVersion->SetForegroundColour("red"); + else txtGameVersion->SetForegroundColour("green"); + } else { + txtGameVersion->SetLabel(wxT("NA")); + txtGameVersion->SetForegroundColour("red"); + } +} + +/////////// Update Game Directory Function /////////// +void MySettingsFrame::UpdateGameDirectory(const std::string& path) { + ctrlGameDirectory->SetPath(path); + UIData::GamePath = path; + MyMainFrame::GameVersionLabel(); +} + /////////// OnClick Account Event /////////// void MyMainFrame::OnClickAccount(wxCommandEvent& event WXUNUSED(event)) { auto* AccountFrame = new MyAccountFrame(); @@ -603,13 +620,6 @@ void MySettingsFrame::OnClickConsole(wxCommandEvent& event) { UpdateConfig("Console", status); } -/////////// Update Game Directory Function /////////// -void MySettingsFrame::UpdateGameDirectory(const std::string& path) { - ctrlGameDirectory->SetPath(path); - UIData::GamePath = path; - MyMainFrame::GameVersionLabel(); -} - /////////// OnChanged Game Path Event /////////// void MySettingsFrame::OnChangedGameDir(wxFileDirPickerEvent& event) { std::string NewPath = event.GetPath().utf8_string(); @@ -624,8 +634,6 @@ void MySettingsFrame::OnChangedBuild(wxCommandEvent& event) { UpdateConfig("Build", key); } - - /////////// AutoDetect Game Function /////////// void MySettingsFrame::OnAutoDetectGame (wxCommandEvent& event) { HKEY BeamNG; From 11e4c111328c58ab858104e53993fa9e2be9126b Mon Sep 17 00:00:00 2001 From: Sam39 Date: Tue, 16 Aug 2022 10:48:15 +0300 Subject: [PATCH 05/10] change button IDs and function locations --- src/gui/Gui.cpp | 171 +++++++++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 81 deletions(-) diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index bb5c142..e5dc576 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -72,6 +72,7 @@ class MyAccountFrame : public wxFrame { bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); void OnClickRegister(wxCommandEvent& event); void OnClickLogout(wxCommandEvent& event); + void OnClickLogin(wxCommandEvent& event); wxDECLARE_EVENT_TABLE(); }; @@ -98,6 +99,32 @@ class MySettingsFrame : public wxFrame { wxDECLARE_EVENT_TABLE(); }; +/////////// Event Tables /////////// +//MainFrame (ID range 1 to 99): +wxBEGIN_EVENT_TABLE(MyMainFrame, wxFrame) + EVT_BUTTON(1, MyMainFrame::OnClickAccount) + EVT_BUTTON(2, MyMainFrame::OnClickSettings) + EVT_BUTTON(3, MyMainFrame::OnClickLaunch) + EVT_BUTTON(4, MyMainFrame::OnClickLogo) +wxEND_EVENT_TABLE() + +//AccountFrame (ID range 100 to 199): +wxBEGIN_EVENT_TABLE(MyAccountFrame, wxFrame) + EVT_BUTTON(100, MyAccountFrame::OnClickLogout) + EVT_BUTTON(101, MyAccountFrame::OnClickRegister) + EVT_BUTTON(102, MyAccountFrame::OnClickLogin) +wxEND_EVENT_TABLE() + +//SettingsFrame (ID range 200 to 299): +wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame) + EVT_DIRPICKER_CHANGED(200, MySettingsFrame::OnChangedGameDir) + EVT_BUTTON(201, MySettingsFrame::OnAutoDetectGame) + EVT_BUTTON(202, MySettingsFrame::OnAutoDetectProfile) + EVT_BUTTON(203, MySettingsFrame::OnResetCache) + EVT_CHOICE(204, MySettingsFrame::OnChangedBuild) + EVT_CHECKBOX(205, MySettingsFrame::OnClickConsole) +wxEND_EVENT_TABLE() + /////////// Get Stats Function /////////// void MyMainFrame::GetStats () { std::string results = HTTP::Get("https://backend.beammp.com/stats_raw"); @@ -107,12 +134,12 @@ void MyMainFrame::GetStats () { txtPlayers->SetLabel(to_string(jf["Players"])); txtServers->SetLabel(to_string(jf["PublicServers"])); - if (jf["Players"].get() < 699) + if (jf["Players"].get() < 559) txtPlayers->SetForegroundColour("green"); else txtPlayers->SetForegroundColour(wxColour(255,173,0)); - if (jf["PublicServers"].get() < 749) + if (jf["PublicServers"].get() > 679) txtServers->SetForegroundColour("green"); else txtServers->SetForegroundColour(wxColour(255,173,0)); @@ -132,6 +159,13 @@ void MySettingsFrame::UpdateInfo() { ctrlCacheDirectory->SetPath(UIData::CachePath); } +/////////// Update Game Directory Function /////////// +void MySettingsFrame::UpdateGameDirectory(const std::string& path) { + ctrlGameDirectory->SetPath(path); + UIData::GamePath = path; + MyMainFrame::GameVersionLabel(); +} + /////////// Load Config Function /////////// void LoadConfig() { if (fs::exists("Launcher.toml")) { @@ -169,31 +203,6 @@ void LoadConfig() { } } -/////////// Event Tables /////////// -//MainFrame: -wxBEGIN_EVENT_TABLE(MyMainFrame, wxFrame) - EVT_BUTTON(39, MyMainFrame::OnClickAccount) - EVT_BUTTON(40, MyMainFrame::OnClickSettings) - EVT_BUTTON(41, MyMainFrame::OnClickLaunch) - EVT_BUTTON(42, MyMainFrame::OnClickLogo) -wxEND_EVENT_TABLE() - -//AccountFrame: -wxBEGIN_EVENT_TABLE(MyAccountFrame, wxFrame) - EVT_BUTTON(43, MyAccountFrame::OnClickRegister) - EVT_BUTTON(44, MyAccountFrame::OnClickLogout) -wxEND_EVENT_TABLE() - -//SettingsFrame: -wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame) - EVT_CHECKBOX(45, MySettingsFrame::OnClickConsole) - EVT_DIRPICKER_CHANGED(46, MySettingsFrame::OnChangedGameDir) - EVT_CHOICE(47, MySettingsFrame::OnChangedBuild) - EVT_BUTTON(10, MySettingsFrame::OnAutoDetectGame) - EVT_BUTTON(11, MySettingsFrame::OnAutoDetectProfile) - EVT_BUTTON(12, MySettingsFrame::OnResetCache) -wxEND_EVENT_TABLE() - /////////// OnInit Function /////////// bool MyApp::OnInit() { LoadConfig(); @@ -269,16 +278,6 @@ void WindowsConsole (bool isChecked) { std::wcin.clear(); } -/////////// TestFrame Function /////////// -/*MyTestFrame::MyTestFrame() : - wxFrame(nullptr, wxID_ANY, "BeamMP Launcher V3", wxDefaultPosition,wxDefaultSize, - wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX) { - - auto* file = new wxFileDialog (this, wxT("Test"), wxT(""),wxT("")); - file->SetPosition(wxPoint(250,250)); - file->SetForegroundColour("white"); -}*/ - /////////// Read json Function /////////// std::string jsonRead () { fs::path path = fs::path (UIData::GamePath).append("integrity.json"); @@ -291,7 +290,17 @@ std::string jsonRead () { return ""; } -/////////// MainFrame Function /////////// +/////////// TestFrame Function /////////// +/*MyTestFrame::MyTestFrame() : + wxFrame(nullptr, wxID_ANY, "BeamMP Launcher V3", wxDefaultPosition,wxDefaultSize, + wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX) { + +auto* file = new wxFileDialog (this, wxT("Test"), wxT(""),wxT("")); +file->SetPosition(wxPoint(250,250)); +file->SetForegroundColour("white"); +}*/ + +/////////// Main Frame Content /////////// MyMainFrame::MyMainFrame() : wxFrame(nullptr, wxID_ANY, "BeamMP Launcher V3", wxDefaultPosition,wxDefaultSize, wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX) { @@ -355,7 +364,7 @@ MyMainFrame::MyMainFrame() : auto* HorizontalLine3 = new wxStaticLine(panel, wxID_ANY, wxPoint(10, 550), wxSize(950, 1)); //Account: - auto* bitmap = new wxBitmapButton(panel, 39, wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH)), wxPoint(20, 560), wxSize(45,45)); + auto* bitmap = new wxBitmapButton(panel, 1, wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH)), wxPoint(20, 560), wxSize(45,45)); if (isSignedIn()) bitmap->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH))); @@ -363,8 +372,8 @@ MyMainFrame::MyMainFrame() : bitmap->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH))); //Buttons: - auto btnSettings = new wxButton(panel, 40, wxT("Settings"), wxPoint(730,570), wxSize(110, 25)); - btnLaunch = new wxButton(panel, 41, wxT("Launch"), wxPoint(850,570), wxSize(110, 25)); + auto btnSettings = new wxButton(panel, 2, wxT("Settings"), wxPoint(730,570), wxSize(110, 25)); + btnLaunch = new wxButton(panel, 3, wxT("Launch"), wxPoint(850,570), wxSize(110, 25)); GetStats(); @@ -394,12 +403,12 @@ MyMainFrame::MyMainFrame() : HorizontalLine3->SetForegroundColour("white"); //Logo: - auto* logo = new wxBitmapButton(panel, 42, wxBitmapBundle(wxImage("icons/BeamMP_white.png", wxBITMAP_TYPE_PNG).Scale(100,100, wxIMAGE_QUALITY_HIGH)), wxPoint(850, -15), wxSize(100,100), wxBORDER_NONE); + auto* logo = new wxBitmapButton(panel, 4, wxBitmapBundle(wxImage("icons/BeamMP_white.png", wxBITMAP_TYPE_PNG).Scale(100,100, wxIMAGE_QUALITY_HIGH)), wxPoint(850, -15), wxSize(100,100), wxBORDER_NONE); logo->SetBackgroundColour(wxColour(40, 40, 40)); } else { //Logo: - auto* logo = new wxBitmapButton(panel, 42, wxBitmapBundle(wxImage("icons/BeamMP_black.png", wxBITMAP_TYPE_PNG).Scale(100,100, wxIMAGE_QUALITY_HIGH)), wxPoint(850, -15), wxSize(100,100), wxBORDER_NONE); + auto* logo = new wxBitmapButton(panel, 4, wxBitmapBundle(wxImage("icons/BeamMP_black.png", wxBITMAP_TYPE_PNG).Scale(100,100, wxIMAGE_QUALITY_HIGH)), wxPoint(850, -15), wxSize(100,100), wxBORDER_NONE); logo->SetBackgroundColour("white"); } txtStatusResult->SetForegroundColour("green"); @@ -413,13 +422,14 @@ MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", wxImage::AddHandler(handler); wxStaticBitmap *image; image = new wxStaticBitmap( this, wxID_ANY, wxBitmapBundle(wxImage("icons/BeamMP_black.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH)), wxPoint(180,20), wxSize(120, 120)); + auto* panel = new wxPanel(this, wxID_ANY, wxPoint(), wxSize(500,650)); if (isSignedIn()) { image->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH))); - auto* txtName = new wxStaticText(this, wxID_ANY, wxT("Username: BeamMP"), wxPoint(180, 200)); - auto* txtEmail = new wxStaticText(this, wxID_ANY, wxT("Email: beamMP@gmail.com"), wxPoint(180, 250)); - auto btnLogout = new wxButton(this, 44, wxT("Logout"), wxPoint(185,550), wxSize(110, 25)); + auto* txtName = new wxStaticText(panel, wxID_ANY, wxT("Username: BeamMP"), wxPoint(180, 200)); + auto* txtEmail = new wxStaticText(panel, wxID_ANY, wxT("Email: beamMP@gmail.com"), wxPoint(180, 250)); + auto btnLogout = new wxButton(panel, 100, wxT("Logout"), wxPoint(185,550), wxSize(110, 25)); //UI Colors: if (DarkMode) { @@ -429,7 +439,6 @@ MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", } } else { - auto* panel = new wxPanel(this, wxID_ANY, wxPoint(), wxSize(500,650)); image->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH))); auto* txtLogin = new wxStaticText(panel, wxID_ANY, wxT("Login with your BeamMP account."), wxPoint(150, 200)); @@ -439,8 +448,8 @@ MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", ctrlUsername->SetHint("Username / Email"); ctrlPassword->SetHint("Password"); - auto btnLogin = new wxButton(panel, wxID_ANY, wxT("Login"), wxPoint(120,375), wxSize(110, 25)); - auto btnRegister = new wxButton(panel, 43, wxT("Register"), wxPoint(250,375), wxSize(110, 25)); + auto btnRegister = new wxButton(panel, 101, wxT("Register"), wxPoint(250,375), wxSize(110, 25)); + auto btnLogin = new wxButton(panel, 102, wxT("Login"), wxPoint(120,375), wxSize(110, 25)); //UI Colors: if (DarkMode) { @@ -457,20 +466,20 @@ MySettingsFrame::MySettingsFrame() : auto* panel = new wxPanel(this, wxID_ANY, wxPoint(), wxSize(500,650)); auto* txtGameDirectory = new wxStaticText(panel, wxID_ANY, wxT("Game Directory: "), wxPoint(30, 100)); - ctrlGameDirectory = new wxDirPickerCtrl (panel, 46, wxEmptyString, wxT("Game Directory"), wxPoint(130, 100), wxSize(300,-1)); + ctrlGameDirectory = new wxDirPickerCtrl (panel, 200, wxEmptyString, wxT("Game Directory"), wxPoint(130, 100), wxSize(300,-1)); ctrlGameDirectory->SetLabel("GamePath"); MySettingsFrame::SetFocus(); - auto btnDetectGameDirectory = new wxButton(panel, 10, wxT("Detect"), wxPoint(185,140), wxSize(90, 25)); + auto btnDetectGameDirectory = new wxButton(panel, 201, wxT("Detect"), wxPoint(185,140), wxSize(90, 25)); 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, 200, wxEmptyString, wxT("Profile Directory"), wxPoint(130, 200), wxSize(300,-1)); ctrlProfileDirectory->SetLabel("ProfilePath"); - auto btnDetectProfileDirectory = new wxButton(panel, 11, wxT("Detect"), wxPoint(185,240), wxSize(90, 25)); + auto btnDetectProfileDirectory = new wxButton(panel, 202, wxT("Detect"), wxPoint(185,240), wxSize(90, 25)); 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, 200, wxEmptyString, wxT("Cache Directory"), wxPoint(130, 300), wxSize(300,-1)); ctrlCacheDirectory->SetLabel("CachePath"); - auto btnCacheDirectory = new wxButton(panel, 12, wxT("Reset"), wxPoint(185,340), wxSize(90, 25)); + auto btnCacheDirectory = new wxButton(panel, 203, wxT("Reset"), wxPoint(185,340), wxSize(90, 25)); auto* txtBuild = new wxStaticText(panel, wxID_ANY, wxT("Build: "), wxPoint(30, 400)); wxArrayString BuildChoices; @@ -478,10 +487,10 @@ MySettingsFrame::MySettingsFrame() : BuildChoices.Add("Release"); BuildChoices.Add("EA"); BuildChoices.Add("Dev"); - choiceController = new wxChoice (panel, 47, wxPoint(85, 400), wxSize(120, 20), BuildChoices); + choiceController = new wxChoice (panel, 204, wxPoint(85, 400), wxSize(120, 20), BuildChoices); choiceController->Select(0); - checkConsole = new wxCheckBox (panel, 45, " Show Console", wxPoint(30, 450)); + checkConsole = new wxCheckBox (panel, 205, " Show Console", wxPoint(30, 450)); //UI Colors: if (DarkMode) { @@ -531,13 +540,6 @@ void MyMainFrame::GameVersionLabel() { } } -/////////// Update Game Directory Function /////////// -void MySettingsFrame::UpdateGameDirectory(const std::string& path) { - ctrlGameDirectory->SetPath(path); - UIData::GamePath = path; - MyMainFrame::GameVersionLabel(); -} - /////////// OnClick Account Event /////////// void MyMainFrame::OnClickAccount(wxCommandEvent& event WXUNUSED(event)) { auto* AccountFrame = new MyAccountFrame(); @@ -573,23 +575,6 @@ void MyMainFrame::OnClickSettings(wxCommandEvent& event WXUNUSED(event)) { } SettingsFrame->UpdateInfo(); SettingsFrame->Show(true); -} - -/////////// OnClick Logo Event /////////// -void MyMainFrame::OnClickLogo(wxCommandEvent& event WXUNUSED(event)) { - wxLaunchDefaultApplication("https://beammp.com"); -} - -/////////// OnClick Register Event /////////// -void MyAccountFrame::OnClickRegister(wxCommandEvent& event WXUNUSED(event)) { - wxLaunchDefaultApplication("https://forum.beammp.com/signup"); -} - -/////////// OnClick Logout Event /////////// -void MyAccountFrame::OnClickLogout(wxCommandEvent& event WXUNUSED(event)) { - - - } /////////// OnClick Launch Event /////////// @@ -611,6 +596,30 @@ void MyMainFrame::OnClickLaunch(wxCommandEvent& event WXUNUSED(event)) { wxMessageBox("Please launch BeamNG.drive manually in case of Steam issues.", "Alert"); FirstTime = false; } +} + +/////////// OnClick Logo Event /////////// +void MyMainFrame::OnClickLogo(wxCommandEvent& event WXUNUSED(event)) { + wxLaunchDefaultApplication("https://beammp.com"); +} + +/////////// OnClick Register Event /////////// +void MyAccountFrame::OnClickRegister(wxCommandEvent& event WXUNUSED(event)) { + wxLaunchDefaultApplication("https://forum.beammp.com/signup"); +} + +/////////// OnClick Login Event /////////// +void MyAccountFrame::OnClickLogin(wxCommandEvent& event WXUNUSED(event)) { + + + +} + +/////////// OnClick Logout Event /////////// +void MyAccountFrame::OnClickLogout(wxCommandEvent& event WXUNUSED(event)) { + + + } /////////// OnClick Console Event /////////// From 1d5dc1e5458a8fb3c82bca2b4b31c6187bce5130 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Tue, 16 Aug 2022 17:16:18 +0300 Subject: [PATCH 06/10] add login and logout logic --- include/Launcher.h | 4 +- src/Launcher.cpp | 1 - src/Network/HttpAPI.cpp | 2 + src/gui/Gui.cpp | 144 +++++++++++++++++++++++++++++++--------- 4 files changed, 116 insertions(+), 35 deletions(-) diff --git a/include/Launcher.h b/include/Launcher.h index c85fddf..c93a21e 100644 --- a/include/Launcher.h +++ b/include/Launcher.h @@ -102,9 +102,11 @@ class ShutdownException : public std::runtime_error { }; struct UIData { - static inline std::string GamePath, ProfilePath, CachePath; + static inline std::string GamePath, ProfilePath, CachePath, PublicKey, UserRole, Username; + static inline bool LoginAuth{false}; }; +void UpdateKey(const std::string& newKey); void entry(); diff --git a/src/Launcher.cpp b/src/Launcher.cpp index 467f416..2f1b35e 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -28,7 +28,6 @@ Launcher::Launcher() : Exit.store(false); Launcher::StaticAbort(this); DiscordTime = std::time(nullptr); - Log::Init(); WindowsInit(); SetUnhandledExceptionFilter(CrashHandler); LOG(INFO) << "Starting Launcher V" << FullVersion; diff --git a/src/Network/HttpAPI.cpp b/src/Network/HttpAPI.cpp index 32293c9..3a1474f 100644 --- a/src/Network/HttpAPI.cpp +++ b/src/Network/HttpAPI.cpp @@ -23,10 +23,12 @@ std::string HTTP::Get(const std::string& IP) { httplib::Client cli(IP.substr(0, pos)); CliRef.store(&cli); cli.set_connection_timeout(std::chrono::seconds(5)); + cli.set_follow_location(true); auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar); std::string Ret; if (res.error() == httplib::Error::Success) { + LOG(INFO) << res->status; if (res->status == 200) { Ret = res->body; } else LOG(ERROR) << res->reason; diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index e5dc576..70f6a76 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include "Json.h" #include "Launcher.h" #include "Logger.h" #include "HttpAPI.h" @@ -42,11 +42,28 @@ class MyApp : public wxApp { //static inline MyTestFrame* TestFrame; }; +/////////// AccountFrame class /////////// +class MyAccountFrame : public wxFrame { + public: + MyAccountFrame(); + + private: + static inline wxTextCtrl* ctrlUsername, *ctrlPassword; + bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); + void OnClickRegister(wxCommandEvent& event); + void OnClickLogout(wxCommandEvent& event); + void OnClickLogin(wxCommandEvent& event); + wxDECLARE_EVENT_TABLE(); +}; + /////////// MainFrame class /////////// class MyMainFrame : public wxFrame { public: MyMainFrame(); static void GameVersionLabel(); + static inline MyAccountFrame* AccountFrame; + static inline MyMainFrame* MainFrameInstance; + void OnClickAccount(wxCommandEvent& event); private: wxStaticText* txtStatusResult; @@ -56,26 +73,12 @@ class MyMainFrame : public wxFrame { bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); void GetStats(); - void OnClickAccount(wxCommandEvent& event); void OnClickSettings(wxCommandEvent& event); void OnClickLaunch(wxCommandEvent& event); void OnClickLogo(wxCommandEvent& event); wxDECLARE_EVENT_TABLE(); }; -/////////// AccountFrame class /////////// -class MyAccountFrame : public wxFrame { - public: - MyAccountFrame(); - - private: - bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); - void OnClickRegister(wxCommandEvent& event); - void OnClickLogout(wxCommandEvent& event); - void OnClickLogin(wxCommandEvent& event); - wxDECLARE_EVENT_TABLE(); -}; - /////////// SettingsFrame class /////////// class MySettingsFrame : public wxFrame { public: @@ -203,10 +206,80 @@ void LoadConfig() { } } +/////////// Login Function /////////// +bool Login(const std::string& fields) { + if (fields == "LO") { + UIData::LoginAuth = false; + UpdateKey(""); + return false; + } + std::string Buffer = HTTP::Post("https://auth.beammp.com/userlogin", fields); + Json d = Json::parse(Buffer, nullptr, false); + + if (Buffer == "-1") { + wxMessageBox("Failed to communicate with the auth system!", "Error"); + return false; + } + + if (Buffer.at(0) != '{' || d.is_discarded()) { + wxMessageBox( + "Invalid answer from authentication servers, please try again later!", + "Error"); + return false; + } + + if (!d["success"].is_null() && d["success"].get()) { + UIData::LoginAuth = true; + if (!d["private_key"].is_null()) { + UpdateKey(d["private_key"].get()); + } + if (!d["public_key"].is_null()) { + UIData::PublicKey = d["public_key"].get(); + } + if (!d["username"].is_null()) { + UIData::Username = d["username"].get(); + } + return true; + } else if (!d["message"].is_null()) wxMessageBox(d["message"].get(), "Error"); + return false; +} + +/////////// Check Key Function /////////// +void CheckKey() { + if (fs::exists("key") && fs::file_size("key") < 100) { + std::ifstream Key("key"); + if (Key.is_open()) { + auto Size = fs::file_size("key"); + std::string Buffer(Size, 0); + Key.read(&Buffer[0], std::streamsize(Size)); + Key.close(); + + Buffer = HTTP::Post("https://auth.beammp.com/userlogin", + R"({"pk":")" + Buffer + "\"}"); + + Json d = Json::parse(Buffer, nullptr, false); + if (Buffer == "-1" || Buffer.at(0) != '{' || d.is_discarded()) { + wxMessageBox( "Couldn't connect to auth server, you might be offline!", "Warning", wxICON_WARNING); + return; + } + if (d["success"].get()) { + UIData::LoginAuth = true; + UpdateKey(d["private_key"].get()); + UIData::PublicKey = d["public_key"].get(); + UIData::UserRole = d["role"].get(); + UIData::Username = d["username"].get(); + } else UpdateKey(""); + } else UpdateKey(""); + } else UpdateKey(""); +} + /////////// OnInit Function /////////// bool MyApp::OnInit() { + Log::Init(); LoadConfig(); + CheckKey(); auto* MainFrame = new MyMainFrame(); + MyMainFrame::MainFrameInstance = MainFrame; MainFrame->SetIcon(wxIcon("icons/BeamMP_black.png",wxBITMAP_TYPE_PNG)); // Set MainFrame properties: @@ -244,10 +317,6 @@ bool MyApp::OnInit() { return true; } -bool isSignedIn () { - return false; -} - /////////// Windows Console Function /////////// void WindowsConsole (bool isChecked) { if (isChecked) { @@ -366,10 +435,10 @@ MyMainFrame::MyMainFrame() : //Account: auto* bitmap = new wxBitmapButton(panel, 1, wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH)), wxPoint(20, 560), wxSize(45,45)); - if (isSignedIn()) - bitmap->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH))); + if (UIData::LoginAuth && fs::exists( "icons/" + UIData::Username + ".png")) + bitmap->SetBitmap(wxBitmapBundle(wxImage( "icons/" + UIData::Username + ".png", wxBitmapType (wxBITMAP_TYPE_PNG | wxBITMAP_TYPE_JPEG)).Scale(45, 45, wxIMAGE_QUALITY_HIGH))); else - bitmap->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH))); + bitmap->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH))); //Buttons: auto btnSettings = new wxButton(panel, 2, wxT("Settings"), wxPoint(730,570), wxSize(110, 25)); @@ -424,18 +493,19 @@ MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", image = new wxStaticBitmap( this, wxID_ANY, wxBitmapBundle(wxImage("icons/BeamMP_black.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH)), wxPoint(180,20), wxSize(120, 120)); auto* panel = new wxPanel(this, wxID_ANY, wxPoint(), wxSize(500,650)); - if (isSignedIn()) { - image->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH))); + if (UIData::LoginAuth) { + if (fs::exists( "icons/" + UIData::Username + ".png")) + image->SetBitmap(wxBitmapBundle(wxImage( "icons/" + UIData::Username + ".png", wxBITMAP_TYPE_PNG).Scale(120, 120, wxIMAGE_QUALITY_HIGH))); + else + image->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH))); - auto* txtName = new wxStaticText(panel, wxID_ANY, wxT("Username: BeamMP"), wxPoint(180, 200)); - auto* txtEmail = new wxStaticText(panel, wxID_ANY, wxT("Email: beamMP@gmail.com"), wxPoint(180, 250)); + auto* txtName = new wxStaticText(panel, wxID_ANY, wxT("Username: " + UIData::Username), wxPoint(180, 200)); auto btnLogout = new wxButton(panel, 100, wxT("Logout"), wxPoint(185,550), wxSize(110, 25)); //UI Colors: if (DarkMode) { //Text: txtName->SetForegroundColour("white"); - txtEmail->SetForegroundColour("white"); } } else { @@ -443,8 +513,8 @@ MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", auto* txtLogin = new wxStaticText(panel, wxID_ANY, wxT("Login with your BeamMP account."), wxPoint(150, 200)); - auto* ctrlUsername = new wxTextCtrl (panel, wxID_ANY, wxT(""), wxPoint(131, 230), wxSize(220,25)); - auto* ctrlPassword = new wxTextCtrl (panel, wxID_ANY, wxT(""), wxPoint(131, 300), wxSize(220,25), wxTE_PASSWORD); + ctrlUsername = new wxTextCtrl (panel, wxID_ANY, wxT(""), wxPoint(131, 230), wxSize(220,25)); + ctrlPassword = new wxTextCtrl (panel, wxID_ANY, wxT(""), wxPoint(131, 300), wxSize(220,25), wxTE_PASSWORD); ctrlUsername->SetHint("Username / Email"); ctrlPassword->SetHint("Password"); @@ -542,7 +612,7 @@ void MyMainFrame::GameVersionLabel() { /////////// OnClick Account Event /////////// void MyMainFrame::OnClickAccount(wxCommandEvent& event WXUNUSED(event)) { - auto* AccountFrame = new MyAccountFrame(); + AccountFrame = new MyAccountFrame(); AccountFrame->SetSize(500, 650); AccountFrame->Center(); AccountFrame->SetIcon(wxIcon("icons/BeamMP_black.png",wxBITMAP_TYPE_PNG)); @@ -611,15 +681,23 @@ void MyAccountFrame::OnClickRegister(wxCommandEvent& event WXUNUSED(event)) { /////////// OnClick Login Event /////////// void MyAccountFrame::OnClickLogin(wxCommandEvent& event WXUNUSED(event)) { + Json json; + json ["password"] = ctrlPassword->GetValue().utf8_string(); + json ["username"] = ctrlUsername->GetValue().utf8_string(); + if (Login(json.dump())) { + HTTP::Download("https://forum.beammp.com/user_avatar/forum.beammp.com/" + UIData::Username + "/240/4411_2.png", "icons/" + UIData::Username + ".png"); + MyMainFrame::AccountFrame->Destroy(); + MyMainFrame::MainFrameInstance->OnClickAccount(event); + } } /////////// OnClick Logout Event /////////// void MyAccountFrame::OnClickLogout(wxCommandEvent& event WXUNUSED(event)) { - - - + Login("LO"); + MyMainFrame::AccountFrame->Destroy(); + MyMainFrame::MainFrameInstance->OnClickAccount(event); } /////////// OnClick Console Event /////////// From b9a2572b72ac8ea084518971c4e7b174d6cc5b2c Mon Sep 17 00:00:00 2001 From: Sam39 Date: Thu, 18 Aug 2022 11:23:11 +0300 Subject: [PATCH 07/10] fix profile picture on login and logout --- src/Network/HttpAPI.cpp | 1 - src/gui/Gui.cpp | 55 ++++++++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/Network/HttpAPI.cpp b/src/Network/HttpAPI.cpp index 3a1474f..793a7ab 100644 --- a/src/Network/HttpAPI.cpp +++ b/src/Network/HttpAPI.cpp @@ -28,7 +28,6 @@ std::string HTTP::Get(const std::string& IP) { std::string Ret; if (res.error() == httplib::Error::Success) { - LOG(INFO) << res->status; if (res->status == 200) { Ret = res->body; } else LOG(ERROR) << res->reason; diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index 70f6a76..9ad7e6f 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -63,6 +63,7 @@ class MyMainFrame : public wxFrame { static void GameVersionLabel(); static inline MyAccountFrame* AccountFrame; static inline MyMainFrame* MainFrameInstance; + wxBitmapButton* BitAccount; void OnClickAccount(wxCommandEvent& event); private: @@ -359,6 +360,27 @@ std::string jsonRead () { return ""; } +/////////// Picture Type Function /////////// +// JPG 0 / PNG 1 +std::string PictureType (const std::string& picture) { + for (int i = 0; i < 15; i++) { + if(picture[i] == 'J') + return ".jpg"; + else if (picture[i] == 'P' && picture[i+1] == 'N') + return ".png"; + } + return ""; +} + +/////////// Get Picture Name Function /////////// +std::string GetPictureName () { + for (const auto& entry : fs::recursive_directory_iterator("icons")) { + if (entry.path().filename().string().find(UIData::Username) != std::string::npos) { + return entry.path().string(); + } + } +} + /////////// TestFrame Function /////////// /*MyTestFrame::MyTestFrame() : wxFrame(nullptr, wxID_ANY, "BeamMP Launcher V3", wxDefaultPosition,wxDefaultSize, @@ -383,10 +405,6 @@ MyMainFrame::MyMainFrame() : auto* HorizontalLine1 = new wxStaticLine(panel, wxID_ANY, wxPoint(10, 60), wxSize(950, 1)); auto* HorizontalLine2 = new wxStaticLine(panel, wxID_ANY, wxPoint(10, 480), wxSize(950, 1)); - //PNG Handler: - auto *handler = new wxPNGHandler; - wxImage::AddHandler(handler); - //Hyperlinks: auto* HyperForum = new wxHyperlinkCtrl(panel, wxID_ANY, wxT("Forum"), wxT("https://forum.beammp.com"), wxPoint(10, 10)); auto* txtSeparator1 = new wxStaticText(panel, wxID_ANY, wxT("|"), wxPoint(55, 10)); @@ -432,13 +450,15 @@ MyMainFrame::MyMainFrame() : auto* HorizontalLine3 = new wxStaticLine(panel, wxID_ANY, wxPoint(10, 550), wxSize(950, 1)); - //Account: - auto* bitmap = new wxBitmapButton(panel, 1, wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH)), wxPoint(20, 560), wxSize(45,45)); + wxInitAllImageHandlers(); - if (UIData::LoginAuth && fs::exists( "icons/" + UIData::Username + ".png")) - bitmap->SetBitmap(wxBitmapBundle(wxImage( "icons/" + UIData::Username + ".png", wxBitmapType (wxBITMAP_TYPE_PNG | wxBITMAP_TYPE_JPEG)).Scale(45, 45, wxIMAGE_QUALITY_HIGH))); + //Account: + BitAccount = new wxBitmapButton(panel, 1, wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH)), wxPoint(20, 560), wxSize(45,45)); + std::string PictureString = GetPictureName(); + if (UIData::LoginAuth && fs::exists( PictureString)) + BitAccount->SetBitmap(wxBitmapBundle(wxImage( PictureString).Scale(45, 45, wxIMAGE_QUALITY_HIGH))); else - bitmap->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH))); + BitAccount->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45,45, wxIMAGE_QUALITY_HIGH))); //Buttons: auto btnSettings = new wxButton(panel, 2, wxT("Settings"), wxPoint(730,570), wxSize(110, 25)); @@ -492,10 +512,10 @@ MyAccountFrame::MyAccountFrame() : wxFrame(nullptr, wxID_ANY, "Account Manager", wxStaticBitmap *image; image = new wxStaticBitmap( this, wxID_ANY, wxBitmapBundle(wxImage("icons/BeamMP_black.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH)), wxPoint(180,20), wxSize(120, 120)); auto* panel = new wxPanel(this, wxID_ANY, wxPoint(), wxSize(500,650)); - + std::string PictureString = GetPictureName(); if (UIData::LoginAuth) { - if (fs::exists( "icons/" + UIData::Username + ".png")) - image->SetBitmap(wxBitmapBundle(wxImage( "icons/" + UIData::Username + ".png", wxBITMAP_TYPE_PNG).Scale(120, 120, wxIMAGE_QUALITY_HIGH))); + if (fs::exists( PictureString)) + image->SetBitmap(wxBitmapBundle(wxImage( PictureString).Scale(120, 120, wxIMAGE_QUALITY_HIGH))); else image->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(120,120, wxIMAGE_QUALITY_HIGH))); @@ -680,23 +700,28 @@ void MyAccountFrame::OnClickRegister(wxCommandEvent& event WXUNUSED(event)) { /////////// OnClick Login Event /////////// void MyAccountFrame::OnClickLogin(wxCommandEvent& event WXUNUSED(event)) { - Json json; json ["password"] = ctrlPassword->GetValue().utf8_string(); json ["username"] = ctrlUsername->GetValue().utf8_string(); if (Login(json.dump())) { - HTTP::Download("https://forum.beammp.com/user_avatar/forum.beammp.com/" + UIData::Username + "/240/4411_2.png", "icons/" + UIData::Username + ".png"); + std::string picture = HTTP::Get("https://forum.beammp.com/user_avatar/forum.beammp.com/" + UIData::Username + "/240/4411_2.png"); + std::ofstream File("icons/" + UIData::Username + PictureType(picture), std::ios::binary); + if (File.is_open()) { + File << picture; + File.close(); + MyMainFrame::MainFrameInstance->BitAccount->SetBitmap(wxBitmapBundle(wxImage(GetPictureName()).Scale(45, 45, wxIMAGE_QUALITY_HIGH))); + } MyMainFrame::AccountFrame->Destroy(); MyMainFrame::MainFrameInstance->OnClickAccount(event); } - } /////////// OnClick Logout Event /////////// void MyAccountFrame::OnClickLogout(wxCommandEvent& event WXUNUSED(event)) { Login("LO"); MyMainFrame::AccountFrame->Destroy(); + MyMainFrame::MainFrameInstance->BitAccount->SetBitmap(wxBitmapBundle(wxImage("icons/default.png", wxBITMAP_TYPE_PNG).Scale(45, 45, wxIMAGE_QUALITY_HIGH))); MyMainFrame::MainFrameInstance->OnClickAccount(event); } From ee99246428357a38c255c7aa02e906c1055d0b30 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Thu, 18 Aug 2022 15:10:19 +0300 Subject: [PATCH 08/10] fix game path accidentally linked to profile and cache path --- src/gui/Gui.cpp | 100 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index 9ad7e6f..fadc806 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -86,6 +86,8 @@ class MySettingsFrame : public wxFrame { MySettingsFrame(); void UpdateInfo(); void UpdateGameDirectory(const std::string& path); + void UpdateProfileDirectory(const std::string& path); + void UpdateCacheDirectory(const std::string& path); private: wxDirPickerCtrl* ctrlGameDirectory, *ctrlProfileDirectory, *ctrlCacheDirectory; @@ -96,6 +98,8 @@ class MySettingsFrame : public wxFrame { void OnClickConsole(wxCommandEvent& event); void OnChangedGameDir (wxFileDirPickerEvent& event); + void OnChangedProfileDir (wxFileDirPickerEvent& event); + void OnChangedCacheDir (wxFileDirPickerEvent& event); void OnChangedBuild (wxCommandEvent& event); void OnAutoDetectGame(wxCommandEvent& event); void OnAutoDetectProfile(wxCommandEvent& event); @@ -106,31 +110,33 @@ class MySettingsFrame : public wxFrame { /////////// Event Tables /////////// //MainFrame (ID range 1 to 99): wxBEGIN_EVENT_TABLE(MyMainFrame, wxFrame) - EVT_BUTTON(1, MyMainFrame::OnClickAccount) - EVT_BUTTON(2, MyMainFrame::OnClickSettings) - EVT_BUTTON(3, MyMainFrame::OnClickLaunch) - EVT_BUTTON(4, MyMainFrame::OnClickLogo) -wxEND_EVENT_TABLE() + EVT_BUTTON(1, MyMainFrame::OnClickAccount) + EVT_BUTTON(2, MyMainFrame::OnClickSettings) + EVT_BUTTON(3, MyMainFrame::OnClickLaunch) + EVT_BUTTON(4, MyMainFrame::OnClickLogo) + wxEND_EVENT_TABLE() -//AccountFrame (ID range 100 to 199): -wxBEGIN_EVENT_TABLE(MyAccountFrame, wxFrame) - EVT_BUTTON(100, MyAccountFrame::OnClickLogout) - EVT_BUTTON(101, MyAccountFrame::OnClickRegister) - EVT_BUTTON(102, MyAccountFrame::OnClickLogin) -wxEND_EVENT_TABLE() + //AccountFrame (ID range 100 to 199): + wxBEGIN_EVENT_TABLE(MyAccountFrame, wxFrame) + EVT_BUTTON(100, MyAccountFrame::OnClickLogout) + EVT_BUTTON(101, MyAccountFrame::OnClickRegister) + EVT_BUTTON(102, MyAccountFrame::OnClickLogin) + wxEND_EVENT_TABLE() -//SettingsFrame (ID range 200 to 299): -wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame) - EVT_DIRPICKER_CHANGED(200, MySettingsFrame::OnChangedGameDir) - EVT_BUTTON(201, MySettingsFrame::OnAutoDetectGame) - EVT_BUTTON(202, MySettingsFrame::OnAutoDetectProfile) - EVT_BUTTON(203, MySettingsFrame::OnResetCache) - EVT_CHOICE(204, MySettingsFrame::OnChangedBuild) - EVT_CHECKBOX(205, MySettingsFrame::OnClickConsole) -wxEND_EVENT_TABLE() + //SettingsFrame (ID range 200 to 299): + wxBEGIN_EVENT_TABLE(MySettingsFrame, wxFrame) + EVT_DIRPICKER_CHANGED(200, MySettingsFrame::OnChangedGameDir) + EVT_DIRPICKER_CHANGED(201, MySettingsFrame::OnChangedProfileDir) + EVT_DIRPICKER_CHANGED(202, MySettingsFrame::OnChangedCacheDir) + EVT_BUTTON(203, MySettingsFrame::OnAutoDetectGame) + EVT_BUTTON(204, MySettingsFrame::OnAutoDetectProfile) + EVT_BUTTON(205, MySettingsFrame::OnResetCache) + EVT_CHOICE(206, MySettingsFrame::OnChangedBuild) + EVT_CHECKBOX(207, MySettingsFrame::OnClickConsole) + wxEND_EVENT_TABLE() -/////////// Get Stats Function /////////// -void MyMainFrame::GetStats () { + /////////// Get Stats Function /////////// + void MyMainFrame::GetStats () { std::string results = HTTP::Get("https://backend.beammp.com/stats_raw"); nlohmann::json jf = nlohmann::json::parse(results, nullptr, false); @@ -170,6 +176,18 @@ void MySettingsFrame::UpdateGameDirectory(const std::string& path) { MyMainFrame::GameVersionLabel(); } +/////////// Update Profile Directory Function /////////// +void MySettingsFrame::UpdateProfileDirectory(const std::string& path) { + ctrlProfileDirectory->SetPath(path); + UIData::ProfilePath = path; +} + +/////////// Update Cache Directory Function /////////// +void MySettingsFrame::UpdateCacheDirectory(const std::string& path) { + ctrlCacheDirectory->SetPath(path); + UIData::CachePath = path; +} + /////////// Load Config Function /////////// void LoadConfig() { if (fs::exists("Launcher.toml")) { @@ -559,17 +577,17 @@ MySettingsFrame::MySettingsFrame() : ctrlGameDirectory = new wxDirPickerCtrl (panel, 200, wxEmptyString, wxT("Game Directory"), wxPoint(130, 100), wxSize(300,-1)); ctrlGameDirectory->SetLabel("GamePath"); MySettingsFrame::SetFocus(); - auto btnDetectGameDirectory = new wxButton(panel, 201, wxT("Detect"), wxPoint(185,140), wxSize(90, 25)); + auto btnDetectGameDirectory = new wxButton(panel, 203, wxT("Detect"), wxPoint(185,140), wxSize(90, 25)); auto* txtProfileDirectory = new wxStaticText(panel, wxID_ANY, wxT("Profile Directory: "), wxPoint(30, 200)); - ctrlProfileDirectory = new wxDirPickerCtrl (panel, 200, wxEmptyString, wxT("Profile Directory"), wxPoint(130, 200), wxSize(300,-1)); + ctrlProfileDirectory = new wxDirPickerCtrl (panel, 201, wxEmptyString, wxT("Profile Directory"), wxPoint(130, 200), wxSize(300,-1)); ctrlProfileDirectory->SetLabel("ProfilePath"); - auto btnDetectProfileDirectory = new wxButton(panel, 202, wxT("Detect"), wxPoint(185,240), wxSize(90, 25)); + auto btnDetectProfileDirectory = new wxButton(panel, 204, wxT("Detect"), wxPoint(185,240), wxSize(90, 25)); auto* txtCacheDirectory = new wxStaticText(panel, wxID_ANY, wxT("Cache Directory: "), wxPoint(30, 300)); - ctrlCacheDirectory = new wxDirPickerCtrl (panel, 200, wxEmptyString, wxT("Cache Directory"), wxPoint(130, 300), wxSize(300,-1)); + ctrlCacheDirectory = new wxDirPickerCtrl (panel, 202, wxEmptyString, wxT("Cache Directory"), wxPoint(130, 300), wxSize(300,-1)); ctrlCacheDirectory->SetLabel("CachePath"); - auto btnCacheDirectory = new wxButton(panel, 203, wxT("Reset"), wxPoint(185,340), wxSize(90, 25)); + auto btnCacheDirectory = new wxButton(panel, 205, wxT("Reset"), wxPoint(185,340), wxSize(90, 25)); auto* txtBuild = new wxStaticText(panel, wxID_ANY, wxT("Build: "), wxPoint(30, 400)); wxArrayString BuildChoices; @@ -577,10 +595,10 @@ MySettingsFrame::MySettingsFrame() : BuildChoices.Add("Release"); BuildChoices.Add("EA"); BuildChoices.Add("Dev"); - choiceController = new wxChoice (panel, 204, wxPoint(85, 400), wxSize(120, 20), BuildChoices); + choiceController = new wxChoice (panel, 206, wxPoint(85, 400), wxSize(120, 20), BuildChoices); choiceController->Select(0); - checkConsole = new wxCheckBox (panel, 205, " Show Console", wxPoint(30, 450)); + checkConsole = new wxCheckBox (panel, 207, " Show Console", wxPoint(30, 450)); //UI Colors: if (DarkMode) { @@ -727,9 +745,9 @@ void MyAccountFrame::OnClickLogout(wxCommandEvent& event WXUNUSED(event)) { /////////// OnClick Console Event /////////// void MySettingsFrame::OnClickConsole(wxCommandEvent& event) { - WindowsConsole(checkConsole->IsChecked()); - bool status = event.IsChecked(); - UpdateConfig("Console", status); + WindowsConsole(checkConsole->IsChecked()); + bool status = event.IsChecked(); + UpdateConfig("Console", status); } /////////// OnChanged Game Path Event /////////// @@ -740,6 +758,22 @@ void MySettingsFrame::OnChangedGameDir(wxFileDirPickerEvent& event) { UpdateGameDirectory(NewPath); } +/////////// OnChanged Profile Path Event /////////// +void MySettingsFrame::OnChangedProfileDir(wxFileDirPickerEvent& event) { + std::string NewPath = event.GetPath().utf8_string(); + std::string key = reinterpret_cast (event.GetEventObject())->GetLabel(); + UpdateConfig(key, NewPath); + UpdateProfileDirectory(NewPath); +} + +/////////// OnChanged Cache Path Event /////////// +void MySettingsFrame::OnChangedCacheDir(wxFileDirPickerEvent& event) { + std::string NewPath = event.GetPath().utf8_string(); + std::string key = reinterpret_cast (event.GetEventObject())->GetLabel(); + UpdateConfig(key, NewPath); + UpdateCacheDirectory(NewPath); +} + /////////// OnChanged Build Event /////////// void MySettingsFrame::OnChangedBuild(wxCommandEvent& event) { std::string key = reinterpret_cast (event.GetEventObject())->GetString(event.GetSelection()); @@ -763,7 +797,7 @@ void MySettingsFrame::OnAutoDetectGame (wxCommandEvent& event) { UpdateGameDirectory(GamePath); } else - wxMessageBox("Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive", "Error"); + wxMessageBox("Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive", "Error"); } /////////// AutoDetect Profile Function /////////// From e9608e0f7e24fdf1db7647c2d2aa124d820fc3a5 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Thu, 18 Aug 2022 15:57:52 +0300 Subject: [PATCH 09/10] fix show console state not saving --- include/Launcher.h | 2 +- src/gui/Gui.cpp | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/Launcher.h b/include/Launcher.h index c93a21e..439d797 100644 --- a/include/Launcher.h +++ b/include/Launcher.h @@ -103,7 +103,7 @@ class ShutdownException : public std::runtime_error { struct UIData { static inline std::string GamePath, ProfilePath, CachePath, PublicKey, UserRole, Username; - static inline bool LoginAuth{false}; + static inline bool LoginAuth{false}, Console{false}; }; diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index fadc806..abd20dd 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -89,9 +89,10 @@ class MySettingsFrame : public wxFrame { void UpdateProfileDirectory(const std::string& path); void UpdateCacheDirectory(const std::string& path); + private: - wxDirPickerCtrl* ctrlGameDirectory, *ctrlProfileDirectory, *ctrlCacheDirectory; wxCheckBox* checkConsole; + wxDirPickerCtrl* ctrlGameDirectory, *ctrlProfileDirectory, *ctrlCacheDirectory; wxChoice* choiceController; bool DarkMode = wxSystemSettings::GetAppearance().IsDark(); @@ -167,6 +168,7 @@ void MySettingsFrame::UpdateInfo() { ctrlGameDirectory->SetPath(UIData::GamePath); ctrlProfileDirectory->SetPath(UIData::ProfilePath); ctrlCacheDirectory->SetPath(UIData::CachePath); + checkConsole->SetValue(UIData::Console); } /////////// Update Game Directory Function /////////// @@ -197,6 +199,7 @@ void LoadConfig() { auto GamePath = config["GamePath"]; auto ProfilePath = config["ProfilePath"]; auto CachePath = config["CachePath"]; + auto Console = config["Console"]; if (GamePath.is_string()) { UIData::GamePath = GamePath.as_string()->get(); @@ -210,6 +213,11 @@ void LoadConfig() { UIData::CachePath = CachePath.as_string()->get(); } else wxMessageBox("Cache path not found!", "Error"); + if (Console.is_boolean()) { + UIData::Console = Console.as_boolean()->get(); + wxMessageBox(std::to_string(UIData::Console), "DEBUG"); + } else wxMessageBox("Unable to retrieve console state!", "Error"); + } else { std::ofstream tml("Launcher.toml"); if (tml.is_open()) { @@ -292,11 +300,16 @@ void CheckKey() { } else UpdateKey(""); } +void WindowsConsole (bool isChecked); + /////////// OnInit Function /////////// bool MyApp::OnInit() { Log::Init(); LoadConfig(); CheckKey(); + + WindowsConsole(UIData::Console); + auto* MainFrame = new MyMainFrame(); MyMainFrame::MainFrameInstance = MainFrame; MainFrame->SetIcon(wxIcon("icons/BeamMP_black.png",wxBITMAP_TYPE_PNG)); @@ -748,6 +761,7 @@ void MySettingsFrame::OnClickConsole(wxCommandEvent& event) { WindowsConsole(checkConsole->IsChecked()); bool status = event.IsChecked(); UpdateConfig("Console", status); + UIData::Console = status; } /////////// OnChanged Game Path Event /////////// From 53fffdb80214cd198c2f4ffef7f7fc6ff4ae5280 Mon Sep 17 00:00:00 2001 From: Sam39 Date: Thu, 18 Aug 2022 16:18:39 +0300 Subject: [PATCH 10/10] fix build state not saving --- include/Launcher.h | 2 +- src/gui/Gui.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/Launcher.h b/include/Launcher.h index 439d797..2e16ee7 100644 --- a/include/Launcher.h +++ b/include/Launcher.h @@ -102,7 +102,7 @@ class ShutdownException : public std::runtime_error { }; struct UIData { - static inline std::string GamePath, ProfilePath, CachePath, PublicKey, UserRole, Username; + static inline std::string GamePath, ProfilePath, CachePath, Build, PublicKey, UserRole, Username; static inline bool LoginAuth{false}, Console{false}; diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index abd20dd..cf47ff8 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -169,6 +169,7 @@ void MySettingsFrame::UpdateInfo() { ctrlProfileDirectory->SetPath(UIData::ProfilePath); ctrlCacheDirectory->SetPath(UIData::CachePath); checkConsole->SetValue(UIData::Console); + choiceController->SetStringSelection(UIData::Build); } /////////// Update Game Directory Function /////////// @@ -195,7 +196,7 @@ void LoadConfig() { if (fs::exists("Launcher.toml")) { toml::parse_result config = toml::parse_file("Launcher.toml"); auto ui = config["UI"]; - auto build = config["Build"]; + auto Build = config["Build"]; auto GamePath = config["GamePath"]; auto ProfilePath = config["ProfilePath"]; auto CachePath = config["CachePath"]; @@ -215,9 +216,12 @@ void LoadConfig() { if (Console.is_boolean()) { UIData::Console = Console.as_boolean()->get(); - wxMessageBox(std::to_string(UIData::Console), "DEBUG"); } else wxMessageBox("Unable to retrieve console state!", "Error"); + if (Build.is_string()) { + UIData::Build = Build.as_string()->get(); + } else wxMessageBox("Unable to retrieve build state!", "Error"); + } else { std::ofstream tml("Launcher.toml"); if (tml.is_open()) { @@ -792,6 +796,7 @@ void MySettingsFrame::OnChangedCacheDir(wxFileDirPickerEvent& event) { void MySettingsFrame::OnChangedBuild(wxCommandEvent& event) { std::string key = reinterpret_cast (event.GetEventObject())->GetString(event.GetSelection()); UpdateConfig("Build", key); + UIData::Build = key; } /////////// AutoDetect Game Function ///////////