diff --git a/src/Components/Modules/IPCHandler.cpp b/src/Components/Modules/IPCHandler.cpp index 54c5c51a..1f05893e 100644 --- a/src/Components/Modules/IPCHandler.cpp +++ b/src/Components/Modules/IPCHandler.cpp @@ -2,36 +2,12 @@ namespace Components { - std::unordered_map IPCHandler::WorkerCallbacks; std::unordered_map IPCHandler::ClientCallbacks; - - std::unique_ptr IPCHandler::WorkerChannel; std::unique_ptr IPCHandler::ClientChannel; - std::unordered_map> IPCHandler::FunctionInterfaces; - - std::shared_ptr IPCHandler::NewInterface(std::string command) - { - std::shared_ptr fInterface(new IPCHandler::FunctionInterface()); - IPCHandler::FunctionInterfaces[command] = fInterface; - return fInterface; - } - - void IPCHandler::SendWorker(std::string message, std::string data) - { - IPCHandler::InitChannels(); - if (!Singleton::IsFirstInstance()) return; - - Proto::IPC::Command command; - command.set_name(message); - command.set_data(data); - - IPCHandler::WorkerChannel->send(command.SerializeAsString()); - } - void IPCHandler::SendClient(std::string message, std::string data) { - IPCHandler::InitChannels(); + IPCHandler::InitChannel(); Proto::IPC::Command command; command.set_name(message); @@ -40,52 +16,22 @@ namespace Components IPCHandler::ClientChannel->send(command.SerializeAsString()); } - void IPCHandler::OnWorker(std::string message, IPCHandler::Callback callback) - { - IPCHandler::WorkerCallbacks[message] = callback; - } - void IPCHandler::OnClient(std::string message, IPCHandler::Callback callback) { IPCHandler::ClientCallbacks[message] = callback; } - void IPCHandler::InitChannels() + void IPCHandler::InitChannel() { - if (Singleton::IsFirstInstance()) - { - if (!IPCHandler::WorkerChannel) - { - IPCHandler::WorkerChannel.reset(new Utils::IPC::BidirectionalChannel("IW4x-Worker-Channel", !Worker::IsWorker())); - } - } - if (!IPCHandler::ClientChannel) { IPCHandler::ClientChannel.reset(new Utils::IPC::BidirectionalChannel("IW4x-Client-Channel", Singleton::IsFirstInstance())); } } - void IPCHandler::StartWorker() - { - if (!Singleton::IsFirstInstance()) return; - - STARTUPINFOA sInfo; - PROCESS_INFORMATION pInfo; - - ZeroMemory(&sInfo, sizeof(sInfo)); - ZeroMemory(&pInfo, sizeof(pInfo)); - sInfo.cb = sizeof(sInfo); - - 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); - } - void IPCHandler::HandleClient() { - IPCHandler::InitChannels(); + IPCHandler::InitChannel(); std::string packet; if(IPCHandler::ClientChannel->receive(&packet)) @@ -102,53 +48,18 @@ namespace Components } } - void IPCHandler::HandleWorker() - { - IPCHandler::InitChannels(); - if (!Singleton::IsFirstInstance()) return; - - std::string packet; - if (IPCHandler::WorkerChannel->receive(&packet)) - { - Proto::IPC::Command command; - if (command.ParseFromString(packet)) - { - auto callback = IPCHandler::WorkerCallbacks.find(command.name()); - auto fInterface = IPCHandler::FunctionInterfaces.find(command.name()); - if (callback != IPCHandler::WorkerCallbacks.end()) - { - callback->second(command.data()); - } - else if(fInterface != IPCHandler::FunctionInterfaces.end()) - { - fInterface->second->handle(command.data()); - } - } - } - } - IPCHandler::IPCHandler() { if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled() || Loader::PerformingUnitTests()) return; - IPCHandler::InitChannels(); - IPCHandler::StartWorker(); + IPCHandler::InitChannel(); - QuickPatch::OnFrame([]() - { - IPCHandler::HandleWorker(); - IPCHandler::HandleClient(); - }); + QuickPatch::OnFrame(IPCHandler::HandleClient); } IPCHandler::~IPCHandler() { - IPCHandler::FunctionInterfaces.clear(); - - IPCHandler::WorkerCallbacks.clear(); IPCHandler::ClientCallbacks.clear(); - - IPCHandler::WorkerChannel.release(); IPCHandler::ClientChannel.release(); } } diff --git a/src/Components/Modules/IPCHandler.hpp b/src/Components/Modules/IPCHandler.hpp index 407ba255..fe28bc47 100644 --- a/src/Components/Modules/IPCHandler.hpp +++ b/src/Components/Modules/IPCHandler.hpp @@ -5,34 +5,6 @@ namespace Components class IPCHandler : public Component { public: - class FunctionInterface - { - public: - typedef std::function)> Callback; - - void map(std::string name, Callback function) - { - this->functions[name] = function; - } - - void handle(std::string data) - { - Proto::IPC::Function function; - if (function.ParseFromString(data)) - { - auto handler = this->functions.find(function.name()); - if (handler != this->functions.end()) - { - auto params = function.params(); - handler->second(std::vector(params.begin(), params.end())); - } - } - } - - private: - std::unordered_map functions; - }; - typedef Utils::Slot Callback; IPCHandler(); @@ -42,27 +14,14 @@ namespace Components const char* getName() override { return "IPCHandler"; }; #endif - static void SendWorker(std::string message, std::string data); static void SendClient(std::string message, std::string data); - - static void OnWorker(std::string message, Callback callback); static void OnClient(std::string message, Callback callback); - static std::shared_ptr NewInterface(std::string command); - private: - static std::unique_ptr WorkerChannel; static std::unique_ptr ClientChannel; - - static std::unordered_map WorkerCallbacks; static std::unordered_map ClientCallbacks; - static std::unordered_map> FunctionInterfaces; - - static void InitChannels(); - static void StartWorker(); - + static void InitChannel(); static void HandleClient(); - static void HandleWorker(); }; } diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index 4400fcbf..ebe69e62 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -120,7 +120,6 @@ 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/Worker/Handlers/Friends.cpp b/src/Worker/Handlers/Friends.cpp deleted file mode 100644 index 9e8b0a71..00000000 --- a/src/Worker/Handlers/Friends.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include "STDInclude.hpp" - -namespace Handlers -{ - void Friends::handle(Worker::Endpoint endpoint, std::string data) - { - Proto::IPC::Function function; - if (function.ParseFromString(data)) - { - auto handler = this->functions.find(function.name()); - if (handler != this->functions.end()) - { - printf("Handing function %s\n", function.name().data()); - - auto params = function.params(); - handler->second(endpoint, std::vector(params.begin(), params.end())); - } - else - { - printf("No handler for function %s\n", function.name().data()); - } - } - } - - void Friends::addFunction(std::string function, Friends::Callback callback) - { - this->functions[function] = callback; - } - - void Friends::getFriends(Worker::Endpoint endpoint, std::vector params) - { - if (params.size() >= 1 && Steam::Proxy::SteamFriends) - { - int flag = atoi(params[0].data()); - int count = Steam::Proxy::SteamFriends->GetFriendCount(flag); - - Proto::IPC::Function response; - response.set_name("friendsResponse"); - - for (int i = 0; i < count; ++i) - { - SteamID id = Steam::Proxy::SteamFriends->GetFriendByIndex(i, flag); - *response.add_params() = Utils::String::VA("%llX", id.Bits); - } - - endpoint.send(this->getCommand(), response.SerializeAsString()); - } - } - - void Friends::getName(Worker::Endpoint endpoint, std::vector params) - { - if(Steam::Proxy::SteamFriends) - { - std::string name; - SteamID id; - - if(params.size() >= 1) - { - id.Bits = strtoull(params[0].data(), nullptr, 16); - name = Steam::Proxy::SteamFriends->GetFriendPersonaName(id); - } - else - { - id.Bits = 0; - name = Steam::Proxy::SteamFriends->GetPersonaName(); - } - - Proto::IPC::Function response; - response.set_name("nameResponse"); - *response.add_params() = Utils::String::VA("%llX", id.Bits); - *response.add_params() = name; - - endpoint.send(this->getCommand(), response.SerializeAsString()); - } - } - - void Friends::setPresence(Worker::Endpoint /*endpoint*/, std::vector params) - { - if (params.size() >= 1 && Steam::Proxy::SteamFriends) - { - Steam::Proxy::SteamFriends->SetRichPresence(params[0].data(), (params.size() >= 2 ? params[1].data() : nullptr)); - } - } - - void Friends::getPresence(Worker::Endpoint endpoint, std::vector params) - { - if (params.size() >= 2 && Steam::Proxy::SteamFriends) - { - SteamID id; - id.Bits = strtoull(params[0].data(), nullptr, 16); - - Proto::IPC::Function response; - response.set_name("presenceResponse"); - *response.add_params() = Utils::String::VA("%llX", id.Bits); - *response.add_params() = params[1].data(); - *response.add_params() = Steam::Proxy::SteamFriends->GetFriendRichPresence(id, params[1].data()); - - endpoint.send(this->getCommand(), response.SerializeAsString()); - } - } - - void Friends::requestPresence(Worker::Endpoint /*endpoint*/, std::vector params) - { - if (params.size() >= 1 && Steam::Proxy::SteamFriends) - { - SteamID id; - id.Bits = strtoull(params[0].data(), nullptr, 16); - - Steam::Proxy::SteamFriends->RequestFriendRichPresence(id); - } - } - - void Friends::notifyChange(Worker::Endpoint /*endpoint*/, std::vector params) - { - // Ugly, but for now it works - int state = Steam::Proxy::SteamLegacyFriends->GetPersonaState(); - Steam::Proxy::SteamLegacyFriends->SetPersonaState((state == 1 ? 2 : 1)); - } - - void Friends::getInfo(Worker::Endpoint endpoint, std::vector params) - { - if (params.size() >= 1 && Steam::Proxy::SteamFriends) - { - SteamID id; - id.Bits = strtoull(params[0].data(), nullptr, 16); - - Proto::IPC::Function response; - response.set_name("infoResponse"); - *response.add_params() = Utils::String::VA("%llX", id.Bits); - - for(unsigned int i = 1; i < params.size(); ++i) - { - std::string key = params[i]; - *response.add_params() = key; - - if(key == "name") - { - *response.add_params() = Steam::Proxy::SteamFriends->GetFriendPersonaName(id); - } - else if(key == "state") - { - *response.add_params() = Utils::String::VA("%d", Steam::Proxy::SteamFriends->GetFriendPersonaState(id)); - } - else - { - *response.add_params() = Steam::Proxy::SteamFriends->GetFriendRichPresence(id, key.data()); - } - } - - endpoint.send(this->getCommand(), response.SerializeAsString()); - } - } - - Friends::Friends() : personaState(1) - { - using namespace std::placeholders; - this->addFunction("getFriends", std::bind(&Friends::getFriends, this, _1, _2)); - this->addFunction("getName", std::bind(&Friends::getName, this, _1, _2)); - this->addFunction("setPresence", std::bind(&Friends::setPresence, this, _1, _2)); - this->addFunction("getPresence", std::bind(&Friends::getPresence, this, _1, _2)); - this->addFunction("requestPresence", std::bind(&Friends::requestPresence, this, _1, _2)); - this->addFunction("getInfo", std::bind(&Friends::getInfo, this, _1, _2)); - this->addFunction("notifyChange", std::bind(&Friends::notifyChange, this, _1, _2)); - - if (Steam::Proxy::SteamLegacyFriends) - { - this->personaState = Steam::Proxy::SteamLegacyFriends->GetPersonaState(); - } - } - - Friends::~Friends() - { - if(Steam::Proxy::SteamFriends) - { - Steam::Proxy::SteamFriends->SetRichPresence("iw4x_server", nullptr); - Steam::Proxy::SteamFriends->SetRichPresence("iw4x_playing", nullptr); - } - - if(Steam::Proxy::SteamLegacyFriends) - { - Steam::Proxy::SteamLegacyFriends->SetPersonaState(this->personaState); - } - } -} diff --git a/src/Worker/Handlers/Friends.hpp b/src/Worker/Handlers/Friends.hpp deleted file mode 100644 index df32d676..00000000 --- a/src/Worker/Handlers/Friends.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -namespace Handlers -{ - class Friends : public Worker::Runner::Handler - { - public: - typedef std::function)> Callback; - - Friends(); - ~Friends(); - - std::string getCommand() override { return "friends"; }; - void handle(Worker::Endpoint endpoint, std::string data) override; - - private: - int personaState; - - std::unordered_map functions; - void addFunction(std::string function, Callback callback); - - void getFriends(Worker::Endpoint endpoint, std::vector params); - void getName(Worker::Endpoint endpoint, std::vector params); - void setPresence(Worker::Endpoint endpoint, std::vector params); - void getPresence(Worker::Endpoint endpoint, std::vector params); - void requestPresence(Worker::Endpoint endpoint, std::vector params); - void getInfo(Worker::Endpoint endpoint, std::vector params); - void notifyChange(Worker::Endpoint /*endpoint*/, std::vector params); - }; -} diff --git a/src/Worker/Handlers/SteamCallbacks.cpp b/src/Worker/Handlers/SteamCallbacks.cpp deleted file mode 100644 index e2ed0ac1..00000000 --- a/src/Worker/Handlers/SteamCallbacks.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "STDInclude.hpp" - -namespace Handlers -{ - void SteamCallbacks::handle(Worker::Endpoint endpoint, std::string data) - { - Proto::IPC::Function function; - if (function.ParseFromString(data)) - { - auto handler = this->functions.find(function.name()); - if (handler != this->functions.end()) - { - printf("Handing function %s\n", function.name().data()); - - auto params = function.params(); - handler->second(endpoint, std::vector(params.begin(), params.end())); - } - else - { - printf("No handler for function %s\n", function.name().data()); - } - } - } - - void SteamCallbacks::addFunction(std::string function, Friends::Callback callback) - { - this->functions[function] = callback; - } - - void SteamCallbacks::HandleCallback(int32_t callId, void* data, size_t size) - { - if(Worker::Runner::Channel) - { - Proto::IPC::Function response; - response.set_name(Utils::String::VA("%d", callId)); - response.add_params()->append(static_cast(data), size); - - Proto::IPC::Command command; - command.set_name(SteamCallbacks().getCommand()); - command.set_data(response.SerializeAsString()); - - Worker::Runner::Channel->send(command.SerializeAsString()); - } - } - - SteamCallbacks::SteamCallbacks() - { - - } - - SteamCallbacks::~SteamCallbacks() - { - - } -} diff --git a/src/Worker/Handlers/SteamCallbacks.hpp b/src/Worker/Handlers/SteamCallbacks.hpp deleted file mode 100644 index 968510ea..00000000 --- a/src/Worker/Handlers/SteamCallbacks.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -namespace Handlers -{ - class SteamCallbacks : public Worker::Runner::Handler - { - public: - typedef std::function)> Callback; - - SteamCallbacks(); - ~SteamCallbacks(); - - std::string getCommand() override { return "steamCallbacks"; }; - void handle(Worker::Endpoint endpoint, std::string data) override; - - static void HandleCallback(int32_t callId, void* data, size_t size); - - private: - std::unordered_map functions; - void addFunction(std::string function, Callback callback); - }; -} diff --git a/src/Worker/Runner.cpp b/src/Worker/Runner.cpp deleted file mode 100644 index 1403fee5..00000000 --- a/src/Worker/Runner.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "STDInclude.hpp" - -namespace Worker -{ - Utils::IPC::BidirectionalChannel* Runner::Channel; - - Runner::Runner(int pid) : processId(pid), terminate(false) - { - Runner::Channel = nullptr; - } - - Runner::~Runner() - { - Runner::Channel = nullptr; - } - - void Runner::run() - { - printf("Attaching to parent process %d...\n", this->processId); - HANDLE processHandle = OpenProcess(SYNCHRONIZE, FALSE, this->processId); - - if ((!processHandle || processHandle == INVALID_HANDLE_VALUE)) - { - printf("Passive attach failed, trying actively...\n"); - - if (!Runner::isProcessAlive()) - { - printf("Unable to attach to parent process\n"); - return; - } - } - - printf("Successfully attached to parent process\n"); - printf("Starting worker...\n"); - - std::thread workerThread(&Runner::worker, this); - - if (!processHandle || processHandle == INVALID_HANDLE_VALUE) - { - while(this->isProcessAlive()) - { - std::this_thread::sleep_for(100ms); - } - } - else - { - WaitForSingleObject(processHandle, INFINITE); - CloseHandle(processHandle); - } - - printf("Awaiting worker termination...\n"); - this->terminate = true; - if (workerThread.joinable()) workerThread.join(); - printf("Worker terminated\n"); - } - - void Runner::attachHandler(Runner::Handler* handler) - { - this->handlers[handler->getCommand()] = std::shared_ptr(handler); - } - - bool Runner::isProcessAlive() - { - DWORD aProcesses[1024], cbNeeded; - if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return false; - - for(DWORD i = 0; i < cbNeeded / sizeof(DWORD); ++i) - { - if(aProcesses[i] == static_cast(this->processId)) - { - return true; - } - } - - return false; - } - - void Runner::worker() - { - printf("Worker started\n"); - Utils::IPC::BidirectionalChannel channel("IW4x-Worker-Channel", !Worker::IsWorker()); - Runner::Channel = &channel; - - while (!this->terminate) - { - Steam::Proxy::RunFrame(); - - std::string buffer; - if (channel.receive(&buffer)) - { - Proto::IPC::Command command; - if(command.ParseFromString(buffer)) - { - auto handler = this->handlers.find(command.name()); - if (handler != this->handlers.end()) - { - printf("Dispatching command %s to handler\n", command.name().data()); - handler->second->handle(&channel, command.data()); - } - else - { - printf("No handler found for command %s\n", command.name().data()); - } - } - } - - std::this_thread::sleep_for(1ms); - } - - printf("Terminating worker\n"); - Runner::Channel = nullptr; - } -} diff --git a/src/Worker/Runner.hpp b/src/Worker/Runner.hpp deleted file mode 100644 index 9aa2784b..00000000 --- a/src/Worker/Runner.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -namespace Worker -{ - class Endpoint - { - public: - Endpoint() : Endpoint(nullptr) {} - Endpoint(Utils::IPC::BidirectionalChannel* _channel) : channel(_channel) {} - Endpoint(const Endpoint& obj) : Endpoint(obj.channel) {} - - void send(std::string message, std::string data) - { - if (this->channel) - { - Proto::IPC::Command command; - command.set_name(message); - command.set_data(data); - - this->channel->send(command.SerializeAsString()); - } - } - - private: - Utils::IPC::BidirectionalChannel* channel; - }; - - class Runner - { - public: - class Handler - { - public: - virtual ~Handler() {}; - virtual std::string getCommand() = 0; - virtual void handle(Endpoint endpoint, std::string data) = 0; - }; - - Runner(int pid); - ~Runner(); - - void run(); - - void attachHandler(Runner::Handler* handler); - - static Utils::IPC::BidirectionalChannel* Channel; - - private: - void worker(); - bool isProcessAlive(); - - int processId; - bool terminate; - std::unordered_map> handlers; - }; -} - -#include "Handlers/Friends.hpp" -#include "Handlers/SteamCallbacks.hpp" diff --git a/src/Worker/Worker.cpp b/src/Worker/Worker.cpp deleted file mode 100644 index 3d85042e..00000000 --- a/src/Worker/Worker.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "STDInclude.hpp" - -namespace Worker -{ - int ProcessId; - - int __stdcall EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, char* /*lpCmdLine*/, int /*nCmdShow*/) - { - Runner runner(Worker::ProcessId); - runner.attachHandler(new Handlers::Friends()); - runner.attachHandler(new Handlers::SteamCallbacks()); - 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 deleted file mode 100644 index 4f700b23..00000000 --- a/src/Worker/Worker.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -namespace Worker -{ - void Initialize(); - void Uninitialize(); - - bool IsWorker(); -} - -#include "Runner.hpp"