using System; using System.Collections.Concurrent; using System.IO; using System.Text; using System.Threading; using MrWu.Debug; using Server.Core; using Server.DB.Redis; namespace GameDAL.FriendRoom { public class FightDataManager : SingleInstance { private Thread thead; private bool IsDispose = false; private const string dirPath = "fightData"; private ConcurrentQueue CommandQueue = new ConcurrentQueue(); public FightDataManager() { if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } thead = new Thread(Run); thead.Start(); } private string OldFileName(string weiyima) { return $"{dirPath}/{weiyima}"; } private string NewFileName(string weiyima) { return $"{dirPath}/{weiyima}.bytes"; } private string TempFileName(string weiyima) { return $"{dirPath}/{weiyima}.temp"; } public byte[] LoadFightData(string weiyima,out bool isOld) { byte[] result = null; try { isOld = false; string fileName = NewFileName(weiyima); if (File.Exists(fileName)) { result = File.ReadAllBytes(fileName); Debug.Info("加载战斗数据!" + weiyima); }else { //旧文件 fileName = OldFileName(weiyima); if (File.Exists(fileName)) { string jsonData = File.ReadAllText(fileName); isOld = true; return Encoding.UTF8.GetBytes(jsonData); } } } catch (Exception e) { Debug.Error($"读取战绩还能报错?? {e.Message}"); throw; } return result; } public void SaveFightData(string weiyima,byte[] data) { CommandQueue.Enqueue(FightDataCommand.Create(Command.Save, weiyima, data)); } public void DelFightData(string weiyima) { CommandQueue.Enqueue(FightDataCommand.Create(Command.Del, weiyima)); } private void Run() { #if DEBUG uint threadId = ThreadHelper.GetOSThreadId(); Debug.Info($"ThreadStart FightDataManager {threadId}"); #endif while (true) { if (CommandQueue.TryDequeue(out FightDataCommand command)) { try { string fileName = NewFileName(command.WeiYiMa); string tempFileName = TempFileName(command.WeiYiMa); switch (command.Command) { case Command.Save: //保证文件的原子性,存到临时文件,再移动到正式文件 File.WriteAllBytes(tempFileName,command.Data); if (File.Exists(fileName)) { File.Delete(fileName); } File.Move(tempFileName,fileName); break; case Command.Del: File.Delete(fileName); break; } } catch (Exception e) { Debug.Error($"执行战斗数据指令报错:{command.Command} {command.WeiYiMa} {e.Message}"); } ReferencePool.Recycle(command); } else { //如果关闭了,就退出 if (IsDispose) { break; } } Thread.Sleep(1); } } public void Dispose() { IsDispose = true; thead.Join(); } public class FightDataCommand : Reference { public string WeiYiMa; public byte[] Data; public Command Command; public static FightDataCommand Create(Command command,string weiyima,byte[] data= null) { FightDataCommand fightDataCommand = ReferencePool.Fetch(); fightDataCommand.WeiYiMa = weiyima; fightDataCommand.Data = data; fightDataCommand.Command = command; return fightDataCommand; } public override void Dispose() { WeiYiMa = null; Data = null; ReferencePool.Recycle(this); } } public enum Command { /// /// 保存 /// Save, /// /// 加载 /// Del, } } }