-
Notifications
You must be signed in to change notification settings - Fork 17
feat: Implement data-driven provider definition configurations with external JSON #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
feat: Implement data-driven provider definition configurations with external JSON #205
Conversation
Greptile OverviewGreptile SummaryThis PR successfully implements a data-driven provider configuration system that externalizes content source settings to JSON files, enabling runtime configuration without code changes. Key AchievementsArchitecture & Infrastructure- **Provider Definition System**: Introduced `ProviderDefinition` model with comprehensive JSON serialization support for endpoints, timeouts, catalog formats, and mirror preferences - **Auto-Loading Mechanism**: `ProviderDefinitionLoader` loads from both bundled and user directories with thread-safe caching, synchronous fallback, and hot-reload support - **Pluggable Parsers**: `ICatalogParser` and `ICatalogParserFactory` enable format-specific catalog parsing (GenPatcher DAT, JSON API, GitHub releases) - **Pipeline Factory**: `ContentPipelineFactory` matches provider IDs to discoverers, resolvers, and deliverers with case-insensitive lookupProvider Implementations- **Community Outpost**: Full GenPatcher dl.dat catalog support with multi-mirror downloads, version extraction, and metadata integration via `GenPatcherContentRegistry` - **Generals Online**: Updated to use provider definition for JSON API catalog and CDN endpoints - **TheSuperHackers**: Configured for GitHub releases with repository metadata from JSONDependency & Version Management- **BaseDependencyBuilder**: Abstract base for dependency creation with factory methods for common game dependencies (ZH 1.04, Generals 1.08) - **VersionConstraint**: Comprehensive semantic versioning with range support, comparison operators, caret/tilde rangesCode Quality
Integration PointsAll providers successfully integrate the new system:
Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant App as Application
participant Loader as ProviderDefinitionLoader
participant Provider as CommunityOutpostProvider
participant Discoverer as CommunityOutpostDiscoverer
participant ParserFactory as CatalogParserFactory
participant Parser as GenPatcherDatCatalogParser
participant Registry as GenPatcherContentRegistry
participant Resolver as CommunityOutpostResolver
participant Builder as ManifestBuilder
Note over App,Loader: Startup: Load Provider Definitions
App->>Loader: LoadProvidersAsync()
Loader->>Loader: Load bundled/*.provider.json
Loader->>Loader: Load user/*.provider.json
Loader-->>App: ProviderDefinition[]
Note over App,Provider: Content Discovery Flow
App->>Provider: DiscoverAsync(query)
Provider->>Provider: GetProviderDefinition()
Provider->>Loader: GetProvider("community-outpost")
Loader-->>Provider: ProviderDefinition (cached)
Provider->>Discoverer: DiscoverAsync(provider, query)
Note over Discoverer,Parser: Catalog Parsing
Discoverer->>Discoverer: Get catalogUrl from provider.Endpoints
Discoverer->>ParserFactory: GetParser(provider.CatalogFormat)
ParserFactory-->>Discoverer: GenPatcherDatCatalogParser
Discoverer->>Parser: ParseAsync(catalogContent, provider)
loop For each catalog entry
Parser->>Registry: GetMetadata(contentCode)
Registry-->>Parser: ContentMetadata
Parser->>Parser: ConvertToContentSearchResult()
Parser->>Parser: GetPreferredDownloadUrl(provider.MirrorPreference)
end
Parser-->>Discoverer: ContentSearchResult[]
Discoverer-->>Provider: ContentSearchResult[]
Provider-->>App: ContentSearchResult[]
Note over App,Resolver: Content Resolution Flow
App->>Provider: ResolveAsync(searchResult)
Provider->>Resolver: ResolveAsync(provider, searchResult)
Resolver->>Loader: GetProvider("community-outpost")
Loader-->>Resolver: ProviderDefinition
Resolver->>Registry: GetMetadata(contentCode)
Registry-->>Resolver: ContentMetadata
Note over Resolver,Builder: Manifest Building
Resolver->>Builder: WithBasicInfo(publisher, name, version)
Resolver->>Builder: WithContentType(type, game)
Resolver->>Builder: WithPublisher(provider.Endpoints)
Resolver->>Builder: AddDependency(from metadata)
Resolver->>Builder: AddRemoteFileAsync(url from provider)
Resolver->>Builder: Build()
Builder-->>Resolver: ContentManifest
Resolver-->>Provider: ContentManifest
Provider-->>App: ContentManifest
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
86 files reviewed, 1 comment
9eeabac to
0f1043e
Compare
|
Are the serialization intended to be a form of approved publishers baked into GenHub? Because if it is more general then it would make more sense that these are shipped with the application but that there also is a place where users can add their own publisher json files. This would then be a way for new publishers to link back to their respective husting site for downloadable content? |
Regarding provider definitions, they are all stored under the following directories. With user providers with matching
An addition to provider definitions is that we could implement a |
|
And what about the custom section in the provider template? What are these used for exactly? I can't really be custom fields if we do not look / parse that specific field name. I am not sure but it seems like we are not using it currently - but still providing some custom information in the |
GenHub/GenHub.Core/Interfaces/Content/IPublisherManifestFactory.cs
Outdated
Show resolved
Hide resolved
GenHub/GenHub.Core/Interfaces/Providers/IProviderDefinitionLoader.cs
Outdated
Show resolved
Hide resolved
GenHub/GenHub.Core/Services/Dependencies/BaseDependencyBuilder.cs
Outdated
Show resolved
Hide resolved
GenHub/GenHub/Features/Content/Services/GeneralsOnline/GeneralsOnlineProvider.cs
Show resolved
Hide resolved
GenHub/GenHub/Features/Content/Services/GeneralsOnline/GeneralsOnlineResolver.cs
Outdated
Show resolved
Hide resolved
GenHub/GenHub/Features/Content/Services/GeneralsOnline/GeneralsOnlineResolver.cs
Outdated
Show resolved
Hide resolved
GenHub/GenHub/Features/Content/Services/GeneralsOnline/GeneralsOnlineUpdateService.cs
Outdated
Show resolved
Hide resolved
GenHub/GenHub/Features/Downloads/ViewModels/DownloadsViewModel.cs
Outdated
Show resolved
Hide resolved
78beccc to
c5f0d58
Compare
c5f0d58 to
efb28c1
Compare
undead2146
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay so that took a while, a couple force pushes to get the branch correct again.
I addressed all the comments.
Merge after:
Summary
This PR introduces a comprehensive data-driven provider configuration system that externalizes content source settings into JSON files. This enables runtime configuration of endpoints, timeouts, catalog parsing, and provider behavior without code changes.
Key Changes
🏗️ Architecture
New Core Infrastructure
IProviderDefinitionLoader- Service interface for loading/managing provider definitionsProviderDefinitionLoader- Implementation with auto-loading, caching, and hot-reload supportICatalogParser- Interface for pluggable catalog format parsersICatalogParserFactory- Factory for obtaining parsers by format identifierIContentPipelineFactory- Factory for obtaining pipeline components by provider IDProvider Definition Files (JSON)
communityoutpost.provider.json- Community Outpost (GenPatcher) configurationgeneralsonline.provider.json- Generals Online CDN configurationthesuperhackers.provider.json- TheSuperHackers GitHub configuration📁 New Files
GenHub.Core/Interfaces/Providers/ICatalogParser.csGenHub.Core/Interfaces/Providers/ICatalogParserFactory.csGenHub.Core/Services/Providers/CatalogParserFactory.csGenHub/Features/Content/Services/CommunityOutpost/GenPatcherDatCatalogParser.csGenHub/Features/Content/Services/GeneralsOnline/GeneralsOnlineJsonCatalogParser.csGenHub/Features/Content/Services/ContentPipelineFactory.csGenHub/Providers/*.provider.jsondocs/features/content/provider-configuration.mddocs/features/content/provider-infrastructure.md🔧 Modified Files
Content Providers
All content providers now:
IProviderDefinitionLoaderGetProviderDefinition()to provide cached configurationCommunityOutpostProviderCommunityOutpostDiscovererCommunityOutpostResolverGeneralsOnlineProviderGeneralsOnlineDiscovererGeneralsOnlineManifestFactorySuperHackersProviderSuperHackersUpdateServiceBase Infrastructure
BaseContentProvider- AddedGetProviderDefinition()virtual methodIContentDiscoverer- Added provider-awareDiscoverAsync()overloadIContentResolver- Added provider-awareResolveAsync()overload📝 Documentation Updates
docs/architecture.md- Added section on data-driven provider configurationdocs/features/content/index.md- Added link to provider configuration docsProvider Definition Schema
{ "providerId": "community-outpost", "publisherType": "communityoutpost", "displayName": "Community Outpost", "description": "Official patches, tools, and addons from GenPatcher (Community Outpost)", "iconColor": "#2196F3", "providerType": "Static", "catalogFormat": "genpatcher-dat", "endpoints": { "catalogUrl": "https://legi.cc/gp2/dl.dat", "websiteUrl": "https://legi.cc", "supportUrl": "https://legi.cc/patch", "custom": { "patchPageUrl": "https://legi.cc/patch", "gentoolWebsite": "https://gentool.net" } }, "mirrorPreference": ["legi.cc", "gentool.net"], "targetGame": "ZeroHour", "defaultTags": ["community", "genpatcher"], "timeouts": { "catalogTimeoutSeconds": 30, "contentTimeoutSeconds": 300 }, "enabled": true }Usage Example
Provider Implementation
Discoverer Implementation
Deployment Notes
Provider JSON files are automatically copied to the output directory via MSBuild: