Compare commits
No commits in common. "master" and "master" have entirely different histories.
@ -1,26 +1,15 @@
|
||||
namespace SoulstormReplayReader.Core.Domain;
|
||||
|
||||
public sealed class GameSettings(int gameSettingsCount = 8)
|
||||
public sealed class GameSettings
|
||||
{
|
||||
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 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; }
|
||||
|
||||
public bool IsQuickStart => StartResources == 1;
|
||||
public bool AreCheatsOn => CheatsOn == 1;
|
||||
|
||||
@ -23,7 +23,7 @@ public sealed class ReplayModel
|
||||
public List<IGameAction> Actions { get; set; }
|
||||
public List<ChatMessageModel> ChatMessages { get; set; }
|
||||
|
||||
public GameSettings GameSettings { get; set; }
|
||||
public GameSettings GameSettings { get; } = new();
|
||||
public WinConditions WinConditions { get; } = new();
|
||||
|
||||
public Exception Exception { get; set; }
|
||||
|
||||
@ -19,6 +19,13 @@ 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))
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
<PackageId>SoulstormReplayReader.Core</PackageId>
|
||||
<Authors>Bununic</Authors>
|
||||
<Company>Dowonline</Company>
|
||||
<Version>1.0.7</Version>
|
||||
<Version>1.0.5</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<LangVersion>12</LangVersion>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<LangVersion>12.0</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
@ -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<byte>(0));
|
||||
Replay.ModName = Encoding.ASCII.GetString(modNameSpan.TrimEnd());
|
||||
|
||||
_binaryReader // relic chunky
|
||||
.Skip(44)
|
||||
@ -152,6 +152,7 @@ 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;
|
||||
@ -187,30 +188,42 @@ public sealed class SsReplayReader(Stream stream) : IDisposable
|
||||
// Game setting:
|
||||
// * 0000 - value
|
||||
// * AAAA - compact name
|
||||
// res: 0000COLS = (0000)(COLS=SLOC=Starting locations)
|
||||
// res: 0000COLS = (0000)random (COLS=SLOC)Starting locations
|
||||
private void ReadGameSettings()
|
||||
{
|
||||
var gameSettingsCount = _binaryReader.ReadInt32();
|
||||
Replay.GameSettings = new GameSettings(gameSettingsCount);
|
||||
Replay.GameSettings.AiDifficulty = _binaryReader.ReadByte(); // FDIA = AIDF = AI Difficulty
|
||||
_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.StartResources = _binaryReader.ReadByte(); // TSSR = RSST = Starting Resources
|
||||
_binaryReader.Skip(7);
|
||||
|
||||
#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"
|
||||
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}"
|
||||
);
|
||||
#endif
|
||||
|
||||
@ -371,7 +384,7 @@ public sealed class SsReplayReader(Stream stream) : IDisposable
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckForBugs)
|
||||
if (!Replay.GameSettings.IsQuickStart && !Replay.GameSettings.AreCheatsOn && CheckForBugs)
|
||||
AttachBugCheckers();
|
||||
|
||||
Replay.Actions = new List<IGameAction>(Replay.TotalTicks / 2);
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
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",
|
||||
@ -19,8 +18,6 @@ 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"
|
||||
@ -28,7 +25,6 @@ string[] filePaths =
|
||||
};
|
||||
string[] dirPaths =
|
||||
{
|
||||
// "TestReplaysDE",
|
||||
// "TestReplays\\Many",
|
||||
// "TestReplays\\Many",
|
||||
// "TestReplays\\Many",
|
||||
@ -76,9 +72,6 @@ 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
|
||||
|
||||
@ -12,8 +12,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="TestReplays/**" CopyToOutputDirectory="PreserveNewest"/>
|
||||
<None Include="TestReplaysDE/**" CopyToOutputDirectory="PreserveNewest"/>
|
||||
<None Include="TestReplays/*" CopyToOutputDirectory="PreserveNewest"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user