[IPC] Use iw4x as worker process instead of creating a separate binary
This commit is contained in:
parent
fc0bf1acc1
commit
4e84c297e4
@ -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). |
|
||||
|
122
premake5.lua
122
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" }
|
||||
@ -480,117 +469,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
|
||||
bitmrc.project()
|
||||
|
@ -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<char*>(Utils::String::VA("-parentProc %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo);
|
||||
CreateProcessA("iw4x.exe", const_cast<char*>(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);
|
||||
|
19
src/Main.cpp
19
src/Main.cpp
@ -20,8 +20,14 @@ namespace Main
|
||||
Main::EntryPointHook.uninstall();
|
||||
|
||||
Main::SetEnvironment();
|
||||
|
||||
Utils::Cryptography::Initialize();
|
||||
|
||||
if(Worker::IsWorker())
|
||||
{
|
||||
Worker::Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Components::Loader::Initialize();
|
||||
|
||||
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
|
||||
@ -38,10 +44,19 @@ namespace Main
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void 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<DWORD>(0x4C0FFF) != 0x6824748B)
|
||||
{
|
||||
|
@ -117,6 +117,7 @@ template <size_t S> class Sizer { };
|
||||
#include "Utils/Stream.hpp"
|
||||
|
||||
#include "Components/Loader.hpp"
|
||||
#include "Worker/Worker.hpp"
|
||||
|
||||
// Libraries
|
||||
#pragma comment(lib, "Winmm.lib")
|
||||
|
@ -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<char*>(packet.data()), packet.size(), recvd_size, priority);
|
||||
if (!this->queue->try_receive(const_cast<char*>(packet.data()), packet.size(), recvd_size, priority)) return false;
|
||||
|
||||
if (header->packetId != mainHeader.packetId || header->totalSize != mainHeader.totalSize || header->fragmentPart != (++part))
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
#include "STDInclude.hpp"
|
||||
#include <conio.h>
|
||||
|
||||
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;
|
||||
}
|
@ -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
|
||||
|
60
src/Worker/Runner.cpp
Normal file
60
src/Worker/Runner.cpp
Normal file
@ -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");
|
||||
}
|
||||
}
|
19
src/Worker/Runner.hpp
Normal file
19
src/Worker/Runner.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
namespace Worker
|
||||
{
|
||||
class Runner
|
||||
{
|
||||
public:
|
||||
Runner(int pid);
|
||||
~Runner();
|
||||
|
||||
void run();
|
||||
|
||||
private:
|
||||
void worker();
|
||||
|
||||
int processId;
|
||||
bool terminate;
|
||||
};
|
||||
}
|
@ -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() {}
|
||||
};
|
@ -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 <vld.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
#include <shellapi.h>
|
||||
#include <Wininet.h>
|
||||
#include <d3d9.h>
|
||||
#include <Aclapi.h>
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4996)
|
||||
#include <xutility>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <cctype>
|
||||
#include <regex>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
||||
// Experimental C++17 features
|
||||
#include <filesystem>
|
||||
|
||||
// Usefull for debugging
|
||||
template <size_t S> class Sizer { };
|
||||
#define BindNum(x, y) Sizer<x> 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 <zlib.h>
|
||||
|
||||
#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
|
65
src/Worker/Worker.cpp
Normal file
65
src/Worker/Worker.cpp
Normal file
@ -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<bool> flag;
|
||||
|
||||
if (!flag.isValid())
|
||||
{
|
||||
flag.set(Worker::ParseWorkerFlag());
|
||||
}
|
||||
|
||||
return flag.get();
|
||||
}
|
||||
}
|
11
src/Worker/Worker.hpp
Normal file
11
src/Worker/Worker.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace Worker
|
||||
{
|
||||
void Initialize();
|
||||
void Uninitialize();
|
||||
|
||||
bool IsWorker();
|
||||
}
|
||||
|
||||
#include "Runner.hpp"
|
Loading…
Reference in New Issue
Block a user