Interposer 1.0.5 Release Notes
Downloads
Loading release downloads…
What's Changed
Rich Presence
Rich presence lets games display detailed status information in Discord — showing the current game, activity details, images, party info, and clickable buttons — all configured through Config.yml with no code changes to the game itself.
The implementation communicates directly with the Discord client over local named pipes (\\.\pipe\discord-ipc-N) using length-prefixed JSON frames. There are no external SDK dependencies — the entire IPC protocol (handshake, SET_ACTIVITY, close) is handled internally.
Configuration
Add a RichPresence section to .interposer\Config.yml:
RichPresence:
Discord:
Enabled: true
ApplicationId: "123456789012345678"
Name: "My Game"
Details: "In Menu"
State: "Idle"
LargeImage: "logo"
LargeImageText: "My Game v1.0"
You'll need a Discord Application ID from the Discord Developer Portal — no bot token is required. All default activity fields (Type, Name, Details, State, images, buttons) are optional and define the presence shown immediately when the game starts. See the Rich Presence documentation page for the full configuration reference.
Behavior
- Rich presence is initialized after all hooks are installed and enabled, so it doesn't interfere with the hook setup sequence.
- If Discord is not running, a
[RICH PRESENCE]log entry is written and the game continues normally — presence never blocks startup. - If Discord restarts while the game is running, the next presence update from a plugin will automatically reconnect.
- On DLL detach, presence is cleared and the pipe is closed gracefully.
Backend Architecture
The system is built around an abstract IRichPresenceBackend interface (Connect, Disconnect, IsConnected, UpdatePresence, ClearPresence). Discord is the first backend, but the interface is designed so that additional presence services (e.g. a LANCommander-native presence system) can be added in the future. All backends receive the same PresenceData — plugins don't need to know which backends are active.
Rich Presence Plugin API
Plugins can update presence at runtime to show dynamic information like the current map, score, or match progress. The API exposes 11 C-callable functions resolved via GetProcAddress:
| Function | Description |
|---|---|
InterposerSetPresenceDetails | Set the first detail line |
InterposerSetPresenceState | Set the second detail line |
InterposerSetPresenceTimestamps | Set start/end epoch timestamps |
InterposerSetPresenceLargeImage | Set large image key and tooltip |
InterposerSetPresenceSmallImage | Set small image key and tooltip |
InterposerSetPresenceParty | Set party ID, current size, and max |
InterposerSetPresenceButton | Set button text and URL (index 0 or 1) |
InterposerSetPresenceType | Set activity type (Playing, Streaming, etc.) |
InterposerSetPresenceName | Set the display name |
InterposerUpdatePresence | Push accumulated changes to all backends |
InterposerClearPresence | Reset to config defaults and clear all backends |
The pattern is: call one or more setters to stage changes, then call InterposerUpdatePresence to push them. All functions are thread-safe (guarded by a mutex). InterposerClearPresence resets to the default values from Config.yml rather than blanking everything.
See the Rich Presence Plugin API documentation for the full reference, including C/C++ type definitions and usage examples.
Plugin Init Entry Point
Plugins no longer need to guess the Interposer's DLL name (which varies between LANCommander.Interposer.dll, version.dll, dinput8.dll, and .asi depending on the deployment variant). Instead, the Interposer calls an optional exported function on each plugin immediately after loading it:
extern "C" __declspec(dllexport) void WINAPI InterposerPluginInit(HMODULE hInterposer);
The Interposer passes its own HMODULE, which the plugin uses for all GetProcAddress calls. This eliminates the name-guessing problem entirely and is now the recommended way to initialize a plugin. The old DllMain + GetModuleHandle approach still works for backwards compatibility.
See the updated Creating a Plugin guide for the full pattern.
Plugin Config Registration
Plugins can now declare their default configuration at init time. The new InterposerRegisterPluginConfig export accepts a plugin name and a YAML string of default key-value pairs:
using FnRegConfig = BOOL (WINAPI*)(const wchar_t* pluginName, const wchar_t* yamlDefaults);
auto pfnRegConfig = (FnRegConfig)GetProcAddress(hInterposer, "InterposerRegisterPluginConfig");
pfnRegConfig(L"MyPlugin", L"Setting: 'default'\nCount: 42");
On first run, the defaults are merged into the in-memory config and appended to Config.yml under Plugins.<name>. On subsequent runs, the user's existing configuration is preserved — registration is a no-op if the section already exists.
This means plugin authors no longer need to document "add these lines to Config.yml" — the plugin populates its own defaults automatically, and users only need to edit the values they want to change.
See the updated Creating a Plugin guide and the Plugin API reference for details.
Expanded Logging
Four new logging categories have been added:
| Key | Default | Description |
|---|---|---|
Plugins | false | Log plugin load, unload, error, and config registration events. |
Identity | false | Log identity override operations — when GetUserNameW/A or GetComputerNameW/A hooks return the configured override value. |
RichPresence | false | Log rich presence field changes, update pushes, and clear operations. |
DnsRedirects | true | Log DNS redirect matches. Enabled by default because DNS redirects are deliberate user-configured actions. Has its own toggle separate from Network. |
Previously, plugin load/error events were gated behind Logging.Files, which was misleading — they now have their own dedicated Logging.Plugins toggle. DNS redirect logging was previously gated behind Logging.Network and now has its own dedicated flag.
See the updated Logging documentation for the full verb reference.
Example Plugin
A new LANCommander.Interposer.Plugin.Example project is included in the solution as a minimal, well-commented reference for plugin authors. It demonstrates:
- The
InterposerPluginInitentry point pattern - Resolving API exports from the provided
HMODULE - Registering default config with
InterposerRegisterPluginConfig - Reading config values and logging
The example project includes a ready-to-build .vcxproj and can be used as a starting point for new plugins.