--[[ 使用说明: 这个存档操作文件是为了将存档抽象出来。 注册该操作文件后,可以自动注册需要同步的存档变量到GameState. 注册时也会注册OnRep函数,为的是当服务器修改了需要同步的存档后,同步信息到客户端发送修改的通知事件。 配置方法: ArchiveDataConfig: 设置玩家登录的绑定事件: ArchiveDataConfig.PlayerLoginEvent 设置存档类型: EArchiveType 存档变量名: ArchiveParamName 需要同步的存档类型: ReplicatedProperties GameState: BeginPlay添加 ArchiveDataConfig.Register(self) GetReplicatedProperties的return添加 ArchiveDataConfig.GetAllReplicatedPropertiesName() API使用: -- 获取玩家存档信息,若没有该存档则返回nil ArchiveDataConfig.GetPlayerArchiveDataFromType(PlayerKey, InArchiveType) -- 保存玩家存档信息 ArchiveDataConfig.SavePlayerArchiveData(PlayerKey, InArchiveType, Data) -- 绑定存档改变的事件 UGCEventSystem.AddListener(ArchiveDataConfig.GetParamNotifyEvent(EArchiveType), Func, Obj) ]] ArchiveDataConfig = ArchiveDataConfig or {} -- 玩家登录的事件 ArchiveDataConfig.PlayerLoginEvent = EventEnum.PlayerLogin -- 存储的类型 ArchiveDataConfig.EArchiveType = { NumberOfPlays = 1; -- 游玩次数 SavedMap = 2; -- 保存的地图 table {MapName, MapCode} UnsavedPlacement = 3; -- 未保存的放置 SelectMapIndex = 4; -- 选中游玩的地图索引,若为0则为默认地图,1~6则为自己所保存的地图 Exp = 5; -- 玩家的经验 Gold = 6; -- 玩家的金币数 GoldBrick = 7; -- 玩家拥有的金砖数量 ItemIncrement = 8; -- 可放置物的增加的数量 {[EPlaceItemType] = uint;} DailyTasks = 9; -- 每日任务 DailyTasksUpdateDay = 10; -- 上次刷新每日任务的时间 Like = 11; -- 玩家点赞数 } -- 变量命名 ArchiveDataConfig.ArchiveParamName = { [ArchiveDataConfig.EArchiveType.NumberOfPlays] = "NumberOfPlays"; [ArchiveDataConfig.EArchiveType.SavedMap] = "SavedMap"; [ArchiveDataConfig.EArchiveType.UnsavedPlacement] = "UnsavedPlacement"; [ArchiveDataConfig.EArchiveType.SelectMapIndex] = "SelectMapIndex"; [ArchiveDataConfig.EArchiveType.Exp] = "Exp"; [ArchiveDataConfig.EArchiveType.Gold] = "Gold"; [ArchiveDataConfig.EArchiveType.GoldBrick] = "GoldBrick"; [ArchiveDataConfig.EArchiveType.ItemIncrement] = "ItemIncrement"; [ArchiveDataConfig.EArchiveType.DailyTasks] = "DailyTasks"; [ArchiveDataConfig.EArchiveType.DailyTasksUpdateDay]= "DailyTasksUpdateDay"; [ArchiveDataConfig.EArchiveType.Like] = "Like"; } -- 需要进行客户端同步的参数 ArchiveDataConfig.ReplicatedProperties = { ArchiveDataConfig.EArchiveType.NumberOfPlays; ArchiveDataConfig.EArchiveType.SavedMap; ArchiveDataConfig.EArchiveType.SelectMapIndex; ArchiveDataConfig.EArchiveType.Exp; ArchiveDataConfig.EArchiveType.Gold; ArchiveDataConfig.EArchiveType.GoldBrick; ArchiveDataConfig.EArchiveType.ItemIncrement; ArchiveDataConfig.EArchiveType.DailyTasks; ArchiveDataConfig.EArchiveType.Like; } -- 客户端同步参数的后缀 ArchiveDataConfig.ReplicatedPropertiesListSuffix = "List" -- 生成通知事件的类型区间,生成的事件为 ParamNotifyEventRange + EArchiveType ArchiveDataConfig.ParamNotifyEventRange = -10000 -- 设置到GameState的存储Data名字 ArchiveDataConfig.SavePlayerArchiveDataName = "SavePlayerArchiveData" ArchiveDataConfig.GameState = nil --- GameState注册 function ArchiveDataConfig.Register(InGameState) UGCLogSystem.Log("[ArchiveDataConfig_Register] Start") ArchiveDataConfig.GameState = InGameState if UGCGameSystem.IsServer() then -- 注册参数 ArchiveDataConfig.RegisterParam(InGameState) UGCEventSystem.AddListener(ArchiveDataConfig.PlayerLoginEvent, ArchiveDataConfig.UpdatePlayerArchiveData) InGameState[ArchiveDataConfig.SavePlayerArchiveDataName] = function(GameState, PlayerKey, InArchiveType, Data) ArchiveDataConfig.SavePlayerArchiveData(PlayerKey, InArchiveType, Data) end else -- 注册OnRep函数 ArchiveDataConfig.RegisterReplicatedProperties(InGameState) end UGCLogSystem.Log("[ArchiveDataConfig_Register] Finish") end function ArchiveDataConfig.GetGameState() if ArchiveDataConfig.GameState then return ArchiveDataConfig.GameState else return UGCGameSystem.GameState end end --- 通过类型获取同步的参数名 function ArchiveDataConfig.GetParamListName(InArchiveType) if ArchiveDataConfig.ArchiveParamName[InArchiveType] then local ParamName = ArchiveDataConfig.ArchiveParamName[InArchiveType] .. ArchiveDataConfig.ReplicatedPropertiesListSuffix -- UGCLogSystem.Log("[ArchiveDataConfig_GetParamListName] ParamName:%s", tostring(ParamName)) return ParamName else UGCLogSystem.LogError("[ArchiveDataConfig_GetParamListName] ArchiveParamName[%s] is nil", tostring(InArchiveType)) return nil end end --- 获取所有同步的参数名 function ArchiveDataConfig.GetAllReplicatedPropertiesName() local ResName = {} for i, v in pairs(ArchiveDataConfig.ReplicatedProperties) do ResName[#ResName + 1] = ArchiveDataConfig.GetParamListName(v) end return table.unpack(ResName) end --- 获取参数更新的通知事件 function ArchiveDataConfig.GetParamNotifyEvent(InArchiveType) return InArchiveType + ArchiveDataConfig.ParamNotifyEventRange end --- 获取OnRep函数名 function ArchiveDataConfig.GetOnRepFunctionName(InArchiveType) return "OnRep_" .. ArchiveDataConfig.GetParamListName(InArchiveType) end --- 注册参数到GameState function ArchiveDataConfig.RegisterParam(InGameState) for i, ArchiveType in pairs(ArchiveDataConfig.EArchiveType) do InGameState[ArchiveDataConfig.GetParamListName(ArchiveType)] = {} end end --- Client --- 注册OnRep函数 function ArchiveDataConfig.RegisterReplicatedProperties(InGameState) for i, ArchiveType in pairs(ArchiveDataConfig.ReplicatedProperties) do InGameState[ArchiveDataConfig.GetOnRepFunctionName(ArchiveType)] = function(GameState) UGCLogSystem.Log("[ArchiveDataConfig_RegisterReplicatedProperties] ArchiveType:%s", tostring(ArchiveType)) UGCEventSystem.SendEvent(ArchiveDataConfig.GetParamNotifyEvent(ArchiveType)) end end end --- 同步新加入的玩家的存档到GameState function ArchiveDataConfig.UpdatePlayerArchiveData(PlayerPawn, InPlayerKey) UGCLogSystem.Log("[ArchiveDataConfig_UpdatePlayerArchiveData] InPlayerKey:%s", tostring(InPlayerKey)) local PlayerAccountInfo = UGCPlayerStateSystem.GetPlayerAccountInfo(InPlayerKey) if PlayerAccountInfo then local UID = PlayerAccountInfo.UID -- Test -- UGCPlayerStateSystem.SavePlayerArchiveData(UID, {[2] = {[1] = 3, [16] = 3}}) local ArchiveData = UGCPlayerStateSystem.GetPlayerArchiveData(UID) if ArchiveData then for i, ArchiveType in pairs(ArchiveDataConfig.EArchiveType) do if ArchiveData[ArchiveType] then ArchiveDataConfig.SetPlayerArchiveParam(InPlayerKey, ArchiveType, ArchiveData[ArchiveType]) end end end UGCLogSystem.LogTree("[ArchiveDataConfig_UpdatePlayerArchiveData] ArchiveData:", ArchiveData) end end --- Server or Client --- 获取玩家存档参数 function ArchiveDataConfig.GetPlayerArchiveDataFromType(PlayerKey, InArchiveType) local ParamList = ArchiveDataConfig.GetGameState()[ArchiveDataConfig.GetParamListName(InArchiveType)] if ParamList then return ParamList[PlayerKey] end return nil end --- Server --- 设置玩家存档参数到GameState,但不保存 function ArchiveDataConfig.SetPlayerArchiveParam(PlayerKey, InArchiveType, InArchiveDate) if ArchiveDataConfig.GetGameState()[ArchiveDataConfig.GetParamListName(InArchiveType)] == nil then ArchiveDataConfig.GetGameState()[ArchiveDataConfig.GetParamListName(InArchiveType)] = {} end ArchiveDataConfig.GetGameState()[ArchiveDataConfig.GetParamListName(InArchiveType)][PlayerKey] = InArchiveDate end --- Server --- 更新玩家存档信息,保存并同步 function ArchiveDataConfig.SavePlayerArchiveData(PlayerKey, InArchiveType, Data) local PlayerAccountInfo = UGCPlayerStateSystem.GetPlayerAccountInfo(PlayerKey) if PlayerAccountInfo then local UID = PlayerAccountInfo.UID UGCLogSystem.Log("[ArchiveDataConfig_SavePlayerArchiveData] UID:%s", tostring(UID)) local ArchiveData = UGCPlayerStateSystem.GetPlayerArchiveData(UID) -- UGCLogSystem.LogTree("[ArchiveDataConfig_SavePlayerArchiveData]ArchiveData:", ArchiveData) if ArchiveData == nil then ArchiveData = {} end ArchiveData[InArchiveType] = Data -- GameState同步设置新存档信息 ArchiveDataConfig.SetPlayerArchiveParam(PlayerKey, InArchiveType, Data) -- 保存存档 local SavedSucceed = UGCPlayerStateSystem.SavePlayerArchiveData(UID, ArchiveData) -- 发送修改存档通知事件 UGCEventSystem.SendEvent(ArchiveDataConfig.GetParamNotifyEvent(InArchiveType)) ArchiveData = UGCPlayerStateSystem.GetPlayerArchiveData(UID) UGCLogSystem.LogTree("[ArchiveDataConfig_SavePlayerArchiveData]SavedSucceed:" .. tostring(SavedSucceed), ArchiveData) return true end return false end --- Debug Server --- 清除玩家存档信息,保存并同步 function ArchiveDataConfig.ClearPlayerArchiveData(PlayerKey) if GlobalConfigs.IsDebug then for i, v in pairs(ArchiveDataConfig.EArchiveType) do ArchiveDataConfig.SavePlayerArchiveData(PlayerKey, v, nil) end end end