GiantsTools/Giants.Services/Services/ServerRegistryService.cs

93 lines
3.8 KiB
C#

namespace Giants.Services
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
public class ServerRegistryService : IServerRegistryService
{
private static readonly string[] SupportedGameNames = new[] { "Giants", "Giants Beta", "Giants Beta Dedicated", "Giants Dedicated" };
private readonly ILogger<ServerRegistryService> logger;
private readonly IServerRegistryStore registryStore;
private readonly IConfiguration configuration;
private readonly int maxServerCount;
private readonly int maxServersPerIp;
public ServerRegistryService(
ILogger<ServerRegistryService> logger,
IServerRegistryStore registryStore,
IConfiguration configuration)
{
this.logger = logger;
this.registryStore = registryStore;
this.configuration = configuration;
this.maxServerCount = Convert.ToInt32(this.configuration["MaxServerCount"]);
this.maxServersPerIp = Convert.ToInt32(this.configuration["MaxServersPerIp"]);
}
public async Task AddServer(
ServerInfo serverInfo)
{
ArgumentUtility.CheckForNull(serverInfo, nameof(serverInfo));
ArgumentUtility.CheckStringForNullOrEmpty(serverInfo.HostIpAddress, nameof(serverInfo.HostIpAddress));
string gameName = serverInfo.GameName.Replace("Dedicated", string.Empty).Trim();
serverInfo.GameName = gameName;
if (!SupportedGameNames.Contains(serverInfo.GameName, StringComparer.OrdinalIgnoreCase))
{
throw new ArgumentException($"Unsupported game name {serverInfo.GameName}", nameof(serverInfo));
}
var existingServers = await this.registryStore.GetServerInfos(whereExpression: x => x.HostIpAddress == serverInfo.HostIpAddress);
if (existingServers.GroupBy(g => new { g.HostIpAddress }).Any(g => g.Count() > this.maxServersPerIp))
{
throw new InvalidOperationException("Exceeded maximum servers per IP.");
}
await this.registryStore.UpsertServerInfo(serverInfo);
}
public async Task<IEnumerable<ServerInfo>> GetAllServers()
{
return (await this.registryStore.GetServerInfos())
.Take(this.maxServerCount);
}
// Old API, soon to be deprecated
public async Task DeleteServer(string ipAddress)
{
ArgumentUtility.CheckStringForNullOrEmpty(ipAddress, nameof(ipAddress));
var serverInfos = await this.registryStore.GetServerInfos(whereExpression: x => x.HostIpAddress == ipAddress);
foreach (var serverInfo in serverInfos)
{
await this.registryStore.DeleteServer(serverInfo.id);
}
}
public async Task DeleteServer(string ipAddress, string gameName, int port)
{
ArgumentUtility.CheckStringForNullOrEmpty(ipAddress, nameof(ipAddress));
ArgumentUtility.CheckStringForNullOrEmpty(gameName, nameof(gameName));
ArgumentUtility.CheckForNonnegativeInt(port, nameof(port));
var existingServerInfo = (await this.registryStore.GetServerInfos(
whereExpression:
x => x.HostIpAddress == ipAddress &&
x.Port == port &&
x.GameName.Equals(gameName, StringComparison.OrdinalIgnoreCase)))
.FirstOrDefault();
if (existingServerInfo != null)
{
await this.registryStore.DeleteServer(existingServerInfo.id);
}
}
}
}