Merge remote-tracking branch 'origin/develop' into 191-dedicated-server-optimization
# Conflicts: # src/Components/Modules/News.cpp
This commit is contained in:
commit
741d5788bd
@ -12,6 +12,11 @@ namespace Components
|
|||||||
return Loader::Pregame;
|
return Loader::Pregame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Loader::IsPostgame()
|
||||||
|
{
|
||||||
|
return Loader::Postgame;
|
||||||
|
}
|
||||||
|
|
||||||
void Loader::Initialize()
|
void Loader::Initialize()
|
||||||
{
|
{
|
||||||
Loader::Pregame = true;
|
Loader::Pregame = true;
|
||||||
@ -93,7 +98,7 @@ namespace Components
|
|||||||
|
|
||||||
void Loader::Uninitialize()
|
void Loader::Uninitialize()
|
||||||
{
|
{
|
||||||
Loader::PreDestroy();
|
Loader::PreDestroyNoPostGame();
|
||||||
|
|
||||||
std::reverse(Loader::Components.begin(), Loader::Components.end());
|
std::reverse(Loader::Components.begin(), Loader::Components.end());
|
||||||
for (auto component : Loader::Components)
|
for (auto component : Loader::Components)
|
||||||
@ -119,14 +124,32 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Loader::Postgame = true;
|
Loader::Postgame = true;
|
||||||
|
|
||||||
std::reverse(Loader::Components.begin(), Loader::Components.end());
|
auto components = Loader::Components;
|
||||||
for (auto component : Loader::Components)
|
|
||||||
|
std::reverse(components.begin(), components.end());
|
||||||
|
for (auto component : components)
|
||||||
{
|
{
|
||||||
component->preDestroy();
|
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 Loader::PerformUnitTests()
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
@ -25,11 +25,13 @@ namespace Components
|
|||||||
static void Initialize();
|
static void Initialize();
|
||||||
static void Uninitialize();
|
static void Uninitialize();
|
||||||
static void PreDestroy();
|
static void PreDestroy();
|
||||||
|
static void PreDestroyNoPostGame();
|
||||||
static bool PerformUnitTests();
|
static bool PerformUnitTests();
|
||||||
static bool PerformingUnitTests();
|
static bool PerformingUnitTests();
|
||||||
static void Register(Component* component);
|
static void Register(Component* component);
|
||||||
|
|
||||||
static bool IsPregame();
|
static bool IsPregame();
|
||||||
|
static bool IsPostgame();
|
||||||
|
|
||||||
static Utils::Memory::Allocator* GetAlloctor();
|
static Utils::Memory::Allocator* GetAlloctor();
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ namespace Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//maxclientCount = Dvar::Var("sv_maxclients").get<int>();
|
maxclientCount = Dvar::Var("party_maxplayers").get<int>();
|
||||||
maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
//maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
||||||
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData_s*>(0x1081C00));
|
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData_s*>(0x1081C00));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,8 +195,50 @@ namespace Components
|
|||||||
Logger::MessageMutex.unlock();
|
Logger::MessageMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Logger::RedirectOSPath(const char* file, char* folder)
|
||||||
|
{
|
||||||
|
if (Dvar::Var("g_log").get<std::string>() == file)
|
||||||
|
{
|
||||||
|
if (folder != "userraw"s)
|
||||||
|
{
|
||||||
|
if (Dvar::Var("g_log").get<bool>())
|
||||||
|
{
|
||||||
|
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()
|
Logger::Logger()
|
||||||
{
|
{
|
||||||
|
Dvar::Register<bool>("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);
|
Logger::PipeOutput(nullptr);
|
||||||
|
|
||||||
QuickPatch::OnFrame(Logger::Frame);
|
QuickPatch::OnFrame(Logger::Frame);
|
||||||
|
@ -39,6 +39,9 @@ namespace Components
|
|||||||
static void PrintMessagePipe(const char* data);
|
static void PrintMessagePipe(const char* data);
|
||||||
static void EnqueueMessage(std::string message);
|
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 void NetworkLog(const char* data, bool gLog);
|
||||||
|
|
||||||
static std::string Format(const char** message);
|
static std::string Format(const char** message);
|
||||||
|
@ -169,9 +169,9 @@ namespace Components
|
|||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Game::menuDef_t*> Menus::LoadMenu(std::string menu)
|
std::vector<std::pair<bool, Game::menuDef_t*>> Menus::LoadMenu(std::string menu)
|
||||||
{
|
{
|
||||||
std::vector<Game::menuDef_t*> menus;
|
std::vector<std::pair<bool, Game::menuDef_t*>> menus;
|
||||||
FileSystem::File menuFile(menu);
|
FileSystem::File menuFile(menu);
|
||||||
|
|
||||||
if (menuFile.exists())
|
if (menuFile.exists())
|
||||||
@ -200,7 +200,7 @@ namespace Components
|
|||||||
if (!_stricmp(token.string, "menudef"))
|
if (!_stricmp(token.string, "menudef"))
|
||||||
{
|
{
|
||||||
Game::menuDef_t* menudef = Menus::ParseMenu(handle);
|
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;
|
return menus;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Game::menuDef_t*> Menus::LoadMenu(Game::menuDef_t* menudef)
|
std::vector<std::pair<bool, Game::menuDef_t*>> Menus::LoadMenu(Game::menuDef_t* menudef)
|
||||||
{
|
{
|
||||||
std::vector<Game::menuDef_t*> menus = Menus::LoadMenu(Utils::String::VA("ui_mp\\%s.menu", menudef->window.name));
|
std::vector<std::pair<bool, Game::menuDef_t*>> menus = Menus::LoadMenu(Utils::String::VA("ui_mp\\%s.menu", menudef->window.name));
|
||||||
|
|
||||||
if (menus.empty())
|
if (menus.empty())
|
||||||
{
|
{
|
||||||
@ -222,11 +222,11 @@ namespace Components
|
|||||||
//
|
//
|
||||||
// if (originalMenu)
|
// if (originalMenu)
|
||||||
// {
|
// {
|
||||||
// menus.push_back(originalMenu);
|
// menus.push_back({ false, originalMenu });
|
||||||
// }
|
// }
|
||||||
// else
|
// 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)
|
Game::MenuList* Menus::LoadScriptMenu(const char* menu)
|
||||||
{
|
{
|
||||||
std::vector<Game::menuDef_t*> menus = Menus::LoadMenu(menu);
|
std::vector<std::pair<bool, Game::menuDef_t*>> menus = Menus::LoadMenu(menu);
|
||||||
if (menus.empty()) return nullptr;
|
if (menus.empty()) return nullptr;
|
||||||
|
|
||||||
// Allocate new menu list
|
// Allocate new menu list
|
||||||
@ -253,7 +253,10 @@ namespace Components
|
|||||||
newList->menuCount = menus.size();
|
newList->menuCount = menus.size();
|
||||||
|
|
||||||
// Copy new menus
|
// 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::RemoveMenuList(newList->name);
|
||||||
Menus::MenuListList[newList->name] = newList;
|
Menus::MenuListList[newList->name] = newList;
|
||||||
@ -261,14 +264,60 @@ namespace Components
|
|||||||
return newList;
|
return newList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menus::SafeMergeMenus(std::vector<std::pair<bool, Game::menuDef_t*>>* menus, std::vector<std::pair<bool, Game::menuDef_t*>> newMenus)
|
||||||
|
{
|
||||||
|
// Check if we overwrote a menu
|
||||||
|
for (unsigned int i = 0; i < menus->size(); ++i)
|
||||||
|
{
|
||||||
|
// Try to find the native menu
|
||||||
|
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).second == 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).second->window.name == std::string(newMenu.second->window.name))
|
||||||
|
{
|
||||||
|
Menus::RemoveMenu(menus->at(i).second);
|
||||||
|
|
||||||
|
menus->erase(menus->begin() + i);
|
||||||
|
--i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::Merge(menus, newMenus);
|
||||||
|
}
|
||||||
|
|
||||||
Game::MenuList* Menus::LoadMenuList(Game::MenuList* menuList)
|
Game::MenuList* Menus::LoadMenuList(Game::MenuList* menuList)
|
||||||
{
|
{
|
||||||
std::vector<Game::menuDef_t*> menus;
|
std::vector<std::pair<bool, Game::menuDef_t*>> menus;
|
||||||
|
|
||||||
for (int i = 0; i < menuList->menuCount; ++i)
|
for (int i = 0; i < menuList->menuCount; ++i)
|
||||||
{
|
{
|
||||||
if (!menuList->menus[i]) continue;
|
if (!menuList->menus[i]) continue;
|
||||||
Utils::Merge(&menus, Menus::LoadMenu(menuList->menus[i]));
|
Menus::SafeMergeMenus(&menus, Menus::LoadMenu(menuList->menus[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load custom menus
|
// Load custom menus
|
||||||
@ -279,14 +328,14 @@ namespace Components
|
|||||||
bool hasMenu = false;
|
bool hasMenu = false;
|
||||||
for(auto &loadedMenu : menus)
|
for(auto &loadedMenu : menus)
|
||||||
{
|
{
|
||||||
if(loadedMenu->window.name == menu)
|
if(loadedMenu.second->window.name == menu)
|
||||||
{
|
{
|
||||||
hasMenu = true;
|
hasMenu = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!hasMenu) Utils::Merge(&menus, Menus::LoadMenu(menu));
|
if (!hasMenu) Menus::SafeMergeMenus(&menus, Menus::LoadMenu(menu));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +355,10 @@ namespace Components
|
|||||||
newList->menuCount = size;
|
newList->menuCount = size;
|
||||||
|
|
||||||
// Copy new menus
|
// 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::RemoveMenuList(newList->name);
|
||||||
Menus::MenuListList[newList->name] = newList;
|
Menus::MenuListList[newList->name] = newList;
|
||||||
|
@ -29,8 +29,9 @@ namespace Components
|
|||||||
|
|
||||||
static Game::MenuList* LoadMenuList(Game::MenuList* menuList);
|
static Game::MenuList* LoadMenuList(Game::MenuList* menuList);
|
||||||
static Game::MenuList* LoadScriptMenu(const char* menu);
|
static Game::MenuList* LoadScriptMenu(const char* menu);
|
||||||
static std::vector<Game::menuDef_t*> LoadMenu(Game::menuDef_t* menudef);
|
static std::vector<std::pair<bool, Game::menuDef_t*>> LoadMenu(Game::menuDef_t* menudef);
|
||||||
static std::vector<Game::menuDef_t*> LoadMenu(std::string file);
|
static std::vector<std::pair<bool, Game::menuDef_t*>> LoadMenu(std::string file);
|
||||||
|
static void SafeMergeMenus(std::vector<std::pair<bool, Game::menuDef_t*>>* menus, std::vector<std::pair<bool, Game::menuDef_t*>> newMenus);
|
||||||
|
|
||||||
static Game::script_t* LoadMenuScript(std::string name, std::string buffer);
|
static Game::script_t* LoadMenuScript(std::string name, std::string buffer);
|
||||||
static int LoadMenuSource(std::string name, std::string buffer);
|
static int LoadMenuSource(std::string name, std::string buffer);
|
||||||
|
@ -7,6 +7,8 @@ namespace Components
|
|||||||
bool News::Terminate;
|
bool News::Terminate;
|
||||||
std::thread News::Thread;
|
std::thread News::Thread;
|
||||||
std::string News::UpdaterArgs;
|
std::string News::UpdaterArgs;
|
||||||
|
std::string News::UpdaterHash;
|
||||||
|
int News::UpdaterRefresh;
|
||||||
|
|
||||||
bool News::unitTest()
|
bool News::unitTest()
|
||||||
{
|
{
|
||||||
@ -50,6 +52,56 @@ namespace Components
|
|||||||
TerminateProcess(GetCurrentProcess(), exitCode);
|
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()
|
const char* News::GetNewsText()
|
||||||
{
|
{
|
||||||
return Localization::Get("MPUI_MOTD_TEXT");
|
return Localization::Get("MPUI_MOTD_TEXT");
|
||||||
@ -95,21 +147,18 @@ namespace Components
|
|||||||
|
|
||||||
std::thread([]()
|
std::thread([]()
|
||||||
{
|
{
|
||||||
std::string data = Utils::Cache::GetFile("/iw4/updater.exe");
|
if (News::GetLatestUpdater())
|
||||||
|
{
|
||||||
if (data.empty())
|
Console::SetSkipShutdown();
|
||||||
|
Command::Execute("wait 300; quit;", false);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Localization::ClearTemp();
|
Localization::ClearTemp();
|
||||||
News::UpdaterArgs.clear();
|
News::UpdaterArgs.clear();
|
||||||
Command::Execute("closemenu popup_reconnectingtoparty", false);
|
Command::Execute("closemenu popup_reconnectingtoparty", false);
|
||||||
Game::ShowMessageBox("Failed to download the updater!", "Error");
|
Game::ShowMessageBox("Failed to download the updater!", "Error");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Console::SetSkipShutdown();
|
|
||||||
Utils::IO::WriteFile("updater.exe", data);
|
|
||||||
Command::Execute("wait 300; quit;", false);
|
|
||||||
}
|
|
||||||
}).detach();
|
}).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +170,8 @@ namespace Components
|
|||||||
News::News()
|
News::News()
|
||||||
{
|
{
|
||||||
News::UpdaterArgs.clear();
|
News::UpdaterArgs.clear();
|
||||||
|
News::UpdaterHash.clear();
|
||||||
|
News::UpdaterRefresh = 0;
|
||||||
if (ZoneBuilder::IsEnabled() || Dedicated::IsEnabled()) return; // Maybe also dedi?
|
if (ZoneBuilder::IsEnabled() || Dedicated::IsEnabled()) return; // Maybe also dedi?
|
||||||
|
|
||||||
Dvar::Register<bool>("g_firstLaunch", true, Game::DVAR_FLAG_SAVED, "");
|
Dvar::Register<bool>("g_firstLaunch", true, Game::DVAR_FLAG_SAVED, "");
|
||||||
@ -152,10 +202,7 @@ namespace Components
|
|||||||
Localization::Set("MPUI_CHANGELOG_TEXT", "Loading...");
|
Localization::Set("MPUI_CHANGELOG_TEXT", "Loading...");
|
||||||
Localization::Set("MPUI_MOTD_TEXT", NEWS_MOTD_DEFAULT);
|
Localization::Set("MPUI_MOTD_TEXT", NEWS_MOTD_DEFAULT);
|
||||||
|
|
||||||
if (Utils::IO::FileExists("updater.exe"))
|
//News::GetLatestUpdater();
|
||||||
{
|
|
||||||
remove("updater.exe");
|
|
||||||
}
|
|
||||||
|
|
||||||
// make newsfeed (ticker) menu items not cut off based on safe area
|
// make newsfeed (ticker) menu items not cut off based on safe area
|
||||||
Utils::Hook::Nop(0x63892D, 5);
|
Utils::Hook::Nop(0x63892D, 5);
|
||||||
@ -209,6 +256,7 @@ namespace Components
|
|||||||
News::~News()
|
News::~News()
|
||||||
{
|
{
|
||||||
News::UpdaterArgs.clear();
|
News::UpdaterArgs.clear();
|
||||||
|
News::UpdaterHash.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void News::preDestroy()
|
void News::preDestroy()
|
||||||
|
@ -20,8 +20,13 @@ namespace Components
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string UpdaterArgs;
|
static std::string UpdaterArgs;
|
||||||
|
static std::string UpdaterHash;
|
||||||
|
static int UpdaterRefresh;
|
||||||
static std::thread Thread;
|
static std::thread Thread;
|
||||||
|
|
||||||
static bool Terminate;
|
static bool Terminate;
|
||||||
|
static bool GetLatestUpdater();
|
||||||
|
static bool DownloadUpdater();
|
||||||
|
|
||||||
static void CheckForUpdate();
|
static void CheckForUpdate();
|
||||||
static void ExitProcessStub(unsigned int exitCode);
|
static void ExitProcessStub(unsigned int exitCode);
|
||||||
|
@ -302,8 +302,8 @@ namespace Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//maxclientCount = Dvar::Var("sv_maxclients").get<int>();
|
maxclientCount = Dvar::Var("party_maxplayers").get<int>();
|
||||||
maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
//maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
||||||
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData_s*>(0x1081C00));
|
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData_s*>(0x1081C00));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,8 +116,8 @@ namespace Components
|
|||||||
|
|
||||||
if (!maxclientCount)
|
if (!maxclientCount)
|
||||||
{
|
{
|
||||||
//maxclientCount = Dvar::Var("sv_maxclients").get<int>();
|
maxclientCount = Dvar::Var("party_maxplayers").get<int>();
|
||||||
maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
//maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::InfoString info(Game::Dvar_InfoString_Big(1024));
|
Utils::InfoString info(Game::Dvar_InfoString_Big(1024));
|
||||||
|
@ -146,6 +146,8 @@ namespace Components
|
|||||||
|
|
||||||
Toast::Toast()
|
Toast::Toast()
|
||||||
{
|
{
|
||||||
|
if (Dedicated::IsEnabled()) return;
|
||||||
|
|
||||||
Toast::ToastHandler = new WinToastLib::WinToastHandler;
|
Toast::ToastHandler = new WinToastLib::WinToastHandler;
|
||||||
|
|
||||||
WinToastLib::WinToast::instance()->setAppName(L"IW4x");
|
WinToastLib::WinToast::instance()->setAppName(L"IW4x");
|
||||||
@ -170,13 +172,28 @@ namespace Components
|
|||||||
|
|
||||||
void Toast::preDestroy()
|
void Toast::preDestroy()
|
||||||
{
|
{
|
||||||
// Destroying that on the main thread deadlocks, for whatever reason.
|
if (Dedicated::IsEnabled()) return;
|
||||||
|
|
||||||
|
// Destroying that on the main thread deadlocks.
|
||||||
// I did not write the library, so whatever.
|
// 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;
|
delete Toast::ToastHandler;
|
||||||
Toast::ToastHandler = nullptr;
|
Toast::ToastHandler = nullptr;
|
||||||
}).join();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define PROTOCOL 0x93
|
#define PROTOCOL 0x94
|
||||||
#define NUM_CUSTOM_CLASSES 15
|
#define NUM_CUSTOM_CLASSES 15
|
||||||
|
|
||||||
// This allows us to compile our structures in IDA, for easier reversing :3
|
// This allows us to compile our structures in IDA, for easier reversing :3
|
||||||
|
@ -18,6 +18,10 @@ namespace Steam
|
|||||||
Utils* Proxy::SteamUtils = nullptr;
|
Utils* Proxy::SteamUtils = nullptr;
|
||||||
User* Proxy::SteamUser_ = nullptr;
|
User* Proxy::SteamUser_ = nullptr;
|
||||||
|
|
||||||
|
HANDLE Proxy::Process = nullptr;
|
||||||
|
HANDLE Proxy::CancelHandle = nullptr;
|
||||||
|
std::thread Proxy::WatchGuard;
|
||||||
|
|
||||||
uint32_t Proxy::AppId = 0;
|
uint32_t Proxy::AppId = 0;
|
||||||
|
|
||||||
std::recursive_mutex Proxy::CallMutex;
|
std::recursive_mutex Proxy::CallMutex;
|
||||||
@ -325,6 +329,41 @@ namespace Steam
|
|||||||
Proxy::UnregisterCalls();
|
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<BYTE*>(&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()
|
void Proxy::StartSteamIfNecessary()
|
||||||
{
|
{
|
||||||
if (Proxy::GetSteamDirectory().empty() || !Steam::Enabled()) return;
|
if (Proxy::GetSteamDirectory().empty() || !Steam::Enabled()) return;
|
||||||
@ -348,6 +387,11 @@ namespace Steam
|
|||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
allocator.reference(allocator.allocate(1), [](void*)
|
||||||
|
{
|
||||||
|
Proxy::LaunchWatchGuard();
|
||||||
|
});
|
||||||
|
|
||||||
DWORD exitCode;
|
DWORD exitCode;
|
||||||
if (!GetExitCodeProcess(process, &exitCode)) return;
|
if (!GetExitCodeProcess(process, &exitCode)) return;
|
||||||
if (exitCode == STILL_ACTIVE) return;
|
if (exitCode == STILL_ACTIVE) return;
|
||||||
@ -375,6 +419,8 @@ namespace Steam
|
|||||||
while (!interval.elapsed(15s) && !Proxy::GetActiveUser()) std::this_thread::sleep_for(10ms);
|
while (!interval.elapsed(15s) && !Proxy::GetActiveUser()) std::this_thread::sleep_for(10ms);
|
||||||
std::this_thread::sleep_for(1s);
|
std::this_thread::sleep_for(1s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Proxy::LaunchWatchGuard();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Proxy::Inititalize()
|
bool Proxy::Inititalize()
|
||||||
@ -442,6 +488,30 @@ namespace Steam
|
|||||||
|
|
||||||
void Proxy::Uninititalize()
|
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::SteamClient && Proxy::SteamPipe)
|
||||||
{
|
{
|
||||||
if (Proxy::SteamUser)
|
if (Proxy::SteamUser)
|
||||||
@ -452,6 +522,9 @@ namespace Steam
|
|||||||
Proxy::SteamClient->ReleaseSteamPipe(Proxy::SteamPipe);
|
Proxy::SteamClient->ReleaseSteamPipe(Proxy::SteamPipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Proxy::SteamPipe = nullptr;
|
||||||
|
Proxy::SteamUser = nullptr;
|
||||||
|
Proxy::SteamClient = nullptr;
|
||||||
Proxy::Client = ::Utils::Library();
|
Proxy::Client = ::Utils::Library();
|
||||||
Proxy::Overlay = ::Utils::Library();
|
Proxy::Overlay = ::Utils::Library();
|
||||||
}
|
}
|
||||||
|
@ -302,6 +302,10 @@ namespace Steam
|
|||||||
static void* SteamPipe;
|
static void* SteamPipe;
|
||||||
static void* SteamUser;
|
static void* SteamUser;
|
||||||
|
|
||||||
|
static HANDLE Process;
|
||||||
|
static HANDLE CancelHandle;
|
||||||
|
static std::thread WatchGuard;
|
||||||
|
|
||||||
static std::recursive_mutex CallMutex;
|
static std::recursive_mutex CallMutex;
|
||||||
static std::vector<CallContainer> Calls;
|
static std::vector<CallContainer> Calls;
|
||||||
static std::unordered_map<int32_t, void*> Callbacks;
|
static std::unordered_map<int32_t, void*> Callbacks;
|
||||||
@ -314,6 +318,7 @@ namespace Steam
|
|||||||
|
|
||||||
static void UnregisterCalls();
|
static void UnregisterCalls();
|
||||||
static void StartSteamIfNecessary();
|
static void StartSteamIfNecessary();
|
||||||
|
static void LaunchWatchGuard();
|
||||||
|
|
||||||
static void ResetActiveUser();
|
static void ResetActiveUser();
|
||||||
static uint32_t GetActiveUser();
|
static uint32_t GetActiveUser();
|
||||||
|
@ -9,7 +9,7 @@ namespace Utils
|
|||||||
|
|
||||||
bool IsWineEnvironment();
|
bool IsWineEnvironment();
|
||||||
|
|
||||||
template <typename T> void Merge(std::vector<T>* target, T* source, size_t length)
|
template <typename T> inline void Merge(std::vector<T>* target, T* source, size_t length)
|
||||||
{
|
{
|
||||||
if (source)
|
if (source)
|
||||||
{
|
{
|
||||||
@ -20,7 +20,7 @@ namespace Utils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void Merge(std::vector<T>* target, std::vector<T> source)
|
template <typename T> inline void Merge(std::vector<T>* target, std::vector<T> source)
|
||||||
{
|
{
|
||||||
for (auto &entry : source)
|
for (auto &entry : source)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user