Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da8cd46bc6 |
+2
-1
@@ -3,4 +3,5 @@ obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
.idea/*
|
||||
.idea/*
|
||||
/.vs
|
||||
|
||||
@@ -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>
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user