// Host side of the IPC channel: creates the shared-memory section (named by the // target game's pid) and publishes the forwarded controller state each frame. #pragma once #include #include #include "coop/protocol.hpp" #include "coop/shared_memory.hpp" #include "input/input_source.hpp" namespace coop { // Plain (non-atomic) snapshot of the hook's back-channel for the overlay. struct HookStatusView { bool attached = false; // XInput hooks installed in the game bool focus_spoof = false; // focus spoofing active std::uint32_t heartbeat = 0; // DLL liveness counter std::uint64_t get_state[kMaxPads] = {}; std::uint64_t get_caps[kMaxPads] = {}; std::uint64_t focus_calls[FocusApi_Count] = {}; std::uint32_t game_pid = 0; std::uint64_t game_hwnd = 0; bool raw_input_registered = false; bool raw_input_gamepad = false; bool raw_input_gamepad_sink = false; bool dinput_loaded = false; // Audio render-hook diagnostics (for the Audio panel's stream-count view). std::uint32_t audio_streams_seen = 0; AudioStreamInfo audio_streams[kMaxAudioStreams] = {}; // Installed-hooks registry (for the Injection panel's hook list). std::uint32_t hook_entry_count = 0; HookEntry hook_entries[kMaxHookEntries] = {}; }; class IpcServer { public: // Creates and initializes the section for `target_pid`. The injected hook // derives the same name from its own pid and opens it. bool start(unsigned long target_pid); // Pushes the current pad snapshot to the hook. No-op if not started. void publish(const std::array& pads); void stop(); // Reads the hook's diagnostics back-channel (zeroed if not started). [[nodiscard]] HookStatusView hook_status() const; // Request a hook subsystem be installed (true) or removed (false). The hook // reconciles on its next tick. No-op if not started. void set_subsystem_enabled(std::uint32_t subsystem, bool enabled); [[nodiscard]] bool running() const { return block_ != nullptr; } [[nodiscard]] unsigned long target_pid() const { return target_pid_; } private: SharedMemory shm_; SharedBlock* block_ = nullptr; unsigned long target_pid_ = 0; }; } // namespace coop