From 4e84c297e4a8ad6a82dbb38bd1b1eccc26178914 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 22:03:35 +0100 Subject: [PATCH] [IPC] Use iw4x as worker process instead of creating a separate binary --- README.md | 1 - premake5.lua | 122 ---------------------------- src/Components/Modules/IPCPipe.cpp | 29 ++++++- src/Main.cpp | 43 ++++++---- src/STDInclude.hpp | 1 + src/Utils/IPC.cpp | 6 +- src/Utils/IPC.hpp | 40 ++++++++- src/Worker/Main.cpp | 67 --------------- src/Worker/Resource.rc | 99 ----------------------- src/Worker/Runner.cpp | 60 ++++++++++++++ src/Worker/Runner.hpp | 19 +++++ src/Worker/STDInclude.cpp | 77 ------------------ src/Worker/STDInclude.hpp | 126 ----------------------------- src/Worker/Worker.cpp | 65 +++++++++++++++ src/Worker/Worker.hpp | 11 +++ 15 files changed, 251 insertions(+), 515 deletions(-) delete mode 100644 src/Worker/Main.cpp delete mode 100644 src/Worker/Resource.rc create mode 100644 src/Worker/Runner.cpp create mode 100644 src/Worker/Runner.hpp delete mode 100644 src/Worker/STDInclude.cpp delete mode 100644 src/Worker/STDInclude.hpp create mode 100644 src/Worker/Worker.cpp create mode 100644 src/Worker/Worker.hpp diff --git a/README.md b/README.md index 1587e2f7..c4c4eee9 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,5 @@ | `--disable-bitmessage` | Disable use of BitMessage completely. | | `--disable-node-log` | Disable debugging messages for Nodes in Debug builds. | | `--disable-base128` | Disable base128 encoding for minidumps. | -| `--disable-steam-game` | Disable Steam's in-game setting. | | `--no-new-structure` | Do not use new virtual path structure (separating headers and source files). | | `--enable-dxsdk` | Enable DirectX SDK (required for GfxMap exporting). | diff --git a/premake5.lua b/premake5.lua index c14c35d3..70f9e661 100644 --- a/premake5.lua +++ b/premake5.lua @@ -88,11 +88,6 @@ newoption { description = "Disable base128 encoding for minidumps." } -newoption { - trigger = "disable-steam-game", - description = "Disable Steam's in-game setting." -} - newoption { trigger = "enable-dxsdk", description = "Enable DirectX SDK (required for GfxMap exporting)." @@ -307,9 +302,6 @@ workspace "iw4x" "./src/**.cpp", --"./src/**.proto", } - removefiles { - "./src/Worker/**.*", - } includedirs { "%{prj.location}/src", "./src", @@ -349,9 +341,6 @@ workspace "iw4x" if _OPTIONS["disable-base128"] then defines { "DISABLE_BASE128" } end - if _OPTIONS["disable-steam-game"] then - defines { "DISABLE_STEAM_GAME" } - end if _OPTIONS["enable-dxsdk"] then defines { "ENABLE_DXSDK" } includedirs { "%DXSDK_DIR%Include" } @@ -479,117 +468,6 @@ workspace "iw4x" } filter {} ]] - -project "iw4xworker" - language "C++" - flags { "C++14" } - files { - "./src/Worker/**.rc", - "./src/Worker/**.hpp", - "./src/Worker/**.cpp", - "./src/Utils/**.hpp", - "./src/Utils/**.cpp", - --"./src/**.proto", - } - removefiles { - "./src/Utils/CSV.*", - "./src/Utils/Cache.*", - "./src/Utils/Stream.*", - "./src/Utils/Hooking.*", - "./src/Utils/InfoString.*", - "./src/Utils/Cryptography.*", - } - includedirs { - "%{prj.location}/src", - --"./src", - "./src/Worker", - } - resincludedirs { - "$(ProjectDir)src/Worker" -- fix for VS IDE - } - - -- Pre-compiled header - pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives - pchsource "src/Worker/STDInclude.cpp" -- real path - buildoptions { "/Zm200" } - - protobuf.import() - zlib.import() - boost.import() - - -- fix vpaths for protobuf sources - vpaths - { - ["*"] = { "./src/Worker/**" }, - --["Proto/Generated"] = { "**.pb.*" }, -- meh. - } - - -- Virtual paths - if not _OPTIONS["no-new-structure"] then - vpaths - { - ["Headers/*"] = { "./src/Worker/**.hpp" }, - ["Headers/Utils/*"] = { "./src/Utils/**.hpp" }, - ["Sources/*"] = { "./src/Worker/**.cpp" }, - ["Sources/Utils/*"] = { "./src/Utils/**.cpp" }, - ["Resource/*"] = { "./src/Worker/**.rc" }, - } - else - vpaths - { - ["Utils/*"] = { "./src/Utils/**" }, - } - end - - vpaths - { - ["Docs/*"] = { "**.txt","**.md" }, - } - - -- Pre-build - prebuildcommands - { - "pushd %{_MAIN_SCRIPT_DIR}", - "tools\\premake5 generate-buildinfo", - "popd", - } - - -- Post-build - if _OPTIONS["copy-to"] then - saneCopyToPath = string.gsub(_OPTIONS["copy-to"] .. "\\", "\\\\", "\\") - postbuildcommands { - "if not exist \"" .. saneCopyToPath .. "\" mkdir \"" .. saneCopyToPath .. "iw4x\\\"", - } - - if _OPTIONS["copy-pdb"] then - postbuildcommands { - "copy /y \"$(TargetDir)*.pdb\" \"" .. saneCopyToPath .. "iw4x\\\"", - } - end - - -- This has to be the last one, as otherwise VisualStudio will succeed building even if copying fails - postbuildcommands { - "copy /y \"$(TargetDir)*.exe\" \"" .. saneCopyToPath .. "iw4x\\\"", - } - end - - -- Specific configurations - flags { "UndefinedIdentifiers", "ExtraWarnings" } - - if symbols ~= nil then - symbols "On" - else - flags { "Symbols" } - end - - kind "ConsoleApp" - configuration "Release*" - kind "WindowedApp" - flags { - "FatalCompileWarnings", - "FatalLinkWarnings", - } - configuration {} group "External dependencies" if not _OPTIONS["disable-bitmessage"] then diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp index 640ca0f7..1b558082 100644 --- a/src/Components/Modules/IPCPipe.cpp +++ b/src/Components/Modules/IPCPipe.cpp @@ -236,8 +236,7 @@ namespace Components IPCPipe::Write("ping", ""); }); - static Utils::IPC::Channel channel("iw4xChannel"); - static Utils::IPC::Channel channel2("iw4xChannel2"); + static Utils::IPC::BidirectionalChannel channel("iw4xChannel", !Worker::IsWorker()); channel.send("Hello world!"); Command::Add("ipcchan", [](Command::Params* params) @@ -245,10 +244,32 @@ namespace Components channel.send(params->join(1)); }); + Command::Add("ipcchantest", [](Command::Params*) + { + std::string buffer; + buffer.reserve(2048); + + for(int i = 0; i < 1020; ++i) + { + buffer.append("a", 1); + } + + buffer.append("lolsnakerules!"); + + for (int i = 0; i < 1020; ++i) + { + buffer.append("a", 1); + } + + buffer.append("lolsnakerules!"); + + channel.send(buffer); + }); + QuickPatch::OnFrame([]() { std::string buffer; - if(channel2.receive(&buffer)) + if(channel.receive(&buffer)) { Logger::Print("Data received: %s\n", buffer.data()); } @@ -261,7 +282,7 @@ namespace Components ZeroMemory(&pInfo, sizeof(pInfo)); sInfo.cb = sizeof(sInfo); - CreateProcessA("iw4x/iw4xworker.exe", const_cast(Utils::String::VA("-parentProc %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); + CreateProcessA("iw4x.exe", const_cast(Utils::String::VA("-parent %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hThread); if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess); diff --git a/src/Main.cpp b/src/Main.cpp index 59728f33..3587fd52 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -20,28 +20,43 @@ namespace Main Main::EntryPointHook.uninstall(); Main::SetEnvironment(); - Utils::Cryptography::Initialize(); - Components::Loader::Initialize(); + + if(Worker::IsWorker()) + { + Worker::Initialize(); + } + else + { + Components::Loader::Initialize(); #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - if (Components::Loader::PerformingUnitTests()) - { - DWORD result = (Components::Loader::PerformUnitTests() ? 0 : -1); - Components::Loader::Uninitialize(); - ExitProcess(result); - } + if (Components::Loader::PerformingUnitTests()) + { + DWORD result = (Components::Loader::PerformUnitTests() ? 0 : -1); + Components::Loader::Uninitialize(); + ExitProcess(result); + } #else - if (Components::Flags::HasFlag("tests")) - { - Components::Logger::Print("Unit tests are disabled outside the debug environment!\n"); - } + if (Components::Flags::HasFlag("tests")) + { + Components::Logger::Print("Unit tests are disabled outside the debug environment!\n"); + } #endif + } } void Uninitialize() { - Components::Loader::Uninitialize(); + if(Worker::IsWorker()) + { + Worker::Uninitialize(); + } + else + { + Components::Loader::Uninitialize(); + } + Utils::Cache::Uninitialize(); google::protobuf::ShutdownProtobufLibrary(); } @@ -51,8 +66,6 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { - Steam::Proxy::RunMod(); - // Ensure we're working with our desired binary if (Utils::Hook::Get(0x4C0FFF) != 0x6824748B) { diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index 2667fb2d..d6cb65ab 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -117,6 +117,7 @@ template class Sizer { }; #include "Utils/Stream.hpp" #include "Components/Loader.hpp" +#include "Worker/Worker.hpp" // Libraries #pragma comment(lib, "Winmm.lib") diff --git a/src/Utils/IPC.cpp b/src/Utils/IPC.cpp index e763be18..79ab2c86 100644 --- a/src/Utils/IPC.cpp +++ b/src/Utils/IPC.cpp @@ -4,9 +4,9 @@ namespace Utils { namespace IPC { - Channel::Channel(std::string _name, int queueSize, int bufferSize) : name(_name) + Channel::Channel(std::string _name, int queueSize, int bufferSize, bool creator) : name(_name) { - //boost::interprocess::message_queue::remove(this->name.data()); + if(creator) boost::interprocess::message_queue::remove(this->name.data()); queue.reset(new boost::interprocess::message_queue(boost::interprocess::open_or_create, this->name.data(), queueSize, bufferSize + sizeof(Channel::Header))); } @@ -43,7 +43,7 @@ namespace Utils while (true) { - this->queue->receive(const_cast(packet.data()), packet.size(), recvd_size, priority); + if (!this->queue->try_receive(const_cast(packet.data()), packet.size(), recvd_size, priority)) return false; if (header->packetId != mainHeader.packetId || header->totalSize != mainHeader.totalSize || header->fragmentPart != (++part)) { diff --git a/src/Utils/IPC.hpp b/src/Utils/IPC.hpp index 72c72382..7d91c9d4 100644 --- a/src/Utils/IPC.hpp +++ b/src/Utils/IPC.hpp @@ -29,7 +29,7 @@ namespace Utils class Channel { public: - Channel(std::string _name, int queueSize = 100, int bufferSize = 20); + Channel(std::string _name, int queueSize = 100, int bufferSize = 1024, bool creator = false); ~Channel(); bool receive(std::string* data); @@ -51,5 +51,43 @@ namespace Utils std::string packet; std::string name; }; + + class BidirectionalChannel + { + public: + BidirectionalChannel(std::string name, bool server, int queueSize = 100, int bufferSize = 1024) : isServer(server), + channel1(name, queueSize, bufferSize, server), + channel2(name + "2", queueSize, bufferSize, server) + {} + + bool receive(std::string* data) + { + if(this->isServer) + { + return channel1.receive(data); + } + else + { + return channel2.receive(data); + } + } + + void send(std::string data) + { + if (this->isServer) + { + return channel2.send(data); + } + else + { + return channel1.send(data); + } + } + + private: + const bool isServer; + Channel channel1; + Channel channel2; + }; } } diff --git a/src/Worker/Main.cpp b/src/Worker/Main.cpp deleted file mode 100644 index 6050ff4f..00000000 --- a/src/Worker/Main.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "STDInclude.hpp" -#include - -void worker(bool* terminator) -{ - printf("Worker started\n"); - Utils::IPC::Channel channel("iw4xChannel"); - Utils::IPC::Channel channel2("iw4xChannel2"); - - while(!*terminator) - { - std::string buffer; - if(channel.receive(&buffer)) - { - printf("Data received: %s\n", buffer.data()); - channel2.send("OK " + buffer); - } - - std::this_thread::sleep_for(1ms); - } - - printf("Terminating worker\n"); -} - -int main() -{ - bool terminator = false; - char* command = "-parentProc "; - char* parentProc = strstr(GetCommandLineA(), command); - - if (!parentProc) - { - printf("No parent process argument found\n"); - return 0; - } - - parentProc += strlen(command); - int pid = atoi(parentProc); - - printf("Attaching to process %d...\n", pid); - - HANDLE processHandle = OpenProcess(SYNCHRONIZE, FALSE, pid); - if (!processHandle || processHandle == INVALID_HANDLE_VALUE) - { - printf("Unable to attach to parent process\n"); - return 0; - } - - printf("Successfully attached to parent process\n"); - printf("Starting worker...\n"); - - std::thread runner(worker, &terminator); - - WaitForSingleObject(processHandle, INFINITE); - CloseHandle(processHandle); - - terminator = true; - - printf("Awaiting worker termination...\n"); - if (runner.joinable()) runner.join(); - printf("Worker terminated\n"); - - //_getch(); - - google::protobuf::ShutdownProtobufLibrary(); - return 0; -} diff --git a/src/Worker/Resource.rc b/src/Worker/Resource.rc deleted file mode 100644 index 1a74c1b4..00000000 --- a/src/Worker/Resource.rc +++ /dev/null @@ -1,99 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) - -#include "STDInclude.hpp" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "windows.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "#include ""windows.h""\r\n" - "\0" -END - -2 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_RC - PRODUCTVERSION VERSION_RC - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE VFT_DLL - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "IW4x" -#ifdef _DEBUG - VALUE "FileDescription", "IW4 client modification (DEBUG)" -#else - VALUE "FileDescription", "IW4 client modification" -#endif - VALUE "FileVersion", SHORTVERSION - VALUE "InternalName", "iw4x" - VALUE "LegalCopyright", "No rights reserved." - VALUE "OriginalFilename", "iw4x.dll" - VALUE "ProductName", "IW4x" - VALUE "ProductVersion", SHORTVERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/Worker/Runner.cpp b/src/Worker/Runner.cpp new file mode 100644 index 00000000..19e56d93 --- /dev/null +++ b/src/Worker/Runner.cpp @@ -0,0 +1,60 @@ +#include "STDInclude.hpp" + +namespace Worker +{ + Runner::Runner(int pid) : processId(pid), terminate(false) + { + + } + + Runner::~Runner() + { + + } + + void Runner::run() + { + HANDLE processHandle = OpenProcess(SYNCHRONIZE, FALSE, this->processId); + if (!processHandle || processHandle == INVALID_HANDLE_VALUE) + { + printf("Unable to attach to parent process\n"); + } + else + { + printf("Successfully attached to parent process\n"); + printf("Starting worker...\n"); + + std::thread workerThread(&Runner::worker, this); + + WaitForSingleObject(processHandle, INFINITE); + CloseHandle(processHandle); + + this->terminate = true; + printf("Awaiting worker termination...\n"); + if (workerThread.joinable()) workerThread.join(); + printf("Worker terminated\n"); + } + } + + void Runner::worker() + { + printf("Worker started\n"); + Utils::IPC::BidirectionalChannel channel("iw4xChannel", !Worker::IsWorker()); + + while (!this->terminate) + { + Steam::Proxy::RunFrame(); + + std::string buffer; + if (channel.receive(&buffer)) + { + printf("Data received: %s\n", buffer.data()); + channel.send("OK " + buffer); + } + + std::this_thread::sleep_for(1ms); + } + + printf("Terminating worker\n"); + } +} diff --git a/src/Worker/Runner.hpp b/src/Worker/Runner.hpp new file mode 100644 index 00000000..4c13444b --- /dev/null +++ b/src/Worker/Runner.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace Worker +{ + class Runner + { + public: + Runner(int pid); + ~Runner(); + + void run(); + + private: + void worker(); + + int processId; + bool terminate; + }; +} diff --git a/src/Worker/STDInclude.cpp b/src/Worker/STDInclude.cpp deleted file mode 100644 index 2edc9db6..00000000 --- a/src/Worker/STDInclude.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "STDInclude.hpp" - -// Rename sections -#ifndef DEBUG -#pragma comment(linker, "/merge:.text=.UPX0") -#pragma comment(linker, "/merge:.data=.UPX1") -#pragma comment(linker, "/merge:.rdata=.UPX2") -#pragma comment(linker, "/merge:.tls=.UPX3") -#pragma comment(linker, "/merge:.gfids=.UPX4") -#endif - -#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") - -// Do necessary assertions here -// Some compilers treat them differently which causes a size mismatch - -// WinAPI types -AssertSize(DWORD, 4); -AssertSize(WORD, 2); -AssertSize(BYTE, 1); - -// 128 bit integers (only x64) -//AssertSize(__int128, 16); -//AssertSize(unsigned __int128, 16); - -// 64 bit integers -AssertSize(__int64, 8); -AssertSize(unsigned __int64, 8); -AssertSize(long long, 8); -AssertSize(unsigned long long, 8); -AssertSize(int64_t, 8); -AssertSize(uint64_t, 8); -AssertSize(std::int64_t, 8); -AssertSize(std::uint64_t, 8); - -// 32 bit integers -AssertSize(__int32, 4); -AssertSize(unsigned __int32, 4); -AssertSize(int, 4); -AssertSize(unsigned int, 4); -AssertSize(int32_t, 4); -AssertSize(uint32_t, 4); -AssertSize(std::int32_t, 4); -AssertSize(std::uint32_t, 4); - -// 16 bit integers -AssertSize(__int16, 2); -AssertSize(unsigned __int16, 2); -AssertSize(short, 2); -AssertSize(unsigned short, 2); -AssertSize(int16_t, 2); -AssertSize(uint16_t, 2); -AssertSize(std::int16_t, 2); -AssertSize(std::uint16_t, 2); - -// 8 bit integers -AssertSize(bool, 1); -AssertSize(__int8, 1); -AssertSize(unsigned __int8, 1); -AssertSize(char, 1); -AssertSize(unsigned char, 1); -AssertSize(int8_t, 1); -AssertSize(uint8_t, 1); -AssertSize(std::int8_t, 1); -AssertSize(std::uint8_t, 1); - -// Ensure pointers are 4 bytes in size (32-bit) -static_assert(sizeof(intptr_t) == 4 && sizeof(void*) == 4 && sizeof(size_t) == 4, "This doesn't seem to be a 32-bit environment!"); - -extern "C" -{ - // Disable telemetry data logging - void __cdecl __vcrt_initialize_telemetry_provider() {} - void __cdecl __telemetry_main_invoke_trigger() {} - void __cdecl __telemetry_main_return_trigger() {} - void __cdecl __vcrt_uninitialize_telemetry_provider() {} -}; diff --git a/src/Worker/STDInclude.hpp b/src/Worker/STDInclude.hpp deleted file mode 100644 index 2237256d..00000000 --- a/src/Worker/STDInclude.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#pragma once - -// Version number -#include "version.h" - -#ifndef RC_INVOKED - -#define VC_EXTRALEAN -#define WIN32_LEAN_AND_MEAN - -// Requires Visual Leak Detector plugin: http://vld.codeplex.com/ -//#include - -#include -#include -#include -#include -#include -#include - -#pragma warning(push) -#pragma warning(disable: 4996) -#include -#pragma warning(pop) - -#include -#include -#include -#include -#include -#include -#include -#include - -// Experimental C++17 features -#include - -// Usefull for debugging -template class Sizer { }; -#define BindNum(x, y) Sizer y; -#define SizeOf(x, y) BindNum(sizeof(x), y) -#define OffsetOf(x, y, z) BindNum(offsetof(x, y), z) - -// Submodules -// Ignore the warnings, it's no our code! -#pragma warning(push) -#pragma warning(disable: 4005) -#pragma warning(disable: 4100) -#pragma warning(disable: 4389) -#pragma warning(disable: 4702) -#pragma warning(disable: 4996) // _CRT_SECURE_NO_WARNINGS -#pragma warning(disable: 6001) -#pragma warning(disable: 6011) -#pragma warning(disable: 6031) -#pragma warning(disable: 6255) -#pragma warning(disable: 6258) -#pragma warning(disable: 6386) -#pragma warning(disable: 6387) - -#include - -#ifdef max -#undef max -#endif - -#ifdef min -#undef min -#endif - -// Protobuf -#include "proto/network.pb.h" -#include "proto/party.pb.h" -#include "proto/auth.pb.h" -#include "proto/node.pb.h" -#include "proto/rcon.pb.h" - -#pragma warning(pop) - -#include "../Utils/IO.hpp" -#include "../Utils/IPC.hpp" -#include "../Utils/Time.hpp" -#include "../Utils/Chain.hpp" -#include "../Utils/Utils.hpp" -#include "../Utils/WebIO.hpp" -#include "../Utils/Memory.hpp" -#include "../Utils/String.hpp" -#include "../Utils/Library.hpp" -#include "../Utils/Compression.hpp" - -// Libraries -#pragma comment(lib, "Winmm.lib") -#pragma comment(lib, "Crypt32.lib") -#pragma comment(lib, "Ws2_32.lib") -#pragma comment(lib, "d3d9.lib") -#pragma comment(lib, "Wininet.lib") -#pragma comment(lib, "shlwapi.lib") -#pragma comment(lib, "Urlmon.lib") -#pragma comment(lib, "Advapi32.lib") -#pragma comment(lib, "rpcrt4.lib") - -// Enable additional literals -using namespace std::literals; - -#endif - -#define STRINGIZE_(x) #x -#define STRINGIZE(x) STRINGIZE_(x) - -#define AssertSize(x, size) static_assert(sizeof(x) == size, STRINGIZE(x) " structure has an invalid size.") -#define AssertOffset(x, y, offset) static_assert(offsetof(x, y) == offset, STRINGIZE(x) "::" STRINGIZE(y) " is not at the right offset.") - -// Resource stuff -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -// Defines below make accessing the resources from the code easier. -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif - -// Enables custom map code -#ifdef DEBUG -#define ENABLE_EXPERIMENTAL_MAP_CODE -#endif diff --git a/src/Worker/Worker.cpp b/src/Worker/Worker.cpp new file mode 100644 index 00000000..e27c2619 --- /dev/null +++ b/src/Worker/Worker.cpp @@ -0,0 +1,65 @@ +#include "STDInclude.hpp" + +namespace Worker +{ + int ProcessId; + + int __stdcall EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, char* /*lpCmdLine*/, int /*nCmdShow*/) + { + Runner runner(Worker::ProcessId); + runner.run(); + return 0; + } + + void Initialize() + { + if(!Steam::Proxy::Inititalize()) + { + printf("Failed to initialize worker!\n"); + ExitProcess(1); + } + else + { +#ifdef DEBUG + SetConsoleTitleA("IW4x Worker"); +#else + FreeConsole(); +#endif + + Utils::Hook(0x6BABA1, Worker::EntryPoint, HOOK_CALL).install()->quick(); + } + } + + void Uninitialize() + { + Steam::Proxy::Uninititalize(); + } + + bool ParseWorkerFlag() + { + char* command = "-parent "; + char* parentProc = strstr(GetCommandLineA(), command); + + if (parentProc) + { + parentProc += strlen(command); + Worker::ProcessId = atoi(parentProc); + + return true; + } + + return false; + } + + bool IsWorker() + { + static Utils::Value flag; + + if (!flag.isValid()) + { + flag.set(Worker::ParseWorkerFlag()); + } + + return flag.get(); + } +} diff --git a/src/Worker/Worker.hpp b/src/Worker/Worker.hpp new file mode 100644 index 00000000..4f700b23 --- /dev/null +++ b/src/Worker/Worker.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace Worker +{ + void Initialize(); + void Uninitialize(); + + bool IsWorker(); +} + +#include "Runner.hpp"