Compare commits

...

7 Commits

13 changed files with 55 additions and 56 deletions

View File

@ -1,15 +1,26 @@
namespace SoulstormReplayReader.Core.Domain;
public sealed class GameSettings
public sealed class GameSettings(int gameSettingsCount = 8)
{
public byte AiDifficulty { get; set; }
public byte StartResources { get; set; }
public byte LockTeams { get; set; }
public byte CheatsOn { get; set; }
public byte StartingLocation { get; set; }
public byte GameSpeed { get; set; }
public byte ResourceSharing { get; set; }
public byte ResourceRate { get; set; }
private readonly Dictionary<string, int?> _settings = new(gameSettingsCount);
public IReadOnlyDictionary<string, int?> Settings => _settings;
public int? this[string name] => _settings.GetValueOrDefault(name);
internal void AddSetting(string name, int value)
{
_settings.Add(name, value);
}
public int? AiDifficulty => _settings.GetValueOrDefault("FDIA"); // FDIA = AIDF = AI Difficulty
public int? StartResources => _settings.GetValueOrDefault("TSSR"); // TSSR = RSST = Starting Resources
public int? LockTeams => _settings.GetValueOrDefault("MTKL"); // MTKL = LKTM = Lock Teams
public int? CheatsOn => _settings.GetValueOrDefault("AEHC"); // AEHC = CHEA = Cheats Enabled
public int? StartingLocation => _settings.GetValueOrDefault("COLS"); // COLS = SLOC = Starting Location
public int? GameSpeed => _settings.GetValueOrDefault("DPSG"); // DPSG = GSPD = Game Speed
public int? ResourceSharing => _settings.GetValueOrDefault("HSSR"); // HSSR = RSSH = Resource Sharing
public int? ResourceRate => _settings.GetValueOrDefault("TRSR"); // TRSR = RSRT = Resource Rate
public int? DisableFlyers => _settings.GetValueOrDefault("YLFN"); // YLFN = NFLY = No flyers
public bool IsQuickStart => StartResources == 1;
public bool AreCheatsOn => CheatsOn == 1;

View File

@ -23,7 +23,7 @@ public sealed class ReplayModel
public List<IGameAction> Actions { get; set; }
public List<ChatMessageModel> ChatMessages { get; set; }
public GameSettings GameSettings { get; } = new();
public GameSettings GameSettings { get; set; }
public WinConditions WinConditions { get; } = new();
public Exception Exception { get; set; }

View File

@ -19,13 +19,6 @@ public static class Extensions
(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))

View File

@ -4,13 +4,13 @@
<PackageId>SoulstormReplayReader.Core</PackageId>
<Authors>Bununic</Authors>
<Company>Dowonline</Company>
<Version>1.0.5</Version>
<Version>1.0.7</Version>
</PropertyGroup>
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<LangVersion>12.0</LangVersion>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
<LangVersion>12</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>

View File

@ -91,7 +91,7 @@ public sealed class SsReplayReader(Stream stream) : IDisposable
Replay.Version = (ReplayVersion)_binaryReader.ReadInt32();
var modNameSpan = _binaryReader.ReadBytes(stackalloc byte[32]);
Replay.ModName = Encoding.ASCII.GetString(modNameSpan.TrimEnd());
Replay.ModName = Encoding.ASCII.GetString(modNameSpan.TrimEnd<byte>(0));
_binaryReader // relic chunky
.Skip(44)
@ -152,7 +152,6 @@ public sealed class SsReplayReader(Stream stream) : IDisposable
_binaryReader.SkipInt32(3);
Replay.WorldSeed = _binaryReader.ReadUInt32();
_binaryReader.SkipInt32(); // Размер слотов в игре. Всегда 8
Descriptor.DataBaseStart = _binaryReader.Position;
Descriptor.DataBaseSize = Descriptor.DataBaseChunkSize - 20;
@ -188,42 +187,30 @@ public sealed class SsReplayReader(Stream stream) : IDisposable
// Game setting:
// * 0000 - value
// * AAAA - compact name
// res: 0000COLS = (0000)random (COLS=SLOC)Starting locations
// res: 0000COLS = (0000)(COLS=SLOC=Starting locations)
private void ReadGameSettings()
{
Replay.GameSettings.AiDifficulty = _binaryReader.ReadByte(); // FDIA = AIDF = AI Difficulty
_binaryReader.Skip(7);
var gameSettingsCount = _binaryReader.ReadInt32();
Replay.GameSettings = new GameSettings(gameSettingsCount);
Replay.GameSettings.StartResources = _binaryReader.ReadByte(); // TSSR = RSST = Starting Resources
_binaryReader.Skip(7);
for (var i = 0; i < gameSettingsCount; i++)
{
var value = _binaryReader.ReadInt32();
var name = _binaryReader.ReadAsciiString(4);
Replay.GameSettings.AddSetting(name, value);
}
Replay.GameSettings.LockTeams = _binaryReader.ReadByte(); // MTKL = LKTM = Lock Teams
_binaryReader.Skip(7);
Replay.GameSettings.CheatsOn = _binaryReader.ReadByte(); // AEHC = CHEA = Cheats Enabled
_binaryReader.Skip(7);
Replay.GameSettings.StartingLocation = _binaryReader.ReadByte(); // COLS = SLOC = Starting Location
_binaryReader.Skip(7);
Replay.GameSettings.GameSpeed = _binaryReader.ReadByte(); // DPSG = GSPD = Game Speed
_binaryReader.Skip(7);
Replay.GameSettings.ResourceSharing = _binaryReader.ReadByte(); // HSSR = RSSH = Resource Sharing
_binaryReader.Skip(7);
Replay.GameSettings.ResourceRate = _binaryReader.ReadByte(); // TRSR = RSRT = Resource Rate
_binaryReader.Skip(7);
#if DEBUGLOGGING
Console.WriteLine($"{Replay.GameSettings.AiDifficulty} " +
$"{Replay.GameSettings.StartResources} " +
$"{Replay.GameSettings.LockTeams} " +
$"{Replay.GameSettings.CheatsOn} " +
$"{Replay.GameSettings.StartingLocation} " +
$"{Replay.GameSettings.GameSpeed} " +
$"{Replay.GameSettings.ResourceSharing} " +
$"{Replay.GameSettings.ResourceRate}"
#if DEBUG
Console.WriteLine($"Game settings ({gameSettingsCount}):\n"
+ $"AI Difficulty: {Replay.GameSettings.AiDifficulty}\n"
+ $"Starting Resources: {Replay.GameSettings.StartResources}\n"
+ $"Lock Teams: {Replay.GameSettings.LockTeams}\n"
+ $"Cheats Enabled: {Replay.GameSettings.CheatsOn}\n"
+ $"Starting Location: {Replay.GameSettings.StartingLocation}\n"
+ $"Game Speed: {Replay.GameSettings.GameSpeed}\n"
+ $"Resource Sharing: {Replay.GameSettings.ResourceSharing}\n"
+ $"Resource Rate: {Replay.GameSettings.ResourceRate}\n"
+ $"No flyers: {Replay.GameSettings.DisableFlyers}\n"
);
#endif
@ -384,7 +371,7 @@ public sealed class SsReplayReader(Stream stream) : IDisposable
return;
}
if (!Replay.GameSettings.IsQuickStart && !Replay.GameSettings.AreCheatsOn && CheckForBugs)
if (CheckForBugs)
AttachBugCheckers();
Replay.Actions = new List<IGameAction>(Replay.TotalTicks / 2);

View File

@ -2,6 +2,7 @@
string[] filePaths =
{
@"TestReplaysDE\Broken\2p_blood_river_[Rem].2025-10-26.18-13-28.rec",
// @"TestReplays\replay_6p_2v2v2_001.rec",
// @"TestReplays\gens_builds\ork_many_researches.rec",
// @"TestReplays\lag\lag3.rec",
@ -18,6 +19,8 @@ string[] filePaths =
// "TestReplays\\unification_anon_2_races.rec"
// "TestReplays\\Unfair\\Bugs\\SoB_2commanders_1squad.rec",
// @"TestReplays\Unfair\Cheats\eresArchitect_delet.rec",
// @"TestReplays\Unfair\Cheats\deleted_necron_mainbuilding.rec",
// @"TestReplays\destroy_actions\destroy_necron_mainbuilding.rec",
// @"TestReplays\Broken\#860994_empty_name.rec",
// "TestReplays\\Unfair\\Cheats\\mono_in_1_min.rec",
// @"TestReplays\old\BM.rec"
@ -25,6 +28,7 @@ string[] filePaths =
};
string[] dirPaths =
{
// "TestReplaysDE",
// "TestReplays\\Many",
// "TestReplays\\Many",
// "TestReplays\\Many",
@ -72,6 +76,9 @@ foreach (var replayPath in replayPaths)
};
var replay = replayReader.ReadFull();
Console.WriteLine(string.Join('\n', replay.Players.Select(x => $"{x.Name} {x.Badge.Name} {x.ColorScheme.Eyes}")));
Console.WriteLine(replay.Version);
Console.WriteLine(string.Join(' ', replay.WinConditions));
// #if DEBUGLOGGING

View File

@ -12,7 +12,8 @@
</ItemGroup>
<ItemGroup>
<None Include="TestReplays/*" CopyToOutputDirectory="PreserveNewest"/>
<None Include="TestReplays/**" CopyToOutputDirectory="PreserveNewest"/>
<None Include="TestReplaysDE/**" CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>
</Project>