97 lines
3.0 KiB
C#
97 lines
3.0 KiB
C#
using System.Diagnostics;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text;
|
|
using SoulstormReplayReader.Core.Domain.Player;
|
|
using SoulstormReplayReader.Core.Models;
|
|
|
|
namespace SoulstormReplayReader.Core.Extensions;
|
|
|
|
public static class Extensions
|
|
{
|
|
public static void RequireInRange(this int num, int min, int max, string errorMsg)
|
|
{
|
|
if (num < min || num > max)
|
|
throw new ArgumentOutOfRangeException(errorMsg);
|
|
}
|
|
|
|
public static void Swap<T>(this IList<T> list, int i1, int i2)
|
|
{
|
|
(list[i1], list[i2]) = (list[i2], list[i1]);
|
|
}
|
|
|
|
public static Span<byte> TrimEnd(this Span<byte> span, byte val = 0)
|
|
{
|
|
var i = span.Length - 1;
|
|
while (i > 0 && span[i--] == val) ;
|
|
return span[..i];
|
|
}
|
|
|
|
public static ExBinaryReader NextAsciiStringMustEqual(this ExBinaryReader binReader, ReadOnlySpan<byte> text)
|
|
{
|
|
if (!binReader.IsNextAsciiStringEquals(text))
|
|
{
|
|
throw new Exception(Encoding.ASCII.GetString(text) + "Нарушение структуры файла. ");
|
|
}
|
|
|
|
return binReader;
|
|
}
|
|
|
|
public static bool IsNextAsciiStringEquals(this ExBinaryReader binReader, ReadOnlySpan<byte> textSpan)
|
|
{
|
|
var nextTextSpan = binReader.ReadBytes(stackalloc byte[textSpan.Length]);
|
|
|
|
if (textSpan.SequenceEqual(nextTextSpan))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return textSpan.Length == nextTextSpan.Length && SpansEqualInvariant(textSpan, nextTextSpan);
|
|
|
|
static bool SpansEqualInvariant(ReadOnlySpan<byte> span1, ReadOnlySpan<byte> span2)
|
|
{
|
|
for (var i = 0; i < span1.Length; i++)
|
|
{
|
|
if (span1[i] == span2[i])
|
|
continue;
|
|
|
|
var char1 = char.ToLower((char)span1[i]);
|
|
var char2 = char.ToLower((char)span2[i]);
|
|
if (char1 != char2)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public static ReplayColor ReadBgraToArgb(this ExBinaryReader binReader)
|
|
{
|
|
var bgra = binReader.ReadUInt32();
|
|
|
|
var argb = ReverseBytes(bgra);
|
|
|
|
return Unsafe.As<uint, ReplayColor>(ref argb);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static uint ReverseBytes(uint value) =>
|
|
((value & 0x000000FFU) << 24) | ((value & 0x0000FF00U) << 8) |
|
|
((value & 0x00FF0000U) >> 8) | ((value & 0xFF000000U) >> 24);
|
|
|
|
public static string ToContentString(this IEnumerable<byte> bytes) =>
|
|
string.Join(' ',
|
|
bytes.Select(b => $"{b:x}".PadLeft(2, '0'))
|
|
);
|
|
|
|
[Conditional("DEBUGLOGGING")]
|
|
public static void LogPlayers(this List<PlayerModel> players)
|
|
{
|
|
Console.WriteLine("NAME TEAM TYPE RACE");
|
|
foreach (var pl in players.Where(p => p != null))
|
|
{
|
|
Console.WriteLine($"{pl.Name ?? "",-15} {pl.Team,-8} {pl.RawType} {pl.ResolvedType,-10} {pl.Race}");
|
|
}
|
|
}
|
|
} |