- reduce the amount of data required from the registry

- remove wxWidgets
- general cleanup
This commit is contained in:
Anonymous275 2022-12-19 20:41:45 +00:00
parent b436ef4b21
commit 9d01ae939a
9 changed files with 140 additions and 1090 deletions

View File

@ -15,17 +15,9 @@ if (WIN32)
set(VcpkgRoot ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}) set(VcpkgRoot ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET})
include_directories(${VcpkgRoot}/include) include_directories(${VcpkgRoot}/include)
link_directories(${VcpkgRoot}/lib) link_directories(${VcpkgRoot}/lib)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNICODE")
endif(WIN32) endif(WIN32)
set(wxUSE_STL ON)
set(BUILD_EXAMPLES OFF)
set(wxBUILD_SHARED OFF)
set(wxUSE_HTML ON)
set(wxUSE_STREAMS ON)
set(wxBUILD_MSVC_MULTIPROC ON)
set(wxBUILD_USE_STATIC_RUNTIME ON)
add_subdirectory(include/wxWidgets)
add_subdirectory(include/cpp-httplib) add_subdirectory(include/cpp-httplib)
add_subdirectory(include/tomlplusplus) add_subdirectory(include/tomlplusplus)
@ -33,7 +25,7 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
add_executable(${PROJECT_NAME} WIN32 add_executable(${PROJECT_NAME}
src/main.cpp include/easyloggingpp/src/easylogging++.cc src/main.cpp include/easyloggingpp/src/easylogging++.cc
src/Launcher.cpp include/Launcher.h include/Memory/Hook.h src/Launcher.cpp include/Launcher.h include/Memory/Hook.h
src/Memory/Definitions.cpp include/Memory/Definitions.h src/Memory/Definitions.cpp include/Memory/Definitions.h
@ -42,7 +34,7 @@ add_executable(${PROJECT_NAME} WIN32
src/Memory/GELua.cpp include/Memory/GELua.h src/Memory/GELua.cpp include/Memory/GELua.h
src/Memory/IPC.cpp include/Memory/IPC.h src/Memory/IPC.cpp include/Memory/IPC.h
src/Logger.cpp include/Logger.h src/Logger.cpp include/Logger.h
src/gui/Gui.cpp #src/gui/Gui.cpp
include/Json.h include/Json.h
src/Network/HttpAPI.cpp include/HttpAPI.h src/Network/HttpAPI.cpp include/HttpAPI.h
src/Network/Server.cpp include/Server.h src/Network/Server.cpp include/Server.h
@ -56,7 +48,6 @@ if (WIN32)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
target_link_libraries(${PROJECT_NAME} PRIVATE discord-rpc) target_link_libraries(${PROJECT_NAME} PRIVATE discord-rpc)
endif() endif()
target_link_libraries(${PROJECT_NAME} PRIVATE wx::net wx::html wx::webview wx::core wx::base)
target_link_libraries(${PROJECT_NAME} PRIVATE target_link_libraries(${PROJECT_NAME} PRIVATE
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32 ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32
Dbghelp comsuppw minhook::minhook nlohmann_json nlohmann_json::nlohmann_json) Dbghelp comsuppw minhook::minhook nlohmann_json nlohmann_json::nlohmann_json)

View File

@ -24,16 +24,16 @@ typedef HKEY__* HKEY;
class Launcher { class Launcher {
public: // constructors public: // constructors
Launcher(); Launcher(int argc, char* argv[]);
~Launcher(); ~Launcher();
public: // available functions public: // available functions
static void StaticAbort(Launcher* Instance = nullptr); static void StaticAbort(Launcher* Instance = nullptr);
std::string Login(const std::string& fields); std::string Login(const std::string& fields);
void SendIPC(const std::string& Data, bool core = true); void SendIPC(const std::string& Data, bool core = true);
void LoadConfig(const fs::path& conf);
void RunDiscordRPC(); void RunDiscordRPC();
void WaitForGame(); void WaitForGame();
void LoadConfig();
void LaunchGame(); void LaunchGame();
void CheckKey(); void CheckKey();
void SetupMOD(); void SetupMOD();
@ -53,6 +53,7 @@ class Launcher {
private: // functions private: // functions
void HandleIPC(const std::string& Data); void HandleIPC(const std::string& Data);
fs::path GetBeamNGProfile();
void UpdatePresence(); void UpdatePresence();
void RichPresence(); void RichPresence();
void WindowsInit(); void WindowsInit();
@ -63,16 +64,14 @@ class Launcher {
public: // variables public: // variables
static inline std::thread EntryThread{}; static inline std::thread EntryThread{};
static inline VersionParser SupportedVersion{"0.26.1.0"};
static inline std::string Version{"3.0"}; static inline std::string Version{"3.0"};
static inline std::string FullVersion{Version + ".0"}; static inline std::string FullVersion{Version + ".0"};
private: // variables private: // variables
uint32_t GamePID{0}; uint32_t GamePID{0};
bool EnableUI = true;
fs::path MPUserPath{}; fs::path MPUserPath{};
fs::path BeamUserPath{}; fs::path BeamUserPath{};
fs::path LauncherCache{}; fs::path LauncherCache{"Resources"};
int64_t DiscordTime{}; int64_t DiscordTime{};
bool LoginAuth = false; bool LoginAuth = false;
fs::path CurrentPath{}; fs::path CurrentPath{};
@ -97,10 +96,4 @@ class ShutdownException : public std::runtime_error {
runtime_error(message){}; runtime_error(message){};
}; };
struct UIData {
static inline std::string GamePath, ProfilePath, CachePath, Build, PublicKey, UserRole, Username, GameVer, ConfigPath;
static inline bool LoginAuth{false}, Console{false}, UI;
};
void UpdateKey(const std::string& newKey);
int entry();

View File

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

View File

@ -21,9 +21,10 @@ LONG WINAPI CrashHandler(EXCEPTION_POINTERS* p) {
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
} }
Launcher::Launcher() : Launcher::Launcher(int argc, char* argv[]) :
CurrentPath(std::filesystem::current_path()), CurrentPath(std::filesystem::current_path()),
DiscordMessage("Just launched") { DiscordMessage("Just launched") {
Log::Init();
Shutdown.store(false); Shutdown.store(false);
Exit.store(false); Exit.store(false);
Launcher::StaticAbort(this); Launcher::StaticAbort(this);
@ -31,6 +32,8 @@ Launcher::Launcher() :
WindowsInit(); WindowsInit();
SetUnhandledExceptionFilter(CrashHandler); SetUnhandledExceptionFilter(CrashHandler);
LOG(INFO) << "Starting Launcher V" << FullVersion; LOG(INFO) << "Starting Launcher V" << FullVersion;
if (argc > 1) LoadConfig(fs::current_path() / argv[1]);
else LoadConfig(fs::current_path() / "Launcher.toml");
} }
void Launcher::Abort() { void Launcher::Abort() {
@ -88,7 +91,7 @@ void Launcher::WindowsInit() {
} }
void Launcher::LaunchGame() { void Launcher::LaunchGame() {
VersionParser GameVersion(BeamVersion); /*VersionParser GameVersion(BeamVersion);
if (GameVersion.data[1] > SupportedVersion.data[1]) { if (GameVersion.data[1] > SupportedVersion.data[1]) {
LOG(FATAL) << "BeamNG V" << BeamVersion LOG(FATAL) << "BeamNG V" << BeamVersion
<< " not yet supported, please wait until we update BeamMP!"; << " not yet supported, please wait until we update BeamMP!";
@ -105,7 +108,9 @@ void Launcher::LaunchGame() {
LOG(WARNING) LOG(WARNING)
<< "BeamNG V" << BeamVersion << "BeamNG V" << BeamVersion
<< " is slightly older than recommended, this might cause issues!"; << " is slightly older than recommended, this might cause issues!";
} }*/
if (Memory::GetBeamNGPID({}) == 0) { if (Memory::GetBeamNGPID({}) == 0) {
if(Memory::GetLauncherPID({GetCurrentProcessId()}) != 0) { if(Memory::GetLauncherPID({GetCurrentProcessId()}) != 0) {
@ -225,5 +230,8 @@ const std::string& Launcher::getPublicKey() {
} }
const fs::path& Launcher::getCachePath() { const fs::path& Launcher::getCachePath() {
if (!fs::exists(LauncherCache)) {
fs::create_directories(LauncherCache);
}
return LauncherCache; return LauncherCache;
} }

View File

@ -13,7 +13,6 @@ void Log::Init() {
Conf.setGlobally(ConfigurationType::Format, Conf.setGlobally(ConfigurationType::Format,
"%datetime{[%d/%M/%y %H:%m:%s]} [%level] %msg"); "%datetime{[%d/%M/%y %H:%m:%s]} [%level] %msg");
Conf.setGlobally(ConfigurationType::LogFlushThreshold, "2"); Conf.setGlobally(ConfigurationType::LogFlushThreshold, "2");
Conf.setGlobally(ConfigurationType::ToStandardOutput, "false");
Conf.set(Level::Verbose, ConfigurationType::Format, DFormat); Conf.set(Level::Verbose, ConfigurationType::Format, DFormat);
Conf.set(Level::Debug, ConfigurationType::Format, DFormat); Conf.set(Level::Debug, ConfigurationType::Format, DFormat);
Conf.set(Level::Trace, ConfigurationType::Format, DFormat); Conf.set(Level::Trace, ConfigurationType::Format, DFormat);

View File

@ -87,16 +87,14 @@ bool HTTP::ProgressBar(size_t c, size_t t) {
if (isDownload) { if (isDownload) {
static double progress_bar_adv; static double progress_bar_adv;
progress_bar_adv = round(double(c) / double(t) * 25); progress_bar_adv = round(double(c) / double(t) * 25);
if (UIData::Console) { std::cout << "\r";
std::cout << "\r"; std::cout << "Progress: [ ";
std::cout << "Progress: [ "; std::cout << round(double(c) / double(t) * 100);
std::cout << round(double(c) / double(t) * 100); std::cout << "% ] [";
std::cout << "% ] ["; int i;
int i; for (i = 0; i <= progress_bar_adv; i++) std::cout << "#";
for (i = 0; i <= progress_bar_adv; i++) std::cout << "#"; for (i = 0; i < 25 - progress_bar_adv; i++) std::cout << ".";
for (i = 0; i < 25 - progress_bar_adv; i++) std::cout << "."; std::cout << "]";
std::cout << "]";
}
} }
if (Launcher::Terminated()) { if (Launcher::Terminated()) {
CliRef.load()->stop(); CliRef.load()->stop();
@ -117,9 +115,8 @@ bool HTTP::Download(const std::string& IP, const std::string& Path, DownloadProg
if (Ret.empty()) return false; if (Ret.empty()) return false;
if (UIData::Console) { std::cout << "\n";
std::cout << "\n";
}
std::ofstream File(Path, std::ios::binary); std::ofstream File(Path, std::ios::binary);
if (File.is_open()) { if (File.is_open()) {

View File

@ -31,11 +31,6 @@ std::vector<std::string> Split(const std::string& String,
return Val; return Val;
} }
void CheckForDir() {
if (!fs::exists("Resources")) {
_wmkdir(L"Resources");
}
}
void Server::WaitForConfirm() { void Server::WaitForConfirm() {
while (!Terminate && !ModLoaded) { while (!Terminate && !ModLoaded) {
@ -218,7 +213,7 @@ void Server::SyncResources() {
std::string Ret = Auth(); std::string Ret = Auth();
if (Ret.empty()) return; if (Ret.empty()) return;
LOG(INFO) << "Checking Resources..."; LOG(INFO) << "Checking Resources...";
CheckForDir();
std::vector<std::string> list = Split(Ret, ";"); std::vector<std::string> list = Split(Ret, ";");
std::vector<std::string> FNames(list.begin(), std::vector<std::string> FNames(list.begin(),
@ -281,7 +276,7 @@ void Server::SyncResources() {
continue; continue;
} else remove(a.c_str()); } else remove(a.c_str());
} }
CheckForDir();
std::string FName = a.substr(a.find_last_of("/\\")+1); std::string FName = a.substr(a.find_last_of("/\\")+1);
do { do {
TCPSend("f" + *FN); TCPSend("f" + *FN);

File diff suppressed because it is too large Load Diff

View File

@ -6,13 +6,11 @@
#include "Launcher.h" #include "Launcher.h"
#include "Logger.h" #include "Logger.h"
int entry() { int main(int argc, char* argv[]) {
try { try {
Launcher launcher; Launcher launcher(argc, argv);
launcher.RunDiscordRPC(); launcher.RunDiscordRPC();
launcher.LoadConfig(); // check if json (issue)
launcher.CheckKey(); launcher.CheckKey();
// UI call
// launcher.SetupMOD(); // launcher.SetupMOD();
launcher.LaunchGame(); launcher.LaunchGame();
launcher.WaitForGame(); launcher.WaitForGame();