diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index bb972dc5..1c668411 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -53,6 +53,7 @@ namespace Components Loader::Register(new Friends()); Loader::Register(new IPCPipe()); Loader::Register(new ModList()); + Loader::Register(new Monitor()); Loader::Register(new Network()); Loader::Register(new Theatre()); Loader::Register(new Download()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 96f6acc1..a66eb98e 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -63,6 +63,7 @@ namespace Components #include "Modules/Console.hpp" #include "Modules/UIScript.hpp" #include "Modules/ModList.hpp" +#include "Modules/Monitor.hpp" #include "Modules/Network.hpp" #include "Modules/Theatre.hpp" #include "Modules/Node.hpp" diff --git a/src/Components/Modules/BitMessage.cpp b/src/Components/Modules/BitMessage.cpp index 82ee2ac5..848136bb 100644 --- a/src/Components/Modules/BitMessage.cpp +++ b/src/Components/Modules/BitMessage.cpp @@ -9,6 +9,8 @@ namespace Components BitMessage::BitMessage() { + if (Monitor::IsEnabled()) return; + #ifdef DEBUG Logger::Print("Initializing BitMessage...\n"); #endif diff --git a/src/Components/Modules/Console.cpp b/src/Components/Modules/Console.cpp index 247772f3..7b249bd7 100644 --- a/src/Components/Modules/Console.cpp +++ b/src/Components/Modules/Console.cpp @@ -484,7 +484,7 @@ namespace Components void Console::FreeNativeConsole() { - if (!Flags::HasFlag("stdout") && (!Dedicated::IsEnabled() || Flags::HasFlag("console"))) + if (!Monitor::IsEnabled() && !Flags::HasFlag("stdout") && (!Dedicated::IsEnabled() || Flags::HasFlag("console"))) { FreeConsole(); } @@ -574,10 +574,15 @@ namespace Components if (Loader::PerformingUnitTests()) return; // External console - if (Flags::HasFlag("stdout")) + if (Flags::HasFlag("stdout") || Monitor::IsEnabled()) { - Utils::Hook(0x4B2080, Console::StdOutPrint, HOOK_JUMP).install()->quick(); - Utils::Hook(0x43D570, Console::StdOutError, HOOK_JUMP).install()->quick(); +#ifndef DEBUG + if (!Monitor::IsEnabled()) +#endif + { + Utils::Hook(0x4B2080, Console::StdOutPrint, HOOK_JUMP).install()->quick(); + Utils::Hook(0x43D570, Console::StdOutError, HOOK_JUMP).install()->quick(); + } } else if (Flags::HasFlag("console") || ZoneBuilder::IsEnabled()) // ZoneBuilder uses the game's console, until the native one is adapted. { diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp index bc664de4..3cb814d9 100644 --- a/src/Components/Modules/IPCPipe.cpp +++ b/src/Components/Modules/IPCPipe.cpp @@ -206,7 +206,7 @@ namespace Components IPCPipe::IPCPipe() { - if (Dedicated::IsEnabled()) return; + if (Dedicated::IsEnabled() || Monitor::IsEnabled()) return; // Server pipe IPCPipe::ServerPipe.onConnect(IPCPipe::ConnectClient); diff --git a/src/Components/Modules/MinidumpUpload.cpp b/src/Components/Modules/MinidumpUpload.cpp index a2e53732..fc6733bb 100644 --- a/src/Components/Modules/MinidumpUpload.cpp +++ b/src/Components/Modules/MinidumpUpload.cpp @@ -154,6 +154,8 @@ namespace Components MinidumpUpload::MinidumpUpload() { + if (Monitor::IsEnabled()) return; + #if !defined(DEBUG) || defined(FORCE_MINIDUMP_UPLOAD) if (Loader::PerformingUnitTests() || ZoneBuilder::IsEnabled()) return; this->uploadThread = std::thread([&]() { this->UploadQueuedMinidumps(); }); diff --git a/src/Components/Modules/Monitor.cpp b/src/Components/Modules/Monitor.cpp new file mode 100644 index 00000000..9e250b24 --- /dev/null +++ b/src/Components/Modules/Monitor.cpp @@ -0,0 +1,78 @@ +#include "STDInclude.hpp" +#undef getch +#include + +namespace Components +{ + bool Monitor::IsEnabled() + { + static Utils::Value flag; + + if (!flag.isValid()) + { + flag.set(Flags::HasFlag("monitor")); + } + + return flag.get(); + } + + int __stdcall Monitor::EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/) + { + Utils::Hook::Call(0x4D8220)(); // Dvar_Init + Utils::Hook::Call(0x4D2280)(); // SL_Init + Utils::Hook::Call(0x47F390)(); // Swap_Init + Utils::Hook::Call(0x60AD10)(); // Com_InitDvars + Utils::Hook::Call(0x420830)(); // Com_InitHunkMemory + Utils::Hook::Call(0x4A62A0)(); // LargeLocalInit + Utils::Hook::Call(0x502580)(static_cast(__rdtsc())); // Netchan_Init + Game::NET_Init(); + + Utils::Time::Interval interval; + while(!interval.elapsed(15s)) + { + Utils::Hook::Call(0x49F0B0)(); // Com_EventLoop + Node::FrameHandler(); + ServerList::Frame(); + + std::this_thread::sleep_for(10ms); + } + + auto list = ServerList::GetList(); + if (!list) + { + printf("1 IW4x player=0|server=0 Returned list was null"); + return 1; + } + + int servers = list->size(); + int players = 0; + + for(unsigned int i = 0; i < list->size(); ++i) + { + players += list->at(i).clients; + } + + printf("0 IW4x player=%d|server=%d\n", players, servers); + + Utils::Hook::Call(0x430630)(); // LargeLocalReset + Utils::Hook::Call(0x4A0460)(); // Hunk_ClearTempMemory + Utils::Hook::Call(0x4AB3A0)(); // Hunk_ClearTempMemoryHigh + Utils::Hook::Call(0x4B3AD0)(); // SL_Shutdown + Utils::Hook::Call(0x502C50)(); // Dvar_Shutdown + + if (*Game::ip_socket && *Game::ip_socket != INVALID_SOCKET) + { + closesocket(*Game::ip_socket); + } + + WSACleanup(); + return 0; + } + + Monitor::Monitor() + { + if (!Monitor::IsEnabled()) return; + + Utils::Hook(0x4513DA, Monitor::EntryPoint, HOOK_JUMP).install()->quick(); + } +} diff --git a/src/Components/Modules/Monitor.hpp b/src/Components/Modules/Monitor.hpp new file mode 100644 index 00000000..d95ca242 --- /dev/null +++ b/src/Components/Modules/Monitor.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace Components +{ + class Monitor : public Component + { + public: + Monitor(); + +#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) + const char* getName() override { return "Monitor"; }; +#endif + + static bool IsEnabled(); + + private: + static int __stdcall EntryPoint(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd); + }; +} diff --git a/src/Components/Modules/Node.hpp b/src/Components/Modules/Node.hpp index 79f15a38..01ab5e79 100644 --- a/src/Components/Modules/Node.hpp +++ b/src/Components/Modules/Node.hpp @@ -34,6 +34,8 @@ namespace Components static void LoadNodeRemotePreset(); + static void FrameHandler(); + private: enum EntryState { @@ -92,8 +94,6 @@ namespace Components static void DeleteInvalidNodes(); static void DeleteInvalidSessions(); - static void FrameHandler(); - static const char* GetStateName(EntryState state); }; } diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 63594daa..b94391e9 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -44,7 +44,7 @@ namespace Components bool ServerList::IsOnlineList() { - return (Dvar::Var("ui_netSource").get() == 1); + return (Monitor::IsEnabled() || Dvar::Var("ui_netSource").get() == 1); } unsigned int ServerList::GetServerCount() diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp index 3d5065b6..9bd39a77 100644 --- a/src/Components/Modules/ServerList.hpp +++ b/src/Components/Modules/ServerList.hpp @@ -48,6 +48,9 @@ namespace Components static bool IsOfflineList(); static bool IsOnlineList(); + static void Frame(); + static std::vector* GetList(); + private: enum Column { @@ -115,8 +118,6 @@ namespace Components static void UpdateSource(); static void UpdateGameType(); - static void Frame(); - static void SortList(); static void LoadFavourties(); @@ -124,7 +125,6 @@ namespace Components static void RemoveFavourite(std::string server); static ServerInfo* GetServer(unsigned int index); - static std::vector* GetList(); static bool CompareVersion(std::string version1, std::string version2); diff --git a/src/Components/Modules/Toast.cpp b/src/Components/Modules/Toast.cpp index 5953c85b..bd55ae68 100644 --- a/src/Components/Modules/Toast.cpp +++ b/src/Components/Modules/Toast.cpp @@ -146,7 +146,7 @@ namespace Components Toast::Toast() { - if (Dedicated::IsEnabled()) return; + if (Dedicated::IsEnabled() || Monitor::IsEnabled()) return; Toast::ToastHandler = new WinToastLib::WinToastHandler; @@ -172,7 +172,7 @@ namespace Components void Toast::preDestroy() { - if (Dedicated::IsEnabled()) return; + if (Dedicated::IsEnabled() || Monitor::IsEnabled()) return; // Destroying that on the main thread deadlocks. // I did not write the library, so whatever.