OfflineGameBackend.cs
1 using System.Text.Json; 2 using GUNRPG.Application.Backend; 3 using GUNRPG.Infrastructure.Persistence; 4 5 namespace GUNRPG.Infrastructure.Backend; 6 7 /// <summary> 8 /// Offline game backend that uses local LiteDB for operator state. 9 /// Only available when an operator has been previously infiled from the server. 10 /// Combat remains interactive and player-driven — this backend handles 11 /// operator data access, not gameplay execution. 12 /// </summary> 13 public sealed class OfflineGameBackend : IGameBackend 14 { 15 private readonly OfflineStore _offlineStore; 16 17 public OfflineGameBackend(OfflineStore offlineStore) 18 { 19 _offlineStore = offlineStore; 20 } 21 22 /// <inheritdoc /> 23 public Task<OperatorDto?> GetOperatorAsync(string id) 24 { 25 var infiled = _offlineStore.GetInfiledOperator(id); 26 if (infiled == null || !infiled.IsActive) 27 return Task.FromResult<OperatorDto?>(null); 28 29 try 30 { 31 var dto = JsonSerializer.Deserialize<OperatorDto>(infiled.SnapshotJson); 32 return Task.FromResult<OperatorDto?>(dto); 33 } 34 catch (JsonException ex) 35 { 36 throw new InvalidOperationException( 37 "[OFFLINE] Stored operator snapshot is invalid or incompatible. " + 38 "Please reconnect and re-infil the operator from the server.", 39 ex); 40 } 41 } 42 43 /// <inheritdoc /> 44 public Task<OperatorDto> InfilOperatorAsync(string id) 45 { 46 // Infil is not available in offline mode - requires server connection 47 throw new InvalidOperationException( 48 "[OFFLINE] Cannot infil operator while offline. Server connection required."); 49 } 50 51 /// <inheritdoc /> 52 public async Task<bool> OperatorExistsAsync(string id) 53 { 54 var op = await GetOperatorAsync(id); 55 return op != null; 56 } 57 }