Skip to content

Downloads Flow ​

NOTE

This document details the Unified Downloads User Flow implemented in PR #443 (feat/downloads-browser, carved from PR #265 feat/ui-downloads), illustrating how user interaction in DownloadsBrowserViewModel connects with discovery, resolution, state tracking via ContentStateService, background download coordination via ContentDownloadCoordinator, and game profile integration.

This flowchart details the complete user journey from browsing publishers to downloading, verifying, and adding content to profiles, including state management, deduplication, and caching.


Table of Contents ​

  1. User Browsing Flow
  2. Content State Management
  3. Publisher Selection
  4. Content Acquisition Flow
  5. Profile Selection Flow
  6. Roadmap & External Web Scraper Pipeline
  7. Content Caching Layer
  8. Key Components
  9. Error Handling

User Browsing Flow ​


Content State Management ​

The ContentStateService centralizes content state determination for UI display, enabling the Downloads browser to show appropriate buttons (Download, Update, Add to Profile) based on local manifest presence.

State Transitions ​

ContentStateService Mechanics ​

Location: GenHub/Features/Downloads/Services/ContentStateService.cs

The service uses the 5-segment manifest ID structure to correlate content versions:

text
Format: schemaVersion.userVersion.publisher.contentType.contentName
Example: 1.20240315.superhackers.patch.generals

Detection Logic:

  1. Exact Match: Generates prospective manifest ID using ManifestIdGenerator.GeneratePublisherContentId(publisher, contentType, name, releaseDate) (or publisher-specific conventions such as 1.0.genlauncher{gameToken}.{contentType}.{slug}) and checks IContentManifestPool.IsManifestAcquiredAsync(id). For multi-release packages and synthetic file rows (file:...), verifies URL, version, and slug metadata against persisted manifests (FileRowMatchesManifest) to ensure exact release recovery after application restarts.
  2. Update Detection: Searches for local manifests with matching publisher, contentType, and contentName but older userVersion.
  3. State Evaluation:
    • Downloaded: Exact match found in manifest pool.
    • UpdateAvailable: Older version found in pool.
    • NotDownloaded: No matching version found.
csharp
var state = await contentStateService.GetStateAsync(searchResult);
switch (state)
{
    case ContentState.NotDownloaded:
        // Show Download button
        break;
    case ContentState.UpdateAvailable:
        // Show Update button (orange accent)
        break;
    case ContentState.Downloaded:
        // Show "Add to Profile" button
        break;
}

Content State Sequence Diagram ​


Publisher Selection ​


Content Acquisition Flow ​

This sequence diagram illustrates the coordinated download pipeline managed by ContentDownloadCoordinator:


Profile Selection Flow ​

The ProfileSelectionViewModel provides compatibility filtering for game profiles, showing compatible profiles first and flagging incompatible profiles with warnings to prevent accidental cross-game attachment.

Profile Selection Sequence Diagram ​


Roadmap & External Web Scraper Pipeline ​

Web-scraping discoverers for external repositories (ModDB, CNC Labs, AOD Maps) are part of GenHub's content ingestion architecture:

  • ModDB Web Ingestion: Uses Playwright for JavaScript rendering and AngleSharp for structured HTML extraction. Supports persistent browser cookies for Cloudflare clearance.
  • Section Parsing: Handles separate /downloads and /addons sections with FileSectionType.Downloads vs FileSectionType.Addons.
  • Planned Browser Integration: Once scraper sandboxes are finalized, these providers will be added to the downloads browser sidebar alongside static partners.

Content Caching Layer ​

The ContentCacheService provides an in-memory cache for parsed content with a configurable TTL (Time To Live). This reduces redundant network traffic and page parsing.

Cache Architecture ​


Key Components ​

DownloadsBrowserViewModel ​

Location: GenHub/Features/Downloads/ViewModels/DownloadsBrowserViewModel.cs

Property / CommandTypePurpose
PublishersObservableCollection<PublisherItemViewModel>Available content sources
SelectedPublisherPublisherItemViewModel?Currently selected publisher
ContentItemsObservableCollection<ContentGridItemViewModel>Discovered content items
CurrentFilterViewModelIFilterPanelViewModel?Publisher-specific filter model
DownloadContentCommandIAsyncRelayCommandInitiates content acquisition
AddContentToProfileCommandIAsyncRelayCommandOpens profile selection modal and attaches content
ViewContentCommandIRelayCommandOpens content detail view overlay

ContentDownloadCoordinator ​

Location: GenHub/Features/Downloads/Services/ContentDownloadCoordinator.cs

MethodReturn TypePurpose
DownloadContentAsyncTask<OperationResult<ContentManifest>>Deduplicates in-flight downloads, multiplexes progress, acquires content via IContentOrchestrator, and updates ContentStateService.
IsDownloadingboolChecks whether content is actively downloading.
TryGetDownloadProgressboolRetrieves current progress percentage and message for in-flight tasks.

ContentGridItemViewModel ​

Location: GenHub/Features/Downloads/ViewModels/ContentGridItemViewModel.cs

PropertyConditionPurpose
ShowDownloadButtonCurrentState == NotDownloadedShows download action
ShowUpdateButtonCurrentState == UpdateAvailableShows update action
ShowAddToProfileButtonCurrentState == DownloadedShows profile addition action
CanDownload!IsDownloaded && !IsDownloadingEnables download button

Filter ViewModels ​

Location: GenHub/Features/Downloads/ViewModels/Filters/

PublisherFilter ViewModelCapabilities
GitHubGitHubFilterViewModelSort order (recent, popular), release types
Community OutpostCommunityOutpostFilterViewModelContent type (tools vs. patches)
TheSuperHackersSuperHackersFilterViewModelGame client vs. patch releases
Static CuratedStaticPublisherFilterViewModelContent type and target game

ContentStateService ​

Location: GenHub/Features/Downloads/Services/ContentStateService.cs

Method / EventPurpose
GetStateAsync(item)Evaluates state (NotDownloaded, UpdateAvailable, Downloaded)
GetStateByManifestIdAsync(manifestId)Checks state for a specific manifest ID
NotifyStateChanged(contentId, newState)Broadcasts state updates to UI subscribers
ContentStateChangedEvent raised when content state changes

Error Handling ​


GeneralsHub Docs