Role.lua 14.2 KB
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") -- 跨服务请求相关

RoleLog.bind(Role)
RolePlugin.bind(Role)
RoleTimeReset.bind(Role)
RoleTask.bind(Role)
RoleChangeStruct.bind(Role)
RolePvp.bind(Role)
RoleCross.bind(Role)

function Role:ctor( properties )
	Role.super.ctor(self, properties)
	self.ignoreHeartbeat = false
	self.dailyData = nil
	self.heros = {}
	self.runeBag = {}
	self.advData = nil
	self.activity = nil
	self.advElChapter = tonum(redisproxy:hget("adv_season", "chapter"), globalCsv.adv_endless_default_chapter) -- 无尽模式记录的赛季对应章节
	self.advOverTime = tonum(redisproxy:hget("adv_season", "overTime")) -- 无尽模式关闭时间戳
end

Role.schema = {
	id 					= {"number"},
	uid 				= {"string", ""},
	name 				= {"string", ""},
	intro				= {"string", ""},
	headId				= {"number", globalCsv.defaultHead},
	sid 				= {"number", 0},
	device 				= {"string", ""},
	banTime 			= {"number", 0},
	banType 			= {"number", 0},
	heartWarning 		= {"number", 0},
	ltime 				= {"number", 0}, -- 最后登录时间
	ctime 				= {"number", skynet.timex()},  -- 创建时间
	ignoreMt			= {"number", 0},  -- 忽略维护拦截
	sversion			= {"number", globalCsv.StructVersion 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
	
	--挂机相关
	hangPass 			= {"table", {}}, -- 挂机通过的最大关卡
	hangGift			= {"table", {}}, -- 挂机奖励 {id = 1}
	hangTeam 			= {"table", {}}, -- 挂机队伍
	hangTS				= {"table", {}}, -- 挂机队伍他人可读的队伍信息
	hangTB 				= {"table", {}}, -- 挂机队伍他人可用的战斗信息mao
	hangTBV				= {"number", 0}, -- 挂机队伍他人可用的战斗力

	hangInfo			= {"table", {}},  -- 当前挂机信息
	hangBag				= {"table", {}},	-- 背包
	hangBagLimit 		= {"number", globalCsv.idle_field_origin}, --背包上限
	bTeam				= {"table", {}}, -- 奖励副本队伍

	--引导相关
	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}}, -- 当天爬塔消耗的次数  -- {t = time, c = count, l = layer, k = battleKey}
	towerF				= {"table", {}}, -- 爬塔阵容 

	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}

	rechargeF			= {"table", {}}, -- 是否首次充值某一项 -- —{[id] = 1}  -- 不存在就是没有充值过
	dinerS				= {"table", {}}, -- 美食币商城 购买记录 {[id] = count}

	rmbC				= {"number", 0}, -- 人民币重置额

	emailSync			= {"number", 0}, -- 已经同步到的邮件Id

	-- repayHero			= {"number", 0}, -- 超级招募 回馈
	floorHero			= {"table", {}}, -- 招募保底 -- {[poolId] = count}
	ssrUp				= {"table", {}}, -- ssr up -- {[poolId] = count}
	newerDraw			= {"table", {}}, -- 新手池子 {N, 1} 抽了多少次, 是否出了ssr

	sudoku				= {"table", {}}, -- 九宫格   {[-1] = 1, task = {[1] = {}, [2] = {}}}} -- [-1] 阶段 如果为 -1 关闭(都做完了), task 当前阶段任务进度, reward  连串奖励领取情况
	sign 				= {"table", {}}, -- 签到记录 {[1] = 20181029}

	redp 				= {"table", {}}, -- 待消除红点 -- 通常打开对应界面就消除的红点  红点消除的方法 在对应的协议中使用 {tag = pms }
}


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"),

		hangPass = self:getProperty("hangPass"),
		hangGift = self:getProperty("hangGift"),
		hangTeam = self:getProperty("hangTeam"),
		hangInfo = self:getProperty("hangInfo"),
		hangBag = self:getProperty("hangBag"),
		hangBagLimit = self:getProperty("hangBagLimit"),
		bTeam = self:getProperty("bTeam"),

		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"),
		towerF = self:getProperty("towerF"),
		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"),
		
		rmbC = self:getProperty("rmbC"),
		-- repayHero = self:getProperty("repayHero"),
		newerDraw = self:getProperty("newerDraw"),
		floorHero = self:getProperty("floorHero"),

		sudoku = self:getProperty("sudoku"),
		sign = self:getProperty("sign"),

		redp = self:getProperty("redp"),
	}
end

return Role