From 5735731c3ef023596c35b1c6bb7ac28c314eac53 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 23 Feb 2017 21:36:02 +0100 Subject: [PATCH 01/13] [Toast] Disable toasts for dedis --- src/Components/Modules/Toast.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Components/Modules/Toast.cpp b/src/Components/Modules/Toast.cpp index 501db34a..a22767cd 100644 --- a/src/Components/Modules/Toast.cpp +++ b/src/Components/Modules/Toast.cpp @@ -146,6 +146,8 @@ namespace Components Toast::Toast() { + if (Dedicated::IsEnabled()) return; + Toast::ToastHandler = new WinToastLib::WinToastHandler; WinToastLib::WinToast::instance()->setAppName(L"IW4x"); @@ -170,6 +172,8 @@ namespace Components void Toast::preDestroy() { + if (Dedicated::IsEnabled()) return; + // Destroying that on the main thread deadlocks, for whatever reason. // I did not write the library, so whatever. std::thread([]() From 76c3a2f3309d8da480340f6d0262047ac6053b7b Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 24 Feb 2017 09:01:28 +0100 Subject: [PATCH 02/13] [Submodules] Update libtomcrypt and protobuf --- deps/libtomcrypt | 2 +- deps/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index c39390db..ecb2402b 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit c39390dba1dc519988fe8f6b1af6fdec24f86fc5 +Subproject commit ecb2402ba8d5f8f7fdacbbdf0e8e168d4c435ab5 diff --git a/deps/protobuf b/deps/protobuf index 17174b54..963473b1 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 17174b54ddd040a326dec6db75d1bfb5e5b3caa9 +Subproject commit 963473b1dd4f37c5c0b8ca72f1c4a05225b927b7 From 1d7006c420b39ac1a63f6e5c33a2605191b7e246 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 24 Feb 2017 11:43:05 +0100 Subject: [PATCH 03/13] [Utils] Inline array merging --- src/Utils/Utils.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Utils/Utils.hpp b/src/Utils/Utils.hpp index 13b25be9..130075ba 100644 --- a/src/Utils/Utils.hpp +++ b/src/Utils/Utils.hpp @@ -9,7 +9,7 @@ namespace Utils bool IsWineEnvironment(); - template void Merge(std::vector* target, T* source, size_t length) + template inline void Merge(std::vector* target, T* source, size_t length) { if (source) { @@ -20,7 +20,7 @@ namespace Utils } } - template void Merge(std::vector* target, std::vector source) + template inline void Merge(std::vector* target, std::vector source) { for (auto &entry : source) { From d3ca680e7ad718eed97104ea594d0d3b664bfa58 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 24 Feb 2017 12:15:15 +0100 Subject: [PATCH 04/13] [Menus] Safely merge menus when loading them --- src/Components/Modules/Menus.cpp | 61 ++++++++++++++++++++++++++++++-- src/Components/Modules/Menus.hpp | 1 + 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index 465abc40..ea20d855 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -261,6 +261,63 @@ namespace Components return newList; } + void Menus::SafeMergeMenus(std::vector* menus, std::vector newMenus) + { + // Check if we overwrote a menu + for (unsigned int i = 0; i < menus->size(); ++i) + { + // Try to find the native menu + bool found = false; + std::pair pair(menus->at(i), &found); + Game::DB_EnumXAssets_Internal(Game::XAssetType::ASSET_TYPE_MENU, [](Game::XAssetHeader header, void* data) + { + std::pair* pairPtr = reinterpret_cast*>(data); + + if(pairPtr->first == header.menu) + { + *pairPtr->second = true; + } + + }, &pair, false); + + // If there is none, try to find a custom menu + if (!found) + { + for (auto& entry : Menus::MenuList) + { + if (menus->at(i) == entry.second) + { + found = true; + break; + } + } + } + + // Remove the menu if it has been deallocated (not found) + if (!found) + { + menus->erase(menus->begin() + i); + --i; + continue; + } + + // Remove the menu if it has been loaded twice + for (auto& newMenu : newMenus) + { + if (menus->at(i)->window.name == std::string(newMenu->window.name)) + { + Menus::RemoveMenu(menus->at(i)); + + menus->erase(menus->begin() + i); + --i; + break; + } + } + } + + Utils::Merge(menus, newMenus); + } + Game::MenuList* Menus::LoadMenuList(Game::MenuList* menuList) { std::vector menus; @@ -268,7 +325,7 @@ namespace Components for (int i = 0; i < menuList->menuCount; ++i) { if (!menuList->menus[i]) continue; - Utils::Merge(&menus, Menus::LoadMenu(menuList->menus[i])); + Menus::SafeMergeMenus(&menus, Menus::LoadMenu(menuList->menus[i])); } // Load custom menus @@ -286,7 +343,7 @@ namespace Components } } - if(!hasMenu) Utils::Merge(&menus, Menus::LoadMenu(menu)); + if (!hasMenu) Menus::SafeMergeMenus(&menus, Menus::LoadMenu(menu)); } } diff --git a/src/Components/Modules/Menus.hpp b/src/Components/Modules/Menus.hpp index 87a04915..2fc9d234 100644 --- a/src/Components/Modules/Menus.hpp +++ b/src/Components/Modules/Menus.hpp @@ -31,6 +31,7 @@ namespace Components static Game::MenuList* LoadScriptMenu(const char* menu); static std::vector LoadMenu(Game::menuDef_t* menudef); static std::vector LoadMenu(std::string file); + static void SafeMergeMenus(std::vector* menus, std::vector newMenus); static Game::script_t* LoadMenuScript(std::string name, std::string buffer); static int LoadMenuSource(std::string name, std::string buffer); From a3cb37f7e4fde811b7c66006d984867bd58acaba Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 24 Feb 2017 13:30:31 +0100 Subject: [PATCH 05/13] [Toast] Uninitialize if possible --- src/Components/Loader.cpp | 29 ++++++++++++++++++++++++++--- src/Components/Loader.hpp | 2 ++ src/Components/Modules/Toast.cpp | 21 +++++++++++++++++---- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 9d0e6fc9..bb972dc5 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -12,6 +12,11 @@ namespace Components return Loader::Pregame; } + bool Loader::IsPostgame() + { + return Loader::Postgame; + } + void Loader::Initialize() { Loader::Pregame = true; @@ -93,7 +98,7 @@ namespace Components void Loader::Uninitialize() { - Loader::PreDestroy(); + Loader::PreDestroyNoPostGame(); std::reverse(Loader::Components.begin(), Loader::Components.end()); for (auto component : Loader::Components) @@ -119,14 +124,32 @@ namespace Components { Loader::Postgame = true; - std::reverse(Loader::Components.begin(), Loader::Components.end()); - for (auto component : Loader::Components) + auto components = Loader::Components; + + std::reverse(components.begin(), components.end()); + for (auto component : components) { component->preDestroy(); } } } + void Loader::PreDestroyNoPostGame() + { + if (!Loader::Postgame) + { + auto components = Loader::Components; + + std::reverse(components.begin(), components.end()); + for (auto component : components) + { + component->preDestroy(); + } + + Loader::Postgame = true; + } + } + bool Loader::PerformUnitTests() { bool result = true; diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 48297593..96f6acc1 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -25,11 +25,13 @@ namespace Components static void Initialize(); static void Uninitialize(); static void PreDestroy(); + static void PreDestroyNoPostGame(); static bool PerformUnitTests(); static bool PerformingUnitTests(); static void Register(Component* component); static bool IsPregame(); + static bool IsPostgame(); static Utils::Memory::Allocator* GetAlloctor(); diff --git a/src/Components/Modules/Toast.cpp b/src/Components/Modules/Toast.cpp index a22767cd..5953c85b 100644 --- a/src/Components/Modules/Toast.cpp +++ b/src/Components/Modules/Toast.cpp @@ -174,13 +174,26 @@ namespace Components { if (Dedicated::IsEnabled()) return; - // Destroying that on the main thread deadlocks, for whatever reason. + // Destroying that on the main thread deadlocks. // I did not write the library, so whatever. - std::thread([]() + // If we are not in the postgame state, + // we are not allowed to spawn threads, + // so just don't uninitialize the library. + // That means we did not uninitialize the game + // correctly anyways. + if (Loader::IsPostgame()) + { + std::thread([]() + { + delete WinToastLib::WinToast::instance(); + delete Toast::ToastHandler; + Toast::ToastHandler = nullptr; + }).join(); + } + else { - delete WinToastLib::WinToast::instance(); delete Toast::ToastHandler; Toast::ToastHandler = nullptr; - }).join(); + } } } From 63e7426d8e308ce45b7a9aec3e8153efc4c2259e Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 24 Feb 2017 20:21:48 +0100 Subject: [PATCH 06/13] [Submodules] Update libtomcrypt --- deps/libtomcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index ecb2402b..f60e0450 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit ecb2402ba8d5f8f7fdacbbdf0e8e168d4c435ab5 +Subproject commit f60e04503464a05265796134a244847019f08075 From 04d09b39e034fe842a82525b1dd97269edb35b7e Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 24 Feb 2017 20:22:53 +0100 Subject: [PATCH 07/13] [Menus] Store if menu is native of custom instead of enumerating menus --- src/Components/Modules/Menus.cpp | 51 ++++++++++++++------------------ src/Components/Modules/Menus.hpp | 6 ++-- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index ea20d855..9917c956 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -169,9 +169,9 @@ namespace Components return menu; } - std::vector Menus::LoadMenu(std::string menu) + std::vector> Menus::LoadMenu(std::string menu) { - std::vector menus; + std::vector> menus; FileSystem::File menuFile(menu); if (menuFile.exists()) @@ -200,7 +200,7 @@ namespace Components if (!_stricmp(token.string, "menudef")) { Game::menuDef_t* menudef = Menus::ParseMenu(handle); - if (menudef) menus.push_back(menudef); + if (menudef) menus.push_back({ true, menudef }); // Custom menu } } @@ -211,9 +211,9 @@ namespace Components return menus; } - std::vector Menus::LoadMenu(Game::menuDef_t* menudef) + std::vector> Menus::LoadMenu(Game::menuDef_t* menudef) { - std::vector menus = Menus::LoadMenu(Utils::String::VA("ui_mp\\%s.menu", menudef->window.name)); + std::vector> menus = Menus::LoadMenu(Utils::String::VA("ui_mp\\%s.menu", menudef->window.name)); if (menus.empty()) { @@ -222,11 +222,11 @@ namespace Components // // if (originalMenu) // { -// menus.push_back(originalMenu); +// menus.push_back({ false, originalMenu }); // } // else // { - menus.push_back(menudef); + menus.push_back({ false, menudef }); // Native menu // } } @@ -235,7 +235,7 @@ namespace Components Game::MenuList* Menus::LoadScriptMenu(const char* menu) { - std::vector menus = Menus::LoadMenu(menu); + std::vector> menus = Menus::LoadMenu(menu); if (menus.empty()) return nullptr; // Allocate new menu list @@ -253,7 +253,10 @@ namespace Components newList->menuCount = menus.size(); // Copy new menus - std::memcpy(newList->menus, menus.data(), menus.size() * sizeof(Game::menuDef_t *)); + for(unsigned int i = 0; i < menus.size(); ++i) + { + newList->menus[i] = menus[i].second; + } Menus::RemoveMenuList(newList->name); Menus::MenuListList[newList->name] = newList; @@ -261,31 +264,20 @@ namespace Components return newList; } - void Menus::SafeMergeMenus(std::vector* menus, std::vector newMenus) + void Menus::SafeMergeMenus(std::vector>* menus, std::vector> newMenus) { // Check if we overwrote a menu for (unsigned int i = 0; i < menus->size(); ++i) { // Try to find the native menu - bool found = false; - std::pair pair(menus->at(i), &found); - Game::DB_EnumXAssets_Internal(Game::XAssetType::ASSET_TYPE_MENU, [](Game::XAssetHeader header, void* data) - { - std::pair* pairPtr = reinterpret_cast*>(data); - - if(pairPtr->first == header.menu) - { - *pairPtr->second = true; - } - - }, &pair, false); + bool found = !menus->at(i).first; // Only if custom menu, try to find it // If there is none, try to find a custom menu if (!found) { for (auto& entry : Menus::MenuList) { - if (menus->at(i) == entry.second) + if (menus->at(i).second == entry.second) { found = true; break; @@ -304,9 +296,9 @@ namespace Components // Remove the menu if it has been loaded twice for (auto& newMenu : newMenus) { - if (menus->at(i)->window.name == std::string(newMenu->window.name)) + if (menus->at(i).second->window.name == std::string(newMenu.second->window.name)) { - Menus::RemoveMenu(menus->at(i)); + Menus::RemoveMenu(menus->at(i).second); menus->erase(menus->begin() + i); --i; @@ -320,7 +312,7 @@ namespace Components Game::MenuList* Menus::LoadMenuList(Game::MenuList* menuList) { - std::vector menus; + std::vector> menus; for (int i = 0; i < menuList->menuCount; ++i) { @@ -336,7 +328,7 @@ namespace Components bool hasMenu = false; for(auto &loadedMenu : menus) { - if(loadedMenu->window.name == menu) + if(loadedMenu.second->window.name == menu) { hasMenu = true; break; @@ -363,7 +355,10 @@ namespace Components newList->menuCount = size; // Copy new menus - std::memcpy(newList->menus, menus.data(), size * sizeof(Game::menuDef_t *)); + for (unsigned int i = 0; i < menus.size(); ++i) + { + newList->menus[i] = menus[i].second; + } Menus::RemoveMenuList(newList->name); Menus::MenuListList[newList->name] = newList; diff --git a/src/Components/Modules/Menus.hpp b/src/Components/Modules/Menus.hpp index 2fc9d234..4a099a2e 100644 --- a/src/Components/Modules/Menus.hpp +++ b/src/Components/Modules/Menus.hpp @@ -29,9 +29,9 @@ namespace Components static Game::MenuList* LoadMenuList(Game::MenuList* menuList); static Game::MenuList* LoadScriptMenu(const char* menu); - static std::vector LoadMenu(Game::menuDef_t* menudef); - static std::vector LoadMenu(std::string file); - static void SafeMergeMenus(std::vector* menus, std::vector newMenus); + static std::vector> LoadMenu(Game::menuDef_t* menudef); + static std::vector> LoadMenu(std::string file); + static void SafeMergeMenus(std::vector>* menus, std::vector> newMenus); static Game::script_t* LoadMenuScript(std::string name, std::string buffer); static int LoadMenuSource(std::string name, std::string buffer); From 0fcf3ea0143df09e64f98e470db61e1880b4bcc4 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 24 Feb 2017 23:14:23 +0100 Subject: [PATCH 08/13] [Proxy] Watch if steam crashes --- src/Steam/Proxy.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++ src/Steam/Proxy.hpp | 5 ++++ 2 files changed, 78 insertions(+) diff --git a/src/Steam/Proxy.cpp b/src/Steam/Proxy.cpp index 124cf253..369bbeb6 100644 --- a/src/Steam/Proxy.cpp +++ b/src/Steam/Proxy.cpp @@ -18,6 +18,10 @@ namespace Steam Utils* Proxy::SteamUtils = nullptr; User* Proxy::SteamUser_ = nullptr; + HANDLE Proxy::Process = nullptr; + HANDLE Proxy::CancelHandle = nullptr; + std::thread Proxy::WatchGuard; + uint32_t Proxy::AppId = 0; std::recursive_mutex Proxy::CallMutex; @@ -325,6 +329,41 @@ namespace Steam Proxy::UnregisterCalls(); } + void Proxy::LaunchWatchGuard() + { + if (Proxy::WatchGuard.joinable()) return; + + HKEY hRegKey; + DWORD pid = 0; + if (RegOpenKeyExA(HKEY_CURRENT_USER, STEAM_REGISTRY_PROCESS_PATH, 0, KEY_QUERY_VALUE, &hRegKey) != ERROR_SUCCESS) return; + + DWORD dwLength = sizeof(pid); + RegQueryValueExA(hRegKey, "pid", nullptr, nullptr, reinterpret_cast(&pid), &dwLength); + RegCloseKey(hRegKey); + + Proxy::CancelHandle = CreateEventA(nullptr, TRUE, FALSE, "CancelEvent"); + if (!Proxy::CancelHandle) return; + + Proxy::Process = OpenProcess(SYNCHRONIZE, FALSE, pid); + if (!Proxy::Process) return; + + Proxy::WatchGuard = std::thread([]() + { + HANDLE handles[] = { Proxy::Process, Proxy::CancelHandle }; + + DWORD result = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE); + CloseHandle(Proxy::Process); + CloseHandle(Proxy::CancelHandle); + + if (result == WAIT_OBJECT_0) + { + Proxy::SteamPipe = nullptr; + Proxy::SteamUser = nullptr; + Proxy::Uninititalize(); + } + }); + } + void Proxy::StartSteamIfNecessary() { if (Proxy::GetSteamDirectory().empty() || !Steam::Enabled()) return; @@ -348,6 +387,11 @@ namespace Steam CloseHandle(hProcess); }); + allocator.reference(allocator.allocate(1), [](void*) + { + Proxy::LaunchWatchGuard(); + }); + DWORD exitCode; if (!GetExitCodeProcess(process, &exitCode)) return; if (exitCode == STILL_ACTIVE) return; @@ -375,6 +419,8 @@ namespace Steam while (!interval.elapsed(15s) && !Proxy::GetActiveUser()) std::this_thread::sleep_for(10ms); std::this_thread::sleep_for(1s); } + + Proxy::LaunchWatchGuard(); } bool Proxy::Inititalize() @@ -442,6 +488,30 @@ namespace Steam void Proxy::Uninititalize() { + if(Proxy::WatchGuard.get_id() != std::this_thread::get_id() && Proxy::WatchGuard.joinable()) + { + if (Proxy::CancelHandle) + { + SetEvent(Proxy::CancelHandle); + Proxy::WatchGuard.join(); + } + else + { + Proxy::WatchGuard.detach(); + } + } + + Proxy::Process = nullptr; + Proxy::CancelHandle = nullptr; + + Proxy::ClientEngine = nullptr; + Proxy::ClientUser = nullptr; + Proxy::ClientFriends = nullptr; + Proxy::SteamApps = nullptr; + Proxy::SteamFriends = nullptr; + Proxy::SteamUtils = nullptr; + Proxy::SteamUser_ = nullptr; + if (Proxy::SteamClient && Proxy::SteamPipe) { if (Proxy::SteamUser) @@ -452,6 +522,9 @@ namespace Steam Proxy::SteamClient->ReleaseSteamPipe(Proxy::SteamPipe); } + Proxy::SteamPipe = nullptr; + Proxy::SteamUser = nullptr; + Proxy::SteamClient = nullptr; Proxy::Client = ::Utils::Library(); Proxy::Overlay = ::Utils::Library(); } diff --git a/src/Steam/Proxy.hpp b/src/Steam/Proxy.hpp index 2159384d..c7630523 100644 --- a/src/Steam/Proxy.hpp +++ b/src/Steam/Proxy.hpp @@ -302,6 +302,10 @@ namespace Steam static void* SteamPipe; static void* SteamUser; + static HANDLE Process; + static HANDLE CancelHandle; + static std::thread WatchGuard; + static std::recursive_mutex CallMutex; static std::vector Calls; static std::unordered_map Callbacks; @@ -314,6 +318,7 @@ namespace Steam static void UnregisterCalls(); static void StartSteamIfNecessary(); + static void LaunchWatchGuard(); static void ResetActiveUser(); static uint32_t GetActiveUser(); From fe126a43083c668009a83a2e8fce93f1371e33c5 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 25 Feb 2017 00:52:11 +0100 Subject: [PATCH 09/13] [Party] Correctly parse max players --- src/Components/Modules/Console.cpp | 4 ++-- src/Components/Modules/Party.cpp | 4 ++-- src/Components/Modules/ServerInfo.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Components/Modules/Console.cpp b/src/Components/Modules/Console.cpp index 3a8a66f7..247772f3 100644 --- a/src/Components/Modules/Console.cpp +++ b/src/Components/Modules/Console.cpp @@ -66,8 +66,8 @@ namespace Components } else { - //maxclientCount = Dvar::Var("sv_maxclients").get(); - maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame); + maxclientCount = Dvar::Var("party_maxplayers").get(); + //maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame); clientCount = Game::PartyHost_CountMembers(reinterpret_cast(0x1081C00)); } diff --git a/src/Components/Modules/Party.cpp b/src/Components/Modules/Party.cpp index 5597dd34..d4639913 100644 --- a/src/Components/Modules/Party.cpp +++ b/src/Components/Modules/Party.cpp @@ -302,8 +302,8 @@ namespace Components } else { - //maxclientCount = Dvar::Var("sv_maxclients").get(); - maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame); + maxclientCount = Dvar::Var("party_maxplayers").get(); + //maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame); clientCount = Game::PartyHost_CountMembers(reinterpret_cast(0x1081C00)); } diff --git a/src/Components/Modules/ServerInfo.cpp b/src/Components/Modules/ServerInfo.cpp index 433b433b..65cf600c 100644 --- a/src/Components/Modules/ServerInfo.cpp +++ b/src/Components/Modules/ServerInfo.cpp @@ -116,8 +116,8 @@ namespace Components if (!maxclientCount) { - //maxclientCount = Dvar::Var("sv_maxclients").get(); - maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame); + maxclientCount = Dvar::Var("party_maxplayers").get(); + //maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame); } Utils::InfoString info(Game::Dvar_InfoString_Big(1024)); From 86e1f6f807ff0b0be6564f98a23b4aa935057740 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 25 Feb 2017 01:17:11 +0100 Subject: [PATCH 10/13] [Logger] Add iw4x_onelog dvar --- src/Components/Modules/Logger.cpp | 42 +++++++++++++++++++++++++++++++ src/Components/Modules/Logger.hpp | 3 +++ 2 files changed, 45 insertions(+) diff --git a/src/Components/Modules/Logger.cpp b/src/Components/Modules/Logger.cpp index f632a6c3..c9dcd920 100644 --- a/src/Components/Modules/Logger.cpp +++ b/src/Components/Modules/Logger.cpp @@ -195,8 +195,50 @@ namespace Components Logger::MessageMutex.unlock(); } + void Logger::RedirectOSPath(const char* file, char* folder) + { + if (Dvar::Var("g_log").get() == file) + { + if (folder != "userraw"s) + { + if (Dvar::Var("g_log").get()) + { + strcpy_s(folder, 256, "userraw"); + } + } + } + } + + __declspec(naked) void Logger::BuildOSPathStub() + { + __asm + { + pushad + + push [esp + 28h] + push [esp + 30h] + + call Logger::RedirectOSPath + + add esp, 8h + + popad + + mov eax, [esp + 8h] + push ebp + push esi + mov esi, [esp + 0Ch] + + push 64213Fh + retn + } + } + Logger::Logger() { + Dvar::Register("iw4x_onelog", false, Game::dvar_flag::DVAR_FLAG_LATCHED | Game::dvar_flag::DVAR_FLAG_SAVED, "Only write the game log to the 'userraw' OS folder"); + Utils::Hook(0x642139, Logger::BuildOSPathStub, HOOK_JUMP).install()->quick(); + Logger::PipeOutput(nullptr); QuickPatch::OnFrame(Logger::Frame); diff --git a/src/Components/Modules/Logger.hpp b/src/Components/Modules/Logger.hpp index eabab8fa..accafa62 100644 --- a/src/Components/Modules/Logger.hpp +++ b/src/Components/Modules/Logger.hpp @@ -39,6 +39,9 @@ namespace Components static void PrintMessagePipe(const char* data); static void EnqueueMessage(std::string message); + static void BuildOSPathStub(); + static void RedirectOSPath(const char* file, char* folder); + static void NetworkLog(const char* data, bool gLog); static std::string Format(const char** message); From 571b0461d6ef08cd7bc4fd6fba9269e68e8967db Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 25 Feb 2017 01:19:05 +0100 Subject: [PATCH 11/13] [Submodules] Update libtomcrypt and protobuf --- deps/libtomcrypt | 2 +- deps/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index f60e0450..824f3af9 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit f60e04503464a05265796134a244847019f08075 +Subproject commit 824f3af98c68880ba2d186d0632996730dd58a98 diff --git a/deps/protobuf b/deps/protobuf index 963473b1..b4b0e304 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 963473b1dd4f37c5c0b8ca72f1c4a05225b927b7 +Subproject commit b4b0e304be5a68de3d0ee1af9b286f958750f5e4 From 8b50bb567c1fb8beed268c004a23c55c04eb3a6f Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 25 Feb 2017 12:27:59 +0100 Subject: [PATCH 12/13] [General] Update the protocol (15 classes are not backwards compatible) --- src/Game/Structs.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 87450fa4..303262d8 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -1,6 +1,6 @@ #pragma once -#define PROTOCOL 0x93 +#define PROTOCOL 0x94 #define NUM_CUSTOM_CLASSES 15 // This allows us to compile our structures in IDA, for easier reversing :3 From af8801c9c5d53e41f34ee2fa21a12a2c74a96bbe Mon Sep 17 00:00:00 2001 From: /dev/root Date: Sat, 25 Feb 2017 12:45:03 +0100 Subject: [PATCH 13/13] [Updater] Only download updater when required --- src/Components/Modules/News.cpp | 75 +++++++++++++++++++++++++++------ src/Components/Modules/News.hpp | 5 +++ 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/Components/Modules/News.cpp b/src/Components/Modules/News.cpp index 02b0c73c..51ee2436 100644 --- a/src/Components/Modules/News.cpp +++ b/src/Components/Modules/News.cpp @@ -7,6 +7,8 @@ namespace Components bool News::Terminate; std::thread News::Thread; std::string News::UpdaterArgs; + std::string News::UpdaterHash; + int News::UpdaterRefresh; bool News::unitTest() { @@ -50,6 +52,56 @@ namespace Components TerminateProcess(GetCurrentProcess(), exitCode); } + bool News::GetLatestUpdater() + { + if (Utils::IO::FileExists("updater.exe")) + { + // Generate hash of local updater.exe + std::string localUpdater = Utils::IO::ReadFile("updater.exe"); + localUpdater = Utils::Cryptography::SHA1::Compute(localUpdater, true); + + if (News::UpdaterHash.empty() || (News::UpdaterRefresh - Game::Sys_Milliseconds() > 900000)) // Check for updater Update every 15 mins max + { + News::UpdaterRefresh = Game::Sys_Milliseconds(); + + std::string data = Utils::Cache::GetFile("/json/updater"); // {"updater.exe":{"SHA1":"*HASH*"}} + + std::string error; + json11::Json listData = json11::Json::parse(data, error); + + if (error.empty() || listData.is_object()) + { + News::UpdaterHash = listData["updater.exe"]["SHA1"].string_value(); + } + } + + if (!News::UpdaterHash.empty() && localUpdater != News::UpdaterHash) + { + remove("updater.exe"); + } + } + + if (!Utils::IO::FileExists("updater.exe")) + { + return News::DownloadUpdater(); + } + + return true; + } + + bool News::DownloadUpdater() + { + std::string data = Utils::Cache::GetFile("/iw4/updater.exe"); + + if (!data.empty()) + { + Utils::IO::WriteFile("updater.exe", data); + return true; + } + + return false; + } + const char* News::GetNewsText() { return Localization::Get("MPUI_MOTD_TEXT"); @@ -95,21 +147,18 @@ namespace Components std::thread([]() { - std::string data = Utils::Cache::GetFile("/iw4/updater.exe"); - - if (data.empty()) + if (News::GetLatestUpdater()) + { + Console::SetSkipShutdown(); + Command::Execute("wait 300; quit;", false); + } + else { Localization::ClearTemp(); News::UpdaterArgs.clear(); Command::Execute("closemenu popup_reconnectingtoparty", false); Game::ShowMessageBox("Failed to download the updater!", "Error"); } - else - { - Console::SetSkipShutdown(); - Utils::IO::WriteFile("updater.exe", data); - Command::Execute("wait 300; quit;", false); - } }).detach(); } @@ -121,6 +170,8 @@ namespace Components News::News() { News::UpdaterArgs.clear(); + News::UpdaterHash.clear(); + News::UpdaterRefresh = 0; if (ZoneBuilder::IsEnabled()) return; // Maybe also dedi? Dvar::Register("g_firstLaunch", true, Game::DVAR_FLAG_SAVED, ""); @@ -151,10 +202,7 @@ namespace Components Localization::Set("MPUI_CHANGELOG_TEXT", "Loading..."); Localization::Set("MPUI_MOTD_TEXT", NEWS_MOTD_DEFAULT); - if (Utils::IO::FileExists("updater.exe")) - { - remove("updater.exe"); - } + //News::GetLatestUpdater(); // make newsfeed (ticker) menu items not cut off based on safe area Utils::Hook::Nop(0x63892D, 5); @@ -208,6 +256,7 @@ namespace Components News::~News() { News::UpdaterArgs.clear(); + News::UpdaterHash.clear(); } void News::preDestroy() diff --git a/src/Components/Modules/News.hpp b/src/Components/Modules/News.hpp index e374efaf..36ad52d8 100644 --- a/src/Components/Modules/News.hpp +++ b/src/Components/Modules/News.hpp @@ -20,8 +20,13 @@ namespace Components private: static std::string UpdaterArgs; + static std::string UpdaterHash; + static int UpdaterRefresh; static std::thread Thread; + static bool Terminate; + static bool GetLatestUpdater(); + static bool DownloadUpdater(); static void CheckForUpdate(); static void ExitProcessStub(unsigned int exitCode);