Skip to content

Conversation

@undead2146
Copy link
Member

@undead2146 undead2146 commented Jan 5, 2026

  • Added SteamLauncher service to manage game directory preparation for Steam-tracked profiles.
  • Introduced ProxyConfig for configuring the proxy launcher with target executable and working directory.
  • Implemented methods for deploying the proxy launcher and creating necessary configuration files.
  • Enhanced manifest generation to support backup executable handling from the Steam Proxy Launcher.
  • Updated SteamManifestPatcher to improve executable validation logic.
  • Refactored HardLinkStrategy to prioritize file deduplication based on content type.
  • Improved error handling and logging throughout the game installation and manifest processes.
  • Updated documentation to reflect changes in detection and manifest creation workflows.

Greptile Summary

This PR introduces a comprehensive Steam integration solution that enables full Steam features (overlay, playtime tracking) for modded game profiles while maintaining GenHub's workspace isolation model.

Key Changes:

  • Implemented proxy launcher mechanism that acts as a middleman between Steam and workspace executables
  • Added SteamLauncher service to deploy/cleanup proxy, backup original executables, and manage Steam environment
  • Created standalone GenHub.ProxyLauncher project that handles Steam environment injection and spawned process detection
  • Refactored HardLinkStrategy to prioritize files by content type (GameClient > GameInstallation) preventing modded clients from being overwritten
  • Enhanced ManifestGenerationService to use backup executables (.ghbak) as source during manifest generation
  • Added SteamAppIdResolver helper for dynamic AppID detection from Steam appmanifest files
  • Updated documentation with comprehensive explanation of proxy launcher mechanism and workflows

Architecture:
The proxy launcher approach replaces generals.exe with the proxy, which then launches the workspace executable. This ensures Steam tracks the proxy process while the actual game runs from an isolated workspace. The proxy handles edge cases like launcher processes that spawn children and exit immediately, ensuring playtime tracking remains accurate.

File Deduplication Improvement:
The refactored HardLinkStrategy now prioritizes files by content type during workspace preparation, ensuring that modded game client executables (ContentType.GameClient) are never overwritten by base installation files (ContentType.GameInstallation). This fixes a critical bug where modded clients could be replaced by vanilla game files.

Confidence Score: 4/5

  • This PR is well-architected and implements a complex Steam integration feature with thorough documentation and proper error handling
  • The implementation is comprehensive with good separation of concerns, extensive logging, and defensive coding practices. The proxy launcher mechanism is well-designed and handles edge cases. Documentation is excellent. One minor concern is the complexity of the file swapping mechanism which relies on correct cleanup timing
  • Pay close attention to SteamLauncher.cs for the file backup/restore logic and GameLauncher.cs for the cleanup timing during profile switches

Important Files Changed

Filename Overview
GenHub/GenHub/Features/Launching/SteamLauncher.cs Implements proxy launcher deployment to enable Steam integration while maintaining workspace isolation - backs up original executables, deploys proxy, creates junctions, and ensures runtime dependencies are present
GenHub/GenHub.ProxyLauncher/Program.cs Proxy launcher that acts as middleman between Steam and workspace executables - handles Steam environment injection, spawned process detection, and proper playtime tracking
GenHub/GenHub/Features/Launching/GameLauncher.cs Orchestrates profile launches with Steam integration support - prepares workspace, deploys proxy for Steam profiles, discovers spawned processes, and manages launch lifecycle
GenHub/GenHub/Features/Manifest/ManifestGenerationService.cs Enhanced to support backup executable handling - resolves .ghbak files as source for manifests to ensure original game files are referenced instead of proxy launcher
GenHub/GenHub/Features/Workspace/Strategies/HardLinkStrategy.cs Refactored file deduplication to prioritize by content type (GameClient > GameInstallation) preventing modded clients from being overwritten by base game files
GenHub/GenHub.Core/Helpers/SteamAppIdResolver.cs Resolves Steam AppID from installation path by reading appmanifest files - enables dynamic AppID detection instead of hardcoded values

Sequence Diagram

sequenceDiagram
    participant User
    participant GameLauncher
    participant SteamLauncher
    participant WorkspaceManager
    participant Steam
    participant ProxyLauncher
    participant GameProcess

    User->>GameLauncher: LaunchProfileAsync(profile, useSteamLaunch=true)
    
    Note over GameLauncher: Validate profile and resolve dependencies
    
    GameLauncher->>SteamLauncher: CleanupGameDirectoryAsync()
    Note over SteamLauncher: Restore generals.exe from .ghbak if exists
    SteamLauncher-->>GameLauncher: Cleanup complete
    
    GameLauncher->>WorkspaceManager: PrepareWorkspaceAsync()
    Note over WorkspaceManager: Create isolated workspace with<br/>prioritized file deduplication<br/>(GameClient > GameInstallation)
    WorkspaceManager-->>GameLauncher: Workspace ready
    
    GameLauncher->>SteamLauncher: PrepareForProfileAsync()
    Note over SteamLauncher: 1. Backup generals.exe → generals.exe.ghbak
    SteamLauncher->>SteamLauncher: Deploy GenHub.ProxyLauncher.exe as generals.exe
    SteamLauncher->>SteamLauncher: Create proxy_config.json with workspace path
    SteamLauncher->>SteamLauncher: Write steam_appid.txt files
    SteamLauncher->>SteamLauncher: Copy runtime dependencies (steam_api.dll, etc.)
    SteamLauncher->>SteamLauncher: Create workspace junction
    SteamLauncher-->>GameLauncher: Proxy deployed
    
    GameLauncher->>Steam: Launch via steam://rungameid/{appId}
    Steam->>ProxyLauncher: Start generals.exe (proxy)
    
    Note over ProxyLauncher: Read proxy_config.json<br/>Inject Steam environment variables
    
    ProxyLauncher->>GameProcess: Launch workspace executable
    Note over ProxyLauncher: Wait for process to exit
    
    alt Launcher exits quickly (spawned child)
        ProxyLauncher->>ProxyLauncher: Detect spawned process
        Note over ProxyLauncher: Continue waiting on child process<br/>to preserve Steam tracking
    end
    
    GameProcess-->>ProxyLauncher: Process exits
    ProxyLauncher-->>Steam: Exit (playtime recorded)
    
    Note over User: When switching profiles or closing
    User->>GameLauncher: Switch profile or cleanup
    GameLauncher->>SteamLauncher: CleanupGameDirectoryAsync()
    SteamLauncher->>SteamLauncher: Restore generals.exe from .ghbak
    SteamLauncher->>SteamLauncher: Remove proxy_config.json
    SteamLauncher->>SteamLauncher: Remove workspace junction
    SteamLauncher-->>GameLauncher: Original state restored
Loading

Context used:

  • Context from dashboard - Custom context (source)
  • Context from dashboard - Use dedicated constants classes instead of hardcoding constants string, integers or variables in ser... (source)

@undead2146 undead2146 force-pushed the feat/steam-launcher branch from 1fe0877 to ac8dd94 Compare January 5, 2026 02:23
greptile-apps[bot]

This comment was marked as outdated.

@undead2146 undead2146 force-pushed the feat/steam-launcher branch 2 times, most recently from 492ab77 to 4b58221 Compare January 5, 2026 10:42
@undead2146
Copy link
Member Author

@greptile

greptile-apps[bot]

This comment was marked as outdated.

@undead2146 undead2146 force-pushed the feat/steam-launcher branch from 4b58221 to 63876df Compare January 5, 2026 11:16
@undead2146
Copy link
Member Author

@greptile

greptile-apps[bot]

This comment was marked as resolved.

…y launching

- Added SteamLauncher service to manage game directory preparation for Steam-tracked profiles.
- Introduced ProxyConfig for configuring the proxy launcher with target executable and working directory.
- Implemented methods for deploying the proxy launcher and creating necessary configuration files.
- Enhanced manifest generation to support backup executable handling from the Steam Proxy Launcher.
- Updated SteamManifestPatcher to improve executable validation logic.
- Refactored HardLinkStrategy to prioritize file deduplication based on content type.
- Improved error handling and logging throughout the game installation and manifest processes.
- Updated documentation to reflect changes in detection and manifest creation workflows.
@undead2146 undead2146 force-pushed the feat/steam-launcher branch from b8b656a to bbd995f Compare January 6, 2026 08:25
@undead2146
Copy link
Member Author

@greptile

@undead2146 undead2146 merged commit d7d92fd into community-outpost:development Jan 7, 2026
4 checks passed
@undead2146 undead2146 deleted the feat/steam-launcher branch January 7, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant