local Role = class("Role", require("shared.ModelBase")) local RoleLog = import(".RoleLog") --日志相关 local RolePlugin = import(".RolePlugin") --基础功能 local RoleTimeReset = import(".RoleTimeReset") --时间重置相关 local RoleTask = import(".RoleTask") --角色任务 local RoleChangeStruct = import(".RoleChangeStruct") --角色数据额结构更改 local RolePvp = import(".RolePvp") -- pvp local RoleCross = import(".RoleCross") -- 跨服务请求相关 local RoleBattle = import(".RoleBattle") -- 跨服务请求相关 RoleLog.bind(Role) RolePlugin.bind(Role) RoleTimeReset.bind(Role) RoleTask.bind(Role) RoleChangeStruct.bind(Role) RolePvp.bind(Role) RoleCross.bind(Role) RoleBattle.bind(Role) function Role:ctor( properties ) Role.super.ctor(self, properties) self.ignoreHeartbeat = false self.dailyData = nil self.storeData = nil self.heros = {} self.runeBag = {} self.sparkBag = {} self.advData = nil self.activity = nil self._pushToken = nil self.advElChapter = tonum(redisproxy:hget("adv_season", "chapter"), globalCsv.adv_endless_default_chapter) -- 无尽模式记录的赛季对应章节 self.advOverTime = tonum(redisproxy:hget("adv_season", "overTime")) -- 无尽模式关闭时间戳 if self.advOverTime == 0 then local now = skynet.timex() if math.floor(now / (3600 * 24 * 7)) % 2 == 1 then self.advOverTime = 3600 * 24 * 7 end self.advOverTime = self.advOverTime + specMonday(now) + 3600 * 24 * 6 end self.sendMailFlag = false --发送邮件标识 end Role.schema = { id = {"number"}, uid = {"string", ""}, name = {"string", ""}, intro = {"string", ""}, headId = {"number", globalCsv.defaultHead}, sid = {"number", 0}, device = {"string", ""}, dmode = {"string", ""}, lday = {"number", 0}, banTime = {"number", 0}, banType = {"number", 0}, heartWarning = {"number", 0}, cheatCount = {"number", 0}, ltime = {"number", 0}, -- 最后登录时间 ctime = {"number", skynet.timex()}, -- 创建时间 ignoreMt = {"number", 0}, -- 忽略维护拦截 sversion = {"number", STRUCT_VERSION or 0}, -- 重整数据版本 timeReset = {"table", {}}, --重置轮回记录 diamond = {"number", 0}, reDiamond = {"number", 0}, setting = {"table", {}}, --设置 codeStr = {"string", ""}, --已经领过的礼包码 -- roleInfo level = {"number", 1}, exp = {"number", 0}, items = {"string", ""}, expireItem = {"table", {}}, --物品过期检查 funcOpen = {"table", {}}, --功能是否开放 funcLv = {"table", {}}, --功能等级 -- loveStatus = {"string", ""}, --统计角色的最高 好感度等级 类型相关 -- type=loveL type=loveL crown = {"number", 0}, -- 看伴娘 silent = {"number", 0}, --禁言解禁时间 bagLimit = {"table", globalCsv.store_limit_max}, --冒险相关 advPass = {"table", {}}, -- 通关记录 {chapterId = layer} advItems = {"string", ""}, -- 冒险临时背包 advInfo = {"table", {}}, -- 冒险关卡信息 advTeam = {"table", {}}, -- 冒险玩家队伍信息 advHang = {"table", {}}, -- 挂机信息 -- {chapterId = {format = teaminfo, time = endtime}} advTask = {"table", {}}, -- 冒险已领取任务完成状态 {id = status} --每层重置 advMTask = {"table", {id = 1, status = 0, lock = true}}, -- 冒险主线任务 -- {id = id, status = status, lock = true} -- 当前主线id 当前主线状态 是否锁定状态 advAchiev = {"table", {}}, -- 冒险成就 {chapterId = {achievId = status, -1 = pt, pts = {}}, } advL = {"table", {0, 0}}, -- 冒险队等级 {lv, exp} advElM = {"number", 0}, -- 无尽模式通关的最高层数 endless max layer advElS = {"number", 0}, -- 无尽模式记录的赛季 endless season advAFOpen = {"table", {}}, -- 解锁的神器 {[id] = 1} advAFGet = {"table", {}}, -- 当前拥有的神器 {[id] = 等级} advAFWear = {"table", {}}, -- 当前拥有的神器 {[slot] = id} advDrawB = {"table", {}}, -- 冒险抽奖回馈 {[1] = 0, [2] = 100} -- 池子类型 = 点数 advStoryB = {"table", {}}, -- 冒险故事完成记录 (连锁事件绑定的故事) -- {storyId = 1} advShop = {"table", {}}, -- 冒险內的商店限制购买次数记录 {goodId = count} advEAchiev = {"table", {}}, -- 冒险无尽冒险手册 advRelay = {"table", {}}, -- 冒险中继点记录 {[chapter] = {[level] = 1}, [-1] = {[level] = 1}} -- -1 无尽 方便重置 advSup = {"table", {}}, -- 冒险支援效果 待选项 advLimit = {"table", {}}, -- 冒险事件每次的limit advC = {"number", 0}, -- 冒险次数(消耗体力) advCT = {"number", 0}, -- 冒险次数 上次恢复时间 advMine = {"table", {}}, -- -- {1 = {ch = 0, co = {id = count}}, 2 = {ch = 0, co = {id = count}}} 宝藏怪刷出概率 1 宝藏怪 2 宝藏洞 ch 概率 co 不同id 次数记录 --挂机相关 hangPass = {"table", {}}, -- 挂机通过的最大关卡 hangGift = {"table", {}}, -- 挂机奖励 {id = 1} hangTS = {"table", {}}, -- 挂机队伍他人可读的队伍信息 hangTB = {"table", {}}, -- 挂机队伍他人可用的战斗信息mao hangTBV = {"number", 0}, -- 挂机队伍他人可用的战斗力 hangInfo = {"table", {}}, -- 当前挂机信息 hangBag = {"table", {}}, -- 背包 hangBagLimit = {"number", globalCsv.idle_field_origin}, --背包上限 hangTeams = {"table", {}}, -- pve自选编队 teamIndex = {"table", {}}, -- 各个系统使用的编队索引 type->index 见TeamSystemType advTeams = {"table", {}}, -- 拾荒自选编队 towerTeams = {"table", {}}, -- 四个电波塔的队伍 bonusStar = {"table", {}}, -- 奖励关卡 通关星星 {[id] = 1} 三个二进制位 表示三个星 从低到高 (1 << 0) (1 << 1) (1 << 2) 满星 (1 << 3) - 1 workStar = {"table", {}}, -- 夜间玩法 通关星星 {[id] = 1} 三个二进制位 表示三个星 从低到高 (1 << 0) (1 << 1) (1 << 2) 满星 (1 << 3) - 1 workBattle = {"table", {}}, -- 夜间玩法记录 {[1] = 1, [2] = 1, [3] = 1, [4] = 1, round = 10} -- 第N天打了多少次 round 轮次 --引导相关 newerGuide = {"string","1=1"}, -- 新手引导 master=slave funcGuide = {"string",""}, -- 功能引导 0=0跳过次数(999永久跳过) 1=1功能1触发情况 pvpTC = {"table", {}}, -- pvp 编队普通 pvpTSC = {"table", {}}, -- pvp 他人可读的队伍信息 pvpTBC = {"table", {}}, -- pvp 他人可用的战斗信息 pvpTBVC = {"number", 0}, -- pvp 他人可用的战斗力 pvpMC = {"table", {}}, -- pvp 匹配的对手 普通 {{t = 1, id = roleId}, {t = 2, id = id}, {t = 2, id = id}} -- t 1 玩家 2 机器人 pvpTH = {"table", {}}, -- pvp 编队高级 pvpTSH = {"table", {}}, -- pvp 他人可读的队伍信息 pvpTBH = {"table", {}}, -- pvp 他人可用的战斗信息 pvpTBVH = {"table", {}}, -- pvp 他人可用的战斗力 pvpMH = {"table", {}}, -- pvp 匹配的对手 高级 {{t = 1, id = roleId}, {t = 2, id = id}, {t = 2, id = id}} -- t 1 玩家 2 机器人 pvpHGift = {"table", {}}, -- pvp 高级段位每小时奖励缓存 pvpHGTime = {"number", 0}, -- pvp 高级段位上次奖励刷新时间 pvpShop = {"table", {}}, -- pvp 商店{id = count} 对应商店id 购买次数 pvpBet = {"table", {}}, -- 跨服竞技场押注信息 {[round] = {1, 1000}} potionBag = {"table", {}}, -- 营养剂背包 storyB = {"table", {}}, -- 剧情记录 equips = {"table", {}}, -- 装备简化下, 目前的设计足够支撑 -- {t = {l = c}} -- 接口设计好 底层扩展就重写~ boxL = {"table", {}}, -- boxList 正开启的箱子 -- {[1] = {id = 1010, gem = 101, time = 1313}} towerInfo = {"table", {c = globalCsv.tower_count_limit, l = 1, l1 = 10001, l2 = 20001, l3 = 30001}}, -- 当天爬塔消耗的次数 -- {t = time, c = count, l = layer, k = battleKey} towerBnous = {"table", {}}, -- 电波塔加成 {[1] = {[1] = 1, [2] = 1}, [2] = {}, [3] = {}, [4] = {}} spTask = {"table", {}}, -- 特殊任务 -- {id = status} dTask = {"table", {}}, -- 每日任务 {t = {id = status}, a = 0, at = {id = status}} t 任务完成情况 a 获得的活跃数值 at 活跃任务完成情况 wTask = {"table", {}}, -- 每周任务 {t = {id = status}, a = 0, at = {id = status}} t 任务完成情况 a 获得的活跃数值 at 活跃任务完成情况 achiveT = {"table", {}}, -- 成就计数统计 achivement_type {id = status} achiveV = {"table", {}}, -- 成就领奖统计 achivement {id = status} fuxR = {"number", 0}, -- 复兴成就最大完成数量 rechargeF = {"table", {}}, -- 是否首次充值某一项 -- —{[id] = 1} -- 不存在就是没有充值过 dinerS = {"table", {}}, -- 美食币商城 购买记录 {[id] = count} battlePoint = {"number", 0}, -- 赛季卡使用的活跃点 rmbC = {"number", 0}, -- 人民币重置额 twdC = {"number", 0}, -- 台币总充值金额 emailSync = {"number", 0}, -- 已经同步到的邮件Id repayHero = {"number", 0}, -- 招募次数 (除去友情招募) repayMaxC = {"number", 0}, -- 招募保底英雄领取次数 100一次 floorHero = {"table", {}}, -- 招募保底 -- {[poolId] = count} ssrUp = {"table", {}}, -- ssr up -- {[poolId] = count} newerDraw = {"number", 0}, -- 新手池子抽卡次数 wishPool = {"table", {}}, -- 心愿池子 sudoku = {"table", {}}, -- 九宫格 {[-1] = 1, task = {[1] = {}, [2] = {}}}} -- [-1] 阶段 如果为 -1 关闭(都做完了), task 当前阶段任务进度, reward 连串奖励领取情况 sign = {"table", {}}, -- 签到记录 {[1] = 20181029} redp = {"table", {}}, -- 待消除红点 -- 通常打开对应界面就消除的红点 红点消除的方法 在对应的协议中使用 {tag = pms } chatline = {"table", {}}, -- 奖励发放 id=时间 downCvR = {"number", 0}, -- 下载cv扩展包奖励 feedback = {"table", {}}, -- 反馈相关信息 {flag = false, count = 0} flag是否评论过,count 提示次数 calTask = {"table", {}}, -- 英雄令活动 日历任务活动 bcTask = {"table", {}}, -- 英雄令活动 日历任务活动 临时使用 radioTask = {"table", {}}, -- 电台任务 {id = {time=end_ts,heros=heros}} 表crusadeCsv seaport = {"table", {}}, -- 海岛贸易季 {time = 1234567890, donate = {}, collect = {[1] = {team = "1=2=3", time = 1234567890}}, shop = {}} returner = {"table", {}}, -- 回归者 {time = 12334233423, [1] = 1, [2] = 2, status = {[1] = 1}} } function Role:notifyUpdateProperty(field, newValue, oldValue, extraValue) local updateData = { { key = field, newValue = newValue, oldValue = oldValue or "", extraValue = extraValue, } } SendPacket(actionCodes.Role_updateProperty, MsgPack.pack(updateData)) end function Role:updateProperty(params) params = params or {} if not self.schema[params.field] then return end local oldValue = self:getProperty(params.field) local ret = {key = params.field, oldValue = oldValue} if params.value then ret.newValue = params.value self:setProperty(params.field, params.value) elseif params.delta then self:incrProperty(params.field, params.delta) ret.newValue = self:getProperty(params.field) else return end if not params.notNotify then SendPacket(actionCodes.Role_updateProperty, MsgPack.pack({ret})) end end function Role:updateProperties(params, notNotify) self:setProperties(params) if not notNotify then SendPacket(actionCodes.Role_updateProperties, MsgPack.pack(params)) end end function Role:notifyUpdateProperties(params) SendPacket(actionCodes.Role_updateProperties, MsgPack.pack(params)) end local mapToList mapToList = function(map) local result = {} if type(map) == "table" then for k, v in pairs(map) do for _, _one in ipairs(mapToList(v)) do table.insert(result, {k, table.unpack(_one)}) end end else table.insert(result, {map}) end return result end function Role:changeMapUpdates(params, notNotify) local changes = {} for _, one in ipairs(mapToList(params)) do local ftype = table.remove(one, 1) local value = table.remove(one, #one) if ftype and value and #one > 0 then table.insert(changes, {type = ftype, field = #one > 1 and one or one[1], value = value}) else print("ERROR: changeMapUpdates") dump(params) end end self:changeUpdates(changes, notNotify) end -- 某些字段 更新改变量 改变量的定义由字段自身决定 {{type = ""}, } function Role:changeUpdates(params, notNotify) local needSetProperty = {} local changeUpdateFunc = { -- ["loveStatus"] = function(info) -- self:setProperty("loveStatus", self:getProperty("loveStatus"):setv(info["field"], info["value"])) -- return {type = "loveStatus", field = info["field"], value = info["value"]} -- end, --table 类型通用更新 ["tableCommon"] = function(fieldType, info) if self.class.schema[fieldType][1] ~= "table" then error("[ERROR:] need handler for changeUpdate, field : " .. fieldType) return end --支持多深度单字段 local curValue = self:getProperty(fieldType) if type(info["field"]) == "table" then for _idx, _field in ipairs(info["field"]) do if _idx < #info["field"] then curValue[_field] = curValue[_field] or {} curValue = curValue[_field] else curValue[_field] = info["value"] end end else curValue[info["field"]] = info["value"] end needSetProperty[fieldType] = 1 return {type = fieldType, field = info["field"], value = info["value"]} end, ["onlyToC"] = function(info) return info end, } local updates = {} for _, one in ipairs(params) do if changeUpdateFunc[one["type"]] then table.insert(updates, changeUpdateFunc[one["type"]](one)) elseif one.isOnlyToC then one.isOnlyToC = nil table.insert(updates, one) else table.insert(updates, changeUpdateFunc["tableCommon"](one["type"], one)) end end for fieldType, _ in pairs(needSetProperty) do self:setProperty(fieldType) end if not notNotify and next(updates) then SendPacket(actionCodes.Role_changeUpdate, MsgPack.pack(updates)) end end function Role:data() return { id = self:getProperty("id"), name = self:getProperty("name"), intro = self:getProperty("intro"), headId = self:getProperty("headId"), setting = self:getProperty("setting"), level = self:getProperty("level"), exp = self:getProperty("exp"), items = self:getProperty("items"):toNumMap(), funcOpen = self:getProperty("funcOpen"), funcLv = self:getProperty("funcLv"), -- loveStatus = self:getProperty("loveStatus"):toNumMap(), timeReset = self:getProperty("timeReset"), diamond = self:getAllDiamond(), bagLimit = self:getProperty("bagLimit"), silent = self:getProperty("silent"), advPass = self:getProperty("advPass"), advInfo = self:getProperty("advInfo"), advItems = self:getProperty("advItems"):toNumMap(), advTeam = self:getProperty("advTeam"), advHang = self:getProperty("advHang"), advTask = self:getProperty("advTask"), advMTask = self:getProperty("advMTask"), advAchiev = self:getProperty("advAchiev"), advL = self:getProperty("advL"), advElM = self:getProperty("advElM"), advElS = self:getProperty("advElS"), advElChapter = self.advElChapter, advOverTime = self.advOverTime, advAFGet = self:getProperty("advAFGet"), advAFOpen = self:getProperty("advAFOpen"), advAFWear = self:getProperty("advAFWear"), advDrawB = self:getProperty("advDrawB"), advShop = self:getProperty("advShop"), advEAchiev = self:getProperty("advEAchiev"), advSup = self:getProperty("advSup"), advC = self:getProperty("advC"), advCT = self:getProperty("advCT"), advRelay = self:getProperty("advRelay"), hangPass = self:getProperty("hangPass"), hangGift = self:getProperty("hangGift"), hangInfo = self:getProperty("hangInfo"), hangBag = self:getProperty("hangBag"), hangBagLimit = self:getProperty("hangBagLimit"), hangTeams = self:getProperty("hangTeams"), teamIndex = self:getProperty("teamIndex"), advTeams = self:getProperty("advTeams"), towerTeams = self:getProperty("towerTeams"), bonusStar = self:getProperty("bonusStar"), workStar = self:getProperty("workStar"), workBattle = self:getProperty("workBattle"), newerGuide = self:getProperty("newerGuide"), funcGuide = self:getProperty("funcGuide"), pvpTC = self:getProperty("pvpTC"), pvpTH = self:getProperty("pvpTH"), pvpHGift = self:getProperty("pvpHGift"), pvpHGTime = self:getProperty("pvpHGTime"), pvpShop = self:getProperty("pvpShop"), potionBag = self:getProperty("potionBag"), storyB = self:getProperty("storyB"), equips = self:getProperty("equips"), boxL = self:getProperty("boxL"), towerInfo = self:getProperty("towerInfo"), towerBnous = self:getProperty("towerBnous"), spTask = self:getProperty("spTask"), dTask = self:getProperty("dTask"), wTask = self:getProperty("wTask"), achiveT = self:getProperty("achiveT"), achiveV = self:getProperty("achiveV"), rechargeF = self:getProperty("rechargeF"), dinerS = self:getProperty("dinerS"), battlePoint = self:getProperty("battlePoint"), rmbC = self:getProperty("rmbC"), twdC = self:getProperty("twdC"), repayHero = self:getProperty("repayHero"), newerDraw = self:getProperty("newerDraw"), floorHero = self:getProperty("floorHero"), wishPool = self:getProperty("wishPool"), sudoku = self:getProperty("sudoku"), sign = self:getProperty("sign"), redp = self:getProperty("redp"), chatline = self:getProperty("chatline"), downCvR = self:getProperty("downCvR"), -- 下载cv扩展包奖励 feedback = self:getProperty("feedback"), ctime = self:getProperty("ctime"), calTask = self:getProperty("calTask"), bcTask = self:getProperty("bcTask"), radioTask = self:getProperty("radioTask"), seaport = self:getProperty("seaport"), returner = self:getProperty("returner"), } end return Role