mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-09-22 22:28:22 +03:00
79 lines
2.1 KiB
C#
79 lines
2.1 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
|
|
namespace AMNet.Server;
|
|
|
|
/// <summary>
|
|
/// Represents a storage location to load/read cards from
|
|
/// </summary>
|
|
internal class CardPresenter
|
|
{
|
|
private readonly Lock _cardLock = new();
|
|
private StoredCard _currentCard;
|
|
|
|
public record StoredCard(byte[] Value, string OriginalValue, long ExpiresAt)
|
|
{
|
|
public bool Expired => Environment.TickCount64 >= ExpiresAt;
|
|
|
|
public override string ToString() => string.Join(" ", Enumerable.Range(0, 5).Select(x => OriginalValue.Substring(x * 4, 4)));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the currently active card without clearing it
|
|
/// </summary>
|
|
public StoredCard PeekActiveCard()
|
|
{
|
|
lock (_cardLock)
|
|
{
|
|
return _currentCard;
|
|
}
|
|
}
|
|
|
|
public StoredCard TakeActiveCard()
|
|
{
|
|
lock (_cardLock)
|
|
{
|
|
var card = _currentCard;
|
|
_currentCard = null;
|
|
|
|
return card;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the card
|
|
/// </summary>
|
|
/// <param name="cardId">The card id to set</param>
|
|
/// <param name="validFor">How long the card should be presented to the game for in milliseconds</param>
|
|
/// <returns>Whether the card was set successfully</returns>
|
|
public StoredCard SetCard(string cardId, long validFor = 5000)
|
|
{
|
|
// ensure the matrix code is 20-digits long, otherwise pad with zeros
|
|
var matrixCode = cardId.Replace(" ", "").PadLeft(20, '0');
|
|
var bytes = new byte[10];
|
|
|
|
for (var i = 0; i < bytes.Length; i++)
|
|
{
|
|
var value = matrixCode.Substring(i * 2, 2);
|
|
if (byte.TryParse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var b))
|
|
{
|
|
bytes[i] = b;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
var card = new StoredCard(bytes, matrixCode, Environment.TickCount64 + validFor);
|
|
|
|
lock (_cardLock)
|
|
{
|
|
_currentCard = card;
|
|
}
|
|
|
|
return card;
|
|
}
|
|
} |