完善Replay fixedbug

This commit is contained in:
sin365 2025-01-16 18:31:34 +08:00
parent e31cd7174c
commit 9098ecb797
6 changed files with 336 additions and 148 deletions

11
IReplayReader.cs Normal file
View File

@ -0,0 +1,11 @@
using System;
namespace AxiReplay
{
internal interface IReplayReader : IDisposable
{
bool NextFrame(out ReplayStep data);
bool TakeFrame(int addFrame, out ReplayStep data);
bool NextFramebyFrameIdx(int FrameID, out ReplayStep data);
}
}

12
IReplayWriter.cs Normal file
View File

@ -0,0 +1,12 @@
using System;
namespace AxiReplay
{
internal interface IReplayWriter : IDisposable
{
void NextFrame(UInt64 frameInput);
void NextFramebyFrameIdx(int FrameID, UInt64 frameInput);
void TakeFrame(int addFrame, UInt64 frameInput);
void SaveData(string path, bool bNeedDump = false, string dumpFilePath = null);
}
}

147
NetReplay.cs Normal file
View File

@ -0,0 +1,147 @@
using System.Collections.Generic;
namespace AxiReplay
{
public class NetReplay
{
/// <summary>
/// 客户端当前帧
/// </summary>
public int mCurrClientFrameIdx = 0;
/// <summary>
/// 服务器远端当前帧
/// </summary>
public int mRemoteFrameIdx { get; private set; }
/// <summary>
/// 服务器远端当前提前量
/// </summary>
public int mRemoteForwardCount { get; private set; }
/// <summary>
/// Remote 2 Client Frame Gap
/// </summary>
public int mDiffFrameCount => mRemoteFrameIdx - mCurrClientFrameIdx;
/// <summary>
/// 网络数据队列
/// </summary>
Queue<ReplayStep> mNetReplayQueue = new Queue<ReplayStep>();
/// <summary>
/// 当前数据
/// </summary>
ReplayStep mCurrReplay;
/// <summary>
/// 下一个数据数据
/// </summary>
ReplayStep mNextReplay;
bool bNetInit = false;
public NetReplay()
{
ResetData();
}
public void ResetData()
{
mNetReplayQueue.Clear();
mCurrReplay = default(ReplayStep);
mCurrReplay.FrameStartID = int.MinValue;
bNetInit = false;
}
public void InData(ReplayStep inputData, int ServerFrameIdx)
{
mNetReplayQueue.Enqueue(inputData);
mRemoteFrameIdx = inputData.FrameStartID;
if (!bNetInit)
{
bNetInit = true;
mNextReplay = mNetReplayQueue.Dequeue();
}
}
public bool TryGetNextFrame(out ReplayStep data, out int frameDiff, out bool inputDiff)
{
if (!bNetInit)
{
data = default(ReplayStep);
frameDiff = default(int);
inputDiff = false;
return false;
}
TakeFrame(1, out data, out frameDiff, out inputDiff);
return frameDiff > 0;
}
public bool TryGetNextFrame(int targetFrame, out ReplayStep data, out int frameDiff, out bool inputDiff)
{
if (!bNetInit)
{
data = default(ReplayStep);
frameDiff = default(int);
inputDiff = false;
return false;
}
return TakeFrameToTargetFrame(targetFrame, out data, out frameDiff, out inputDiff);
}
void TakeFrame(int addFrame, out ReplayStep data, out int bFrameDiff, out bool inputDiff)
{
int targetFrame = mCurrClientFrameIdx + addFrame;
TakeFrameToTargetFrame(targetFrame, out data, out bFrameDiff, out inputDiff);
}
bool TakeFrameToTargetFrame(int targetFrame, out ReplayStep data, out int bFrameDiff, out bool inputDiff)
{
bool result;
inputDiff = false;
if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count > 0)
{
//当前帧追加
mCurrClientFrameIdx = targetFrame;
ulong oldInput = mCurrReplay.InPut;
mCurrReplay = mNextReplay;
if (oldInput != mCurrReplay.InPut)
inputDiff = true;
mNextReplay = mNetReplayQueue.Dequeue();
result = true;
}
else
result = false;
bFrameDiff = mRemoteFrameIdx - mCurrClientFrameIdx;
data = mCurrReplay;
return result;
}
public int GetSkipFrameCount()
{
if(!bNetInit)
return 0;
//本地队列差异高于服务器提前量的值
int moreNum = mDiffFrameCount - mRemoteForwardCount;
//if (mDiffFrameCount < 0 || mDiffFrameCount > 10000)
// return 0;
////游戏刚开始的一小段时间,直接追满
//if (mCurrClientFrameIdx < 60)
// return moreNum;
int skip = 0;
if (mDiffFrameCount > short.MaxValue) skip = 0;
else if (moreNum <= 1) skip = 0;
else if (moreNum <= 3) skip = 2;
else if (moreNum <= 6) skip = 2;
else if (moreNum <= 20) skip = moreNum / 2; //20帧以内平滑跳帧数
else skip = moreNum;//完全追上
return skip;
//var frameGap = mDiffFrameCount;
//if (frameGap > 10000) return 0;
//if (frameGap <= 2) skip = 0;
//if (frameGap > 2 && frameGap < 6) skip = 1 + 1;
//else if (frameGap > 7 && frameGap < 12) skip = 2 + 1;
//else if (frameGap > 13 && frameGap < 20) skip = 3 + 1;
//else skip = frameGap - 2;
//return skip;
}
}
}

View File

@ -6,7 +6,7 @@ using static AxiReplay.ReplayData;
namespace AxiReplay
{
public class ReplayReader : IDisposable
public class ReplayReader : IReplayReader
{
public ReplayData.ReplayFormat mFormat { get; private set; }
public Encoding TexEncoding { get; private set; }
@ -21,10 +21,10 @@ namespace AxiReplay
FileStream mStream;
BinaryReader mBinaryReader;
int mCurrFrame = -1;
int mCurrFrame = 0;
byte[] mNextOutbytes;
ReplayStep currStep;
ReplayStep nextStep;
public ReplayStep currStep;
public ReplayStep nextStep;
bool bEnd;
List<string> dbgList = new List<string>();
@ -82,8 +82,9 @@ namespace AxiReplay
void UpdateNextFrame(int targetFrame)
{
int LastNextFrameStartID = nextStep.FrameStartID;
//如果已经超过
while (targetFrame > nextStep.FrameStartID)
while (targetFrame >= nextStep.FrameStartID)
{
if (nextStep.FrameStartID >= handler.AllFrame)
{
@ -117,20 +118,17 @@ namespace AxiReplay
}
dbgList.Add($"{nextStep.FrameStartID} | {nextStep.InPut}");
//如果这次的NextStep1只推进了1帧则跳过交给下一帧判断
if (nextStep.FrameStartID - LastNextFrameStartID == 1)
{
break;
}
targetFrame++;
}
}
int byFrameIdx = 0;
/// <summary>
/// 往前推进帧的,指定帧下标
/// </summary>
public bool NextFramebyFrameIdx(int FrameID,out ReplayStep data)
{
bool res = TakeFrame(FrameID - byFrameIdx, out data);
byFrameIdx = FrameID;
return res;
}
/// <summary>
/// 往前推进1帧的Input(返回是否变化)
@ -162,6 +160,23 @@ namespace AxiReplay
return Changed;
}
int lastTest = 0;
/// <summary>
/// 往前推进帧的,指定帧下标
/// </summary>
public bool NextFramebyFrameIdx(int FrameID, out ReplayStep data)
{
lastTest = FrameID;
if (FrameID == 3360)
{
}
bool res = TakeFrame(FrameID - byFrameIdx, out data);
byFrameIdx = FrameID;
return res;
}
public void Dispose()
{
mStream.Dispose();

View File

@ -5,7 +5,7 @@ using System.Text;
namespace AxiReplay
{
public class ReplayWriter : IDisposable
public class ReplayWriter : IReplayWriter
{
public ReplayData.ReplayFormat mFormat { get; private set; }
public Encoding TexEncoding { get; private set; }
@ -44,7 +44,8 @@ namespace AxiReplay
mStream = new MemoryStream();
mBinaryWriter = new BinaryWriter(mStream);
mCurrFrame = -1;
//mCurrFrame = -1;
mCurrFrame = 0;
mCurrInput = int.MaxValue;
wirteStep = new ReplayStep();
@ -111,8 +112,10 @@ namespace AxiReplay
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);
byte[] titleData; int titleLenghtWithEnd;
ReplayData.GetStringByteData(mTitle, out titleData, out titleLenghtWithEnd, TexEncoding);
byte[] noteData; int noteLenghtWithEnd;
ReplayData.GetStringByteData(mNote, out noteData, out noteLenghtWithEnd, TexEncoding);
ReplayHandler handler = new ReplayHandler();
handler.Format = (int)this.mFormat;