改了一亿个东西,修了一亿个 BUG
This commit is contained in:
90
ReplayFile/ReplayFooter.cs
Normal file
90
ReplayFile/ReplayFooter.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AnotherReplayReader.ReplayFile
|
||||
{
|
||||
internal enum ReplayFooterOption
|
||||
{
|
||||
SeekToFooter,
|
||||
CurrentlyAtFooter,
|
||||
}
|
||||
|
||||
internal sealed class ReplayFooter
|
||||
{
|
||||
public const uint Terminator = 0x7FFFFFFF;
|
||||
public static readonly byte[] FooterString = Encoding.ASCII.GetBytes("RA3 REPLAY FOOTER");
|
||||
|
||||
private readonly byte[] _data;
|
||||
|
||||
public uint FinalTimeCode { get; }
|
||||
public TimeSpan ReplayLength => TimeSpan.FromSeconds(FinalTimeCode / 15.0);
|
||||
|
||||
public ReplayFooter(BinaryReader reader, ReplayFooterOption option)
|
||||
{
|
||||
var currentPosition = reader.BaseStream.Position;
|
||||
reader.BaseStream.Seek(-4, SeekOrigin.End);
|
||||
var footerLength = reader.ReadInt32();
|
||||
|
||||
if (option == ReplayFooterOption.SeekToFooter)
|
||||
{
|
||||
currentPosition = reader.BaseStream.Length - footerLength;
|
||||
}
|
||||
|
||||
reader.BaseStream.Seek(currentPosition, SeekOrigin.Begin);
|
||||
var footer = reader.ReadBytes(footerLength);
|
||||
|
||||
if (footer.Length != footerLength || reader.BaseStream.Position != reader.BaseStream.Length)
|
||||
{
|
||||
throw new InvalidDataException("Invalid footer");
|
||||
}
|
||||
|
||||
using var footerStream = new MemoryStream(footer);
|
||||
using var footerReader = new BinaryReader(footerStream);
|
||||
var footerString = footerReader.ReadBytes(17);
|
||||
if (!footerString.SequenceEqual(FooterString))
|
||||
{
|
||||
throw new InvalidDataException("Invalid footer, no footer string");
|
||||
}
|
||||
FinalTimeCode = footerReader.ReadUInt32();
|
||||
_data = footerReader.ReadBytes(footer.Length - 25);
|
||||
if (footerReader.ReadInt32() != footerLength)
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
}
|
||||
|
||||
public ReplayFooter(uint finalTimeCode)
|
||||
{
|
||||
FinalTimeCode = finalTimeCode;
|
||||
_data = new byte[] { 0x02, 0x1A, 0x00, 0x00, 0x00 };
|
||||
}
|
||||
|
||||
List<float>? TryGetKillDeathRatio()
|
||||
{
|
||||
if (_data.Length < 24)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var ratios = new List<float>();
|
||||
using var stream = new MemoryStream(_data, _data.Length - 24, 24);
|
||||
using var reader = new BinaryReader(stream);
|
||||
ratios.Add(reader.ReadSingle());
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteTo(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(Terminator);
|
||||
writer.Write(FooterString);
|
||||
writer.Write(FinalTimeCode);
|
||||
writer.Write(_data);
|
||||
writer.Write(FooterString.Length + _data.Length + 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user