-- 此脚本只是给同步玩法使用 local SaveSyncBattleInfoManager = {} --- 记录一个玩法的帧命令 。在stopLevel 向本地保存文件(同步玩法使用) local private = { CmdB2CFramePBInfos = nil -- 所有的帧数据集合 } local replay_pb = require('Proto/fair_play_replay_pb') local battle_common_pb = require 'Proto/battle_common_pb' local common_pb = require 'Proto/common_pb' local FrameFileDirPath = LuaConst.SaveReplayFileDirPath --region 本地保存 -- initMsg : G2CInitFubenInfo function SaveSyncBattleInfoManager.Init(initFubenMsg) local levelId = initFubenMsg.mapCfgId local levelInfoData = DataSheetManager.LevelInfoData:GetDataByLevelID(levelId) if not LevelManager.NeedSaveFrameDatasLevel(levelInfoData.LevelType) then return end private.CmdB2CFramePBInfos = replay_pb.CmdB2CFramePBInfos() private.CreateInitBattleMsg(initFubenMsg) end -- 重新组织初始化数据 function private.CreateInitBattleMsg(initFubenMsg) local initMsg = battle_common_pb.ForCheckBattleAllInfo() initMsg.isClientReplay = true initMsg.BRoomID = initFubenMsg.battleRoomId initMsg.mapInfo.MapCfgId = initFubenMsg.mapCfgId initMsg.mapInfo.SceneType = initFubenMsg.sceneType initMsg.mapInfo.GotoType = initFubenMsg.gotoType for _,playerInfo in ipairs(initFubenMsg.roleList) do local newPlayerInfo = battle_common_pb.ForCheckPlayerInfo() local bytes = playerInfo:SerializeToString() newPlayerInfo.roleInfo:ParseFromString(bytes) table.insert(initMsg.playerInfo, newPlayerInfo) end initMsg.clientIntermediateParams = initFubenMsg.clientIntermediateParams initMsg.serverLevel = initFubenMsg.serverLevel initMsg.randomSeed = initFubenMsg.randomSeed initMsg.hasNext = initFubenMsg.hasNext initMsg.cartPos.X = initFubenMsg.cartPos.X initMsg.cartPos.Y = initFubenMsg.cartPos.Y initMsg.cartPos.Z = initFubenMsg.cartPos.Z initMsg.cartDir.X = initFubenMsg.cartDir.X initMsg.cartDir.Z = initFubenMsg.cartDir.Z initMsg.newBattleInfo.matchStage = initFubenMsg.battleInfo.matchStage initMsg.newBattleInfo.serverFightScore = initFubenMsg.battleInfo.serverFightScore for i,v in ipairs(initFubenMsg.battleInfo.switchInGMS) do local newSwitchInfo = common_pb.SwitchInfo() newSwitchInfo.SwitchType = v.SwitchType newSwitchInfo.SwitchState = v.SwitchState newSwitchInfo.SwitchChannel = v.SwitchChannel table.insert(initMsg.newBattleInfo.switchInGMS, v) end for i,v in ipairs(initFubenMsg.battleInfo.attrInfos) do table.insert(initMsg.newBattleInfo.attrInfos, v) end private.ForCheckBattleAllInfoMsg = initMsg end -- 保存到游戏运行时内存中 function SaveSyncBattleInfoManager.TrySaveB2CFrame(frameNum, playerIds, frameDatas ) if not LevelManager.NeedSaveFrameDatasLevel() then return end if not private.CmdB2CFramePBInfos then return end local cmdB2CFramePB = replay_pb.CmdB2CFramePB() cmdB2CFramePB.FrameNum = frameNum for i,playerId in ipairs(playerIds) do table.insert(cmdB2CFramePB.OnlinePlayers, playerId) end if GameAppInfo.IsVersionGreaterThan113100() then local frameCount = #frameDatas / 8 for j = 1, frameCount do -- frameDatas = { 1-8,9-16, }每8个是一个cmd local playerFrameDataPB = replay_pb.PlayerFrameDataPB() local index = (j - 1) * 8 playerFrameDataPB.PlayerId = frameDatas[index + 1] playerFrameDataPB.data.SkillIdx = frameDatas[index + 2] playerFrameDataPB.data.MoveType = frameDatas[index + 3] playerFrameDataPB.data.DirAngleMulTen = frameDatas[index + 4] playerFrameDataPB.data.Spec = frameDatas[index + 5] playerFrameDataPB.data.UseJoystick = frameDatas[index + 6] playerFrameDataPB.data.SkillJoystickPosX = frameDatas[index + 7] playerFrameDataPB.data.SkillJoystickPosZ = frameDatas[index + 8] table.insert(cmdB2CFramePB.PlayerFrameDatas, playerFrameDataPB) end else for j,data in ipairs(frameDatas) do local playerFrameDataPB = replay_pb.PlayerFrameDataPB() playerFrameDataPB.PlayerId = data[1] playerFrameDataPB.data.SkillIdx = data[2] playerFrameDataPB.data.MoveType = data[3] playerFrameDataPB.data.DirAngleMulTen = data[4] playerFrameDataPB.data.Spec = data[5] playerFrameDataPB.data.UseJoystick = data[6] playerFrameDataPB.data.SkillJoystickPosX = data[7] playerFrameDataPB.data.SkillJoystickPosZ = data[8] table.insert(cmdB2CFramePB.PlayerFrameDatas, playerFrameDataPB) end end table.insert(private.CmdB2CFramePBInfos.frames, cmdB2CFramePB) --print(#private.CmdB2CFramePBInfos) end -- 关卡结算的时候,写入到磁盘 function SaveSyncBattleInfoManager.WriteToFile() if not LevelManager.NeedSaveFrameDatasLevel() then private.CmdB2CFramePBInfos = nil return end if private.CmdB2CFramePBInfos then if not LuaExt.DirectoryExists(FrameFileDirPath) then LuaExt.DirectoryCreate(FrameFileDirPath) end local frameBytes = private.CmdB2CFramePBInfos:SerializeToString() private.ForCheckBattleAllInfoMsg.battleInfo = frameBytes local connectInfo = MultiplayManager.GetKCPConnectInfo() private.ForCheckBattleAllInfoMsg.GRoomID = connectInfo.gRoomId local bytes = private.ForCheckBattleAllInfoMsg:SerializeToString() local filePath = SaveSyncBattleInfoManager.GetFilePath(connectInfo.gRoomId) LuaExt.FileWriteBytes(filePath, false, bytes) private.CmdB2CFramePBInfos = nil BIManager.DispatchBIClientEvent(BIManager.EventName.SaveSyncLevelFrameDatas, "filePath", filePath) end end -- 获取文件路径 function SaveSyncBattleInfoManager.GetFilePath(markStr) return FrameFileDirPath .. markStr end --endregion --region 用文件中的数据组织出帧领命数据 function SaveSyncBattleInfoManager.GetFrameDatasFromBytes(dataBytes) local msg = replay_pb.CmdB2CFramePBInfos() msg:ParseFromString(dataBytes) local frames = msg.frames local maxFrame = 0 for _, frame in ipairs(frames) do local playerFrameDatas = frame.PlayerFrameDatas local frameDatas = {} for _, playerFrame in ipairs(playerFrameDatas) do if GameAppInfo.IsVersionGreaterThan113100() then table.insert(frameDatas, playerFrame.PlayerId) table.insert(frameDatas, playerFrame.data.SkillIdx) table.insert(frameDatas, playerFrame.data.MoveType) table.insert(frameDatas, playerFrame.data.DirAngleMulTen) table.insert(frameDatas, playerFrame.data.Spec) table.insert(frameDatas, playerFrame.data.UseJoystick) table.insert(frameDatas, playerFrame.data.SkillJoystickPosX) table.insert(frameDatas, playerFrame.data.SkillJoystickPosZ) else table.insert(frameDatas,{playerFrame.PlayerId, playerFrame.data.SkillIdx, playerFrame.data.MoveType, playerFrame.data.DirAngleMulTen, playerFrame.data.Spec, playerFrame.data.UseJoystick, playerFrame.data.SkillJoystickPosX, playerFrame.data.SkillJoystickPosZ}) end end if frame.FrameNum > maxFrame then maxFrame = frame.FrameNum --print(maxFrame) end local onlinePlayers if GameAppInfo.IsVersionGreaterThan113100() then frameDatas[0] = #frameDatas onlinePlayers = {} for k,v in ipairs(frame.OnlinePlayers) do onlinePlayers[k] = v end onlinePlayers[0] = #frame.OnlinePlayers else onlinePlayers = frame.OnlinePlayers end KCPTransport.SetCmdByFrameFile(frame.FrameNum, onlinePlayers, frameDatas) end LogicUpdateManager.GetFrameDataFromFile(maxFrame) -- 用上面的数据,塞入到tick队里中 end --endregion return SaveSyncBattleInfoManager