feat: Implement Generals Online API integration with HTML scraping fallback#201
Draft
undead2146 wants to merge 7 commits intocommunity-outpost:mainfrom
Draft
feat: Implement Generals Online API integration with HTML scraping fallback#201undead2146 wants to merge 7 commits intocommunity-outpost:mainfrom
undead2146 wants to merge 7 commits intocommunity-outpost:mainfrom
Conversation
5f42591 to
dbb69d2
Compare
…tch History, and Service Status views - Implemented LeaderboardView and its code-behind. - Created LobbiesView and its code-behind with UI elements for displaying active players and matches. - Developed MatchHistoryView and its code-behind to show recent match details. - Added ServiceStatusView and its code-behind for displaying service statistics. - Introduced various converters for player status, rank, region, and tab names to enhance UI data binding. - Registered new services and ViewModels in the dependency injection container for Generals Online features. - Removed unnecessary await statements in SettingsViewModel.
…ation services, credential storage, and UI components.
dbb69d2 to
8c40523
Compare
…trols - Added `NullableDecimalToIntConverter` to handle data conversion between View and ViewModel. - Defined a new "phantom" style for `NumericUpDown` to match the existing minimalist UI. - Replaced `TextBlock` value displays with `NumericUpDown` controls for Gamma, Audio volumes, Font sizes, and Camera settings. - Adjusted Grid column widths to accommodate interactive input fields.
854a824 to
ffce239
Compare
ffce239 to
f4859ed
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR implements comprehensive Generals Online integration for GenHub, including:
Architecture
Current Implementation (Hybrid Approach)
Target Architecture (When Full JSON API Available)
Core Layer (
GenHub.Core)New Interfaces
IGeneralsOnlineApiClientPrimary HTTP client for all Generals Online API interactions.
Key Methods:
Task<ServiceStats?> GetServiceStatsAsync()- Server statisticsTask<LoginResult?> CheckLoginAsync(string gameCode)- Poll browser login statusTask<LoginResult?> LoginWithTokenAsync(string refreshToken)- Silent re-authenticationTask<List<LobbyInfo>> GetLobbiesAsync()- Active lobbies (JSON)Task<OperationResult<string>> GetActiveMatchesAsync()- Active matches (HTML fallback)Task<List<LeaderboardEntry>> GetLeaderboardAsync(string period)- RankingsTask<OperationResult<string>> GetMatchHistoryAsync()- Match history (HTML fallback)void SetTokenProvider(Func<Task<string?>> tokenProvider)- Break circular dependencyDesign Patterns:
OperationResult<T>for error handling.JsonAsync()) for extensibilityCancellationTokensupportConfigureAwait(false)throughoutIGeneralsOnlineAuthServiceManages authentication state, credentials, and login flow.
Key Features:
IObservable<bool> IsAuthenticated- Reactive auth statestring? CurrentSessionToken- Current API session tokenstring? CurrentDisplayName- Logged-in user's namelong? CurrentUserId- Logged-in user's IDAuthentication Methods:
Task InitializeAsync()- Start service, attempt silent loginTask<LoginResult?> TryLoginWithStoredCredentialsAsync()- Auto-login from saved credentialsTask ProcessLoginSuccessAsync(LoginResult)- Save tokens after successful loginTask LogoutAsync()- Clear credentials and statestring GenerateGameCode()- Create random gamecode for browser flowstring GetLoginUrl(string gameCode)- Build login URL with gamecodeCredentials Management:
Task<string?> GetAuthTokenAsync()- Get current tokenTask SaveRefreshTokenAsync(string)- Store refresh token (DPAPI encrypted)ICredentialsStorageServicePlatform-specific credentials file management.
Methods:
Task<CredentialsModel?> LoadCredentialsAsync()- Read from encrypted fileTask SaveCredentialsAsync(CredentialsModel)- Write with DPAPI encryptionTask DeleteCredentialsAsync()- Remove credentials on logoutbool CredentialsFileExists()- Check if credentials are savedstring GetCredentialsPath()- Get full path to credentials.jsonFile Location:
IExternalLinkServicePlatform-agnostic URL opening for browser authentication.
Method:
bool OpenUrl(string url)- Open URL in default browserNew Models (
GenHub.Core.Models.GeneralsOnline)Authentication Models
CredentialsModelLoginResultPendingLoginState(enum)None = -1- No operationWaiting = 0- Browser auth pendingLoginSuccess = 1- Auth completeLoginFailed = 2- Auth failed/cancelledLobby & Match Models
ActiveLobbyRepresents a live game lobby with full match settings.
LobbySlotLobbySettingsExisting Models
ServiceStats- Connection statistics, player countsLeaderboardEntry- Rankings with scoresLobbyInfo- Basic lobby information (JSON endpoint)ActivePlayer,PlayerProfile,MatchInfo,MatchDetailsNew Constants (
GenHub.Core.Constants.GeneralsOnlineConstants)REST API Endpoints
OAuth & Authentication
Credentials Storage
HTTP Headers
Multiplayer API Endpoints
Feature Layer (
GenHub.Features.GeneralsOnline)Services
GeneralsOnlineApiClientImplementation Highlights:
HttpClientwith proper disposalSetTokenProvider()to break circular dependency with auth serviceOperationResult<T>with success/failure informationAuthentication Flow Methods:
GeneralsOnlineAuthServiceResponsibilities:
Key Implementation:
HtmlParsingServicePurpose: Parse HTML responses until JSON APIs are available.
Uses Source-Generated Regex:
Current Parsing Methods:
List<ActiveLobby> ParseActiveLobbies(string html)- Extract lobby cardsLobbySettings ParseLobbySettings(IElement element)- Parse settings iconsList<LobbySlot> ParseLobbySlots(IElement element)- Extract player slotsServiceStats ParseServiceStats(string html)- Parse stats from HTMLDependencies:
AngleSharp- HTML DOM parsingCredentialsStorageService(Platform-Specific)Windows Implementation:
System.Security.Cryptography.ProtectedData(DPAPI)DataProtectionScope.CurrentUser%MyDocuments%\Command and Conquer Generals Zero Hour Data\GeneralsOnlineData\ViewModels
GeneralsOnlineViewModel(Main Hub)Child ViewModels:
LoginViewModel- Authentication flowServiceStatusViewModel- Server statisticsLobbiesViewModel- Browse lobbies (JSON API)ActiveMatchesViewModel- Active matches (HTML scraping)LeaderboardViewModel- RankingsMatchHistoryViewModel- Recent matchesNavigation:
LoginViewModelFeatures:
Flow:
ActiveMatchesViewModelFeatures:
Data Binding:
ServiceStatusViewModelDisplays:
Views
Visual Design
New UI Components
LoginView.axaml- Authentication interfaceActiveMatchesView.axaml- Lobby grid displayServiceStatusView.axaml- Statistics dashboardGeneralsOnlineView.axaml- Main navigation hubScreenshots
Active Matches View
Displays lobbies with map thumbnails, player slots, and settings
Login Flow
Gamecode display with browser authentication
Service Statistics
Player counts, connection stats, uptime