mirror of
https://gitee.com/xiarenalofs/squad-rain-ops-mini.git
synced 2026-08-08 06:15:34 +08:00
169 lines
6.1 KiB
C#
169 lines
6.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Hosting;
|
|
using RainOpsMini;
|
|
using RainOpsMini.Models;
|
|
using RainOpsMini.Helpers.SquadGameLog;
|
|
using RainOpsMini; // Ensure Program is visible
|
|
|
|
namespace RainOpsMini.Helpers.RCON
|
|
{
|
|
public class RconPollingService : BackgroundService
|
|
{
|
|
private readonly RconDataCache _cache;
|
|
|
|
public RconPollingService(RconDataCache cache)
|
|
{
|
|
_cache = cache;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
RainOpsMini.Helpers.RainOpsLog.Log("RCON Polling Service started.");
|
|
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
int delaySeconds = _cache.RefreshIntervalSeconds;
|
|
|
|
try
|
|
{
|
|
if (Program.Client != null && Program.Client.IsConnected)
|
|
{
|
|
await UpdateRconDataAsync();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RainOpsMini.Helpers.RainOpsLog.Log($"[RconPollingService] Error: {ex.Message}");
|
|
}
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(delaySeconds), stoppingToken);
|
|
}
|
|
}
|
|
|
|
private async Task UpdateRconDataAsync()
|
|
{
|
|
var client = Program.Client;
|
|
if (client == null) return;
|
|
|
|
try
|
|
{
|
|
// 1. Fetch Server Info
|
|
string serverInfoRaw = await client.SendCommandAsync("ShowServerInfo");
|
|
var serverInfo = RconParser.ParseServerInfo(serverInfoRaw);
|
|
|
|
// 2. Fetch Squads
|
|
string squadsRaw = await client.SendCommandAsync("ListSquads");
|
|
var squads = RconParser.ParseSquads(squadsRaw);
|
|
|
|
// 3. Fetch Players (with retry logic similar to original API)
|
|
List<PlayerInfo> players = new List<PlayerInfo>();
|
|
int retryCount = 0;
|
|
const int maxRetries = 3;
|
|
|
|
int expectedPlayerCount = 0;
|
|
if (serverInfo != null && int.TryParse(serverInfo.PlayerCount_I, out int pc))
|
|
{
|
|
expectedPlayerCount = pc;
|
|
}
|
|
|
|
while (retryCount < maxRetries)
|
|
{
|
|
string playersRaw = await client.SendCommandAsync("ListPlayers");
|
|
var currentPlayers = RconParser.ParsePlayers(playersRaw);
|
|
|
|
if (currentPlayers.Count > players.Count)
|
|
{
|
|
players = currentPlayers;
|
|
}
|
|
|
|
if (expectedPlayerCount > 0)
|
|
{
|
|
if (players.Count >= expectedPlayerCount * 0.8)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (players.Count > 0) break;
|
|
}
|
|
|
|
if (retryCount < maxRetries - 1)
|
|
{
|
|
await Task.Delay(500);
|
|
}
|
|
retryCount++;
|
|
}
|
|
|
|
// 4. Enrich Data
|
|
foreach (var squad in squads)
|
|
{
|
|
if (!string.IsNullOrEmpty(squad.CreatorSteamId))
|
|
{
|
|
var creationTime = LogStorage.Instance.GetLastSquadCreationTime(squad.CreatorSteamId);
|
|
if (creationTime.HasValue)
|
|
{
|
|
squad.LastCreatedTime = creationTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
|
|
}
|
|
}
|
|
}
|
|
|
|
DateTime matchStartTime = DateTime.MinValue;
|
|
if (serverInfo != null && serverInfo.PlayTime_I > 0)
|
|
{
|
|
matchStartTime = DateTime.Now.AddSeconds(-serverInfo.PlayTime_I - 60);
|
|
}
|
|
|
|
foreach (var player in players)
|
|
{
|
|
LogStorage.Instance.RegisterPlayer(player.Name, player.SteamId);
|
|
var stats = LogStorage.Instance.GetPlayerStats(player.SteamId, matchStartTime);
|
|
player.Kills = stats.Kills;
|
|
player.Deaths = stats.Deaths;
|
|
}
|
|
|
|
// 5. Update Cache
|
|
_cache.UpdateData(serverInfo, squads, players);
|
|
|
|
// 6. Async Update Steam Playtime
|
|
_ = Task.Run(async () =>
|
|
{
|
|
try
|
|
{
|
|
var cachedTimes = _cache.GetGameTimes();
|
|
foreach (var p in players)
|
|
{
|
|
if (!string.IsNullOrEmpty(p.SteamId))
|
|
{
|
|
// If not in cache, or value is 0 (maybe failed previously), update it.
|
|
// You might also want to re-check periodically, but for now let's stick to missing/zero.
|
|
if (!cachedTimes.ContainsKey(p.SteamId) || cachedTimes[p.SteamId] <= 0)
|
|
{
|
|
int minutes = await SteamHelper.GetSquadPlaytimeAsync(p.SteamId);
|
|
if (minutes > 0)
|
|
{
|
|
_cache.UpdateGameTime(p.SteamId, minutes);
|
|
}
|
|
await Task.Delay(200); // Rate limit
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RainOpsMini.Helpers.RainOpsLog.Log($"[RconPollingService] Playtime update failed: {ex.Message}");
|
|
}
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RainOpsMini.Helpers.RainOpsLog.Log($"[RconPollingService] Update failed: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|