using System; using System.Collections.Generic; using System.IO; using System.Text; namespace AxiReplay { public class ReplayWriter : IReplayWriter { public ReplayData.ReplayFormat mFormat { get; private set; } public Encoding TexEncoding { get; private set; } ReplayHandler handler; string mTitle; string mNote; int mAllFrame; int mAllTime; long mData; int mSingleInputLenght; int mSingleDataLenght; MemoryStream mStream; BinaryWriter mBinaryWriter; int mCurrFrame; UInt64 mCurrInput; ReplayStep wirteStep; List dbgList = new List(); public ReplayWriter(string Title, string Note, ReplayData.ReplayFormat format, Encoding encoding) { mTitle = Title; mNote = Note; TexEncoding = encoding; mFormat = format; switch (mFormat) { case ReplayData.ReplayFormat.FM32IP64: mSingleInputLenght = sizeof(UInt64); break; case ReplayData.ReplayFormat.FM32IP32: mSingleInputLenght = sizeof(UInt32); break; case ReplayData.ReplayFormat.FM32IP16: mSingleInputLenght = sizeof(UInt16); break; case ReplayData.ReplayFormat.FM32IPBYTE: mSingleInputLenght = sizeof(byte); break; } mSingleDataLenght = (sizeof(UInt32)) + mSingleInputLenght; mStream = new MemoryStream(); mBinaryWriter = new BinaryWriter(mStream); mCurrFrame = -1; mCurrInput = int.MaxValue; wirteStep = new ReplayStep(); dbgList.Clear(); } int byFrameIdx = 0; /// /// 往前推进帧的,指定帧下标 /// /// public void NextFramebyFrameIdx(int FrameID, UInt64 frameInput) { TakeFrame(FrameID - byFrameIdx, frameInput); byFrameIdx = FrameID; } /// /// 往前推进1帧的Input /// /// public void NextFrame(UInt64 frameInput) { TakeFrame(1, frameInput); } /// /// 往前推进指定帧数量的Input /// /// public void TakeFrame(int addFrame, UInt64 frameInput) { if (addFrame < 0) { } mCurrFrame += addFrame; if (mCurrInput == frameInput) return; mCurrInput = frameInput; wirteStep.FrameStartID = mCurrFrame; wirteStep.InPut = mCurrInput; dbgList.Add($"{mCurrFrame} | {mCurrInput}"); switch (mFormat) { case ReplayData.ReplayFormat.FM32IP64: mBinaryWriter.Write(wirteStep.FrameStartID); mBinaryWriter.Write(wirteStep.InPut); break; case ReplayData.ReplayFormat.FM32IP32: mBinaryWriter.Write(BitConverter.GetBytes(wirteStep.All64Data), 0, 4 + 4); break; case ReplayData.ReplayFormat.FM32IP16: mBinaryWriter.Write(BitConverter.GetBytes(wirteStep.All64Data), 0, 4 + 2); break; case ReplayData.ReplayFormat.FM32IPBYTE: mBinaryWriter.Write(BitConverter.GetBytes(wirteStep.All64Data), 0, 4 + 1); break; } } public void SaveData(string path, bool bWithDump = false, string dumppath = null) { ReplayData.GetStringByteData(mTitle, out byte[] titleData, out int titleLenghtWithEnd, TexEncoding); ReplayData.GetStringByteData(mNote, out byte[] noteData, out int noteLenghtWithEnd, TexEncoding); ReplayHandler handler = new ReplayHandler(); handler.Format = (int)this.mFormat; handler.DataOffset = ReplayData.HandlerLenght; handler.CreateTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); handler.AllFrame = wirteStep.FrameStartID; handler.SingleLenght = mSingleDataLenght; using (FileStream fs = new FileStream(path, FileMode.Create)) { using (BinaryWriter bw = new BinaryWriter(fs)) { //写入Handler bw.Write(ReplayData.GetHandlerData(handler)); //写入Data bw.Write(mStream.ToArray()); } } if (bWithDump) { List temp = new List(); temp.Add($"Format => {handler.Format}"); temp.Add($"DataOffset => {handler.DataOffset}"); temp.Add($"CreateTime => {handler.CreateTime}"); temp.Add($"AllFrame => {handler.AllFrame}"); temp.Add($"SingleLenght => {handler.SingleLenght}"); dbgList.InsertRange(0, temp); File.WriteAllLines(dumppath, dbgList); } } public void Dispose() { mStream.Dispose(); mBinaryWriter.Dispose(); //TODO } } }