/ GUNRPG.Infrastructure / Backend / OfflineGameBackend.cs
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  }