Files
squad-rain-ops-mini/Services/ServerInfoStorageService.cs

86 lines
3.2 KiB
C#

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<ServerInfoStorageService> _logger;
private readonly RconDataCache _cache;
private readonly TimeSpan _interval = TimeSpan.FromMinutes(10);
public ServerInfoStorageService(ILogger<ServerInfoStorageService> 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<ServerInfoLog>();
// 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<ServerInfoLog>().Where(x => x.Timestamp < sevenDaysAgo).ExecuteCommandAsync();
}
_logger.LogInformation($"[ServerInfoStorage] Recorded: {log.PlayerCount} players on {log.MapName}.");
}
}
}