Files
AnotherReplayReader/ReplayFile/CommandChunk.cs
2026-06-21 14:42:04 +02:00

84 lines
2.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
namespace AnotherReplayReader.ReplayFile
{
public enum CommandArgumentType
{
Int32 = 0,
Float32 = 1,
Bool = 2,
AssetId = 3,
ObjectId = 4,
ObjectId_2 = 5,
UInt32 = 6,
Vector3 = 7,
UInt32_2 = 8,
UInt16 = 9,
AsciiString = 10,
UnicodeString = 11,
}
public record struct CommandArgumentEntry(CommandArgumentType Type, object Value, int Count);
public record struct Vector3(float X, float Y, float Z)
{
public override readonly string ToString() => $"(X={Math.Round(X)},Y={Math.Round(Y)},Z={Math.Round(Z)})";
}
public record struct AssetId(uint TypeId, uint InstanceId)
{
public override readonly string ToString() => $"(TypeId={TypeId:X},InstanceId={InstanceId:X})";
}
public sealed class CommandChunk
{
public int CommandId { get; private set; }
public int PlayerIndex { get; private set; }
public ImmutableArray<CommandArgumentEntry> Data { get; private set; }
public static List<CommandChunk> Parse(ReplayChunk chunk)
{
if (chunk.Type != 1)
{
throw new NotImplementedException();
}
using var reader = chunk.GetReader();
if (reader.ReadByte() != 1)
{
throw new InvalidDataException("Payload first byte not 1");
}
var list = new List<CommandChunk>();
var numberOfCommands = reader.ReadInt32();
for (var i = 0; i < numberOfCommands; ++i)
{
var commandIdAndPlayerId = reader.ReadUInt16();
var commandId = commandIdAndPlayerId & 0x7FF;
var playerId = commandIdAndPlayerId >> 11;
var data = reader.ReadCommandData();
list.Add(new CommandChunk
{
CommandId = commandId,
PlayerIndex = playerId,
Data = data.ToImmutableArray(),
});
}
if (reader.BaseStream.Position != reader.BaseStream.Length)
{
throw new InvalidDataException("Payload not fully parsed");
}
return list;
}
public override string ToString()
{
return $"[玩家 {PlayerIndex}{RA3Commands.GetCommandName(CommandId)}]";
}
}
}