using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using RainOpsMini.Helpers; using RainOpsMini.Helpers.RCON; using RainOpsMini.Models; using System; using System.Threading; using System.Threading.Tasks; namespace RainOpsMini.Services { public class ServerInfoStorageService : BackgroundService { private readonly ILogger _logger; private readonly RconDataCache _cache; private readonly TimeSpan _interval = TimeSpan.FromMinutes(10); public ServerInfoStorageService(ILogger logger, RconDataCache cache) { _logger = logger; _cache = cache; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _logger.LogInformation("[ServerInfoStorage] Service started. Interval: 10 minutes."); // Wait a bit on startup to ensure RCON has connected and fetched first data await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); while (!stoppingToken.IsCancellationRequested) { try { await RecordServerInfo(); } catch (Exception ex) { _logger.LogError(ex, "[ServerInfoStorage] Error recording server info."); } await Task.Delay(_interval, stoppingToken); } } private async Task RecordServerInfo() { var data = _cache.GetData(); if (data?.ServerInfo == null) { _logger.LogWarning("[ServerInfoStorage] Server info is null, skipping record."); return; } int.TryParse(data.ServerInfo.PlayerCount_I, out int playerCount); var log = new ServerInfoLog { Timestamp = DateTime.Now, PlayerCount = playerCount, MaxPlayers = data.ServerInfo.MaxPlayers, MapName = data.ServerInfo.MapName_s, ServerName = data.ServerInfo.ServerName_s }; using (var db = DbHelper.GetInstance()) { // Create table if not exists (SqlSugar does this automatically if configured, but good to be safe or rely on DbHelper's logic) // DbHelper doesn't seem to explicitly create tables on get instance, but usually CodeFirst is used. // We'll rely on SqlSugar's CodeFirst capability if we can call it, or assume it works. // To be safe, let's call InitTables. db.CodeFirst.InitTables(); // 1. Insert new record await db.Insertable(log).ExecuteCommandAsync(); // 2. Cleanup old records (older than 7 days) var sevenDaysAgo = DateTime.Now.AddDays(-7); await db.Deleteable().Where(x => x.Timestamp < sevenDaysAgo).ExecuteCommandAsync(); } _logger.LogInformation($"[ServerInfoStorage] Recorded: {log.PlayerCount} players on {log.MapName}."); } } }