[Friends] Experimental ipc function handler

This commit is contained in:
momo5502 2017-01-28 15:51:50 +01:00
parent 4cf2ca270c
commit 46d3045d6f
8 changed files with 122 additions and 64 deletions

View File

@ -167,6 +167,34 @@ namespace Components
}); });
UIFeeder::Add(6.0f, Friends::GetFriendCount, Friends::GetFriendText, Friends::SelectFriend); UIFeeder::Add(6.0f, Friends::GetFriendCount, Friends::GetFriendText, Friends::SelectFriend);
IPCHandler::OnWorker("friends", [](std::string data)
{
Proto::IPC::Function function;
if(function.ParseFromString(data))
{
if(function.name() == "friendsResponse")
{
auto params = function.params();
Logger::Print("Received friendslist: %d\n", params.size());
for(auto param : params)
{
Logger::Print("%s\n", param.data());
}
}
}
});
Command::Add("getFriends", [](Command::Params*)
{
Proto::IPC::Function function;
function.set_name("getFriends");
function.add_params()->append(Utils::String::VA("%d", 4));
IPCHandler::SendWorker("friends", function.SerializeAsString());
});
} }
Friends::~Friends() Friends::~Friends()

View File

@ -13,7 +13,7 @@ namespace Components
IPCHandler::InitChannels(); IPCHandler::InitChannels();
Proto::IPC::Command command; Proto::IPC::Command command;
command.set_command(message); command.set_name(message);
command.set_data(data); command.set_data(data);
IPCHandler::WorkerChannel->send(command.SerializeAsString()); IPCHandler::WorkerChannel->send(command.SerializeAsString());
@ -24,7 +24,7 @@ namespace Components
IPCHandler::InitChannels(); IPCHandler::InitChannels();
Proto::IPC::Command command; Proto::IPC::Command command;
command.set_command(message); command.set_name(message);
command.set_data(data); command.set_data(data);
IPCHandler::ClientChannel->send(command.SerializeAsString()); IPCHandler::ClientChannel->send(command.SerializeAsString());
@ -78,7 +78,7 @@ namespace Components
Proto::IPC::Command command; Proto::IPC::Command command;
if(command.ParseFromString(packet)) if(command.ParseFromString(packet))
{ {
auto callback = IPCHandler::ClientCallbacks.find(command.command()); auto callback = IPCHandler::ClientCallbacks.find(command.name());
if (callback != IPCHandler::ClientCallbacks.end()) if (callback != IPCHandler::ClientCallbacks.end())
{ {
callback->second(command.data()); callback->second(command.data());
@ -97,7 +97,7 @@ namespace Components
Proto::IPC::Command command; Proto::IPC::Command command;
if (command.ParseFromString(packet)) if (command.ParseFromString(packet))
{ {
auto callback = IPCHandler::WorkerCallbacks.find(command.command()); auto callback = IPCHandler::WorkerCallbacks.find(command.name());
if (callback != IPCHandler::WorkerCallbacks.end()) if (callback != IPCHandler::WorkerCallbacks.end())
{ {
callback->second(command.data()); callback->second(command.data());

View File

@ -4,6 +4,12 @@ package Proto.IPC;
message Command message Command
{ {
bytes command = 1; bytes name = 1;
bytes data = 2; bytes data = 2;
} }
message Function
{
bytes name = 1;
repeated bytes params = 2;
}

View File

@ -1,65 +1,55 @@
#include "STDInclude.hpp" #include "STDInclude.hpp"
namespace Worker namespace Handlers
{ {
int ProcessId; 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());
int __stdcall EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, char* /*lpCmdLine*/, int /*nCmdShow*/) auto params = function.params();
{ handler->second(endpoint, std::vector<std::string>(params.begin(), params.end()));
Runner runner(Worker::ProcessId);
runner.run();
return 0;
}
void Initialize()
{
if(!Steam::Proxy::Inititalize())
{
printf("Failed to initialize worker!\n");
ExitProcess(1);
} }
else else
{ {
#ifdef DEBUG printf("No handler for function %s\n", function.name().data());
SetConsoleTitleA("IW4x: Worker"); }
#else
FreeConsole();
#endif
Utils::Hook(0x6BABA1, Worker::EntryPoint, HOOK_CALL).install()->quick();
} }
} }
void Uninitialize() void Friends::addFunction(std::string function, Friends::Callback callback)
{ {
Steam::Proxy::Uninititalize(); this->functions[function] = callback;
} }
bool ParseWorkerFlag() Friends::Friends()
{ {
char* command = "-parent "; this->addFunction("getFriends", [&](Worker::Endpoint endpoint, std::vector<std::string> params)
char* parentProc = strstr(GetCommandLineA(), command);
if (parentProc)
{ {
parentProc += strlen(command); if (params.size() >= 1 && Steam::Proxy::SteamFriends)
Worker::ProcessId = atoi(parentProc); {
int flag = atoi(params[0].data());
int count = Steam::Proxy::SteamFriends->GetFriendCount(flag);
return true; Proto::IPC::Function response;
response.set_name("friendsResponse");
for (int i = 0; i < count; ++i)
{
std::string* param = response.add_params();
SteamID id = Steam::Proxy::SteamFriends->GetFriendByIndex(i, flag);
param->clear();
param->append(Utils::String::VA("%llX", id.Bits));
} }
return false; endpoint.send(this->getCommand(), response.SerializeAsString());
} }
});
bool IsWorker()
{
static Utils::Value<bool> flag;
if (!flag.isValid())
{
flag.set(Worker::ParseWorkerFlag());
}
return flag.get();
} }
} }

View File

@ -1,11 +1,19 @@
#pragma once #pragma once
namespace Worker namespace Handlers
{ {
void Initialize(); class Friends : public Worker::Runner::Handler
void Uninitialize(); {
public:
typedef std::function<void(Worker::Endpoint, std::vector<std::string>)> Callback;
bool IsWorker(); Friends();
std::string getCommand() override { return "friends"; };
void handle(Worker::Endpoint endpoint, std::string data) override;
private:
void addFunction(std::string function, Callback callback);
std::unordered_map<std::string, Callback> functions;
};
} }
#include "Runner.hpp"

View File

@ -37,9 +37,9 @@ namespace Worker
} }
} }
void Runner::attachHandler(std::shared_ptr<Handler> handler) void Runner::attachHandler(Runner::Handler* handler)
{ {
this->handlers[handler->getCommand()] = handler; this->handlers[handler->getCommand()] = std::shared_ptr<Runner::Handler>(handler);
} }
void Runner::worker() void Runner::worker()
@ -57,15 +57,15 @@ namespace Worker
Proto::IPC::Command command; Proto::IPC::Command command;
if(command.ParseFromString(buffer)) if(command.ParseFromString(buffer))
{ {
auto handler = this->handlers.find(command.command()); auto handler = this->handlers.find(command.name());
if (handler != this->handlers.end()) if (handler != this->handlers.end())
{ {
printf("Handling command %s\n", command.command().data()); printf("Dispathcing command %s to handler\n", command.name().data());
handler->second->handle(&channel, command.data()); handler->second->handle(&channel, command.data());
} }
else else
{ {
printf("No handler found for command %s\n", command.command().data()); printf("No handler found for command %s\n", command.name().data());
} }
} }
} }

View File

@ -2,6 +2,29 @@
namespace Worker 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 class Runner
{ {
public: public:
@ -10,7 +33,7 @@ namespace Worker
public: public:
virtual ~Handler() {}; virtual ~Handler() {};
virtual std::string getCommand() = 0; virtual std::string getCommand() = 0;
virtual void handle(Utils::IPC::BidirectionalChannel* channel, std::string data) = 0; virtual void handle(Endpoint endpoint, std::string data) = 0;
}; };
Runner(int pid); Runner(int pid);
@ -18,13 +41,15 @@ namespace Worker
void run(); void run();
void attachHandler(std::shared_ptr<Handler> handler); void attachHandler(Runner::Handler* handler);
private: private:
void worker(); void worker();
int processId; int processId;
bool terminate; bool terminate;
std::map<std::string, std::shared_ptr<Handler>> handlers; std::unordered_map<std::string, std::shared_ptr<Handler>> handlers;
}; };
} }
#include "Handlers/Friends.hpp"

View File

@ -7,6 +7,7 @@ namespace Worker
int __stdcall EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, char* /*lpCmdLine*/, int /*nCmdShow*/) int __stdcall EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, char* /*lpCmdLine*/, int /*nCmdShow*/)
{ {
Runner runner(Worker::ProcessId); Runner runner(Worker::ProcessId);
runner.attachHandler(new Handlers::Friends());
runner.run(); runner.run();
return 0; return 0;
} }