VanguardReMaster/server/tests/Vanguard.Server.Tests/ServerTestData.cs

142 lines
3.8 KiB
C#

using Vanguard.Content;
using Vanguard.Rules.Cards;
using Vanguard.Server.Configuration;
namespace Vanguard.Server.Tests;
internal static class ServerTestData
{
private static readonly Lazy<CardCatalog> LazyCatalog = new(
() => CatalogLoader.LoadDirectory(ContentPaths.Resolve(null)),
isThreadSafe: true);
public static CardCatalog Catalog => LazyCatalog.Value;
/// <summary>Колода без Sentinel и Heal, ровно 50 карт, до 4 копий на nameId.</summary>
public static List<string> BuildDeck()
{
var deck = new List<string>();
var counts = new Dictionary<string, int>(StringComparer.Ordinal);
foreach (var printing in Catalog.Printings
.Where(p => !p.IsParallel)
.OrderBy(p => p.PrintingId, StringComparer.Ordinal))
{
if (deck.Count >= 50)
break;
var card = Catalog.CardOf(printing.PrintingId);
if (card.IsSentinel || card.Trigger == TriggerType.Heal)
continue;
counts.TryGetValue(card.NameId, out var used);
var room = Math.Min(4 - used, 50 - deck.Count);
for (var i = 0; i < room; i++)
deck.Add(printing.PrintingId);
counts[card.NameId] = used + room;
}
Assert.Equal(50, deck.Count);
return deck;
}
public static GameOptions SmallOptions() => new()
{
TurnSeconds = 90,
BankSeconds = 300,
AbsenceSeconds = 300,
ClockSyncSeconds = 5,
TicketTtlSeconds = 60,
ConnectTimeoutSeconds = 5,
CompletedMatchTtlSeconds = 600,
QueueExpirySeconds = 600,
MmrInitialWindow = 100,
MmrWindowStep = 50,
MmrWindowIntervalSeconds = 5,
MmrMaxWindow = 2000,
};
}
internal sealed class FakeTimeProvider : TimeProvider
{
private DateTimeOffset _now;
public FakeTimeProvider(DateTimeOffset now) => _now = now;
public override DateTimeOffset GetUtcNow() => _now;
public void Advance(TimeSpan delta) => _now += delta;
}
internal sealed class FakeMatchConnection : Matches.IMatchConnection
{
private readonly object _gate = new();
private readonly List<Vanguard.Shared.Protocol.ServerFrame> _frames = new();
public string Id { get; } = Guid.NewGuid().ToString("N");
public bool IsClosed { get; private set; }
public int CloseCode { get; private set; }
public IReadOnlyList<Vanguard.Shared.Protocol.ServerFrame> Frames
{
get
{
lock (_gate)
return _frames.ToList();
}
}
public Task SendAsync(
Vanguard.Shared.Protocol.ServerFrame frame,
CancellationToken cancellationToken = default)
{
lock (_gate)
_frames.Add(frame);
return Task.CompletedTask;
}
public Task CloseAsync(int code, string reason)
{
IsClosed = true;
CloseCode = code;
return Task.CompletedTask;
}
public T Last<T>() where T : Vanguard.Shared.Protocol.ServerFrame
{
lock (_gate)
return _frames.OfType<T>().Last();
}
public IReadOnlyList<T> All<T>() where T : Vanguard.Shared.Protocol.ServerFrame
{
lock (_gate)
return _frames.OfType<T>().ToList();
}
}
internal sealed class RecordingResultSink : Matches.IMatchResultSink
{
private readonly List<Matches.MatchResult> _results = new();
public IReadOnlyList<Matches.MatchResult> Results
{
get
{
lock (_results)
return _results.ToList();
}
}
public Task RecordAsync(Matches.MatchResult result)
{
lock (_results)
_results.Add(result);
return Task.CompletedTask;
}
}