From 3c96bb39594505b70e4d897a6547a96475b051a7 Mon Sep 17 00:00:00 2001 From: Anonymous275 <36374260+Anonymous-275@users.noreply.github.com> Date: Tue, 26 Jul 2022 11:43:45 +0300 Subject: [PATCH] clang format --- .clang-format | 41 +++ include/Compressor.h | 6 +- include/HttpAPI.h | 14 +- include/Launcher.h | 140 +++++----- include/Logger.h | 4 +- include/Memory/BeamNG.h | 36 +-- include/Memory/Definitions.h | 27 +- include/Memory/GELua.h | 65 ++--- include/Memory/Hook.h | 71 ++--- include/Memory/IPC.h | 49 ++-- include/Memory/Memory.h | 22 +- include/Memory/Patterns.h | 107 ++++---- include/Server.h | 120 ++++---- include/atomic_queue.h | 84 +++--- src/Config.cpp | 52 ++-- src/Discord.cpp | 68 ++--- src/Handler.cpp | 147 +++++----- src/Launcher.cpp | 378 +++++++++++++------------ src/Logger.cpp | 32 ++- src/Memory/BeamNG.cpp | 120 ++++---- src/Memory/Definitions.cpp | 2 +- src/Memory/GELua.cpp | 84 ++++-- src/Memory/IPC.cpp | 90 +++--- src/Memory/Memory.cpp | 180 ++++++------ src/Network/Compressor.cpp | 76 ++--- src/Network/HttpAPI.cpp | 191 +++++++------ src/Network/Login.cpp | 157 +++++------ src/Network/Resources.cpp | 509 +++++++++++++++++----------------- src/Network/Server.cpp | 519 +++++++++++++++++------------------ src/Network/Update.cpp | 211 +++++++------- src/gui/Gui.cpp | 97 ++++--- src/gui/gifs.cpp | 3 +- src/gui/gifs.h | 4 +- src/main.cpp | 38 +-- 34 files changed, 1912 insertions(+), 1832 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..9f9743a --- /dev/null +++ b/.clang-format @@ -0,0 +1,41 @@ +--- +BasedOnStyle: Google +AccessModifierOffset: 0 +AlignConsecutiveAssignments: Consecutive +AlignEscapedNewlines: Right +AlignTrailingComments: true +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: AllIfsAndElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeInheritanceComma: false +BreakConstructorInitializers: AfterColon +Cpp11BracedListStyle: true +DerivePointerAlignment: false +FixNamespaceComments: false +IncludeBlocks: Preserve +IndentCaseLabels: true +IndentWidth: 3 +IndentAccessModifiers: false +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: All +PointerAlignment: Left +ReflowComments: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesInAngles: Never +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Latest +TabWidth: 2 +UseTab: Never diff --git a/include/Compressor.h b/include/Compressor.h index 03d2fc4..dae46fd 100644 --- a/include/Compressor.h +++ b/include/Compressor.h @@ -7,7 +7,7 @@ #include class Zlib { -public: - static std::string DeComp(std::string Compressed); - static std::string Comp(std::string Data); + public: + static std::string DeComp(std::string Compressed); + static std::string Comp(std::string Data); }; \ No newline at end of file diff --git a/include/HttpAPI.h b/include/HttpAPI.h index 39f88f9..94fd5d1 100644 --- a/include/HttpAPI.h +++ b/include/HttpAPI.h @@ -7,12 +7,12 @@ #include class HTTP { -public: - static bool Download(const std::string& IP, const std::string& Path); - static std::string Post(const std::string& IP, const std::string& Fields); - static std::string Get(const std::string& IP); - static bool ProgressBar(size_t c, size_t t); + public: + static bool Download(const std::string& IP, const std::string& Path); + static std::string Post(const std::string& IP, const std::string& Fields); + static std::string Get(const std::string& IP); + static bool ProgressBar(size_t c, size_t t); -public: - static bool isDownload; + public: + static bool isDownload; }; \ No newline at end of file diff --git a/include/Launcher.h b/include/Launcher.h index 6615411..1b43f27 100644 --- a/include/Launcher.h +++ b/include/Launcher.h @@ -4,90 +4,90 @@ /// #pragma once -#include "Memory/IPC.h" -#include "Server.h" #include #include +#include "Memory/IPC.h" +#include "Server.h" namespace fs = std::filesystem; struct VersionParser { - explicit VersionParser(const std::string& from_string); - std::strong_ordering operator<=>(VersionParser const& rhs) const noexcept; - bool operator==(VersionParser const& rhs) const noexcept; - std::vector split; - std::vector data; + explicit VersionParser(const std::string& from_string); + std::strong_ordering operator<=>(VersionParser const& rhs) const noexcept; + bool operator==(VersionParser const& rhs) const noexcept; + std::vector split; + std::vector data; }; class Launcher { -public: // constructors - Launcher(int argc, char* argv[]); - ~Launcher(); + public: // constructors + Launcher(int argc, char* argv[]); + ~Launcher(); -public: // available functions - static void StaticAbort(Launcher* Instance = nullptr); - std::string Login(const std::string& fields); - void SendIPC(const std::string& Data, bool core = true); - void RunDiscordRPC(); - void QueryRegistry(); - void WaitForGame(); - void LoadConfig(); - void LaunchGame(); - void CheckKey(); - void SetupMOD(); + public: // available functions + static void StaticAbort(Launcher* Instance = nullptr); + std::string Login(const std::string& fields); + void SendIPC(const std::string& Data, bool core = true); + void RunDiscordRPC(); + void QueryRegistry(); + void WaitForGame(); + void LoadConfig(); + void LaunchGame(); + void CheckKey(); + void SetupMOD(); -public: // Getters and Setters - void setDiscordMessage(const std::string& message); - static void setExit(bool exit) noexcept; - const std::string& getFullVersion(); - const std::string& getMPUserPath(); - static bool Terminated() noexcept; - const std::string& getPublicKey(); - const std::string& getUserRole(); - const std::string& getVersion(); - static bool getExit() noexcept; + public: // Getters and Setters + void setDiscordMessage(const std::string& message); + static void setExit(bool exit) noexcept; + const std::string& getFullVersion(); + const std::string& getMPUserPath(); + static bool Terminated() noexcept; + const std::string& getPublicKey(); + const std::string& getUserRole(); + const std::string& getVersion(); + static bool getExit() noexcept; -private: // functions - void HandleIPC(const std::string& Data); - std::string GetLocalAppdata(); - void UpdatePresence(); - void AdminRelaunch(); - void RichPresence(); - void WindowsInit(); - void UpdateCheck(); - void ResetMods(); - void EnableMP(); - void Relaunch(); - void ListenIPC(); - void Abort(); + private: // functions + void HandleIPC(const std::string& Data); + std::string GetLocalAppdata(); + void UpdatePresence(); + void AdminRelaunch(); + void RichPresence(); + void WindowsInit(); + void UpdateCheck(); + void ResetMods(); + void EnableMP(); + void Relaunch(); + void ListenIPC(); + void Abort(); -private: // variables - uint32_t GamePID { 0 }; - bool EnableUI = true; - int64_t DiscordTime {}; - bool LoginAuth = false; - fs::path CurrentPath {}; - std::string BeamRoot {}; - std::string UserRole {}; - std::string PublicKey {}; - std::thread IPCSystem {}; - std::thread DiscordRPC {}; - std::string MPUserPath {}; - std::string BeamVersion {}; - std::string BeamUserPath {}; - std::string DiscordMessage {}; - std::string Version { "2.0" }; - Server ServerHandler { this }; - std::string TargetBuild { "default" }; - 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 {}; + private: // variables + uint32_t GamePID{0}; + bool EnableUI = true; + int64_t DiscordTime{}; + bool LoginAuth = false; + fs::path CurrentPath{}; + std::string BeamRoot{}; + std::string UserRole{}; + std::string PublicKey{}; + std::thread IPCSystem{}; + std::thread DiscordRPC{}; + std::string MPUserPath{}; + std::string BeamVersion{}; + std::string BeamUserPath{}; + std::string DiscordMessage{}; + std::string Version{"2.0"}; + Server ServerHandler{this}; + std::string TargetBuild{"default"}; + 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{}; }; class ShutdownException : public std::runtime_error { -public: - explicit ShutdownException(const std::string& message) - : runtime_error(message) {}; + public: + explicit ShutdownException(const std::string& message) : + runtime_error(message){}; }; diff --git a/include/Logger.h b/include/Logger.h index c89c848..dbe3ed0 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -8,6 +8,6 @@ #undef min #undef max class Log { -public: - static void Init(); + public: + static void Init(); }; diff --git a/include/Memory/BeamNG.h b/include/Memory/BeamNG.h index 402119e..7a3835e 100644 --- a/include/Memory/BeamNG.h +++ b/include/Memory/BeamNG.h @@ -4,25 +4,27 @@ /// #pragma once -#include "Memory/Hook.h" -#include "Memory/GELua.h" -#include "Memory/IPC.h" #include #include +#include "Memory/GELua.h" +#include "Memory/Hook.h" +#include "Memory/IPC.h" class BeamNG { -public: - static void EntryPoint(); - static void SendIPC(const std::string& Data); -private: - static inline std::unique_ptr> TickCountDetour; - static inline std::unique_ptr> OpenJITDetour; - static inline std::unique_ptr IPCFromLauncher; - static inline std::unique_ptr IPCToLauncher; - static inline uint64_t GameBaseAddr; - static inline uint64_t DllBaseAddr; - static int lua_open_jit_D(lua_State* State); - static void RegisterGEFunctions(); - // static int GetTickCount_D(void* GEState, void* Param2, void* Param3, void* Param4); - static void IPCListener(); + public: + static void EntryPoint(); + static void SendIPC(const std::string& Data); + + private: + static inline std::unique_ptr> TickCountDetour; + static inline std::unique_ptr> OpenJITDetour; + static inline std::unique_ptr IPCFromLauncher; + static inline std::unique_ptr IPCToLauncher; + static inline uint64_t GameBaseAddr; + static inline uint64_t DllBaseAddr; + static int lua_open_jit_D(lua_State* State); + static void RegisterGEFunctions(); + // static int GetTickCount_D(void* GEState, void* Param2, void* Param3, void* + // Param4); + static void IPCListener(); }; diff --git a/include/Memory/Definitions.h b/include/Memory/Definitions.h index 406a653..6c8ff99 100644 --- a/include/Memory/Definitions.h +++ b/include/Memory/Definitions.h @@ -8,18 +8,19 @@ typedef struct lua_State lua_State; typedef int (*lua_CFunction)(lua_State*); -extern int lua_gettop(lua_State *L); +extern int lua_gettop(lua_State* L); namespace def { - typedef int (*GEUpdate)(void* Param1, void* Param2, void* Param3, void* Param4); - typedef uint32_t (*GetTickCount)(); - typedef int (*lua_open_jit)(lua_State* L); - typedef void (*lua_get_field)(lua_State* L, int idx, const char* k); - typedef const char* (*lua_push_fstring)(lua_State* L, const char* fmt, ...); - typedef int (*lua_p_call)(lua_State* L, int arg, int res, int err); - typedef void (*lua_pushcclosure)(lua_State* L, lua_CFunction fn, int n); - typedef int (*lua_settop)(lua_State* L, int idx); - typedef void (*lua_settable)(lua_State* L, int idx); - typedef void (*lua_createtable)(lua_State* L, int narray, int nrec); - typedef void (*lua_setfield)(lua_State* L, int idx, const char* k); - typedef const char* (*lua_tolstring)(lua_State* L, int idx, size_t* len); + typedef int (*GEUpdate)(void* Param1, void* Param2, void* Param3, + void* Param4); + typedef uint32_t (*GetTickCount)(); + typedef int (*lua_open_jit)(lua_State* L); + typedef void (*lua_get_field)(lua_State* L, int idx, const char* k); + typedef const char* (*lua_push_fstring)(lua_State* L, const char* fmt, ...); + typedef int (*lua_p_call)(lua_State* L, int arg, int res, int err); + typedef void (*lua_pushcclosure)(lua_State* L, lua_CFunction fn, int n); + typedef int (*lua_settop)(lua_State* L, int idx); + typedef void (*lua_settable)(lua_State* L, int idx); + typedef void (*lua_createtable)(lua_State* L, int narray, int nrec); + typedef void (*lua_setfield)(lua_State* L, int idx, const char* k); + typedef const char* (*lua_tolstring)(lua_State* L, int idx, size_t* len); } diff --git a/include/Memory/GELua.h b/include/Memory/GELua.h index f0665c4..fa9b82b 100644 --- a/include/Memory/GELua.h +++ b/include/Memory/GELua.h @@ -7,39 +7,40 @@ #include "Definitions.h" class GELua { -public: - static void FindAddresses(); - static inline def::GEUpdate GEUpdate; - static inline def::lua_settop lua_settop; - static inline def::GetTickCount GetTickCount; - static inline def::lua_open_jit lua_open_jit; - static inline def::lua_push_fstring lua_push_fstring; - static inline def::lua_get_field lua_get_field; - static inline def::lua_p_call lua_p_call; - static inline def::lua_createtable lua_createtable; - static inline def::lua_pushcclosure lua_pushcclosure; - static inline def::lua_setfield lua_setfield; - static inline def::lua_settable lua_settable; - static inline def::lua_tolstring lua_tolstring; - static inline lua_State* State; + public: + static void FindAddresses(); + static inline def::GEUpdate GEUpdate; + static inline def::lua_settop lua_settop; + static inline def::GetTickCount GetTickCount; + static inline def::lua_open_jit lua_open_jit; + static inline def::lua_push_fstring lua_push_fstring; + static inline def::lua_get_field lua_get_field; + static inline def::lua_p_call lua_p_call; + static inline def::lua_createtable lua_createtable; + static inline def::lua_pushcclosure lua_pushcclosure; + static inline def::lua_setfield lua_setfield; + static inline def::lua_settable lua_settable; + static inline def::lua_tolstring lua_tolstring; + static inline lua_State* State; }; namespace GELuaTable { - inline void Begin(lua_State* L) { - GELua::lua_createtable(L, 0, 0); - } - inline void End(lua_State* L, const char* name) { - GELua::lua_setfield(L, -10002, name); - } - inline void BeginEntry(lua_State* L, const char* name) { - GELua::lua_push_fstring(L, "%s", name); - } - inline void EndEntry(lua_State* L) { - GELua::lua_settable(L, -3); - } - inline void InsertFunction(lua_State* L, const char* name, lua_CFunction func) { - BeginEntry(L, name); - GELua::lua_pushcclosure(L, func, 0); - EndEntry(L); - } + inline void Begin(lua_State* L) { + GELua::lua_createtable(L, 0, 0); + } + inline void End(lua_State* L, const char* name) { + GELua::lua_setfield(L, -10002, name); + } + inline void BeginEntry(lua_State* L, const char* name) { + GELua::lua_push_fstring(L, "%s", name); + } + inline void EndEntry(lua_State* L) { + GELua::lua_settable(L, -3); + } + inline void InsertFunction(lua_State* L, const char* name, + lua_CFunction func) { + BeginEntry(L, name); + GELua::lua_pushcclosure(L, func, 0); + EndEntry(L); + } } diff --git a/include/Memory/Hook.h b/include/Memory/Hook.h index a8aca04..bb2fe96 100644 --- a/include/Memory/Hook.h +++ b/include/Memory/Hook.h @@ -3,46 +3,49 @@ /// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info. /// #define WIN32_LEAN_AND_MEAN -#include "Memory/Memory.h" #include +#include "Memory/Memory.h" #pragma once -template +template class Hook { - FuncType targetPtr; - FuncType detourFunc; - bool Attached = false; -public: + FuncType targetPtr; + FuncType detourFunc; + bool Attached = false; - Hook(FuncType src, FuncType dest) : targetPtr(src), detourFunc(dest) { - auto status = MH_CreateHook((void*)targetPtr, (void*)detourFunc, (void**)&Original); - if(status != MH_OK) { - Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status)); + public: + Hook(FuncType src, FuncType dest) : targetPtr(src), detourFunc(dest) { + auto status = + MH_CreateHook((void*)targetPtr, (void*)detourFunc, (void**)&Original); + if (status != MH_OK) { + Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status)); + return; + } + } + + void Enable() { + if (!Attached) { + auto status = MH_EnableHook((void*)targetPtr); + if (status != MH_OK) { + Memory::Print(std::string("MH Error -> ") + + MH_StatusToString(status)); return; - } - } + } + Attached = true; + } + } - void Enable() { - if(!Attached){ - auto status = MH_EnableHook((void*)targetPtr); - if(status != MH_OK) { - Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status)); - return; - } - Attached = true; - } - } + void Disable() { + if (Attached) { + auto status = MH_DisableHook((void*)targetPtr); + if (status != MH_OK) { + Memory::Print(std::string("MH Error -> ") + + MH_StatusToString(status)); + return; + } + Attached = false; + } + } - void Disable() { - if(Attached){ - auto status = MH_DisableHook((void*)targetPtr); - if(status != MH_OK) { - Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status)); - return; - } - Attached = false; - } - } - - FuncType Original{}; + FuncType Original{}; }; diff --git a/include/Memory/IPC.h b/include/Memory/IPC.h index 66b2859..76382a5 100644 --- a/include/Memory/IPC.h +++ b/include/Memory/IPC.h @@ -7,28 +7,29 @@ #include class IPC { -public: - IPC() = default; - IPC(uint32_t ID, size_t Size) noexcept; - [[nodiscard]] size_t size() const noexcept; - [[nodiscard]] char* c_str() const noexcept; - void send(const std::string& msg) noexcept; - [[nodiscard]] void* raw() const noexcept; - [[nodiscard]] bool receive_timed_out() const noexcept; - [[nodiscard]] bool send_timed_out() const noexcept; - const std::string& msg() noexcept; - void confirm_receive() noexcept; - void try_receive() noexcept; - void receive() noexcept; - ~IPC() noexcept; - static bool mem_used(uint32_t MemID) noexcept; -private: - void* SemConfHandle_; - void* MemoryHandle_; - void* SemHandle_; - std::string Msg_; - bool SendTimeout; - bool RcvTimeout; - size_t Size_; - char* Data_; + public: + IPC() = default; + IPC(uint32_t ID, size_t Size) noexcept; + [[nodiscard]] size_t size() const noexcept; + [[nodiscard]] char* c_str() const noexcept; + void send(const std::string& msg) noexcept; + [[nodiscard]] void* raw() const noexcept; + [[nodiscard]] bool receive_timed_out() const noexcept; + [[nodiscard]] bool send_timed_out() const noexcept; + const std::string& msg() noexcept; + void confirm_receive() noexcept; + void try_receive() noexcept; + void receive() noexcept; + ~IPC() noexcept; + static bool mem_used(uint32_t MemID) noexcept; + + private: + void* SemConfHandle_; + void* MemoryHandle_; + void* SemHandle_; + std::string Msg_; + bool SendTimeout; + bool RcvTimeout; + size_t Size_; + char* Data_; }; diff --git a/include/Memory/Memory.h b/include/Memory/Memory.h index 7f3d132..386d1ca 100644 --- a/include/Memory/Memory.h +++ b/include/Memory/Memory.h @@ -4,17 +4,17 @@ /// #pragma once -#include #include +#include -class Memory{ -public: - static uint64_t FindPattern(const char* module, const char* Pattern[]); - static uint32_t GetBeamNGPID(const std::set& BL); - static uint64_t GetModuleBase(const char* Name); - static void Print(const std::string& msg); - static void Inject(uint32_t PID); - static uint32_t GetTickCount(); - static uint32_t EntryPoint(); - static uint32_t GetPID(); +class Memory { + public: + static uint64_t FindPattern(const char* module, const char* Pattern[]); + static uint32_t GetBeamNGPID(const std::set& BL); + static uint64_t GetModuleBase(const char* Name); + static void Print(const std::string& msg); + static void Inject(uint32_t PID); + static uint32_t GetTickCount(); + static uint32_t EntryPoint(); + static uint32_t GetPID(); }; diff --git a/include/Memory/Patterns.h b/include/Memory/Patterns.h index f35524d..4af76c5 100644 --- a/include/Memory/Patterns.h +++ b/include/Memory/Patterns.h @@ -5,52 +5,63 @@ #pragma once namespace Patterns { - const char* GetTickCount[2] { - "\x48\xff\x25\x00\x00\x00\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x83\xec\x00\x48\x8d\x4c\x24", - "xxx????xxxxxxxxxxxx?xxxx" - }; - const char* open_jit[2] { - "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b\x05\x00\x00\x00\x00\x48\x33\xc4\x48\x89\x44\x24\x00\x48\x8b\x71\x00\x48\x8d\x54\x24", - "xxxx?xxxx?xxxx?xxx????xxxxxxx?xxx?xxxx" - }; - const char* get_field[2] { - "\x48\x89\x5c\x24\x00\x57\x48\x83\xec\x00\x4d\x8b\xd0\x48\x8b\xd9\xe8\x00\x00\x00\x00\x48\x8b\xf8\x49\xc7\xc0\x00\x00\x00\x00\x90\x49\xff\xc0\x43\x80\x3c\x02\x00\x75\x00\x49\x8b\xd2\x48\x8b\xcb\xe8\x00\x00\x00\x00\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x4c\x8d\x44\x24\x00\x48\x0b\xc1\x48\x8b\xd7\x48\x8b\xcb\x48\x89\x44\x24\x00\xe8\x00\x00\x00\x00\x48\x85\xc0", - "xxxx?xxxx?xxxxxxx????xxxxxx????xxxxxxxx?x?xxxxxxx????xx????????xxxx?xxxxxxxxxxxxx?x????xxx" - }; - const char* push_fstring[2] { - "\x48\x89\x54\x24\x00\x4c\x89\x44\x24\x00\x4c\x89\x4c\x24\x00\x53\x48\x83\xec\x00\x4c\x8b\x41", - "xxxx?xxxx?xxxx?xxxx?xxx" - }; - const char* p_call[2] { - "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b\x59\x00\x41\x8b\xf0\x4c\x63\xda", - "xxxx?xxxx?xxxx?xxx?xxxxxx" - }; - const char* lua_setfield[2] { - "\x48\x89\x5c\x24\x00\x57\x48\x83\xec\x00\x4d\x8b\xd0\x48\x8b\xd9\xe8\x00\x00\x00\x00\x48\x8b\xf8\x49\xc7\xc0\x00\x00\x00\x00\x90\x49\xff\xc0\x43\x80\x3c\x02\x00\x75\x00\x49\x8b\xd2\x48\x8b\xcb\xe8\x00\x00\x00\x00\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x4c\x8d\x44\x24\x00\x48\x0b\xc1\x48\x8b\xd7\x48\x8b\xcb\x48\x89\x44\x24\x00\xe8\x00\x00\x00\x00\x48\x8b\x53", - "xxxx?xxxx?xxxxxxx????xxxxxx????xxxxxxxx?x?xxxxxxx????xx????????xxxx?xxxxxxxxxxxxx?x????xxx" - }; - const char* lua_createtable[2] { - "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x4c\x8b\x49\x00\x41\x8b\xf8", - "xxxx?xxxx?xxxx?xxx?xxx" - }; - const char* lua_settable[2] { - "\x40\x53\x48\x83\xec\x00\x48\x8b\xd9\xe8\x00\x00\x00\x00\x4c\x8b\x43\x00\x48\x8b\xd0\x49\x83\xe8\x00\x48\x8b\xcb\xe8\x00\x00\x00\x00\x48\x8b\x53", - "xxxxx?xxxx????xxx?xxxxxx?xxxx????xxx" - }; - const char* lua_pushcclosure[2] { - "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b\xd9\x49\x63\xf8\x48\x8b\x49\x00\x48\x8b\xf2", - "xxxx?xxxx?xxxx?xxxxxxxxx?xxx" - }; - const char* lua_tolstring[2] { - "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x49\x8b\xf8\x8b\xda\x48\x8b\xf1\xe8", - "xxxx?xxxx?xxxx?xxxxxxxxx" - }; - const char* GEUpdate[2] { - "\x48\x89\x5c\x24\x00\x48\x89\x6c\x24\x00\x56\x57\x41\x56\x48\x83\xec\x00\x4c\x8b\x31\x49\x8b\xf0", - "xxxx?xxxx?xxxxxxx?xxxxxx" - }; - const char* lua_settop[2] { - "\x4c\x8b\xc1\x85\xd2\x7e\x00\x48\x8b\x41\x00\x48\x8b\x49", - "xxxxxx?xxx?xxx" - }; + const char* GetTickCount[2]{ + "\x48\xff\x25\x00\x00\x00\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48" + "\x83\xec\x00\x48\x8d\x4c\x24", + "xxx????xxxxxxxxxxxx?xxxx"}; + const char* open_jit[2]{ + "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b" + "\x05\x00\x00\x00\x00\x48\x33\xc4\x48\x89\x44\x24\x00\x48\x8b\x71\x00" + "\x48\x8d\x54\x24", + "xxxx?xxxx?xxxx?xxx????xxxxxxx?xxx?xxxx"}; + const char* get_field[2]{ + "\x48\x89\x5c\x24\x00\x57\x48\x83\xec\x00\x4d\x8b\xd0\x48\x8b\xd9\xe8" + "\x00\x00\x00\x00\x48\x8b\xf8\x49\xc7\xc0\x00\x00\x00\x00\x90\x49\xff" + "\xc0\x43\x80\x3c\x02\x00\x75\x00\x49\x8b\xd2\x48\x8b\xcb\xe8\x00\x00" + "\x00\x00\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x4c\x8d\x44\x24\x00" + "\x48\x0b\xc1\x48\x8b\xd7\x48\x8b\xcb\x48\x89\x44\x24\x00\xe8\x00\x00" + "\x00\x00\x48\x85\xc0", + "xxxx?xxxx?xxxxxxx????xxxxxx????xxxxxxxx?x?xxxxxxx????xx????????xxxx?" + "xxxxxxxxxxxxx?x????xxx"}; + const char* push_fstring[2]{ + "\x48\x89\x54\x24\x00\x4c\x89\x44\x24\x00\x4c\x89\x4c\x24\x00\x53\x48" + "\x83\xec\x00\x4c\x8b\x41", + "xxxx?xxxx?xxxx?xxxx?xxx"}; + const char* p_call[2]{ + "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b" + "\x59\x00\x41\x8b\xf0\x4c\x63\xda", + "xxxx?xxxx?xxxx?xxx?xxxxxx"}; + const char* lua_setfield[2]{ + "\x48\x89\x5c\x24\x00\x57\x48\x83\xec\x00\x4d\x8b\xd0\x48\x8b\xd9\xe8" + "\x00\x00\x00\x00\x48\x8b\xf8\x49\xc7\xc0\x00\x00\x00\x00\x90\x49\xff" + "\xc0\x43\x80\x3c\x02\x00\x75\x00\x49\x8b\xd2\x48\x8b\xcb\xe8\x00\x00" + "\x00\x00\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x4c\x8d\x44\x24\x00" + "\x48\x0b\xc1\x48\x8b\xd7\x48\x8b\xcb\x48\x89\x44\x24\x00\xe8\x00\x00" + "\x00\x00\x48\x8b\x53", + "xxxx?xxxx?xxxxxxx????xxxxxx????xxxxxxxx?x?xxxxxxx????xx????????xxxx?" + "xxxxxxxxxxxxx?x????xxx"}; + const char* lua_createtable[2]{ + "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x4c\x8b" + "\x49\x00\x41\x8b\xf8", + "xxxx?xxxx?xxxx?xxx?xxx"}; + const char* lua_settable[2]{ + "\x40\x53\x48\x83\xec\x00\x48\x8b\xd9\xe8\x00\x00\x00\x00\x4c\x8b\x43" + "\x00\x48\x8b\xd0\x49\x83\xe8\x00\x48\x8b\xcb\xe8\x00\x00\x00\x00\x48" + "\x8b\x53", + "xxxxx?xxxx????xxx?xxxxxx?xxxx????xxx"}; + const char* lua_pushcclosure[2]{ + "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b" + "\xd9\x49\x63\xf8\x48\x8b\x49\x00\x48\x8b\xf2", + "xxxx?xxxx?xxxx?xxxxxxxxx?xxx"}; + const char* lua_tolstring[2]{ + "\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x49\x8b" + "\xf8\x8b\xda\x48\x8b\xf1\xe8", + "xxxx?xxxx?xxxx?xxxxxxxxx"}; + const char* GEUpdate[2]{ + "\x48\x89\x5c\x24\x00\x48\x89\x6c\x24\x00\x56\x57\x41\x56\x48\x83\xec" + "\x00\x4c\x8b\x31\x49\x8b\xf0", + "xxxx?xxxx?xxxxxxx?xxxxxx"}; + const char* lua_settop[2]{ + "\x4c\x8b\xc1\x85\xd2\x7e\x00\x48\x8b\x41\x00\x48\x8b\x49", + "xxxxxx?xxx?xxx"}; } \ No newline at end of file diff --git a/include/Server.h b/include/Server.h index 6ff2138..f939d50 100644 --- a/include/Server.h +++ b/include/Server.h @@ -12,65 +12,67 @@ struct sockaddr_in; class Launcher; class Server { -public: - Server() = delete; - explicit Server(Launcher* Instance); - ~Server(); + public: + Server() = delete; + explicit Server(Launcher* Instance); + ~Server(); -public: - void ServerSend(std::string Data, bool Rel); - void Connect(const std::string& Data); - const std::string& getModList(); - const std::string& getUIStatus(); - const std::string& getMap(); - void StartUDP(); - void setModLoaded(); - bool Terminated(); - int getPing() const; - void Close(); + public: + void ServerSend(std::string Data, bool Rel); + void Connect(const std::string& Data); + const std::string& getModList(); + const std::string& getUIStatus(); + const std::string& getMap(); + void StartUDP(); + void setModLoaded(); + bool Terminated(); + int getPing() const; + void Close(); -private: - std::chrono::time_point PingStart, PingEnd; - std::string MultiDownload(uint64_t DSock, uint64_t Size, const std::string& Name); - void AsyncUpdate(uint64_t& Rcv, uint64_t Size, const std::string& Name); - std::atomic Terminate { false }, ModLoaded { false }; - char* TCPRcvRaw(uint64_t Sock, uint64_t& GRcv, uint64_t Size); - std::string GetAddress(const std::string& Data); - void InvalidResource(const std::string& File); - void UpdateUl(bool D, const std::string& msg); - std::unique_ptr UDPSockAddress; - void ServerParser(const std::string& Data); - static std::string GetSocketApiError(); - void TCPSend(const std::string& Data); - void UDPParser(std::string Packet); - void SendLarge(std::string Data); - void UDPSend(std::string Data); - void UUl(const std::string& R); - bool CheckBytes(int32_t Bytes); - int KillSocket(uint64_t Dead); - void MultiKill(uint64_t Sock); - Launcher* LauncherInstance; - std::thread TCPConnection; - std::thread UDPConnection; - std::thread AutoPing; - uint64_t TCPSocket = -1; - uint64_t UDPSocket = -1; - void WaitForConfirm(); - std::string UStatus {}; - std::string MStatus {}; - std::string ModList {}; - void TCPClientMain(); - void SyncResources(); - std::string TCPRcv(); - uint64_t InitDSock(); - std::string Auth(); - std::string IP {}; - void UDPClient(); - void PingLoop(); - int ClientID { 0 }; - void UDPMain(); - void UDPRcv(); - void Abort(); - int Port { 0 }; - int Ping { 0 }; + private: + std::chrono::time_point PingStart, + PingEnd; + std::string MultiDownload(uint64_t DSock, uint64_t Size, + const std::string& Name); + void AsyncUpdate(uint64_t& Rcv, uint64_t Size, const std::string& Name); + std::atomic Terminate{false}, ModLoaded{false}; + char* TCPRcvRaw(uint64_t Sock, uint64_t& GRcv, uint64_t Size); + std::string GetAddress(const std::string& Data); + void InvalidResource(const std::string& File); + void UpdateUl(bool D, const std::string& msg); + std::unique_ptr UDPSockAddress; + void ServerParser(const std::string& Data); + static std::string GetSocketApiError(); + void TCPSend(const std::string& Data); + void UDPParser(std::string Packet); + void SendLarge(std::string Data); + void UDPSend(std::string Data); + void UUl(const std::string& R); + bool CheckBytes(int32_t Bytes); + int KillSocket(uint64_t Dead); + void MultiKill(uint64_t Sock); + Launcher* LauncherInstance; + std::thread TCPConnection; + std::thread UDPConnection; + std::thread AutoPing; + uint64_t TCPSocket = -1; + uint64_t UDPSocket = -1; + void WaitForConfirm(); + std::string UStatus{}; + std::string MStatus{}; + std::string ModList{}; + void TCPClientMain(); + void SyncResources(); + std::string TCPRcv(); + uint64_t InitDSock(); + std::string Auth(); + std::string IP{}; + void UDPClient(); + void PingLoop(); + int ClientID{0}; + void UDPMain(); + void UDPRcv(); + void Abort(); + int Port{0}; + int Ping{0}; }; diff --git a/include/atomic_queue.h b/include/atomic_queue.h index 48dde8b..bff70d7 100644 --- a/include/atomic_queue.h +++ b/include/atomic_queue.h @@ -7,55 +7,51 @@ #include #include -template +template class atomic_queue { -public: - bool try_pop(T& val) { - lock_guard guard(semaphore); - if (queue.empty()) - return false; - val = queue.front(); - queue.pop(); - full.release(); - return true; - } + public: + bool try_pop(T& val) { + lock_guard guard(semaphore); + if (queue.empty()) return false; + val = queue.front(); + queue.pop(); + full.release(); + return true; + } - void push(const T& val) { - check_full(); - lock_guard guard(semaphore); - queue.push(val); - } + void push(const T& val) { + check_full(); + lock_guard guard(semaphore); + queue.push(val); + } - size_t size() { - lock_guard guard(semaphore); - return queue.size(); - } + size_t size() { + lock_guard guard(semaphore); + return queue.size(); + } - bool empty() { - lock_guard guard(semaphore); - return queue.empty(); - } + bool empty() { + lock_guard guard(semaphore); + return queue.empty(); + } -private: - void check_full() { - if (size() >= Size) { - full.acquire(); - } - } + private: + void check_full() { + if (size() >= Size) { + full.acquire(); + } + } -private: - struct lock_guard { - explicit lock_guard(std::binary_semaphore& lock) - : lock(lock) { - lock.acquire(); - } - ~lock_guard() { - lock.release(); - } + private: + struct lock_guard { + explicit lock_guard(std::binary_semaphore& lock) : lock(lock) { + lock.acquire(); + } + ~lock_guard() { lock.release(); } - private: - std::binary_semaphore& lock; - }; - std::binary_semaphore semaphore { 1 }, full { 0 }; - std::queue queue {}; + private: + std::binary_semaphore& lock; + }; + std::binary_semaphore semaphore{1}, full{0}; + std::queue queue{}; }; diff --git a/src/Config.cpp b/src/Config.cpp index a6ed58e..e392420 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -3,39 +3,33 @@ /// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info. /// +#include #include "Launcher.h" #include "Logger.h" -#include void Launcher::LoadConfig() { - if (fs::exists("Launcher.toml")) { - toml::parse_result config = toml::parse_file("Launcher.toml"); - auto ui = config["UI"]; - auto build = config["Build"]; - if (ui.is_boolean()) { - EnableUI = ui.as_boolean()->get(); - } else - LOG(ERROR) << "Failed to get 'UI' boolean from config"; + if (fs::exists("Launcher.toml")) { + toml::parse_result config = toml::parse_file("Launcher.toml"); + auto ui = config["UI"]; + auto build = config["Build"]; + if (ui.is_boolean()) { + EnableUI = ui.as_boolean()->get(); + } else LOG(ERROR) << "Failed to get 'UI' boolean from config"; - // Default -1 / Release 1 / EA 2 / Dev 3 / Custom 3 - if (build.is_string()) { - TargetBuild = build.as_string()->get(); - for (char& c : TargetBuild) - c = char(tolower(c)); - } else - LOG(ERROR) << "Failed to get 'Build' string from config"; + // Default -1 / Release 1 / EA 2 / Dev 3 / Custom 3 + if (build.is_string()) { + TargetBuild = build.as_string()->get(); + for (char& c : TargetBuild) c = char(tolower(c)); + } else LOG(ERROR) << "Failed to get 'Build' string from config"; - } else { - std::ofstream tml("Launcher.toml"); - if (tml.is_open()) { - tml << - R"(UI = true -Build = "Default" -)"; - tml.close(); - } else { - LOG(FATAL) << "Failed to write config on disk!"; - throw ShutdownException("Fatal Error"); - } - } + } else { + std::ofstream tml("Launcher.toml"); + if (tml.is_open()) { + tml << "UI = true\n Build = \"Default\""; + tml.close(); + } else { + LOG(FATAL) << "Failed to write config on disk!"; + throw ShutdownException("Fatal Error"); + } + } } diff --git a/src/Discord.cpp b/src/Discord.cpp index f72c10a..77fd8ed 100644 --- a/src/Discord.cpp +++ b/src/Discord.cpp @@ -3,61 +3,61 @@ /// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info. /// #ifndef DEBUG +#include +#include #include "Launcher.h" #include "Logger.h" -#include -#include -void handleReady(const DiscordUser* u) { } -void handleDisconnected(int errcode, const char* message) { } +void handleReady(const DiscordUser* u) {} +void handleDisconnected(int errcode, const char* message) {} void handleError(int errcode, const char* message) { - LOG(ERROR) << "Discord error: " << message; + LOG(ERROR) << "Discord error: " << message; } void Launcher::UpdatePresence() { - auto currentTime = std::time(nullptr); - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - discordPresence.state = DiscordMessage.c_str(); - discordPresence.largeImageKey = "mainlogo"; - discordPresence.startTimestamp = currentTime - (currentTime - DiscordTime); - discordPresence.endTimestamp = 0; - DiscordTime = currentTime; - Discord_UpdatePresence(&discordPresence); + auto currentTime = std::time(nullptr); + DiscordRichPresence discordPresence; + memset(&discordPresence, 0, sizeof(discordPresence)); + discordPresence.state = DiscordMessage.c_str(); + discordPresence.largeImageKey = "mainlogo"; + discordPresence.startTimestamp = currentTime - (currentTime - DiscordTime); + discordPresence.endTimestamp = 0; + DiscordTime = currentTime; + Discord_UpdatePresence(&discordPresence); } void Launcher::setDiscordMessage(const std::string& message) { - DiscordMessage = message; - UpdatePresence(); + DiscordMessage = message; + UpdatePresence(); } void Launcher::RichPresence() { - DiscordEventHandlers handlers; - memset(&handlers, 0, sizeof(handlers)); - handlers.ready = handleReady; - handlers.errored = handleError; - handlers.disconnected = handleDisconnected; - Discord_Initialize("629743237988352010", &handlers, 1, nullptr); - UpdatePresence(); - while (!Shutdown.load()) { - Discord_RunCallbacks(); - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - Discord_ClearPresence(); - Discord_Shutdown(); + DiscordEventHandlers handlers; + memset(&handlers, 0, sizeof(handlers)); + handlers.ready = handleReady; + handlers.errored = handleError; + handlers.disconnected = handleDisconnected; + Discord_Initialize("629743237988352010", &handlers, 1, nullptr); + UpdatePresence(); + while (!Shutdown.load()) { + Discord_RunCallbacks(); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + Discord_ClearPresence(); + Discord_Shutdown(); } void Launcher::RunDiscordRPC() { - DiscordRPC = std::thread(&Launcher::RichPresence, this); + DiscordRPC = std::thread(&Launcher::RichPresence, this); } #else #include "Launcher.h" void Launcher::setDiscordMessage(const std::string& message) { - DiscordMessage = message; + DiscordMessage = message; } void Launcher::RunDiscordRPC() { - DiscordRPC = std::thread(&Launcher::RichPresence, this); + DiscordRPC = std::thread(&Launcher::RichPresence, this); } -void Launcher::RichPresence() {}; -void Launcher::UpdatePresence() {}; +void Launcher::RichPresence(){}; +void Launcher::UpdatePresence(){}; #endif \ No newline at end of file diff --git a/src/Handler.cpp b/src/Handler.cpp index d712eb3..a5b7005 100644 --- a/src/Handler.cpp +++ b/src/Handler.cpp @@ -10,88 +10,83 @@ #include "Memory/Memory.h" void Launcher::HandleIPC(const std::string& Data) { - char Code = Data.at(0), SubCode = 0; - if (Data.length() > 1) - SubCode = Data.at(1); - switch (Code) { - case 'A': - ServerHandler.StartUDP(); - break; - case 'B': - ServerHandler.Close(); - SendIPC(Code + HTTP::Post("https://backend.beammp.com/servers", "")); - LOG(INFO) << "Sent Server List"; - break; - case 'C': - ServerHandler.Close(); - ServerHandler.Connect(Data); - while (ServerHandler.getModList().empty() && !ServerHandler.Terminated()) { + char Code = Data.at(0), SubCode = 0; + if (Data.length() > 1) SubCode = Data.at(1); + switch (Code) { + case 'A': + ServerHandler.StartUDP(); + break; + case 'B': + ServerHandler.Close(); + SendIPC(Code + HTTP::Post("https://backend.beammp.com/servers", "")); + LOG(INFO) << "Sent Server List"; + break; + case 'C': + ServerHandler.Close(); + ServerHandler.Connect(Data); + while (ServerHandler.getModList().empty() && + !ServerHandler.Terminated()) { std::this_thread::sleep_for(std::chrono::seconds(1)); - } - if (ServerHandler.getModList() == "-") - SendIPC("L"); - else - SendIPC("L" + ServerHandler.getModList()); - break; - case 'U': - SendIPC("Ul" + ServerHandler.getUIStatus()); - if (ServerHandler.getPing() > 800) { + } + if (ServerHandler.getModList() == "-") SendIPC("L"); + else SendIPC("L" + ServerHandler.getModList()); + break; + case 'U': + SendIPC("Ul" + ServerHandler.getUIStatus()); + if (ServerHandler.getPing() > 800) { SendIPC("Up-2"); - } else - SendIPC("Up" + std::to_string(ServerHandler.getPing())); - break; - case 'M': - SendIPC(ServerHandler.getMap()); - break; - case 'Q': - if (SubCode == 'S') { + } else SendIPC("Up" + std::to_string(ServerHandler.getPing())); + break; + case 'M': + SendIPC(ServerHandler.getMap()); + break; + case 'Q': + if (SubCode == 'S') { ServerHandler.Close(); - } - if (SubCode == 'G') - exit(2); - break; - case 'R': // will send mod name - ServerHandler.setModLoaded(); - break; - case 'Z': - SendIPC("Z" + Version); - break; - case 'N': - if (SubCode == 'c') { + } + if (SubCode == 'G') exit(2); + break; + case 'R': // will send mod name + ServerHandler.setModLoaded(); + break; + case 'Z': + SendIPC("Z" + Version); + break; + case 'N': + if (SubCode == 'c') { SendIPC("N{\"Auth\":" + std::to_string(LoginAuth) + "}"); - } else { + } else { SendIPC("N" + Login(Data.substr(Data.find(':') + 1))); - } - break; - default: - break; - } + } + break; + default: + break; + } } void Server::ServerParser(const std::string& Data) { - if (Data.empty()) - return; - char Code = Data.at(0), SubCode = 0; - if (Data.length() > 1) - SubCode = Data.at(1); - switch (Code) { - case 'p': - PingEnd = std::chrono::high_resolution_clock::now(); - if (PingStart > PingEnd) - Ping = 0; - else - Ping = int(std::chrono::duration_cast(PingEnd - PingStart).count()); - return; - case 'M': - MStatus = Data; - UStatus = "done"; - return; - case 'K': - Terminate = true; - UStatus = Data.substr(1); - return; - default: - break; - } - LauncherInstance->SendIPC(Data, false); + if (Data.empty()) return; + char Code = Data.at(0), SubCode = 0; + if (Data.length() > 1) SubCode = Data.at(1); + switch (Code) { + case 'p': + PingEnd = std::chrono::high_resolution_clock::now(); + if (PingStart > PingEnd) Ping = 0; + else + Ping = int(std::chrono::duration_cast( + PingEnd - PingStart) + .count()); + return; + case 'M': + MStatus = Data; + UStatus = "done"; + return; + case 'K': + Terminate = true; + UStatus = Data.substr(1); + return; + default: + break; + } + LauncherInstance->SendIPC(Data, false); } diff --git a/src/Launcher.cpp b/src/Launcher.cpp index 8667c9f..7ff0243 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -5,265 +5,279 @@ #define WIN32_LEAN_AND_MEAN #include "Launcher.h" +#include +#include +#include +#include +#include +#include #include "HttpAPI.h" #include "Logger.h" #include "Memory/Memory.h" -#include -#include -#include -#include -#include -#include LONG WINAPI CrashHandler(EXCEPTION_POINTERS* p) { - LOG(ERROR) << "CAUGHT EXCEPTION! Code 0x" << std::hex << std::uppercase << p->ExceptionRecord->ExceptionCode; - return EXCEPTION_EXECUTE_HANDLER; + LOG(ERROR) << "CAUGHT EXCEPTION! Code 0x" << std::hex << std::uppercase + << p->ExceptionRecord->ExceptionCode; + return EXCEPTION_EXECUTE_HANDLER; } -Launcher::Launcher(int argc, char* argv[]) - : CurrentPath(std::filesystem::path(argv[0])) - , DiscordMessage("Just launched") { - Launcher::StaticAbort(this); - DiscordTime = std::time(nullptr); - Log::Init(); - WindowsInit(); - SetUnhandledExceptionFilter(CrashHandler); - LOG(INFO) << "Starting Launcher V" << FullVersion; - UpdateCheck(); +Launcher::Launcher(int argc, char* argv[]) : + CurrentPath(std::filesystem::path(argv[0])), + DiscordMessage("Just launched") { + Launcher::StaticAbort(this); + DiscordTime = std::time(nullptr); + Log::Init(); + WindowsInit(); + SetUnhandledExceptionFilter(CrashHandler); + LOG(INFO) << "Starting Launcher V" << FullVersion; + UpdateCheck(); } void Launcher::Abort() { - Shutdown.store(true); - ServerHandler.Close(); - if (DiscordRPC.joinable()) { - DiscordRPC.join(); - } - if (IPCSystem.joinable()) { - IPCSystem.join(); - } - if (!MPUserPath.empty()) { - ResetMods(); - } - if (GamePID != 0) { - auto Handle = OpenProcess(PROCESS_TERMINATE, false, DWORD(GamePID)); - TerminateProcess(Handle, 0); - CloseHandle(Handle); - } + Shutdown.store(true); + ServerHandler.Close(); + if (DiscordRPC.joinable()) { + DiscordRPC.join(); + } + if (IPCSystem.joinable()) { + IPCSystem.join(); + } + if (!MPUserPath.empty()) { + ResetMods(); + } + if (GamePID != 0) { + auto Handle = OpenProcess(PROCESS_TERMINATE, false, DWORD(GamePID)); + TerminateProcess(Handle, 0); + CloseHandle(Handle); + } } Launcher::~Launcher() { - if (!Shutdown.load()) { - Abort(); - } + if (!Shutdown.load()) { + Abort(); + } } void ShutdownHandler(int sig) { - Launcher::StaticAbort(); - while (HTTP::isDownload) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - LOG(INFO) << "Got termination signal (" << sig << ")"; - while (!Launcher::getExit()) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } + Launcher::StaticAbort(); + while (HTTP::isDownload) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + LOG(INFO) << "Got termination signal (" << sig << ")"; + while (!Launcher::getExit()) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } } void Launcher::StaticAbort(Launcher* Instance) { - static Launcher* Address; - if (Instance) { - Address = Instance; - return; - } - Address->Abort(); + static Launcher* Address; + if (Instance) { + Address = Instance; + return; + } + Address->Abort(); } void Launcher::WindowsInit() { - system("cls"); - SetConsoleTitleA(("BeamMP Launcher v" + FullVersion).c_str()); - signal(SIGINT, ShutdownHandler); - signal(SIGTERM, ShutdownHandler); - signal(SIGABRT, ShutdownHandler); - signal(SIGBREAK, ShutdownHandler); + system("cls"); + SetConsoleTitleA(("BeamMP Launcher v" + FullVersion).c_str()); + signal(SIGINT, ShutdownHandler); + signal(SIGTERM, ShutdownHandler); + signal(SIGABRT, ShutdownHandler); + signal(SIGBREAK, ShutdownHandler); } void Launcher::LaunchGame() { - VersionParser GameVersion(BeamVersion); - if (GameVersion.data[1] > SupportedVersion.data[1]) { - LOG(FATAL) << "BeamNG V" << BeamVersion << " not yet supported, please wait until we update BeamMP!"; - throw ShutdownException("Fatal Error"); - } else if (GameVersion.data[1] < SupportedVersion.data[1]) { - LOG(FATAL) << "BeamNG V" << BeamVersion << " not supported, please update and launch the new update!"; - throw ShutdownException("Fatal Error"); - } else if (GameVersion > SupportedVersion) { - LOG(WARNING) << "BeamNG V" << BeamVersion << " is slightly newer than recommended, this might cause issues!"; - } else if (GameVersion < SupportedVersion) { - LOG(WARNING) << "BeamNG V" << BeamVersion << " is slightly older than recommended, this might cause issues!"; - } - if (Memory::GetBeamNGPID({}) == 0) { - LOG(INFO) << "Launching BeamNG from steam"; - ShellExecuteA(nullptr, nullptr, "steam://rungameid/284160", nullptr, nullptr, SW_SHOWNORMAL); - // ShowWindow(GetConsoleWindow(), HIDE_WINDOW); - } - LOG(INFO) << "Waiting for a game process, please start BeamNG manually in case of steam issues"; + VersionParser GameVersion(BeamVersion); + if (GameVersion.data[1] > SupportedVersion.data[1]) { + LOG(FATAL) << "BeamNG V" << BeamVersion + << " not yet supported, please wait until we update BeamMP!"; + throw ShutdownException("Fatal Error"); + } else if (GameVersion.data[1] < SupportedVersion.data[1]) { + LOG(FATAL) << "BeamNG V" << BeamVersion + << " not supported, please update and launch the new update!"; + throw ShutdownException("Fatal Error"); + } else if (GameVersion > SupportedVersion) { + LOG(WARNING) + << "BeamNG V" << BeamVersion + << " is slightly newer than recommended, this might cause issues!"; + } else if (GameVersion < SupportedVersion) { + LOG(WARNING) + << "BeamNG V" << BeamVersion + << " is slightly older than recommended, this might cause issues!"; + } + if (Memory::GetBeamNGPID({}) == 0) { + LOG(INFO) << "Launching BeamNG from steam"; + ShellExecuteA(nullptr, nullptr, "steam://rungameid/284160", nullptr, + nullptr, SW_SHOWNORMAL); + // ShowWindow(GetConsoleWindow(), HIDE_WINDOW); + } + LOG(INFO) << "Waiting for a game process, please start BeamNG manually in " + "case of steam issues"; } void Launcher::WaitForGame() { - std::set BlackList; - do { - auto PID = Memory::GetBeamNGPID(BlackList); - if (PID != 0 && IPC::mem_used(PID)) { - BlackList.emplace(PID); - } else { - GamePID = PID; - } - std::this_thread::sleep_for(std::chrono::seconds(1)); - } while (GamePID == 0 && !Shutdown.load()); - if (Shutdown.load()) - return; + std::set BlackList; + do { + auto PID = Memory::GetBeamNGPID(BlackList); + if (PID != 0 && IPC::mem_used(PID)) { + BlackList.emplace(PID); + } else { + GamePID = PID; + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } while (GamePID == 0 && !Shutdown.load()); + if (Shutdown.load()) return; - if (GamePID == 0) { - LOG(FATAL) << "Game process not found! aborting"; - throw ShutdownException("Fatal Error"); - } + if (GamePID == 0) { + LOG(FATAL) << "Game process not found! aborting"; + throw ShutdownException("Fatal Error"); + } - LOG(INFO) << "Game found! PID " << GamePID; + LOG(INFO) << "Game found! PID " << GamePID; - IPCToGame = std::make_unique(GamePID, 0x1900000); - IPCFromGame = std::make_unique(GamePID + 1, 0x1900000); + IPCToGame = std::make_unique(GamePID, 0x1900000); + IPCFromGame = std::make_unique(GamePID + 1, 0x1900000); - IPCSystem = std::thread(&Launcher::ListenIPC, this); - Memory::Inject(GamePID); - setDiscordMessage("In menus"); - while (!Shutdown.load() && Memory::GetBeamNGPID(BlackList) != 0) { - std::this_thread::sleep_for(std::chrono::seconds(2)); - } - LOG(INFO) << "Game process was lost"; - GamePID = 0; + IPCSystem = std::thread(&Launcher::ListenIPC, this); + Memory::Inject(GamePID); + setDiscordMessage("In menus"); + while (!Shutdown.load() && Memory::GetBeamNGPID(BlackList) != 0) { + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + LOG(INFO) << "Game process was lost"; + GamePID = 0; } void Launcher::ListenIPC() { - while (!Shutdown.load()) { - IPCFromGame->receive(); - if (!IPCFromGame->receive_timed_out()) { - auto& MSG = IPCFromGame->msg(); - if (MSG[0] == 'C') { - HandleIPC(IPCFromGame->msg().substr(1)); - } else { - ServerHandler.ServerSend(IPCFromGame->msg().substr(1), false); - } - IPCFromGame->confirm_receive(); - } - } + while (!Shutdown.load()) { + IPCFromGame->receive(); + if (!IPCFromGame->receive_timed_out()) { + auto& MSG = IPCFromGame->msg(); + if (MSG[0] == 'C') { + HandleIPC(IPCFromGame->msg().substr(1)); + } else { + ServerHandler.ServerSend(IPCFromGame->msg().substr(1), false); + } + IPCFromGame->confirm_receive(); + } + } } void Launcher::SendIPC(const std::string& Data, bool core) { - static std::mutex Lock; - std::scoped_lock Guard(Lock); - if (core) - IPCToGame->send("C" + Data); - else - IPCToGame->send("G" + Data); - if (IPCToGame->send_timed_out()) { - LOG(WARNING) << "Timed out while sending \"" << Data << "\""; - } + static std::mutex Lock; + std::scoped_lock Guard(Lock); + if (core) IPCToGame->send("C" + Data); + else IPCToGame->send("G" + Data); + if (IPCToGame->send_timed_out()) { + LOG(WARNING) << "Timed out while sending \"" << Data << "\""; + } } std::string QueryValue(HKEY& hKey, const char* Name) { - DWORD keySize; - BYTE buffer[16384]; - if (RegQueryValueExA(hKey, Name, nullptr, nullptr, buffer, &keySize) == ERROR_SUCCESS) { - return { (char*)buffer, keySize - 1 }; - } - return {}; + DWORD keySize; + BYTE buffer[16384]; + if (RegQueryValueExA(hKey, Name, nullptr, nullptr, buffer, &keySize) == + ERROR_SUCCESS) { + return {(char*)buffer, keySize - 1}; + } + return {}; } std::string Launcher::GetLocalAppdata() { - PWSTR folderPath = nullptr; + PWSTR folderPath = nullptr; - HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &folderPath); + HRESULT hr = + SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &folderPath); - if (!SUCCEEDED(hr)) { - LOG(FATAL) << "Failed to get path of localAppData"; - throw ShutdownException("Fatal Error"); - } + if (!SUCCEEDED(hr)) { + LOG(FATAL) << "Failed to get path of localAppData"; + throw ShutdownException("Fatal Error"); + } - _bstr_t bstrPath(folderPath); - std::string Path((char*)bstrPath); - CoTaskMemFree(folderPath); + _bstr_t bstrPath(folderPath); + std::string Path((char*)bstrPath); + CoTaskMemFree(folderPath); - if (!Path.empty()) { - Path += "\\BeamNG.drive\\"; - VersionParser GameVer(BeamVersion); - Path += GameVer.split[0] + '.' + GameVer.split[1] + '\\'; - return Path; - } - return {}; + if (!Path.empty()) { + Path += "\\BeamNG.drive\\"; + VersionParser GameVer(BeamVersion); + Path += GameVer.split[0] + '.' + GameVer.split[1] + '\\'; + return Path; + } + return {}; } void Launcher::QueryRegistry() { - HKEY BeamNG; - LONG RegRes = RegOpenKeyExA(HKEY_CURRENT_USER, R"(Software\BeamNG\BeamNG.drive)", 0, KEY_READ, &BeamNG); - if (RegRes == ERROR_SUCCESS) { - BeamRoot = QueryValue(BeamNG, "rootpath"); - BeamVersion = QueryValue(BeamNG, "version"); - BeamUserPath = QueryValue(BeamNG, "userpath_override"); - RegCloseKey(BeamNG); - if (BeamUserPath.empty() && !BeamVersion.empty()) { - BeamUserPath = GetLocalAppdata(); - } else if (!BeamUserPath.empty() && !BeamVersion.empty()) { - VersionParser GameVer(BeamVersion); - BeamUserPath += GameVer.split[0] + '.' + GameVer.split[1] + '\\'; - } - if (!BeamUserPath.empty()) { - MPUserPath = BeamUserPath + "mods\\multiplayer"; - } - if (!BeamRoot.empty() && !BeamVersion.empty() && !BeamUserPath.empty()) - return; - } - LOG(FATAL) << "Please launch the game at least once, failed to read registry key Software\\BeamNG\\BeamNG.drive"; - throw ShutdownException("Fatal Error"); + HKEY BeamNG; + LONG RegRes = + RegOpenKeyExA(HKEY_CURRENT_USER, R"(Software\BeamNG\BeamNG.drive)", 0, + KEY_READ, &BeamNG); + if (RegRes == ERROR_SUCCESS) { + BeamRoot = QueryValue(BeamNG, "rootpath"); + BeamVersion = QueryValue(BeamNG, "version"); + BeamUserPath = QueryValue(BeamNG, "userpath_override"); + RegCloseKey(BeamNG); + if (BeamUserPath.empty() && !BeamVersion.empty()) { + BeamUserPath = GetLocalAppdata(); + } else if (!BeamUserPath.empty() && !BeamVersion.empty()) { + VersionParser GameVer(BeamVersion); + BeamUserPath += GameVer.split[0] + '.' + GameVer.split[1] + '\\'; + } + if (!BeamUserPath.empty()) { + MPUserPath = BeamUserPath + "mods\\multiplayer"; + } + if (!BeamRoot.empty() && !BeamVersion.empty() && !BeamUserPath.empty()) + return; + } + LOG(FATAL) + << "Please launch the game at least once, failed to read registry " + "key Software\\BeamNG\\BeamNG.drive"; + throw ShutdownException("Fatal Error"); } void Launcher::AdminRelaunch() { - system("cls"); - ShellExecuteA(nullptr, "runas", CurrentPath.string().c_str(), nullptr, nullptr, SW_SHOWNORMAL); - ShowWindow(GetConsoleWindow(), 0); - throw ShutdownException("Relaunching"); + system("cls"); + ShellExecuteA(nullptr, "runas", CurrentPath.string().c_str(), nullptr, + nullptr, SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(), 0); + throw ShutdownException("Relaunching"); } void Launcher::Relaunch() { - ShellExecuteA(nullptr, "open", CurrentPath.string().c_str(), nullptr, nullptr, SW_SHOWNORMAL); - ShowWindow(GetConsoleWindow(), 0); - std::this_thread::sleep_for(std::chrono::seconds(1)); - throw ShutdownException("Relaunching"); + ShellExecuteA(nullptr, "open", CurrentPath.string().c_str(), nullptr, + nullptr, SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(), 0); + std::this_thread::sleep_for(std::chrono::seconds(1)); + throw ShutdownException("Relaunching"); } const std::string& Launcher::getFullVersion() { - return FullVersion; + return FullVersion; } const std::string& Launcher::getVersion() { - return Version; + return Version; } const std::string& Launcher::getUserRole() { - return UserRole; + return UserRole; } bool Launcher::Terminated() noexcept { - return Shutdown.load(); + return Shutdown.load(); } bool Launcher::getExit() noexcept { - return Exit.load(); + return Exit.load(); } void Launcher::setExit(bool exit) noexcept { - Exit.store(exit); + Exit.store(exit); } const std::string& Launcher::getMPUserPath() { - return MPUserPath; + return MPUserPath; } const std::string& Launcher::getPublicKey() { - return PublicKey; + return PublicKey; } diff --git a/src/Logger.cpp b/src/Logger.cpp index a7c246b..7ba9e66 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -7,19 +7,21 @@ INITIALIZE_EASYLOGGINGPP using namespace el; void Log::Init() { - Configurations Conf; - Conf.setToDefault(); - std::string DFormat("%datetime{[%d/%M/%y %H:%m:%s]} %fbase:%line [%level] %msg"); - Conf.setGlobally(ConfigurationType::Format, "%datetime{[%d/%M/%y %H:%m:%s]} [%level] %msg"); - Conf.setGlobally(ConfigurationType::LogFlushThreshold, "2"); - Conf.set(Level::Verbose, ConfigurationType::Format, DFormat); - Conf.set(Level::Debug, ConfigurationType::Format, DFormat); - Conf.set(Level::Trace, ConfigurationType::Format, DFormat); - Conf.set(Level::Fatal, ConfigurationType::Format, DFormat); - Conf.setGlobally(ConfigurationType::Filename, "Launcher.log"); - Conf.setGlobally(ConfigurationType::MaxLogFileSize, "7340032"); - Loggers::reconfigureAllLoggers(Conf); - Loggers::addFlag(LoggingFlag::DisableApplicationAbortOnFatalLog); - Loggers::addFlag(LoggingFlag::HierarchicalLogging); - Loggers::setLoggingLevel(Level::Global); + Configurations Conf; + Conf.setToDefault(); + std::string DFormat( + "%datetime{[%d/%M/%y %H:%m:%s]} %fbase:%line [%level] %msg"); + Conf.setGlobally(ConfigurationType::Format, + "%datetime{[%d/%M/%y %H:%m:%s]} [%level] %msg"); + Conf.setGlobally(ConfigurationType::LogFlushThreshold, "2"); + Conf.set(Level::Verbose, ConfigurationType::Format, DFormat); + Conf.set(Level::Debug, ConfigurationType::Format, DFormat); + Conf.set(Level::Trace, ConfigurationType::Format, DFormat); + Conf.set(Level::Fatal, ConfigurationType::Format, DFormat); + Conf.setGlobally(ConfigurationType::Filename, "Launcher.log"); + Conf.setGlobally(ConfigurationType::MaxLogFileSize, "7340032"); + Loggers::reconfigureAllLoggers(Conf); + Loggers::addFlag(LoggingFlag::DisableApplicationAbortOnFatalLog); + Loggers::addFlag(LoggingFlag::HierarchicalLogging); + Loggers::setLoggingLevel(Level::Global); } diff --git a/src/Memory/BeamNG.cpp b/src/Memory/BeamNG.cpp index 59525f1..59931de 100644 --- a/src/Memory/BeamNG.cpp +++ b/src/Memory/BeamNG.cpp @@ -10,84 +10,86 @@ std::unique_ptr> Queue; int BeamNG::lua_open_jit_D(lua_State* State) { - Memory::Print("Got lua State"); - GELua::State = State; - RegisterGEFunctions(); - return OpenJITDetour->Original(State); + Memory::Print("Got lua State"); + GELua::State = State; + RegisterGEFunctions(); + return OpenJITDetour->Original(State); } void BeamNG::EntryPoint() { - Queue = std::make_unique>(); - uint32_t PID = Memory::GetPID(); - auto status = MH_Initialize(); - if (status != MH_OK) - Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status)); - Memory::Print("PID : " + std::to_string(PID)); - GELua::FindAddresses(); - /*GameBaseAddr = Memory::GetModuleBase(GameModule); - DllBaseAddr = Memory::GetModuleBase(DllModule);*/ - OpenJITDetour = std::make_unique>(GELua::lua_open_jit, lua_open_jit_D); - OpenJITDetour->Enable(); - IPCFromLauncher = std::make_unique(PID, 0x1900000); - IPCToLauncher = std::make_unique(PID + 1, 0x1900000); - IPCListener(); + Queue = std::make_unique>(); + uint32_t PID = Memory::GetPID(); + auto status = MH_Initialize(); + if (status != MH_OK) + Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status)); + Memory::Print("PID : " + std::to_string(PID)); + GELua::FindAddresses(); + /*GameBaseAddr = Memory::GetModuleBase(GameModule); + DllBaseAddr = Memory::GetModuleBase(DllModule);*/ + OpenJITDetour = std::make_unique>( + GELua::lua_open_jit, lua_open_jit_D); + OpenJITDetour->Enable(); + IPCFromLauncher = std::make_unique(PID, 0x1900000); + IPCToLauncher = std::make_unique(PID + 1, 0x1900000); + IPCListener(); } int Core(lua_State* L) { - if (lua_gettop(L) == 1) { - size_t Size; - const char* Data = GELua::lua_tolstring(L, 1, &Size); - // Memory::Print("Core -> " + std::string(Data) + " - " + std::to_string(Size)); - std::string msg(Data, Size); - BeamNG::SendIPC("C" + msg); - } - return 0; + if (lua_gettop(L) == 1) { + size_t Size; + const char* Data = GELua::lua_tolstring(L, 1, &Size); + // Memory::Print("Core -> " + std::string(Data) + " - " + + // std::to_string(Size)); + std::string msg(Data, Size); + BeamNG::SendIPC("C" + msg); + } + return 0; } int Game(lua_State* L) { - if (lua_gettop(L) == 1) { - size_t Size; - const char* Data = GELua::lua_tolstring(L, 1, &Size); - // Memory::Print("Game -> " + std::string(Data) + " - " + std::to_string(Size)); - std::string msg(Data, Size); - BeamNG::SendIPC("G" + msg); - } - return 0; + if (lua_gettop(L) == 1) { + size_t Size; + const char* Data = GELua::lua_tolstring(L, 1, &Size); + // Memory::Print("Game -> " + std::string(Data) + " - " + + // std::to_string(Size)); + std::string msg(Data, Size); + BeamNG::SendIPC("G" + msg); + } + return 0; } int LuaPop(lua_State* L) { - std::string MSG; - if (Queue->try_pop(MSG)) { - GELua::lua_push_fstring(L, "%s", MSG.c_str()); - return 1; - } - return 0; + std::string MSG; + if (Queue->try_pop(MSG)) { + GELua::lua_push_fstring(L, "%s", MSG.c_str()); + return 1; + } + return 0; } void BeamNG::RegisterGEFunctions() { - Memory::Print("Registering GE Functions"); - GELuaTable::Begin(GELua::State); - GELuaTable::InsertFunction(GELua::State, "Core", Core); - GELuaTable::InsertFunction(GELua::State, "Game", Game); - GELuaTable::InsertFunction(GELua::State, "try_pop", LuaPop); - GELuaTable::End(GELua::State, "MP"); - Memory::Print("Registered!"); + Memory::Print("Registering GE Functions"); + GELuaTable::Begin(GELua::State); + GELuaTable::InsertFunction(GELua::State, "Core", Core); + GELuaTable::InsertFunction(GELua::State, "Game", Game); + GELuaTable::InsertFunction(GELua::State, "try_pop", LuaPop); + GELuaTable::End(GELua::State, "MP"); + Memory::Print("Registered!"); } void BeamNG::SendIPC(const std::string& Data) { - IPCToLauncher->send(Data); + IPCToLauncher->send(Data); } void BeamNG::IPCListener() { - int TimeOuts = 0; - while (TimeOuts < 20) { - IPCFromLauncher->receive(); - if (!IPCFromLauncher->receive_timed_out()) { - TimeOuts = 0; - Queue->push(IPCFromLauncher->msg()); - IPCFromLauncher->confirm_receive(); - } else - TimeOuts++; - } - Memory::Print("IPC System shutting down"); + int TimeOuts = 0; + while (TimeOuts < 20) { + IPCFromLauncher->receive(); + if (!IPCFromLauncher->receive_timed_out()) { + TimeOuts = 0; + Queue->push(IPCFromLauncher->msg()); + IPCFromLauncher->confirm_receive(); + } else TimeOuts++; + } + Memory::Print("IPC System shutting down"); } diff --git a/src/Memory/Definitions.cpp b/src/Memory/Definitions.cpp index 7297d4d..20c0068 100644 --- a/src/Memory/Definitions.cpp +++ b/src/Memory/Definitions.cpp @@ -12,5 +12,5 @@ #include "lua/lj_strscan.h" LUA_API int lua_gettop(lua_State* L) { - return (int)(L->top - L->base); + return (int)(L->top - L->base); } diff --git a/src/Memory/GELua.cpp b/src/Memory/GELua.cpp index 44568cc..0562742 100644 --- a/src/Memory/GELua.cpp +++ b/src/Memory/GELua.cpp @@ -8,39 +8,63 @@ #include "Memory/Patterns.h" const char* GameModule = "BeamNG.drive.x64.exe"; -const char* DllModule = "libbeamng.x64.dll"; +const char* DllModule = "libbeamng.x64.dll"; std::string GetHex(uint64_t num) { - char buffer[30]; - sprintf(buffer, "%llx", num); - return std::string { buffer }; + char buffer[30]; + sprintf(buffer, "%llx", num); + return std::string{buffer}; } void GELua::FindAddresses() { - GELua::State = nullptr; - auto Base = Memory::GetModuleBase(GameModule); - GetTickCount = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::GetTickCount)); - Memory::Print("GetTickCount -> " + GetHex(reinterpret_cast(GetTickCount) - Base)); - lua_open_jit = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::open_jit)); - Memory::Print("lua_open_jit -> " + GetHex(reinterpret_cast(lua_open_jit) - Base)); - lua_push_fstring = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::push_fstring)); - Memory::Print("lua_push_fstring -> " + GetHex(reinterpret_cast(lua_push_fstring) - Base)); - lua_get_field = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::get_field)); - Memory::Print("lua_get_field -> " + GetHex(reinterpret_cast(lua_get_field) - Base)); - lua_p_call = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::p_call)); - Memory::Print("lua_p_call -> " + GetHex(reinterpret_cast(lua_p_call) - Base)); - lua_createtable = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::lua_createtable)); - Memory::Print("lua_createtable -> " + GetHex(reinterpret_cast(lua_createtable) - Base)); - lua_pushcclosure = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::lua_pushcclosure)); - Memory::Print("lua_pushcclosure -> " + GetHex(reinterpret_cast(lua_pushcclosure) - Base)); - lua_setfield = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::lua_setfield)); - Memory::Print("lua_setfield -> " + GetHex(reinterpret_cast(lua_setfield) - Base)); - lua_settable = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::lua_settable)); - Memory::Print("lua_settable -> " + GetHex(reinterpret_cast(lua_settable) - Base)); - lua_tolstring = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::lua_tolstring)); - Memory::Print("lua_tolstring -> " + GetHex(reinterpret_cast(lua_tolstring) - Base)); - GEUpdate = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::GEUpdate)); - Memory::Print("GEUpdate -> " + GetHex(reinterpret_cast(GEUpdate) - Base)); - lua_settop = reinterpret_cast(Memory::FindPattern(GameModule, Patterns::lua_settop)); - Memory::Print("lua_settop -> " + GetHex(reinterpret_cast(lua_settop) - Base)); + GELua::State = nullptr; + auto Base = Memory::GetModuleBase(GameModule); + GetTickCount = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::GetTickCount)); + Memory::Print("GetTickCount -> " + + GetHex(reinterpret_cast(GetTickCount) - Base)); + lua_open_jit = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::open_jit)); + Memory::Print("lua_open_jit -> " + + GetHex(reinterpret_cast(lua_open_jit) - Base)); + lua_push_fstring = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::push_fstring)); + Memory::Print("lua_push_fstring -> " + + GetHex(reinterpret_cast(lua_push_fstring) - Base)); + lua_get_field = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::get_field)); + Memory::Print("lua_get_field -> " + + GetHex(reinterpret_cast(lua_get_field) - Base)); + lua_p_call = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::p_call)); + Memory::Print("lua_p_call -> " + + GetHex(reinterpret_cast(lua_p_call) - Base)); + lua_createtable = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::lua_createtable)); + Memory::Print("lua_createtable -> " + + GetHex(reinterpret_cast(lua_createtable) - Base)); + lua_pushcclosure = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::lua_pushcclosure)); + Memory::Print("lua_pushcclosure -> " + + GetHex(reinterpret_cast(lua_pushcclosure) - Base)); + lua_setfield = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::lua_setfield)); + Memory::Print("lua_setfield -> " + + GetHex(reinterpret_cast(lua_setfield) - Base)); + lua_settable = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::lua_settable)); + Memory::Print("lua_settable -> " + + GetHex(reinterpret_cast(lua_settable) - Base)); + lua_tolstring = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::lua_tolstring)); + Memory::Print("lua_tolstring -> " + + GetHex(reinterpret_cast(lua_tolstring) - Base)); + GEUpdate = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::GEUpdate)); + Memory::Print("GEUpdate -> " + + GetHex(reinterpret_cast(GEUpdate) - Base)); + lua_settop = reinterpret_cast( + Memory::FindPattern(GameModule, Patterns::lua_settop)); + Memory::Print("lua_settop -> " + + GetHex(reinterpret_cast(lua_settop) - Base)); } diff --git a/src/Memory/IPC.cpp b/src/Memory/IPC.cpp index 03dd56f..85d6252 100644 --- a/src/Memory/IPC.cpp +++ b/src/Memory/IPC.cpp @@ -7,85 +7,87 @@ #include "Memory/IPC.h" #include -IPC::IPC(uint32_t ID, size_t Size) noexcept - : Size_(Size) { - std::string Sem { "MP_S" + std::to_string(ID) }, - SemConf { "MP_SC" + std::to_string(ID) }, - Mem { "MP_IO" + std::to_string(ID) }; +IPC::IPC(uint32_t ID, size_t Size) noexcept : Size_(Size) { + std::string Sem{"MP_S" + std::to_string(ID)}, + SemConf{"MP_SC" + std::to_string(ID)}, Mem{"MP_IO" + std::to_string(ID)}; - SemHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, Sem.c_str()); - if (SemHandle_ == nullptr) { - SemHandle_ = CreateSemaphoreA(nullptr, 0, 1, Sem.c_str()); - } - SemConfHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, SemConf.c_str()); - if (SemConfHandle_ == nullptr) { - SemConfHandle_ = CreateSemaphoreA(nullptr, 0, 1, SemConf.c_str()); - } - MemoryHandle_ = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str()); - if (MemoryHandle_ == nullptr) { - MemoryHandle_ = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, DWORD(Size), Mem.c_str()); - } - Data_ = (char*)MapViewOfFile(MemoryHandle_, FILE_MAP_ALL_ACCESS, 0, 0, Size); + SemHandle_ = + OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, Sem.c_str()); + if (SemHandle_ == nullptr) { + SemHandle_ = CreateSemaphoreA(nullptr, 0, 1, Sem.c_str()); + } + SemConfHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, + SemConf.c_str()); + if (SemConfHandle_ == nullptr) { + SemConfHandle_ = CreateSemaphoreA(nullptr, 0, 1, SemConf.c_str()); + } + MemoryHandle_ = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str()); + if (MemoryHandle_ == nullptr) { + MemoryHandle_ = + CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, + DWORD(Size), Mem.c_str()); + } + Data_ = (char*)MapViewOfFile(MemoryHandle_, FILE_MAP_ALL_ACCESS, 0, 0, Size); } void IPC::confirm_receive() noexcept { - ReleaseSemaphore(SemConfHandle_, 1, nullptr); + ReleaseSemaphore(SemConfHandle_, 1, nullptr); } void IPC::send(const std::string& msg) noexcept { - size_t Size = msg.size(); - memcpy(Data_, &Size, sizeof(size_t)); - memcpy(Data_ + sizeof(size_t), msg.c_str(), Size); - memset(Data_ + sizeof(size_t) + Size, 0, 3); - ReleaseSemaphore(SemHandle_, 1, nullptr); - SendTimeout = WaitForSingleObject(SemConfHandle_, 5000) == WAIT_TIMEOUT; + size_t Size = msg.size(); + memcpy(Data_, &Size, sizeof(size_t)); + memcpy(Data_ + sizeof(size_t), msg.c_str(), Size); + memset(Data_ + sizeof(size_t) + Size, 0, 3); + ReleaseSemaphore(SemHandle_, 1, nullptr); + SendTimeout = WaitForSingleObject(SemConfHandle_, 5000) == WAIT_TIMEOUT; } void IPC::receive() noexcept { - RcvTimeout = WaitForSingleObject(SemHandle_, 5000) == WAIT_TIMEOUT; + RcvTimeout = WaitForSingleObject(SemHandle_, 5000) == WAIT_TIMEOUT; } void IPC::try_receive() noexcept { - RcvTimeout = WaitForSingleObject(SemHandle_, 0) == WAIT_TIMEOUT; + RcvTimeout = WaitForSingleObject(SemHandle_, 0) == WAIT_TIMEOUT; } size_t IPC::size() const noexcept { - return Size_; + return Size_; } char* IPC::c_str() const noexcept { - return Data_ + sizeof(size_t); + return Data_ + sizeof(size_t); } void* IPC::raw() const noexcept { - return Data_ + sizeof(size_t); + return Data_ + sizeof(size_t); } const std::string& IPC::msg() noexcept { - size_t Size; - memcpy(&Size, Data_, sizeof(size_t)); - Msg_ = std::string(c_str(), Size); - return Msg_; + size_t Size; + memcpy(&Size, Data_, sizeof(size_t)); + Msg_ = std::string(c_str(), Size); + return Msg_; } bool IPC::receive_timed_out() const noexcept { - return RcvTimeout; + return RcvTimeout; } bool IPC::send_timed_out() const noexcept { - return SendTimeout; + return SendTimeout; } IPC::~IPC() noexcept { - UnmapViewOfFile(Data_); - CloseHandle(SemHandle_); - CloseHandle(MemoryHandle_); + UnmapViewOfFile(Data_); + CloseHandle(SemHandle_); + CloseHandle(MemoryHandle_); } bool IPC::mem_used(uint32_t MemID) noexcept { - std::string Mem { "MP_IO" + std::to_string(MemID) }; - HANDLE MEM = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str()); - bool used = MEM != nullptr; - UnmapViewOfFile(MEM); - return used; + std::string Mem{"MP_IO" + std::to_string(MemID)}; + HANDLE MEM = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str()); + bool used = MEM != nullptr; + UnmapViewOfFile(MEM); + return used; } diff --git a/src/Memory/Memory.cpp b/src/Memory/Memory.cpp index 583c3cd..36d66c8 100644 --- a/src/Memory/Memory.cpp +++ b/src/Memory/Memory.cpp @@ -6,131 +6,151 @@ #define WIN32_LEAN_AND_MEAN #undef UNICODE #include "Memory/Memory.h" -#include "Memory/BeamNG.h" #include -#include #include +#include +#include "Memory/BeamNG.h" uint32_t Memory::GetBeamNGPID(const std::set& BL) { - SetLastError(0); - PROCESSENTRY32 pe32; - pe32.dwSize = sizeof(PROCESSENTRY32); - HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + SetLastError(0); + PROCESSENTRY32 pe32; + pe32.dwSize = sizeof(PROCESSENTRY32); + HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (Process32First(Snapshot, &pe32)) { - do { - if (std::string("BeamNG.drive.x64.exe") == pe32.szExeFile - && BL.find(pe32.th32ProcessID) == BL.end() - && BL.find(pe32.th32ParentProcessID) == BL.end()) { - break; - } - } while (Process32Next(Snapshot, &pe32)); - } + if (Process32First(Snapshot, &pe32)) { + do { + if (std::string("BeamNG.drive.x64.exe") == pe32.szExeFile && + BL.find(pe32.th32ProcessID) == BL.end() && + BL.find(pe32.th32ParentProcessID) == BL.end()) { + break; + } + } while (Process32Next(Snapshot, &pe32)); + } - if (Snapshot != INVALID_HANDLE_VALUE) { - CloseHandle(Snapshot); - } + if (Snapshot != INVALID_HANDLE_VALUE) { + CloseHandle(Snapshot); + } - if (GetLastError() != 0) - return 0; - return pe32.th32ProcessID; + if (GetLastError() != 0) return 0; + return pe32.th32ProcessID; } uint64_t Memory::GetModuleBase(const char* Name) { - return (uint64_t)GetModuleHandleA(Name); + return (uint64_t)GetModuleHandleA(Name); } uint32_t Memory::GetPID() { - return GetCurrentProcessId(); + return GetCurrentProcessId(); } uint64_t Memory::FindPattern(const char* module, const char* Pattern[]) { - MODULEINFO mInfo { nullptr }; - GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(module), &mInfo, sizeof(MODULEINFO)); - auto base = uint64_t(mInfo.lpBaseOfDll); - auto size = uint32_t(mInfo.SizeOfImage); - auto len = strlen(Pattern[1]); - for (auto i = 0; i < size - len; i++) { - bool found = true; - for (auto j = 0; j < len && found; j++) { - found &= Pattern[1][j] == '?' || Pattern[0][j] == *(char*)(base + i + j); - } - if (found) { - return base + i; - } - } - return 0; + MODULEINFO mInfo{nullptr}; + GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(module), &mInfo, + sizeof(MODULEINFO)); + auto base = uint64_t(mInfo.lpBaseOfDll); + auto size = uint32_t(mInfo.SizeOfImage); + auto len = strlen(Pattern[1]); + for (auto i = 0; i < size - len; i++) { + bool found = true; + for (auto j = 0; j < len && found; j++) { + found &= + Pattern[1][j] == '?' || Pattern[0][j] == *(char*)(base + i + j); + } + if (found) { + return base + i; + } + } + return 0; } void* operator new(size_t size) { - return GlobalAlloc(GPTR, size); + return GlobalAlloc(GPTR, size); } void* operator new[](size_t size) { - return GlobalAlloc(GPTR, size); + return GlobalAlloc(GPTR, size); } void operator delete(void* p) noexcept { - GlobalFree(p); + GlobalFree(p); } void operator delete[](void* p) noexcept { - GlobalFree(p); + GlobalFree(p); } typedef struct BASE_RELOCATION_ENTRY { - USHORT Offset : 12; - USHORT Type : 4; + USHORT Offset : 12; + USHORT Type : 4; } BASE_RELOCATION_ENTRY, *PBASE_RELOCATION_ENTRY; void Memory::Inject(uint32_t PID) { - PVOID imageBase = GetModuleHandle(nullptr); - auto dosHeader = (PIMAGE_DOS_HEADER)imageBase; - auto ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew); + PVOID imageBase = GetModuleHandle(nullptr); + auto dosHeader = (PIMAGE_DOS_HEADER)imageBase; + auto ntHeader = + (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew); - PVOID localImage = VirtualAlloc(nullptr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE); - memcpy(localImage, imageBase, ntHeader->OptionalHeader.SizeOfImage); + PVOID localImage = + VirtualAlloc(nullptr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, + PAGE_READWRITE); + memcpy(localImage, imageBase, ntHeader->OptionalHeader.SizeOfImage); - HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, PID); - PVOID targetImage = VirtualAllocEx(targetProcess, nullptr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, PID); + PVOID targetImage = VirtualAllocEx(targetProcess, nullptr, + ntHeader->OptionalHeader.SizeOfImage, + MEM_COMMIT, PAGE_EXECUTE_READWRITE); - DWORD_PTR deltaImageBase = DWORD_PTR(targetImage) - DWORD_PTR(imageBase); + DWORD_PTR deltaImageBase = DWORD_PTR(targetImage) - DWORD_PTR(imageBase); - auto relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)localImage + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); - PDWORD_PTR patchedAddress; - while (relocationTable->SizeOfBlock > 0) { - DWORD relocationEntriesCount = (relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - auto relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1); - for (uint32_t i = 0; i < relocationEntriesCount; i++) { - if (relocationRVA[i].Offset) { - patchedAddress = PDWORD_PTR(DWORD_PTR(localImage) + relocationTable->VirtualAddress + relocationRVA[i].Offset); - *patchedAddress += deltaImageBase; - } - } - relocationTable = PIMAGE_BASE_RELOCATION(DWORD_PTR(relocationTable) + relocationTable->SizeOfBlock); - } - WriteProcessMemory(targetProcess, targetImage, localImage, ntHeader->OptionalHeader.SizeOfImage, nullptr); - CreateRemoteThread(targetProcess, nullptr, 0, (LPTHREAD_START_ROUTINE)((DWORD_PTR)EntryPoint + deltaImageBase), nullptr, 0, nullptr); - CloseHandle(targetProcess); + auto relocationTable = + (PIMAGE_BASE_RELOCATION)((DWORD_PTR)localImage + + ntHeader->OptionalHeader + .DataDirectory + [IMAGE_DIRECTORY_ENTRY_BASERELOC] + .VirtualAddress); + PDWORD_PTR patchedAddress; + while (relocationTable->SizeOfBlock > 0) { + DWORD relocationEntriesCount = + (relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / + sizeof(USHORT); + auto relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1); + for (uint32_t i = 0; i < relocationEntriesCount; i++) { + if (relocationRVA[i].Offset) { + patchedAddress = PDWORD_PTR(DWORD_PTR(localImage) + + relocationTable->VirtualAddress + + relocationRVA[i].Offset); + *patchedAddress += deltaImageBase; + } + } + relocationTable = PIMAGE_BASE_RELOCATION(DWORD_PTR(relocationTable) + + relocationTable->SizeOfBlock); + } + WriteProcessMemory(targetProcess, targetImage, localImage, + ntHeader->OptionalHeader.SizeOfImage, nullptr); + CreateRemoteThread( + targetProcess, nullptr, 0, + (LPTHREAD_START_ROUTINE)((DWORD_PTR)EntryPoint + deltaImageBase), + nullptr, 0, nullptr); + CloseHandle(targetProcess); } void Memory::Print(const std::string& msg) { - HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE); - if (stdOut != nullptr && stdOut != INVALID_HANDLE_VALUE) { - DWORD written = 0; - WriteConsoleA(stdOut, "[BeamMP] ", 9, &written, nullptr); - WriteConsoleA(stdOut, msg.c_str(), DWORD(msg.size()), &written, nullptr); - WriteConsoleA(stdOut, "\n", 1, &written, nullptr); - } + HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (stdOut != nullptr && stdOut != INVALID_HANDLE_VALUE) { + DWORD written = 0; + WriteConsoleA(stdOut, "[BeamMP] ", 9, &written, nullptr); + WriteConsoleA(stdOut, msg.c_str(), DWORD(msg.size()), &written, nullptr); + WriteConsoleA(stdOut, "\n", 1, &written, nullptr); + } } uint32_t Memory::EntryPoint() { - AllocConsole(); - SetConsoleTitleA("BeamMP Console"); - BeamNG::EntryPoint(); - return 0; + AllocConsole(); + SetConsoleTitleA("BeamMP Console"); + BeamNG::EntryPoint(); + return 0; } uint32_t Memory::GetTickCount() { - return ::GetTickCount(); + return ::GetTickCount(); } diff --git a/src/Network/Compressor.cpp b/src/Network/Compressor.cpp index 343b786..435542f 100644 --- a/src/Network/Compressor.cpp +++ b/src/Network/Compressor.cpp @@ -8,45 +8,45 @@ #define Biggest 30000 std::string Zlib::Comp(std::string Data) { - char* C = new char[Biggest]; - memset(C, 0, Biggest); - z_stream defstream; - defstream.zalloc = Z_NULL; - defstream.zfree = Z_NULL; - defstream.opaque = Z_NULL; - defstream.avail_in = (uInt)Data.length(); - defstream.next_in = (Bytef*)&Data[0]; - defstream.avail_out = Biggest; - defstream.next_out = reinterpret_cast(C); - deflateInit(&defstream, Z_BEST_COMPRESSION); - deflate(&defstream, Z_SYNC_FLUSH); - deflate(&defstream, Z_FINISH); - deflateEnd(&defstream); - uint32_t TO = defstream.total_out; - std::string Ret(TO, 0); - memcpy_s(&Ret[0], TO, C, TO); - delete[] C; - return Ret; + char* C = new char[Biggest]; + memset(C, 0, Biggest); + z_stream defstream; + defstream.zalloc = Z_NULL; + defstream.zfree = Z_NULL; + defstream.opaque = Z_NULL; + defstream.avail_in = (uInt)Data.length(); + defstream.next_in = (Bytef*)&Data[0]; + defstream.avail_out = Biggest; + defstream.next_out = reinterpret_cast(C); + deflateInit(&defstream, Z_BEST_COMPRESSION); + deflate(&defstream, Z_SYNC_FLUSH); + deflate(&defstream, Z_FINISH); + deflateEnd(&defstream); + uint32_t TO = defstream.total_out; + std::string Ret(TO, 0); + memcpy_s(&Ret[0], TO, C, TO); + delete[] C; + return Ret; } std::string Zlib::DeComp(std::string Compressed) { - char* C = new char[Biggest]; - memset(C, 0, Biggest); - z_stream infstream; - infstream.zalloc = Z_NULL; - infstream.zfree = Z_NULL; - infstream.opaque = Z_NULL; - infstream.avail_in = Biggest; - infstream.next_in = (Bytef*)(&Compressed[0]); - infstream.avail_out = Biggest; - infstream.next_out = (Bytef*)(C); - inflateInit(&infstream); - inflate(&infstream, Z_SYNC_FLUSH); - inflate(&infstream, Z_FINISH); - inflateEnd(&infstream); - uint32_t TO = infstream.total_out; - std::string Ret(TO, 0); - memcpy_s(&Ret[0], TO, C, TO); - delete[] C; - return Ret; + char* C = new char[Biggest]; + memset(C, 0, Biggest); + z_stream infstream; + infstream.zalloc = Z_NULL; + infstream.zfree = Z_NULL; + infstream.opaque = Z_NULL; + infstream.avail_in = Biggest; + infstream.next_in = (Bytef*)(&Compressed[0]); + infstream.avail_out = Biggest; + infstream.next_out = (Bytef*)(C); + inflateInit(&infstream); + inflate(&infstream, Z_SYNC_FLUSH); + inflate(&infstream, Z_FINISH); + inflateEnd(&infstream); + uint32_t TO = infstream.total_out; + std::string Ret(TO, 0); + memcpy_s(&Ret[0], TO, C, TO); + delete[] C; + return Ret; } diff --git a/src/Network/HttpAPI.cpp b/src/Network/HttpAPI.cpp index 15c0e22..32293c9 100644 --- a/src/Network/HttpAPI.cpp +++ b/src/Network/HttpAPI.cpp @@ -4,127 +4,124 @@ /// #define CPPHTTPLIB_OPENSSL_SUPPORT #include "HttpAPI.h" -#include "Launcher.h" -#include "Logger.h" -#include #include +#include #include #include #include +#include "Launcher.h" +#include "Logger.h" -bool HTTP::isDownload = false; +bool HTTP::isDownload = false; std::atomic CliRef = nullptr; std::string HTTP::Get(const std::string& IP) { - static std::mutex Lock; - std::scoped_lock Guard(Lock); + static std::mutex Lock; + std::scoped_lock Guard(Lock); - auto pos = IP.find('/', 10); + auto pos = IP.find('/', 10); - httplib::Client cli(IP.substr(0, pos)); - CliRef.store(&cli); - cli.set_connection_timeout(std::chrono::seconds(5)); - auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar); - std::string Ret; + httplib::Client cli(IP.substr(0, pos)); + CliRef.store(&cli); + cli.set_connection_timeout(std::chrono::seconds(5)); + auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar); + std::string Ret; - if (res.error() == httplib::Error::Success) { - if (res->status == 200) { - Ret = res->body; - } else - LOG(ERROR) << res->reason; + if (res.error() == httplib::Error::Success) { + if (res->status == 200) { + Ret = res->body; + } else LOG(ERROR) << res->reason; - } else { - if (isDownload) { - std::cout << "\n"; - } - LOG(ERROR) << "HTTP Get failed on " << httplib::to_string(res.error()); - } - CliRef.store(nullptr); - return Ret; + } else { + if (isDownload) { + std::cout << "\n"; + } + LOG(ERROR) << "HTTP Get failed on " << httplib::to_string(res.error()); + } + CliRef.store(nullptr); + return Ret; } std::string HTTP::Post(const std::string& IP, const std::string& Fields) { - static std::mutex Lock; - std::scoped_lock Guard(Lock); + static std::mutex Lock; + std::scoped_lock Guard(Lock); - auto pos = IP.find('/', 10); + auto pos = IP.find('/', 10); - httplib::Client cli(IP.substr(0, pos)); - CliRef.store(&cli); - cli.set_connection_timeout(std::chrono::seconds(5)); - std::string Ret; + httplib::Client cli(IP.substr(0, pos)); + CliRef.store(&cli); + cli.set_connection_timeout(std::chrono::seconds(5)); + std::string Ret; - if (!Fields.empty()) { - httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json"); + if (!Fields.empty()) { + httplib::Result res = + cli.Post(IP.substr(pos).c_str(), Fields, "application/json"); - if (res.error() == httplib::Error::Success) { - if (res->status != 200) { - LOG(ERROR) << res->reason; - } - Ret = res->body; - } else { - LOG(ERROR) << "HTTP Post failed on " << httplib::to_string(res.error()); - } - } else { - httplib::Result res = cli.Post(IP.substr(pos).c_str()); - if (res.error() == httplib::Error::Success) { - if (res->status != 200) { - LOG(ERROR) << res->reason; - } - Ret = res->body; - } else { - LOG(ERROR) << "HTTP Post failed on " << httplib::to_string(res.error()); - } - } - CliRef.store(nullptr); - if (Ret.empty()) - return "-1"; - else - return Ret; + if (res.error() == httplib::Error::Success) { + if (res->status != 200) { + LOG(ERROR) << res->reason; + } + Ret = res->body; + } else { + LOG(ERROR) << "HTTP Post failed on " + << httplib::to_string(res.error()); + } + } else { + httplib::Result res = cli.Post(IP.substr(pos).c_str()); + if (res.error() == httplib::Error::Success) { + if (res->status != 200) { + LOG(ERROR) << res->reason; + } + Ret = res->body; + } else { + LOG(ERROR) << "HTTP Post failed on " + << httplib::to_string(res.error()); + } + } + CliRef.store(nullptr); + if (Ret.empty()) return "-1"; + else return Ret; } bool HTTP::ProgressBar(size_t c, size_t t) { - if (isDownload) { - static double progress_bar_adv; - progress_bar_adv = round(double(c) / double(t) * 25); - std::cout << "\r"; - std::cout << "Progress: [ "; - std::cout << round(double(c) / double(t) * 100); - std::cout << "% ] ["; - int i; - for (i = 0; i <= progress_bar_adv; i++) - std::cout << "#"; - for (i = 0; i < 25 - progress_bar_adv; i++) - std::cout << "."; - std::cout << "]"; - } - if (Launcher::Terminated()) { - CliRef.load()->stop(); - std::cout << '\n'; - isDownload = false; - throw ShutdownException("Interrupted"); - } - return true; + if (isDownload) { + static double progress_bar_adv; + progress_bar_adv = round(double(c) / double(t) * 25); + std::cout << "\r"; + std::cout << "Progress: [ "; + std::cout << round(double(c) / double(t) * 100); + std::cout << "% ] ["; + int i; + for (i = 0; i <= progress_bar_adv; i++) std::cout << "#"; + for (i = 0; i < 25 - progress_bar_adv; i++) std::cout << "."; + std::cout << "]"; + } + if (Launcher::Terminated()) { + CliRef.load()->stop(); + std::cout << '\n'; + isDownload = false; + throw ShutdownException("Interrupted"); + } + return true; } bool HTTP::Download(const std::string& IP, const std::string& Path) { - static std::mutex Lock; - std::scoped_lock Guard(Lock); + static std::mutex Lock; + std::scoped_lock Guard(Lock); - isDownload = true; - std::string Ret = Get(IP); - isDownload = false; + isDownload = true; + std::string Ret = Get(IP); + isDownload = false; - if (Ret.empty()) - return false; - std::cout << "\n"; - std::ofstream File(Path, std::ios::binary); - if (File.is_open()) { - File << Ret; - File.close(); - LOG(INFO) << "Download complete!"; - } else { - LOG(ERROR) << "Failed to open file directory: " << Path; - return false; - } - return true; + if (Ret.empty()) return false; + std::cout << "\n"; + std::ofstream File(Path, std::ios::binary); + if (File.is_open()) { + File << Ret; + File.close(); + LOG(INFO) << "Download complete!"; + } else { + LOG(ERROR) << "Failed to open file directory: " << Path; + return false; + } + return true; } diff --git a/src/Network/Login.cpp b/src/Network/Login.cpp index e65aec2..99141ed 100644 --- a/src/Network/Login.cpp +++ b/src/Network/Login.cpp @@ -9,18 +9,18 @@ #include "Logger.h" void UpdateKey(const std::string& newKey) { - if (!newKey.empty()) { - std::ofstream Key("key"); - if (Key.is_open()) { - Key << newKey; - Key.close(); - } else { - LOG(FATAL) << "Cannot write to disk!"; - throw ShutdownException("Fatal Error"); - } - } else if (fs::exists("key")) { - remove("key"); - } + if (!newKey.empty()) { + std::ofstream Key("key"); + if (Key.is_open()) { + Key << newKey; + Key.close(); + } else { + LOG(FATAL) << "Cannot write to disk!"; + throw ShutdownException("Fatal Error"); + } + } else if (fs::exists("key")) { + remove("key"); + } } /// "username":"value","password":"value" @@ -28,82 +28,85 @@ void UpdateKey(const std::string& newKey) { /// "pk":"private_key" std::string GetFail(const std::string& R) { - std::string DRet = R"({"success":false,"message":)"; - DRet += "\"" + R + "\"}"; - LOG(ERROR) << R; - return DRet; + std::string DRet = R"({"success":false,"message":)"; + DRet += "\"" + R + "\"}"; + LOG(ERROR) << R; + return DRet; } std::string Launcher::Login(const std::string& fields) { - if (fields == "LO") { - LoginAuth = false; - UpdateKey(""); - return ""; - } - LOG(INFO) << "Attempting to authenticate..."; - std::string Buffer = HTTP::Post("https://auth.beammp.com/userlogin", fields); - Json d = Json::parse(Buffer, nullptr, false); + if (fields == "LO") { + LoginAuth = false; + UpdateKey(""); + return ""; + } + LOG(INFO) << "Attempting to authenticate..."; + std::string Buffer = HTTP::Post("https://auth.beammp.com/userlogin", fields); + Json d = Json::parse(Buffer, nullptr, false); - if (Buffer == "-1") { - return GetFail("Failed to communicate with the auth system!"); - } + if (Buffer == "-1") { + return GetFail("Failed to communicate with the auth system!"); + } - if (Buffer.at(0) != '{' || d.is_discarded()) { - LOG(ERROR) << Buffer; - return GetFail("Invalid answer from authentication servers, please try again later!"); - } + if (Buffer.at(0) != '{' || d.is_discarded()) { + LOG(ERROR) << Buffer; + return GetFail( + "Invalid answer from authentication servers, please try again " + "later!"); + } - if (!d["success"].is_null() && d["success"].get()) { - LoginAuth = true; - if (!d["private_key"].is_null()) { - UpdateKey(d["private_key"].get()); - } - if (!d["public_key"].is_null()) { - PublicKey = d["public_key"].get(); - } - LOG(INFO) << "Authentication successful!"; - } else - LOG(WARNING) << "Authentication failed!"; + if (!d["success"].is_null() && d["success"].get()) { + LoginAuth = true; + if (!d["private_key"].is_null()) { + UpdateKey(d["private_key"].get()); + } + if (!d["public_key"].is_null()) { + PublicKey = d["public_key"].get(); + } + LOG(INFO) << "Authentication successful!"; + } else LOG(WARNING) << "Authentication failed!"; - if (!d["message"].is_null()) { - d.erase("private_key"); - d.erase("public_key"); - return d.dump(); - } - return GetFail("Invalid message parsing!"); + if (!d["message"].is_null()) { + d.erase("private_key"); + d.erase("public_key"); + return d.dump(); + } + return GetFail("Invalid message parsing!"); } void Launcher::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(); + 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 + "\"}"); + 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()) { - LOG(DEBUG) << Buffer; - LOG(FATAL) << "Invalid answer from authentication servers, please try again later!"; - throw ShutdownException("Fatal Error"); - } - if (d["success"].get()) { - LoginAuth = true; - UpdateKey(d["private_key"].get()); - PublicKey = d["public_key"].get(); - UserRole = d["role"].get(); - LOG(INFO) << "Auto-Authentication was successful"; - } else { - LOG(WARNING) << "Auto-Authentication unsuccessful please re-login!"; - UpdateKey(""); - } - } else { - LOG(WARNING) << "Could not open saved key!"; + Json d = Json::parse(Buffer, nullptr, false); + if (Buffer == "-1" || Buffer.at(0) != '{' || d.is_discarded()) { + LOG(DEBUG) << Buffer; + LOG(FATAL) + << "Invalid answer from authentication servers, please try " + "again later!"; + throw ShutdownException("Fatal Error"); + } + if (d["success"].get()) { + LoginAuth = true; + UpdateKey(d["private_key"].get()); + PublicKey = d["public_key"].get(); + UserRole = d["role"].get(); + LOG(INFO) << "Auto-Authentication was successful"; + } else { + LOG(WARNING) << "Auto-Authentication unsuccessful please re-login!"; UpdateKey(""); - } - } else - UpdateKey(""); + } + } else { + LOG(WARNING) << "Could not open saved key!"; + UpdateKey(""); + } + } else UpdateKey(""); } diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index c774382..5f97a03 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -3,9 +3,7 @@ /// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info. /// -#include "Launcher.h" -#include "Logger.h" -#include "Server.h" +#include #include #include #include @@ -14,319 +12,318 @@ #include #include #include -#include +#include "Launcher.h" +#include "Logger.h" +#include "Server.h" namespace fs = std::filesystem; -std::vector Split(const std::string& String, const std::string& delimiter) { - std::vector Val; - size_t pos; - std::string token, s = String; - while ((pos = s.find(delimiter)) != std::string::npos) { - token = s.substr(0, pos); - if (!token.empty()) - Val.push_back(token); - s.erase(0, pos + delimiter.length()); - } - if (!s.empty()) - Val.push_back(s); - return Val; +std::vector Split(const std::string& String, + const std::string& delimiter) { + std::vector Val; + size_t pos; + std::string token, s = String; + while ((pos = s.find(delimiter)) != std::string::npos) { + token = s.substr(0, pos); + if (!token.empty()) Val.push_back(token); + s.erase(0, pos + delimiter.length()); + } + if (!s.empty()) Val.push_back(s); + return Val; } void CheckForDir() { - if (!fs::exists("Resources")) { - _wmkdir(L"Resources"); - } + if (!fs::exists("Resources")) { + _wmkdir(L"Resources"); + } } void Server::WaitForConfirm() { - while (!Terminate && !ModLoaded) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - ModLoaded = false; + while (!Terminate && !ModLoaded) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + ModLoaded = false; } void Server::Abort() { - Terminate = true; - LOG(INFO) << "Terminated!"; + Terminate = true; + LOG(INFO) << "Terminated!"; } std::string Server::Auth() { - TCPSend("VC" + LauncherInstance->getVersion()); + TCPSend("VC" + LauncherInstance->getVersion()); - auto Res = TCPRcv(); + auto Res = TCPRcv(); - if (Res.empty() || Res[0] == 'E') { - Abort(); - return ""; - } + if (Res.empty() || Res[0] == 'E') { + Abort(); + return ""; + } - TCPSend(LauncherInstance->getPublicKey()); - if (Terminate) - return ""; + TCPSend(LauncherInstance->getPublicKey()); + if (Terminate) return ""; - Res = TCPRcv(); - if (Res.empty() || Res[0] != 'P') { - Abort(); - return ""; - } + Res = TCPRcv(); + if (Res.empty() || Res[0] != 'P') { + Abort(); + return ""; + } - Res = Res.substr(1); - if (std::all_of(Res.begin(), Res.end(), isdigit)) { - ClientID = std::stoi(Res); - } else { - Abort(); - UUl("Authentication failed!"); - return ""; - } - TCPSend("SR"); - if (Terminate) - return ""; + Res = Res.substr(1); + if (std::all_of(Res.begin(), Res.end(), isdigit)) { + ClientID = std::stoi(Res); + } else { + Abort(); + UUl("Authentication failed!"); + return ""; + } + TCPSend("SR"); + if (Terminate) return ""; - Res = TCPRcv(); + Res = TCPRcv(); - if (Res[0] == 'E') { - Abort(); - return ""; - } + if (Res[0] == 'E') { + Abort(); + return ""; + } - if (Res.empty() || Res == "-") { - LOG(INFO) << "Didn't Receive any mods..."; - ModList = "-"; - TCPSend("Done"); - LOG(INFO) << "Done!"; - return ""; - } - return Res; + if (Res.empty() || Res == "-") { + LOG(INFO) << "Didn't Receive any mods..."; + ModList = "-"; + TCPSend("Done"); + LOG(INFO) << "Done!"; + return ""; + } + return Res; } void Server::UpdateUl(bool D, const std::string& msg) { - if (D) - UStatus = "UlDownloading Resource " + msg; - else - UStatus = "UlLoading Resource " + msg; + if (D) UStatus = "UlDownloading Resource " + msg; + else UStatus = "UlLoading Resource " + msg; } -void Server::AsyncUpdate(uint64_t& Rcv, uint64_t Size, const std::string& Name) { - do { - double pr = double(Rcv) / double(Size) * 100; - std::string Per = std::to_string(trunc(pr * 10) / 10); - UpdateUl(true, Name + " (" + Per.substr(0, Per.find('.') + 2) + "%)"); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } while (!Terminate && Rcv < Size); +void Server::AsyncUpdate(uint64_t& Rcv, uint64_t Size, + const std::string& Name) { + do { + double pr = double(Rcv) / double(Size) * 100; + std::string Per = std::to_string(trunc(pr * 10) / 10); + UpdateUl(true, Name + " (" + Per.substr(0, Per.find('.') + 2) + "%)"); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } while (!Terminate && Rcv < Size); } char* Server::TCPRcvRaw(uint64_t Sock, uint64_t& GRcv, uint64_t Size) { - if (Sock == -1) { - Terminate = true; - UUl("Invalid Socket"); - return nullptr; - } - char* File = new char[Size]; - uint64_t Rcv = 0; - do { - int Len = int(Size - Rcv); - if (Len > 1000000) - Len = 1000000; - int32_t Temp = recv(Sock, &File[Rcv], Len, MSG_WAITALL); - if (Temp < 1) { - UUl("Socket Closed Code 1"); - KillSocket(Sock); - Terminate = true; - delete[] File; - return nullptr; - } - Rcv += Temp; - GRcv += Temp; - } while (Rcv < Size && !Terminate); - return File; + if (Sock == -1) { + Terminate = true; + UUl("Invalid Socket"); + return nullptr; + } + char* File = new char[Size]; + uint64_t Rcv = 0; + do { + int Len = int(Size - Rcv); + if (Len > 1000000) Len = 1000000; + int32_t Temp = recv(Sock, &File[Rcv], Len, MSG_WAITALL); + if (Temp < 1) { + UUl("Socket Closed Code 1"); + KillSocket(Sock); + Terminate = true; + delete[] File; + return nullptr; + } + Rcv += Temp; + GRcv += Temp; + } while (Rcv < Size && !Terminate); + return File; } void Server::MultiKill(uint64_t Sock) { - KillSocket(TCPSocket); - KillSocket(Sock); - Terminate = true; + KillSocket(TCPSocket); + KillSocket(Sock); + Terminate = true; } uint64_t Server::InitDSock() { - SOCKET DSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - SOCKADDR_IN ServerAddr; - if (DSock < 1) { - KillSocket(DSock); - Terminate = true; - return 0; - } - ServerAddr.sin_family = AF_INET; - ServerAddr.sin_port = htons(Port); - inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); - if (connect(DSock, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)) != 0) { - KillSocket(DSock); - Terminate = true; - return 0; - } - char Code[2] = { 'D', char(ClientID) }; - if (send(DSock, Code, 2, 0) != 2) { - KillSocket(DSock); - Terminate = true; - return 0; - } - return DSock; + SOCKET DSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + SOCKADDR_IN ServerAddr; + if (DSock < 1) { + KillSocket(DSock); + Terminate = true; + return 0; + } + ServerAddr.sin_family = AF_INET; + ServerAddr.sin_port = htons(Port); + inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); + if (connect(DSock, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)) != 0) { + KillSocket(DSock); + Terminate = true; + return 0; + } + char Code[2] = {'D', char(ClientID)}; + if (send(DSock, Code, 2, 0) != 2) { + KillSocket(DSock); + Terminate = true; + return 0; + } + return DSock; } -std::string Server::MultiDownload(uint64_t DSock, uint64_t Size, const std::string& Name) { +std::string Server::MultiDownload(uint64_t DSock, uint64_t Size, + const std::string& Name) { + uint64_t GRcv = 0, MSize = Size / 2, DSize = Size - MSize; - uint64_t GRcv = 0, MSize = Size / 2, DSize = Size - MSize; + std::thread Au(&Server::AsyncUpdate, this, std::ref(GRcv), Size, Name); - std::thread Au(&Server::AsyncUpdate, this, std::ref(GRcv), Size, Name); + std::packaged_task task( + [&] { return TCPRcvRaw(TCPSocket, GRcv, MSize); }); + std::future f1 = task.get_future(); + std::thread Dt(std::move(task)); + Dt.detach(); - std::packaged_task task([&] { return TCPRcvRaw(TCPSocket, GRcv, MSize); }); - std::future f1 = task.get_future(); - std::thread Dt(std::move(task)); - Dt.detach(); + char* DData = TCPRcvRaw(DSock, GRcv, DSize); - char* DData = TCPRcvRaw(DSock, GRcv, DSize); + if (!DData) { + MultiKill(DSock); + return ""; + } - if (!DData) { - MultiKill(DSock); - return ""; - } + f1.wait(); + char* MData = f1.get(); - f1.wait(); - char* MData = f1.get(); + if (!MData) { + MultiKill(DSock); + return ""; + } - if (!MData) { - MultiKill(DSock); - return ""; - } + if (Au.joinable()) Au.join(); - if (Au.joinable()) - Au.join(); + /// omg yes very ugly my god but i was in a rush will revisit + std::string Ret(Size, 0); + memcpy_s(&Ret[0], MSize, MData, MSize); + delete[] MData; - /// omg yes very ugly my god but i was in a rush will revisit - std::string Ret(Size, 0); - memcpy_s(&Ret[0], MSize, MData, MSize); - delete[] MData; + memcpy_s(&Ret[MSize], DSize, DData, DSize); + delete[] DData; - memcpy_s(&Ret[MSize], DSize, DData, DSize); - delete[] DData; - - return Ret; + return Ret; } void Server::InvalidResource(const std::string& File) { - UUl("Invalid mod \"" + File + "\""); - LOG(WARNING) << "The server tried to sync \"" << File << "\" that is not a .zip file!"; - Terminate = true; + UUl("Invalid mod \"" + File + "\""); + LOG(WARNING) << "The server tried to sync \"" << File + << "\" that is not a .zip file!"; + Terminate = true; } void Server::SyncResources() { - std::string Ret = Auth(); - if (Ret.empty()) - return; - LOG(INFO) << "Checking Resources..."; - CheckForDir(); + std::string Ret = Auth(); + if (Ret.empty()) return; + LOG(INFO) << "Checking Resources..."; + CheckForDir(); - std::vector list = Split(Ret, ";"); - std::vector FNames(list.begin(), list.begin() + (list.size() / 2)); - std::vector FSizes(list.begin() + (list.size() / 2), list.end()); - list.clear(); - Ret.clear(); + std::vector list = Split(Ret, ";"); + std::vector FNames(list.begin(), + list.begin() + (list.size() / 2)); + std::vector FSizes(list.begin() + (list.size() / 2), + list.end()); + list.clear(); + Ret.clear(); - int Amount = 0, Pos = 0; - std::string a, t; - for (const std::string& name : FNames) { - if (!name.empty()) { - t += name.substr(name.find_last_of('/') + 1) + ";"; - } - } - if (t.empty()) - ModList = "-"; - else - ModList = t; - t.clear(); - for (auto FN = FNames.begin(), FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN, ++FS) { - auto pos = FN->find_last_of('/'); - auto ZIP = FN->find(".zip"); - if (ZIP == std::string::npos || FN->length() - ZIP != 4) { - InvalidResource(*FN); - return; - } - if (pos == std::string::npos) + int Amount = 0, Pos = 0; + std::string a, t; + for (const std::string& name : FNames) { + if (!name.empty()) { + t += name.substr(name.find_last_of('/') + 1) + ";"; + } + } + if (t.empty()) ModList = "-"; + else ModList = t; + t.clear(); + for (auto FN = FNames.begin(), FS = FSizes.begin(); + FN != FNames.end() && !Terminate; ++FN, ++FS) { + auto pos = FN->find_last_of('/'); + auto ZIP = FN->find(".zip"); + if (ZIP == std::string::npos || FN->length() - ZIP != 4) { + InvalidResource(*FN); + return; + } + if (pos == std::string::npos) continue; + Amount++; + } + if (!FNames.empty()) LOG(INFO) << "Syncing..."; + SOCKET DSock = InitDSock(); + for (auto FN = FNames.begin(), FS = FSizes.begin(); + FN != FNames.end() && !Terminate; ++FN, ++FS) { + auto pos = FN->find_last_of('/'); + if (pos != std::string::npos) { + a = "Resources" + FN->substr(pos); + } else continue; + Pos++; + if (fs::exists(a)) { + if (!std::all_of(FS->begin(), FS->end(), isdigit)) continue; + if (fs::file_size(a) == std::stoull(*FS)) { + UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + + ": " + a.substr(a.find_last_of('/'))); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + try { + if (!fs::exists(LauncherInstance->getMPUserPath())) { + fs::create_directories(LauncherInstance->getMPUserPath()); + } + fs::copy_file(a, + LauncherInstance->getMPUserPath() + + a.substr(a.find_last_of('/')), + fs::copy_options::overwrite_existing); + } catch (std::exception& e) { + LOG(ERROR) << "Failed copy to the mods folder! " << e.what(); + Terminate = true; + continue; + } + WaitForConfirm(); continue; - Amount++; - } - if (!FNames.empty()) - LOG(INFO) << "Syncing..."; - SOCKET DSock = InitDSock(); - for (auto FN = FNames.begin(), FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN, ++FS) { - auto pos = FN->find_last_of('/'); - if (pos != std::string::npos) { - a = "Resources" + FN->substr(pos); - } else - continue; - Pos++; - if (fs::exists(a)) { - if (!std::all_of(FS->begin(), FS->end(), isdigit)) - continue; - if (fs::file_size(a) == std::stoull(*FS)) { - UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + a.substr(a.find_last_of('/'))); - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - try { - if (!fs::exists(LauncherInstance->getMPUserPath())) { - fs::create_directories(LauncherInstance->getMPUserPath()); - } - fs::copy_file(a, LauncherInstance->getMPUserPath() + a.substr(a.find_last_of('/')), - fs::copy_options::overwrite_existing); - } catch (std::exception& e) { - LOG(ERROR) << "Failed copy to the mods folder! " << e.what(); - Terminate = true; - continue; - } - WaitForConfirm(); - continue; - } else - remove(a.c_str()); - } - CheckForDir(); - std::string FName = a.substr(a.find_last_of('/')); - do { - TCPSend("f" + *FN); + } else remove(a.c_str()); + } + CheckForDir(); + std::string FName = a.substr(a.find_last_of('/')); + do { + TCPSend("f" + *FN); - std::string Data = TCPRcv(); - if (Data == "CO" || Terminate) { - Terminate = true; - UUl("Server cannot find " + FName); - break; - } + std::string Data = TCPRcv(); + if (Data == "CO" || Terminate) { + Terminate = true; + UUl("Server cannot find " + FName); + break; + } - std::string Name = std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + FName; + std::string Name = + std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + FName; - Data = MultiDownload(DSock, std::stoull(*FS), Name); + Data = MultiDownload(DSock, std::stoull(*FS), Name); - if (Terminate) - break; - UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + FName); - std::ofstream LFS; - LFS.open(a.c_str(), std::ios_base::app | std::ios::binary); - if (LFS.is_open()) { - LFS.write(&Data[0], std::streamsize(Data.size())); - LFS.close(); - } + if (Terminate) break; + UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + + ": " + FName); + std::ofstream LFS; + LFS.open(a.c_str(), std::ios_base::app | std::ios::binary); + if (LFS.is_open()) { + LFS.write(&Data[0], std::streamsize(Data.size())); + LFS.close(); + } - } while (fs::file_size(a) != std::stoull(*FS) && !Terminate); - if (!Terminate) { - if (!fs::exists(LauncherInstance->getMPUserPath())) { - fs::create_directories(LauncherInstance->getMPUserPath()); - } - fs::copy_file(a, LauncherInstance->getMPUserPath() + FName, fs::copy_options::overwrite_existing); - } - WaitForConfirm(); - } - KillSocket(DSock); - if (!Terminate) { - TCPSend("Done"); - LOG(INFO) << "Done!"; - } else { - UStatus = "start"; - LOG(INFO) << "Connection Terminated!"; - } + } while (fs::file_size(a) != std::stoull(*FS) && !Terminate); + if (!Terminate) { + if (!fs::exists(LauncherInstance->getMPUserPath())) { + fs::create_directories(LauncherInstance->getMPUserPath()); + } + fs::copy_file(a, LauncherInstance->getMPUserPath() + FName, + fs::copy_options::overwrite_existing); + } + WaitForConfirm(); + } + KillSocket(DSock); + if (!Terminate) { + TCPSend("Done"); + LOG(INFO) << "Done!"; + } else { + UStatus = "start"; + LOG(INFO) << "Connection Terminated!"; + } } diff --git a/src/Network/Server.cpp b/src/Network/Server.cpp index 10da784..fbc5770 100644 --- a/src/Network/Server.cpp +++ b/src/Network/Server.cpp @@ -6,364 +6,345 @@ #define WIN32_LEAN_AND_MEAN #include "Server.h" -#include "Compressor.h" -#include "Launcher.h" -#include "Logger.h" #include #include #include +#include "Compressor.h" +#include "Launcher.h" +#include "Logger.h" -Server::Server(Launcher* Instance) - : LauncherInstance(Instance) { - WSADATA wsaData; - int iRes = WSAStartup(514, &wsaData); // 2.2 - if (iRes != 0) { - LOG(ERROR) << "WSAStartup failed with error: " << iRes; - } - UDPSockAddress = std::make_unique(); +Server::Server(Launcher* Instance) : LauncherInstance(Instance) { + WSADATA wsaData; + int iRes = WSAStartup(514, &wsaData); // 2.2 + if (iRes != 0) { + LOG(ERROR) << "WSAStartup failed with error: " << iRes; + } + UDPSockAddress = std::make_unique(); } Server::~Server() { - Close(); - WSACleanup(); + Close(); + WSACleanup(); } void Server::TCPClientMain() { - SOCKADDR_IN ServerAddr; - TCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (TCPSocket == -1) { - LOG(ERROR) << "Socket failed! Error code: " << GetSocketApiError(); - return; - } - const char optval = 0; - int status = ::setsockopt(TCPSocket, SOL_SOCKET, SO_DONTLINGER, &optval, sizeof(optval)); - if (status < 0) { - LOG(INFO) << "Failed to set DONTLINGER: " << GetSocketApiError(); - } - ServerAddr.sin_family = AF_INET; - ServerAddr.sin_port = htons(Port); - inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); - status = connect(TCPSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)); - if (status != 0) { - UStatus = "Connection Failed!"; - LOG(ERROR) << "Connect failed! Error code: " << GetSocketApiError(); - Terminate.store(true); - return; - } + SOCKADDR_IN ServerAddr; + TCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (TCPSocket == -1) { + LOG(ERROR) << "Socket failed! Error code: " << GetSocketApiError(); + return; + } + const char optval = 0; + int status = ::setsockopt(TCPSocket, SOL_SOCKET, SO_DONTLINGER, &optval, + sizeof(optval)); + if (status < 0) { + LOG(INFO) << "Failed to set DONTLINGER: " << GetSocketApiError(); + } + ServerAddr.sin_family = AF_INET; + ServerAddr.sin_port = htons(Port); + inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); + status = connect(TCPSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)); + if (status != 0) { + UStatus = "Connection Failed!"; + LOG(ERROR) << "Connect failed! Error code: " << GetSocketApiError(); + Terminate.store(true); + return; + } - char Code = 'C'; - if (send(TCPSocket, &Code, 1, 0) != 1) { - Terminate.store(true); - return; - } - LOG(INFO) << "Connected!"; - SyncResources(); - while (!Terminate.load()) { - ServerParser(TCPRcv()); - } - LauncherInstance->SendIPC("T", false); - KillSocket(TCPSocket); + char Code = 'C'; + if (send(TCPSocket, &Code, 1, 0) != 1) { + Terminate.store(true); + return; + } + LOG(INFO) << "Connected!"; + SyncResources(); + while (!Terminate.load()) { + ServerParser(TCPRcv()); + } + LauncherInstance->SendIPC("T", false); + KillSocket(TCPSocket); } void Server::StartUDP() { - if (TCPConnection.joinable() && !UDPConnection.joinable()) { - LOG(INFO) << "Connecting UDP"; - UDPConnection = std::thread(&Server::UDPMain, this); - } + if (TCPConnection.joinable() && !UDPConnection.joinable()) { + LOG(INFO) << "Connecting UDP"; + UDPConnection = std::thread(&Server::UDPMain, this); + } } void Server::UDPSend(std::string Data) { - if (ClientID == -1 || UDPSocket == -1) - return; - if (Data.length() > 400) { - std::string CMP(Zlib::Comp(Data)); - Data = "ABG:" + CMP; - } - std::string Packet = char(ClientID + 1) + std::string(":") + Data; - int sendOk = sendto(UDPSocket, Packet.c_str(), int(Packet.size()), 0, (sockaddr*)UDPSockAddress.get(), - sizeof(sockaddr_in)); - if (sendOk == SOCKET_ERROR) - LOG(ERROR) << "UDP Socket Error Code : " << GetSocketApiError(); + if (ClientID == -1 || UDPSocket == -1) return; + if (Data.length() > 400) { + std::string CMP(Zlib::Comp(Data)); + Data = "ABG:" + CMP; + } + std::string Packet = char(ClientID + 1) + std::string(":") + Data; + int sendOk = sendto(UDPSocket, Packet.c_str(), int(Packet.size()), 0, + (sockaddr*)UDPSockAddress.get(), sizeof(sockaddr_in)); + if (sendOk == SOCKET_ERROR) + LOG(ERROR) << "UDP Socket Error Code : " << GetSocketApiError(); } void Server::UDPParser(std::string Packet) { - if (Packet.substr(0, 4) == "ABG:") { - Packet = Zlib::DeComp(Packet.substr(4)); - } - ServerParser(Packet); + if (Packet.substr(0, 4) == "ABG:") { + Packet = Zlib::DeComp(Packet.substr(4)); + } + ServerParser(Packet); } void Server::UDPRcv() { - sockaddr_in FromServer {}; - int clientLength = sizeof(FromServer); - ZeroMemory(&FromServer, clientLength); - std::string Ret(10240, 0); - if (UDPSocket == -1) - return; - int32_t Rcv = recvfrom(UDPSocket, &Ret[0], 10240, 0, (sockaddr*)&FromServer, &clientLength); - if (Rcv == SOCKET_ERROR) - return; - UDPParser(Ret.substr(0, Rcv)); + sockaddr_in FromServer{}; + int clientLength = sizeof(FromServer); + ZeroMemory(&FromServer, clientLength); + std::string Ret(10240, 0); + if (UDPSocket == -1) return; + int32_t Rcv = recvfrom(UDPSocket, &Ret[0], 10240, 0, (sockaddr*)&FromServer, + &clientLength); + if (Rcv == SOCKET_ERROR) return; + UDPParser(Ret.substr(0, Rcv)); } void Server::UDPClient() { - UDPSockAddress->sin_family = AF_INET; - UDPSockAddress->sin_port = htons(Port); - inet_pton(AF_INET, IP.c_str(), &UDPSockAddress->sin_addr); - UDPSocket = socket(AF_INET, SOCK_DGRAM, 0); - LauncherInstance->SendIPC("P" + std::to_string(ClientID), false); - TCPSend("H"); - UDPSend("p"); - while (!Terminate) - UDPRcv(); - KillSocket(UDPSocket); + UDPSockAddress->sin_family = AF_INET; + UDPSockAddress->sin_port = htons(Port); + inet_pton(AF_INET, IP.c_str(), &UDPSockAddress->sin_addr); + UDPSocket = socket(AF_INET, SOCK_DGRAM, 0); + LauncherInstance->SendIPC("P" + std::to_string(ClientID), false); + TCPSend("H"); + UDPSend("p"); + while (!Terminate) UDPRcv(); + KillSocket(UDPSocket); } void Server::UDPMain() { - AutoPing = std::thread(&Server::PingLoop, this); - UDPClient(); - Terminate = true; - LOG(INFO) << "Connection terminated"; + AutoPing = std::thread(&Server::PingLoop, this); + UDPClient(); + Terminate = true; + LOG(INFO) << "Connection terminated"; } void Server::Connect(const std::string& Data) { - ModList.clear(); - Terminate.store(false); - IP = GetAddress(Data.substr(1, Data.find(':') - 1)); - std::string port = Data.substr(Data.find(':') + 1); - bool ValidPort = std::all_of(port.begin(), port.end(), ::isdigit); - if (IP.find('.') == -1 || !ValidPort) { - if (IP == "DNS") - UStatus = "Connection Failed! (DNS Lookup Failed)"; - else if (!ValidPort) - UStatus = "Connection Failed! (Invalid Port)"; - else - UStatus = "Connection Failed! (WSA failed to start)"; - ModList = "-"; - Terminate.store(true); - return; - } - Port = std::stoi(port); - LauncherInstance->CheckKey(); - UStatus = "Loading..."; - Ping = -1; - TCPConnection = std::thread(&Server::TCPClientMain, this); - LOG(INFO) << "Connecting to server"; + ModList.clear(); + Terminate.store(false); + IP = GetAddress(Data.substr(1, Data.find(':') - 1)); + std::string port = Data.substr(Data.find(':') + 1); + bool ValidPort = std::all_of(port.begin(), port.end(), ::isdigit); + if (IP.find('.') == -1 || !ValidPort) { + if (IP == "DNS") UStatus = "Connection Failed! (DNS Lookup Failed)"; + else if (!ValidPort) UStatus = "Connection Failed! (Invalid Port)"; + else UStatus = "Connection Failed! (WSA failed to start)"; + ModList = "-"; + Terminate.store(true); + return; + } + Port = std::stoi(port); + LauncherInstance->CheckKey(); + UStatus = "Loading..."; + Ping = -1; + TCPConnection = std::thread(&Server::TCPClientMain, this); + LOG(INFO) << "Connecting to server"; } void Server::SendLarge(std::string Data) { - if (Data.length() > 400) { - std::string CMP(Zlib::Comp(Data)); - Data = "ABG:" + CMP; - } - TCPSend(Data); + if (Data.length() > 400) { + std::string CMP(Zlib::Comp(Data)); + Data = "ABG:" + CMP; + } + TCPSend(Data); } std::string Server::GetSocketApiError() { - // This will provide us with the error code and an error message, all in one. - // The resulting format is " - " - int err; - char msgbuf[256]; - msgbuf[0] = '\0'; + // This will provide us with the error code and an error message, all in one. + // The resulting format is " - " + int err; + char msgbuf[256]; + msgbuf[0] = '\0'; - err = WSAGetLastError(); + err = WSAGetLastError(); - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - msgbuf, - sizeof(msgbuf), - nullptr); + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + msgbuf, sizeof(msgbuf), nullptr); - if (*msgbuf) { - return std::to_string(WSAGetLastError()) + " - " + std::string(msgbuf); - } else { - return std::to_string(WSAGetLastError()); - } + if (*msgbuf) { + return std::to_string(WSAGetLastError()) + " - " + std::string(msgbuf); + } else { + return std::to_string(WSAGetLastError()); + } } void Server::ServerSend(std::string Data, bool Rel) { - if (Terminate || Data.empty()) - return; - char C = 0; - int DLen = int(Data.length()); - if (DLen > 3) - C = Data.at(0); - bool Ack = C == 'O' || C == 'T'; - if (C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C') - Rel = true; - if (Ack || Rel) { - if (Ack || DLen > 1000) - SendLarge(Data); - else - TCPSend(Data); - } else - UDPSend(Data); + if (Terminate || Data.empty()) return; + char C = 0; + int DLen = int(Data.length()); + if (DLen > 3) C = Data.at(0); + bool Ack = C == 'O' || C == 'T'; + if (C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C') + Rel = true; + if (Ack || Rel) { + if (Ack || DLen > 1000) SendLarge(Data); + else TCPSend(Data); + } else UDPSend(Data); } void Server::PingLoop() { - while (!Terminate) { - ServerSend("p", false); - PingStart = std::chrono::high_resolution_clock::now(); - std::this_thread::sleep_for(std::chrono::seconds(1)); - } + while (!Terminate) { + ServerSend("p", false); + PingStart = std::chrono::high_resolution_clock::now(); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } } void Server::Close() { - Terminate.store(true); - KillSocket(TCPSocket); - KillSocket(UDPSocket); - Ping = -1; - if (TCPConnection.joinable()) { - TCPConnection.join(); - } - if (UDPConnection.joinable()) { - UDPConnection.join(); - } - if (AutoPing.joinable()) { - AutoPing.join(); - } + Terminate.store(true); + KillSocket(TCPSocket); + KillSocket(UDPSocket); + Ping = -1; + if (TCPConnection.joinable()) { + TCPConnection.join(); + } + if (UDPConnection.joinable()) { + UDPConnection.join(); + } + if (AutoPing.joinable()) { + AutoPing.join(); + } } const std::string& Server::getMap() { - return MStatus; + return MStatus; } bool Server::Terminated() { - return Terminate; + return Terminate; } const std::string& Server::getModList() { - return ModList; + return ModList; } int Server::getPing() const { - return Ping; + return Ping; } const std::string& Server::getUIStatus() { - return UStatus; + return UStatus; } std::string Server::GetAddress(const std::string& Data) { - if (Data.find_first_not_of("0123456789.") == -1) - return Data; - hostent* host; - host = gethostbyname(Data.c_str()); - if (!host) { - LOG(ERROR) << "DNS lookup failed! on " << Data; - return "DNS"; - } - std::string Ret = inet_ntoa(*((struct in_addr*)host->h_addr)); - return Ret; + if (Data.find_first_not_of("0123456789.") == -1) return Data; + hostent* host; + host = gethostbyname(Data.c_str()); + if (!host) { + LOG(ERROR) << "DNS lookup failed! on " << Data; + return "DNS"; + } + std::string Ret = inet_ntoa(*((struct in_addr*)host->h_addr)); + return Ret; } int Server::KillSocket(uint64_t Dead) { - if (Dead == (SOCKET)-1) - return 0; - shutdown(Dead, SD_BOTH); - return closesocket(Dead); + if (Dead == (SOCKET)-1) return 0; + shutdown(Dead, SD_BOTH); + return closesocket(Dead); } void Server::setModLoaded() { - ModLoaded.store(true); + ModLoaded.store(true); } void Server::UUl(const std::string& R) { - UStatus = "Disconnected: " + R; + UStatus = "Disconnected: " + R; } bool Server::CheckBytes(int32_t Bytes) { - if (Bytes == 0) { - // debug("(TCP) Connection closing... CheckBytes(16)"); - Terminate = true; - return false; - } else if (Bytes < 0) { - // debug("(TCP CB) recv failed with error: " + GetSocketApiError(); - KillSocket(TCPSocket); - Terminate = true; - return false; - } - return true; + if (Bytes == 0) { + // debug("(TCP) Connection closing... CheckBytes(16)"); + Terminate = true; + return false; + } else if (Bytes < 0) { + // debug("(TCP CB) recv failed with error: " + GetSocketApiError(); + KillSocket(TCPSocket); + Terminate = true; + return false; + } + return true; } void Server::TCPSend(const std::string& Data) { + if (TCPSocket == -1) { + Terminate = true; + UUl("Invalid Socket"); + return; + } - if (TCPSocket == -1) { - Terminate = true; - UUl("Invalid Socket"); - return; - } - - int32_t Size, Sent, Temp; - std::string Send(4, 0); - Size = int32_t(Data.size()); - memcpy(&Send[0], &Size, sizeof(Size)); - Send += Data; - // Do not use Size before this point for anything but the header - Sent = 0; - Size += 4; - do { - if (size_t(Sent) >= Send.size()) { - LOG(ERROR) << "string OOB in " << std::string(__func__); - UUl("TCP Send OOB"); - Terminate = true; - return; - } - Temp = send(TCPSocket, &Send[Sent], Size - Sent, 0); - if (!CheckBytes(Temp)) { - UUl("Socket Closed Code 2"); - Terminate = true; - return; - } - Sent += Temp; - } while (Sent < Size); + int32_t Size, Sent, Temp; + std::string Send(4, 0); + Size = int32_t(Data.size()); + memcpy(&Send[0], &Size, sizeof(Size)); + Send += Data; + // Do not use Size before this point for anything but the header + Sent = 0; + Size += 4; + do { + if (size_t(Sent) >= Send.size()) { + LOG(ERROR) << "string OOB in " << std::string(__func__); + UUl("TCP Send OOB"); + Terminate = true; + return; + } + Temp = send(TCPSocket, &Send[Sent], Size - Sent, 0); + if (!CheckBytes(Temp)) { + UUl("Socket Closed Code 2"); + Terminate = true; + return; + } + Sent += Temp; + } while (Sent < Size); } std::string Server::TCPRcv() { - if (TCPSocket == -1) { - Terminate = true; - UUl("Invalid Socket"); - return ""; - } - int32_t Header, BytesRcv = 0, Temp; - std::vector Data(sizeof(Header)); - do { - Temp = recv(TCPSocket, &Data[BytesRcv], 4 - BytesRcv, 0); - if (!CheckBytes(Temp)) { - UUl("Socket Closed Code 3"); - Terminate = true; - return ""; - } - BytesRcv += Temp; - } while (BytesRcv < 4); - memcpy(&Header, &Data[0], sizeof(Header)); + if (TCPSocket == -1) { + Terminate = true; + UUl("Invalid Socket"); + return ""; + } + int32_t Header, BytesRcv = 0, Temp; + std::vector Data(sizeof(Header)); + do { + Temp = recv(TCPSocket, &Data[BytesRcv], 4 - BytesRcv, 0); + if (!CheckBytes(Temp)) { + UUl("Socket Closed Code 3"); + Terminate = true; + return ""; + } + BytesRcv += Temp; + } while (BytesRcv < 4); + memcpy(&Header, &Data[0], sizeof(Header)); - if (!CheckBytes(BytesRcv)) { - UUl("Socket Closed Code 4"); - Terminate = true; - return ""; - } - Data.resize(Header); - BytesRcv = 0; - do { - Temp = recv(TCPSocket, &Data[BytesRcv], Header - BytesRcv, 0); - if (!CheckBytes(Temp)) { - UUl("Socket Closed Code 5"); - Terminate = true; - return ""; - } - BytesRcv += Temp; - } while (BytesRcv < Header); + if (!CheckBytes(BytesRcv)) { + UUl("Socket Closed Code 4"); + Terminate = true; + return ""; + } + Data.resize(Header); + BytesRcv = 0; + do { + Temp = recv(TCPSocket, &Data[BytesRcv], Header - BytesRcv, 0); + if (!CheckBytes(Temp)) { + UUl("Socket Closed Code 5"); + Terminate = true; + return ""; + } + BytesRcv += Temp; + } while (BytesRcv < Header); - std::string Ret(Data.data(), Header); + std::string Ret(Data.data(), Header); - if (Ret.substr(0, 4) == "ABG:") { - Ret = Zlib::DeComp(Ret.substr(4)); - } + if (Ret.substr(0, 4) == "ABG:") { + Ret = Zlib::DeComp(Ret.substr(4)); + } - if (Ret[0] == 'E') - UUl(Ret.substr(1)); - return Ret; + if (Ret[0] == 'E') UUl(Ret.substr(1)); + return Ret; } diff --git a/src/Network/Update.cpp b/src/Network/Update.cpp index c37ac21..26d9512 100644 --- a/src/Network/Update.cpp +++ b/src/Network/Update.cpp @@ -9,137 +9,132 @@ #include "Logger.h" VersionParser::VersionParser(const std::string& from_string) { - std::string token; - std::istringstream tokenStream(from_string); - while (std::getline(tokenStream, token, '.')) { - data.emplace_back(std::stol(token)); - split.emplace_back(token); - } + std::string token; + std::istringstream tokenStream(from_string); + while (std::getline(tokenStream, token, '.')) { + data.emplace_back(std::stol(token)); + split.emplace_back(token); + } } -std::strong_ordering VersionParser::operator<=>(const VersionParser& rhs) const noexcept { - size_t const fields = std::min(data.size(), rhs.data.size()); - for (size_t i = 0; i != fields; ++i) { - if (data[i] == rhs.data[i]) - continue; - else if (data[i] < rhs.data[i]) - return std::strong_ordering::less; - else - return std::strong_ordering::greater; - } - if (data.size() == rhs.data.size()) - return std::strong_ordering::equal; - else if (data.size() > rhs.data.size()) - return std::strong_ordering::greater; - else - return std::strong_ordering::less; +std::strong_ordering VersionParser::operator<=>( + const VersionParser& rhs) const noexcept { + size_t const fields = std::min(data.size(), rhs.data.size()); + for (size_t i = 0; i != fields; ++i) { + if (data[i] == rhs.data[i]) continue; + else if (data[i] < rhs.data[i]) return std::strong_ordering::less; + else return std::strong_ordering::greater; + } + if (data.size() == rhs.data.size()) return std::strong_ordering::equal; + else if (data.size() > rhs.data.size()) return std::strong_ordering::greater; + else return std::strong_ordering::less; } bool VersionParser::operator==(const VersionParser& rhs) const noexcept { - return std::is_eq(*this <=> rhs); + return std::is_eq(*this <=> rhs); } void Launcher::UpdateCheck() { - std::string link; - std::string HTTP = HTTP::Get("https://beammp.com/builds/launcher?version=true"); - bool fallback = false; - if (HTTP.find_first_of("0123456789") == std::string::npos) { - HTTP = HTTP::Get("https://backup1.beammp.com/builds/launcher?version=true"); - fallback = true; - if (HTTP.find_first_of("0123456789") == std::string::npos) { - LOG(FATAL) << "Primary Servers Offline! sorry for the inconvenience!"; - throw ShutdownException("Fatal Error"); - } - } - if (fallback) { - link = "https://backup1.beammp.com/builds/launcher?download=true"; - } else - link = "https://beammp.com/builds/launcher?download=true"; + std::string link; + std::string HTTP = + HTTP::Get("https://beammp.com/builds/launcher?version=true"); + bool fallback = false; + if (HTTP.find_first_of("0123456789") == std::string::npos) { + HTTP = + HTTP::Get("https://backup1.beammp.com/builds/launcher?version=true"); + fallback = true; + if (HTTP.find_first_of("0123456789") == std::string::npos) { + LOG(FATAL) << "Primary Servers Offline! sorry for the inconvenience!"; + throw ShutdownException("Fatal Error"); + } + } + if (fallback) { + link = "https://backup1.beammp.com/builds/launcher?download=true"; + } else link = "https://beammp.com/builds/launcher?download=true"; - std::string EP(CurrentPath.string()), Back(CurrentPath.parent_path().string() + "\\BeamMP-Launcher.back"); + std::string EP(CurrentPath.string()), + Back(CurrentPath.parent_path().string() + "\\BeamMP-Launcher.back"); - if (fs::exists(Back)) - remove(Back.c_str()); - std::string RemoteVer; - for (char& c : HTTP) { - if (std::isdigit(c) || c == '.') { - RemoteVer += c; - } - } + if (fs::exists(Back)) remove(Back.c_str()); + std::string RemoteVer; + for (char& c : HTTP) { + if (std::isdigit(c) || c == '.') { + RemoteVer += c; + } + } - if (VersionParser(RemoteVer) > VersionParser(FullVersion)) { - system("cls"); - LOG(INFO) << "Update found! Downloading..."; - if (std::rename(EP.c_str(), Back.c_str())) { - LOG(ERROR) << "Failed to create a backup!"; - } + if (VersionParser(RemoteVer) > VersionParser(FullVersion)) { + system("cls"); + LOG(INFO) << "Update found! Downloading..."; + if (std::rename(EP.c_str(), Back.c_str())) { + LOG(ERROR) << "Failed to create a backup!"; + } - if (!HTTP::Download(link, EP)) { - LOG(ERROR) << "Launcher Update failed! trying again..."; - std::this_thread::sleep_for(std::chrono::seconds(2)); + if (!HTTP::Download(link, EP)) { + LOG(ERROR) << "Launcher Update failed! trying again..."; + std::this_thread::sleep_for(std::chrono::seconds(2)); - if (!HTTP::Download(link, EP)) { - LOG(ERROR) << "Launcher Update failed!"; - std::this_thread::sleep_for(std::chrono::seconds(5)); - AdminRelaunch(); - } - } - Relaunch(); - } else - LOG(INFO) << "Launcher version is up to date"; + if (!HTTP::Download(link, EP)) { + LOG(ERROR) << "Launcher Update failed!"; + std::this_thread::sleep_for(std::chrono::seconds(5)); + AdminRelaunch(); + } + } + Relaunch(); + } else LOG(INFO) << "Launcher version is up to date"; } size_t DirCount(const std::filesystem::path& path) { - return (size_t)std::distance(std::filesystem::directory_iterator { path }, std::filesystem::directory_iterator {}); + return (size_t)std::distance(std::filesystem::directory_iterator{path}, + std::filesystem::directory_iterator{}); } void Launcher::ResetMods() { - if (!fs::exists(MPUserPath)) { - fs::create_directories(MPUserPath); - return; - } - if (DirCount(fs::path(MPUserPath)) > 3) { - LOG(WARNING) << "mods/multiplayer will be cleared in 15 seconds, close to abort"; - std::this_thread::sleep_for(std::chrono::seconds(15)); - } - fs::remove_all(MPUserPath); - fs::create_directories(MPUserPath); + if (!fs::exists(MPUserPath)) { + fs::create_directories(MPUserPath); + return; + } + if (DirCount(fs::path(MPUserPath)) > 3) { + LOG(WARNING) + << "mods/multiplayer will be cleared in 15 seconds, close to abort"; + std::this_thread::sleep_for(std::chrono::seconds(15)); + } + fs::remove_all(MPUserPath); + fs::create_directories(MPUserPath); } void Launcher::EnableMP() { - std::string File(BeamUserPath + "mods\\db.json"); - if (!fs::exists(File)) - return; - auto Size = fs::file_size(File); - if (Size < 2) - return; - std::ifstream db(File); - if (db.is_open()) { - std::string Data(Size, 0); - db.read(&Data[0], std::streamsize(Size)); - db.close(); - Json d = Json::parse(Data, nullptr, false); - if (Data.at(0) != '{' || d.is_discarded()) - return; - if (!d["mods"].is_null() && !d["mods"]["multiplayerbeammp"].is_null()) { - d["mods"]["multiplayerbeammp"]["active"] = true; - std::ofstream ofs(File); - if (ofs.is_open()) { - ofs << std::setw(4) << d; - ofs.close(); - } else { - LOG(ERROR) << "Failed to write " << File; - } - } - } + std::string File(BeamUserPath + "mods\\db.json"); + if (!fs::exists(File)) return; + auto Size = fs::file_size(File); + if (Size < 2) return; + std::ifstream db(File); + if (db.is_open()) { + std::string Data(Size, 0); + db.read(&Data[0], std::streamsize(Size)); + db.close(); + Json d = Json::parse(Data, nullptr, false); + if (Data.at(0) != '{' || d.is_discarded()) return; + if (!d["mods"].is_null() && !d["mods"]["multiplayerbeammp"].is_null()) { + d["mods"]["multiplayerbeammp"]["active"] = true; + std::ofstream ofs(File); + if (ofs.is_open()) { + ofs << std::setw(4) << d; + ofs.close(); + } else { + LOG(ERROR) << "Failed to write " << File; + } + } + } } void Launcher::SetupMOD() { - ResetMods(); - EnableMP(); - LOG(INFO) << "Downloading mod please wait"; - HTTP::Download("https://backend.beammp.com/builds/client?download=true" - "&pk=" - + PublicKey + "&branch=" + TargetBuild, - MPUserPath + "\\BeamMP.zip"); + ResetMods(); + EnableMP(); + LOG(INFO) << "Downloading mod please wait"; + HTTP::Download( + "https://backend.beammp.com/builds/client?download=true" + "&pk=" + + PublicKey + "&branch=" + TargetBuild, + MPUserPath + "\\BeamMP.zip"); } diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp index 3ed06dd..11b9aa3 100644 --- a/src/gui/Gui.cpp +++ b/src/gui/Gui.cpp @@ -4,86 +4,83 @@ /// #define _CRT_SECURE_NO_WARNINGS -#include #include +#include #ifndef WX_PRECOMP -#include "gifs.h" #include #include #include +#include "gifs.h" #endif class MyApp : public wxApp { -public: - virtual bool OnInit(); + public: + virtual bool OnInit(); }; class MyFrame : public wxFrame { -public: - MyFrame(); + public: + MyFrame(); -private: - void OnHello(wxCommandEvent& event); - void OnExit(wxCommandEvent& event); - void OnAbout(wxCommandEvent& event); - static wxSize FixedSize; -}; -enum { - ID_Hello = 1 + private: + void OnHello(wxCommandEvent& event); + void OnExit(wxCommandEvent& event); + void OnAbout(wxCommandEvent& event); + static wxSize FixedSize; }; +enum { ID_Hello = 1 }; wxSize MyFrame::FixedSize(370, 400); bool MyApp::OnInit() { - auto* frame = new MyFrame(); - frame->Show(true); - return true; + auto* frame = new MyFrame(); + frame->Show(true); + return true; } -MyFrame::MyFrame() - : wxFrame(nullptr, wxID_ANY, "BeamMP V3.0", wxDefaultPosition, FixedSize) { - // SetMaxSize(FixedSize); - // SetMinSize(FixedSize); - Center(); +MyFrame::MyFrame() : + wxFrame(nullptr, wxID_ANY, "BeamMP V3.0", wxDefaultPosition, FixedSize) { + // SetMaxSize(FixedSize); + // SetMinSize(FixedSize); + Center(); - // 27 35 35 + // 27 35 35 - wxColour Colour(27, 35, 35, 1); - SetBackgroundColour(Colour); + wxColour Colour(27, 35, 35, 1); + SetBackgroundColour(Colour); - auto* menuFile = new wxMenu; - menuFile->Append(ID_Hello, "&Hello...\tCtrl-H", - "Help string shown in status bar for this menu item"); - menuFile->AppendSeparator(); - menuFile->Append(wxID_EXIT); - auto* menuHelp = new wxMenu; - menuHelp->Append(wxID_ABOUT); - auto* menuBar = new wxMenuBar; + auto* menuFile = new wxMenu; + menuFile->Append(ID_Hello, "&Hello...\tCtrl-H", + "Help string shown in status bar for this menu item"); + menuFile->AppendSeparator(); + menuFile->Append(wxID_EXIT); + auto* menuHelp = new wxMenu; + menuHelp->Append(wxID_ABOUT); + auto* menuBar = new wxMenuBar; - menuBar->SetOwnBackgroundColour(Colour); - menuBar->Append(menuFile, "&File"); - menuBar->Append(menuHelp, "&Help"); - // SetMenuBar(menuBar); + menuBar->SetOwnBackgroundColour(Colour); + menuBar->Append(menuFile, "&File"); + menuBar->Append(menuHelp, "&Help"); + // SetMenuBar(menuBar); - auto* m_ani = new wxAnimationCtrl(this, wxID_ANY); - wxMemoryInputStream stream(gif::Logo, sizeof(gif::Logo)); - if (m_ani->Load(stream)) - m_ani->Play(); + auto* m_ani = new wxAnimationCtrl(this, wxID_ANY); + wxMemoryInputStream stream(gif::Logo, sizeof(gif::Logo)); + if (m_ani->Load(stream)) m_ani->Play(); - Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello); - Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT); - Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT); + Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello); + Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT); + Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT); } void MyFrame::OnExit(wxCommandEvent& event) { - Close(true); + Close(true); } void MyFrame::OnAbout(wxCommandEvent& event) { - wxMessageBox("This is a wxWidgets Hello World example", - "About Hello World", wxOK | wxICON_INFORMATION); + wxMessageBox("This is a wxWidgets Hello World example", "About Hello World", + wxOK | wxICON_INFORMATION); } void MyFrame::OnHello(wxCommandEvent& event) { - wxLogMessage("Hello world from wxWidgets!"); + wxLogMessage("Hello world from wxWidgets!"); } int GUIEntry(int argc, char* argv[]) { - new MyApp(); - return wxEntry(argc, argv); + new MyApp(); + return wxEntry(argc, argv); } \ No newline at end of file diff --git a/src/gui/gifs.cpp b/src/gui/gifs.cpp index 186c769..5115574 100644 --- a/src/gui/gifs.cpp +++ b/src/gui/gifs.cpp @@ -2541,5 +2541,4 @@ const unsigned char gif::Logo[30427] = { 0x54, 0x60, 0x2a, 0x56, 0xf9, 0x40, 0x72, 0x48, 0xd1, 0x81, 0x5e, 0x5e, 0x63, 0x02, 0x28, 0x40, 0x8a, 0x55, 0x48, 0x70, 0x02, 0x61, 0x96, 0x92, 0x02, 0x96, 0xe1, 0x40, 0x62, 0x2e, 0x40, 0x1a, 0x86, 0x60, 0x00, 0x30, - 0xd5, 0x7c, 0x4a, 0x20, 0x00, 0x00, 0x3b -}; + 0xd5, 0x7c, 0x4a, 0x20, 0x00, 0x00, 0x3b}; diff --git a/src/gui/gifs.h b/src/gui/gifs.h index b4a9f73..03955b0 100644 --- a/src/gui/gifs.h +++ b/src/gui/gifs.h @@ -6,6 +6,6 @@ #pragma once class gif { -public: - static const unsigned char Logo[30427]; + public: + static const unsigned char Logo[30427]; }; diff --git a/src/main.cpp b/src/main.cpp index c9775d9..627e477 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,23 +7,23 @@ #include "Logger.h" int main(int argc, char* argv[]) { - try { - Launcher launcher(argc, argv); - launcher.RunDiscordRPC(); - launcher.LoadConfig(); // check if json (issue) - launcher.CheckKey(); - launcher.QueryRegistry(); - // UI call - // launcher.SetupMOD(); - launcher.LaunchGame(); - launcher.WaitForGame(); - LOG(INFO) << "Launcher shutting down"; - } catch (const ShutdownException& e) { - LOG(INFO) << "Launcher shutting down with reason: " << e.what(); - } catch (const std::exception& e) { - LOG(FATAL) << e.what(); - } - std::this_thread::sleep_for(std::chrono::seconds(2)); - Launcher::setExit(true); - return 0; + try { + Launcher launcher(argc, argv); + launcher.RunDiscordRPC(); + launcher.LoadConfig(); // check if json (issue) + launcher.CheckKey(); + launcher.QueryRegistry(); + // UI call + // launcher.SetupMOD(); + launcher.LaunchGame(); + launcher.WaitForGame(); + LOG(INFO) << "Launcher shutting down"; + } catch (const ShutdownException& e) { + LOG(INFO) << "Launcher shutting down with reason: " << e.what(); + } catch (const std::exception& e) { + LOG(FATAL) << e.what(); + } + std::this_thread::sleep_for(std::chrono::seconds(2)); + Launcher::setExit(true); + return 0; }