The host can now inject coop_hook.dll into a running game and forward controller state to it over shared memory, so the game reads the host's (eventually the guest's) input and nothing else. - hook/: coop_hook.dll. DllMain spawns a worker that opens the shared-memory channel (named by the game's pid) and installs SafetyHook inline hooks on XInputGetState/GetStateEx/GetCapabilities/SetState. Detours synthesize state from shared memory; unmanaged slots report disconnected, hiding physical pads. - host/: process picker (Toolhelp32), CreateRemoteThread(LoadLibraryW) injector with an IsWow64Process2 bitness guard, IPC server publishing pads each frame, and an ImGui Injection panel wiring it together. - tests/: hook_selftest exercises the IPC seqlock + hook detours in-process (no game/controller needed); passes. Build: SafetyHook wired in (COOP_BUILD_HOOK=ON), Zydis via FetchContent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
861 B
C++
45 lines
861 B
C++
// ImGui panel that drives the input-forwarding pipeline: pick a target process,
|
|
// inject coop_hook.dll, and stream pad state to it over shared memory.
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "coop/protocol.hpp"
|
|
#include "imgui.h"
|
|
#include "inject/process_list.hpp"
|
|
#include "ipc/ipc_server.hpp"
|
|
|
|
namespace coop
|
|
{
|
|
|
|
class InjectionPanel
|
|
{
|
|
public:
|
|
InjectionPanel();
|
|
|
|
void draw();
|
|
|
|
// Forward the latest pad snapshot to the injected hook (if connected).
|
|
void publish(const std::array<PadInfo, kMaxPads>& pads)
|
|
{
|
|
server_.publish(pads);
|
|
}
|
|
|
|
private:
|
|
void refresh_processes();
|
|
void inject_selected();
|
|
|
|
std::vector<ProcessEntry> processes_;
|
|
char filter_[128] = {};
|
|
unsigned long selected_pid_ = 0;
|
|
std::wstring selected_name_;
|
|
|
|
IpcServer server_;
|
|
std::string status_;
|
|
ImVec4 status_color_;
|
|
};
|
|
|
|
} // namespace coop
|