123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- using CommonLang.IO;
- using System;
- using System.Collections.Generic;
- using System.IO;
- namespace CommonAI.Zone.Replay
- {
- public class BattleRecordData
- {
- public const string VERSION_1_0 = "1.0.0";
- public readonly static uint HEAD = BitConverter.ToUInt32(new byte[] { (byte)'B', (byte)'R', (byte)'E', (byte)'C' }, 0);
- public string Name;
- public string Desc;
- public int SceneID;
- public DateTime Time = DateTime.Now;
- public string Version = VERSION_1_0;
- public string ResVersion;
- public LinkedList<EventLog> Events = new LinkedList<EventLog>();
- public class EventLog
- {
- public long PassTimeMS;
- public Event EventData;
- }
- public static void EncodeHead(OutputStream output, BattleRecordData data)
- {
- output.PutU32(BattleRecordData.HEAD);
- output.PutUTF(data.Name);
- output.PutUTF(data.Desc);
- output.PutS64(data.Time.ToBinary());
- output.PutUTF(data.Version);
- output.PutS32(data.SceneID);
- output.PutUTF(data.ResVersion);
- }
- public static bool DecodeHead(InputStream input, BattleRecordData data)
- {
- uint head = input.GetU32();
- if (head == HEAD)
- {
- data.Name = input.GetUTF();
- data.Desc = input.GetUTF();
- data.Time = DateTime.FromBinary(input.GetS64());
- data.Version = input.GetUTF();
- data.SceneID = input.GetS32();
- data.ResVersion = input.GetUTF();
- return true;
- }
- return false;
- }
- public static void EncodeLog(TemplateManager templates, OutputStream output, EventLog log)
- {
- if (log.EventData is BattleMessage)
- {
- (log.EventData as BattleMessage).BeforeWrite(templates);
- }
- output.PutS64(log.PassTimeMS);
- output.PutExt(log.EventData);
- }
- public static void DecodeLog(TemplateManager templates, InputStream input, EventLog log)
- {
- log.PassTimeMS = input.GetS64();
- log.EventData = (Event)input.GetExtAny();
- if (log.EventData is BattleMessage)
- {
- (log.EventData as BattleMessage).EndRead(templates);
- }
- }
- public static void EncodeToStream(TemplateManager templates, Stream stream, BattleRecordData data)
- {
- OutputStream output = new OutputStream(stream, TemplateManager.MessageCodec);
- EncodeHead(output, data);
- foreach (BattleRecordData.EventLog log in data.Events)
- {
- EncodeLog(templates, output, log);
- }
- }
- public static bool DecodeFromStream(TemplateManager templates, Stream stream, out BattleRecordData ret)
- {
- InputStream input = new InputStream(stream, TemplateManager.MessageCodec);
- ret = new BattleRecordData();
- if (DecodeHead(input, ret))
- {
- while (stream.CanRead)
- {
- try
- {
- BattleRecordData.EventLog log = new BattleRecordData.EventLog();
- DecodeLog(templates, input, log);
- ret.Events.AddLast(log);
- }
- catch (Exception err)
- {
- Console.WriteLine("UnitBooleanAttribute : " + templates.ToString() + ", catch: " + err);
- break;
- }
- }
- return true;
- }
- ret = null;
- return false;
- }
- public static byte[] ToBinary(TemplateManager templates, BattleRecordData data)
- {
- byte[] ret;
- using (MemoryStream ms = new MemoryStream())
- {
- EncodeToStream(templates, ms, data);
- ret = new byte[ms.Length];
- Array.Copy(ms.GetBuffer(), ret, ret.Length);
- }
- return ret;
- }
- public static BattleRecordData FromBinary(TemplateManager templates, byte[] data)
- {
- BattleRecordData ret = null;
- using (MemoryStream ms = new MemoryStream(data))
- {
- DecodeFromStream(templates, ms, out ret);
- }
- return ret;
- }
- }
- public class BattleRecorder
- {
- public int SceneID { get; private set; }
- public string Name { get; set; }
- public string Desc { get; set; }
- public DateTime Time { get; set; }
- public string ResVersion { get; private set; }
- private bool mIsRunning = false;
- private OutputStream mStream;
- private MemoryStream mDefaultStream;
- private Stream mCurrentStream;
- private TemplateManager mTemplates;
- public BattleRecorder(TemplateManager templates, int sceneID, string name)
- {
- this.mTemplates = templates;
- this.SceneID = sceneID;
- this.Name = name;
- this.Desc = "";
- this.Time = DateTime.Now;
- this.ResVersion = templates.ResourceVersion;
- this.mDefaultStream = new MemoryStream();
- this.mStream = new OutputStream(mDefaultStream, TemplateManager.MessageCodec);
- SetOut(mDefaultStream);
- }
- public void SetOut(Stream stream)
- {
- mCurrentStream = stream;
- mStream.SetStream(stream);
- }
- public void Record(Event evt, long passTimeMS)
- {
- if (mIsRunning == false)
- {
- mIsRunning = true;
- BattleRecordData data = new BattleRecordData();
- data.Name = this.Name;
- data.Desc = this.Desc;
- data.Time = this.Time;
- data.SceneID = this.SceneID;
- data.ResVersion = this.ResVersion;
- BattleRecordData.EncodeHead(mStream, data);
- }
- BattleRecordData.EventLog log = new BattleRecordData.EventLog();
- log.PassTimeMS = passTimeMS;
- log.EventData = evt;
- BattleRecordData.EncodeLog(mTemplates, mStream, log);
- }
- public byte[] ToBinary()
- {
- if (mDefaultStream == mCurrentStream)
- {
- byte[] data = new byte[mDefaultStream.Position];
- Array.Copy(mDefaultStream.GetBuffer(), data, data.Length);
- return data;
- }
- else if (mCurrentStream is MemoryStream)
- {
- byte[] data = new byte[mCurrentStream.Position];
- Array.Copy((mCurrentStream as MemoryStream).GetBuffer(), data, data.Length);
- return data;
- }
- return null;
- }
- }
- public interface IBattleRecordListener
- {
- void onEventHandler(Event evt);
- }
- public class BattleRecordPlayer : IDisposable
- {
- public int SceneID { get; private set; }
- public string Name { get; private set; }
- public string Desc { get; private set; }
- public DateTime Time { get; private set; }
- public string Version { get; private set; }
- public string ResVersion { get; private set; }
- public TemplateManager Templates { get; private set; }
- public BattleRecordPlayer(TemplateManager templates, Stream data)
- {
- this.Templates = templates;
- this.mStream = data;
- this.mInput = new InputStream(data, TemplateManager.MessageCodec);
- BattleRecordData hd = new BattleRecordData();
- if (BattleRecordData.DecodeHead(mInput, hd))
- {
- this.Name = hd.Name;
- this.Desc = hd.Desc;
- this.Time = hd.Time;
- this.Version = hd.Version;
- this.SceneID = hd.SceneID;
- this.ResVersion = hd.ResVersion;
- }
- else { throw new Exception("Error - 数据不包含战报文件头 BattleRecordData.HEAD !"); }
- }
- public BattleRecordPlayer(TemplateManager templates, BattleRecordData data)
- {
- this.Templates = templates;
- this.mData = data;
- this.mLogs = new Queue<BattleRecordData.EventLog>(data.Events);
- {
- this.Name = data.Name;
- this.Desc = data.Desc;
- this.Time = data.Time;
- this.Version = data.Version;
- this.SceneID = data.SceneID;
- this.ResVersion = data.ResVersion;
- }
- }
- public void Dispose()
- {
- mData = null;
- mListener = null;
- Templates = null;
- mWaittingEvent = null;
- mLogs.Clear();
- }
- public bool IsDone { get { return mIsDone; } }
- private IBattleRecordListener mListener;
- private BattleRecordData mData;
- private Queue<BattleRecordData.EventLog> mLogs;
- private Stream mStream;
- private InputStream mInput;
- private BattleRecordData.EventLog mWaittingEvent;
- private long mPassTime;
- private bool mIsDone = false;
- private bool mIsRunning = false;
- public void Start(IBattleRecordListener listener)
- {
- if (mIsDone) return;
- if (!mIsRunning)
- {
- this.mListener = listener;
- this.mIsDone = false;
- this.mPassTime = 0;
- this.mIsRunning = true;
- }
- }
- public void Update(int intervalMS)
- {
- if (mIsRunning)
- {
- mPassTime += intervalMS;
- while (true)
- {
- if (mWaittingEvent == null)
- {
- mWaittingEvent = PickNextLog();
- }
- if (mWaittingEvent != null)
- {
- if (mWaittingEvent.PassTimeMS <= mPassTime)
- {
- mListener.onEventHandler(mWaittingEvent.EventData);
- mWaittingEvent = PickNextLog();
- continue;
- }
- else
- {
- break;
- }
- }
- else
- {
- mIsDone = true;
- mIsRunning = false;
- break;
- }
- }
- }
- }
- private BattleRecordData.EventLog PickNextLog()
- {
- if (mData != null)
- {
- if (mLogs.Count > 0)
- {
- return mLogs.Dequeue();
- }
- }
- else if (mStream != null)
- {
- try
- {
- BattleRecordData.EventLog log = new BattleRecordData.EventLog();
- if (mStream.CanRead)
- {
- BattleRecordData.DecodeLog(Templates, mInput, log);
- return log;
- }
- }
- catch (Exception err)
- {
- Console.WriteLine("PickNextLog catch: " + err);
- }
- }
- return null;
- }
- }
- }
|