Files
SlipItIn/SlipItIn/Services/GameStateService.cs
Tim Krampitz 18a9d1ab74 Robustere Initialisierung & Routing-Refaktor
- InitializeAsync in InitializeSafeAsync mit Fehlerbehandlung umbenannt, App-Start robuster gestaltet
- Asynchrone Initialisierung bei Window.Created
- Navigation vereinheitlicht: Routing.RegisterRoute statt Doppelslash, Navigation ohne Präfix
- Flyout-Menü in AppShell deaktiviert, ShellContent-Einträge entfernt
- Login/Register-ViewModels nutzen private Felder statt ObservableProperty
- SignalRService nutzt AccessToken aus AuthSessionService
- GameStateService: Automatischer Resync bei Verbindung, Fehlerhandling verbessert
- Navigation in ViewModels an neues Routing angepasst
- Aufräumarbeiten: Entfernte auskommentierte Messenger-Registrierungen, Initialisierung vereinheitlicht
2026-08-08 13:12:57 +02:00

134 lines
4.3 KiB
C#

using System.Text.Json;
using CommunityToolkit.Mvvm.Messaging;
using SlipItIn.Messages;
using SlipItIn.Models;
using SlipItIn.Services.Interfaces;
using SlipItIn.Shared.DTOs;
namespace SlipItIn.Services;
public class GameStateService : IGameStateService
{
private readonly ISignalRService _signalR;
private readonly ILocalStorageService _localStorage;
private readonly IMessenger _messenger;
private readonly List<QueuedGameAction> _queuedActions = [];
public GameStateDto? CurrentGameState { get; private set; }
public PlayerHandDto? CurrentPlayerHand { get; private set; }
public SlipChallengeDto? PendingChallenge { get; private set; }
public GameStateService(ISignalRService signalR, ILocalStorageService localStorage)
{
_signalR = signalR;
_localStorage = localStorage;
_messenger = WeakReferenceMessenger.Default;
_signalR.LobbyCreated += (_, value) => _messenger.Send(new LobbyCreatedMessage(value));
_signalR.GameStateUpdated += async (_, state) =>
{
CurrentGameState = state;
await _localStorage.SaveGameStateAsync(state);
_messenger.Send(new GameStateChangedMessage(state));
};
_signalR.GameStarted += (_, gameId) => _messenger.Send(new GameStartedMessage(gameId));
_signalR.PlayerHandUpdated += async (_, hand) =>
{
CurrentPlayerHand = hand;
await _localStorage.SavePlayerHandAsync(hand);
_messenger.Send(new PlayerHandChangedMessage(hand));
};
_signalR.ChallengeReceived += (_, challenge) =>
{
PendingChallenge = challenge;
_messenger.Send(new ChallengeReceivedMessage(challenge));
};
_signalR.ErrorReceived += (_, error) => _messenger.Send(new ErrorOccurredMessage(error));
_signalR.ConnectionStateChanged += async (_, connected) =>
{
_messenger.Send(new ConnectionStateChangedMessage(connected));
if (connected)
{
try
{
await ResyncAsync();
}
catch (Exception ex)
{
_messenger.Send(new ErrorOccurredMessage($"Resync fehlgeschlagen: {ex.Message}"));
}
}
};
}
public async Task InitializeAsync()
{
CurrentGameState = await _localStorage.GetGameStateAsync();
CurrentPlayerHand = await _localStorage.GetPlayerHandAsync();
var queued = await _localStorage.GetQueuedActionsAsync();
_queuedActions.Clear();
_queuedActions.AddRange(queued.OrderBy(a => a.CreatedAtUtc));
if (CurrentGameState is not null)
_messenger.Send(new GameStateChangedMessage(CurrentGameState));
if (CurrentPlayerHand is not null)
_messenger.Send(new PlayerHandChangedMessage(CurrentPlayerHand));
}
public async Task ResyncAsync()
{
if (CurrentGameState?.GameId > 0 && _signalR.IsConnected)
await _signalR.RequestGameStateAsync(CurrentGameState.GameId);
await FlushQueuedActionsAsync();
}
public async Task EnqueueActionAsync(string method, params object[] arguments)
{
var action = new QueuedGameAction
{
Method = method,
ArgumentsJson = JsonSerializer.Serialize(arguments),
CreatedAtUtc = DateTime.UtcNow
};
_queuedActions.Add(action);
await _localStorage.SaveQueuedActionsAsync(_queuedActions);
}
public async Task FlushQueuedActionsAsync()
{
if (!_signalR.IsConnected || _queuedActions.Count == 0)
return;
var snapshot = _queuedActions.ToList();
foreach (var action in snapshot)
{
await _signalR.SendQueuedActionAsync(action);
_queuedActions.Remove(action);
}
await _localStorage.SaveQueuedActionsAsync(_queuedActions);
}
public async Task ClearLocalGameDataAsync()
{
CurrentGameState = null;
CurrentPlayerHand = null;
PendingChallenge = null;
_queuedActions.Clear();
await _localStorage.ClearGameStateAsync();
await _localStorage.ClearPlayerHandAsync();
await _localStorage.ClearQueuedActionsAsync();
}
}