123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- local skynet = require "skynet"
- local util = require "util"
- local logger = require "logger"
- local packstring = skynet.packstring
- local unpack = skynet.unpack
- local intmax = math.maxinteger
- local clamp = util.clamp
- local table_insert = table.insert
- local traceback = debug.traceback
- local spawn = function(readonly)
- -- 首先,定义角色默认的数据结构
- local datasource = {
- -- TODO: 在下面定义 Number 和 String 类型的字段
- uid = nil, -- 角色ID
- sid = nil, -- 服务器ID
- account = nil, -- 帐号唯一标识(渠道分配)
- appid = nil, -- App唯一标识
- channel = nil, -- 渠道唯一标识
- platform = nil, -- 操作系统(pc,ios,android等)
- tourist = nil, -- 游客标识:1:非游客账号 2: 游客账号 -- CDPK3-005 海外SDK
- reported = nil, -- 玩家角色数据上报 --PK3-1366 数据统计
- createtime = nil, -- 创号时间
- lastlogin = nil, -- 最后登录时间
- lastlogout = nil, -- 最后下线时间
- forbidden = 0, -- 封号标志0是正常,非0解封号时间
- silent = 0, -- 禁言标志0是正常,非0解禁言时间
- fb = nil, -- 玩家绑定faceboik帐号使用的云帐号
- facebook = nil, -- 玩家绑定facebook账号
- google = nil, -- 玩家绑定google账号
- ios = nil, -- 玩家绑定ios账号
- nickname = nil, -- 角色名
- rename_time = 0, -- 改变名字的时间
- level = 1, -- 队伍等级
- exp = 0, -- 队伍经验
- avater = 0, -- avater
- vip = 0, -- vip等级
- updiamond = 0, -- vip经验
- money = 0, -- 充值金额
- daily_refresh = 0, -- 每日刷新时间
- weekly_refresh = 0, -- 每周刷新时间
- ban_rank = 0, -- 禁用排行
- power = 0, -- 战斗力
- -- TODO: 在下面定义二进制类型的字段 (BLOB)
- role = nil, -- 角色数据
- currency = nil, -- 货币
- adventure = nil, -- 冒险
- building = nil, -- 建筑
- mail = nil, -- 邮件
- hero = nil, -- 英雄
- embattle = nil, -- 阵容
- debris = nil, -- 碎片
- skill_card = nil, -- 技能卡牌
- equip = nil, -- 装备
- talent = nil, -- 天赋
- sign_in = nil, -- 签到
- stats = nil, -- 任务数据统计
- quest = nil, -- 任务
- manual = nil, -- 战令
- draw = nil, -- 抽奖
- grocery = nil, -- 杂货店
- time_box = nil, -- 宝箱
- activitytimemod = nil, -- 活动时间
-
- }
- -- 定义角色数据的只读元表
- local mt = {
- __index = datasource,
- __newindex = function(t, k, v) assert(false, "attempt to update a read-only table") end
- }
- -- 定义 setter 的基础函数
- local tracker = {}
- local function setter(k, v)
- tracker[k] = v
- datasource[k] = v
- end
- local function n_setter(k, v, low, up)
- v = clamp(v, low, up or intmax)
- tracker[k] = v
- datasource[k] = v
- end
- -- TODO: 在下面定义字段的 setter
- local self = { readonly=readonly }
- function self.set_exp(value, up) n_setter('exp', value, 0, up) end
- function self.set_avater(value, up) n_setter('avater', value, 0, up) end
- function self.set_forbidden(value, up) n_setter('forbidden', value, 0, up) end
- function self.set_silent(value, up) n_setter('silent', value, 0, up) end
- function self.set_lastlogin(value, up) n_setter('lastlogin', value, 0, up) end
- function self.set_lastlogout(value, up) n_setter('lastlogout', value, 0, up) end
- function self.set_level(value, up) n_setter('level', value, 1, up) end
- function self.set_rename_time(value, up) n_setter('rename_time', value, 1, up) end
- function self.set_nickname(value) setter('nickname', value) end
- function self.set_vip(value, up) n_setter('vip', value, 0, up) end
- function self.set_updiamond(value, up) n_setter('updiamond', value, 0, up) end--累计充值钻石
- function self.set_money(value, up) n_setter('money', value, 0, up) end--累计充值的金额
- function self.set_daily_refresh(value, up) n_setter('daily_refresh', value, 0, up) end
- function self.set_weekly_refresh(value, up) n_setter('weekly_refresh', value, 0, up) end
- function self.set_ban_rank(value, up) n_setter('ban_rank', value, 0, up) end
- function self.set_power(value, up) n_setter('power', value, 0, up) end
- function self.set_currency(value) setter('currency', value) end
- function self.set_role(value) setter('role', value) end
- function self.set_adventure(value) setter('adventure', value) end
- function self.set_building(value) setter('building', value) end
- function self.set_mail(value) setter('mail', value) end
- function self.set_hero(value) setter('hero', value) end
- function self.set_embattle(value) setter('embattle', value) end
- function self.set_debris(value) setter('debris', value) end
- function self.set_skill_card(value) setter('skill_card', value) end
- function self.set_equip(value) setter('equip', value) end
- function self.set_talent(value) setter('talent', value) end
- function self.set_sign_in(value) setter('sign_in', value) end
- function self.set_stats(value) setter('stats', value) end
- function self.set_quest(value) setter('quest', value) end
- function self.set_manual(value) setter('manual', value) end
- function self.set_draw(value) setter('draw', value) end
- function self.set_grocery(value) setter('grocery', value) end
- function self.set_time_box(value) setter('time_box', value) end
- --------------------------------- setter end ---------------------------------
- local function loadfrom(metadata)
- assert(metadata)
- local dest = datasource
- for i=1, #metadata, 2 do
- local k = metadata[i]
- local v = metadata[i+1]
- if k == "nickname" then
- dest[k] = v
- else
- dest[k] = tonumber(v) or v
- end
- end
- dest.uid = tostring(dest.uid)
- return self
- end
- local function pack(k)
- if next(tracker) then
- local pkg = { k }
- for field, value in pairs(tracker) do
- table_insert(pkg, field)
- table_insert(pkg, value)
- end
- tracker = {} -- Must do it
- return pkg
- end
- end
- local function packall(k)
- tracker = datasource
- return pack(k)
- end
- -- TODO: 备份抛弃的数据
- local backups_discard = {
- presence = 'presence',
- }
- local function backups_all()
- local ret = {}
- for k, v in pairs(datasource) do
- if not backups_discard[k] then
- if type(v) == 'number'
- or k == 'uid'
- or k == 'channel'
- or k == 'nickname'
- or k == 'account'
- or k == 'appid'
- or k == 'platform'
- then
- ret[k] = v
- else
- ret[k] = unpack(v)
- end
- end
- end
- return ret
- end
- local listener = {}
- local function dispatch(signame, ...)
- local sigslot = listener[signame] or {}
- for i, v in ipairs(sigslot) do
- local ok,info = xpcall(v, traceback, self, ...)
- if not ok then
- logger.trace("dispatch errno %s, errno info %s", signame, info)
- end
- end
- end
- local function monitor(signame, f)
- listener[signame] = listener[signame] or {}
- table_insert(listener[signame], f)
- end
- local specific = {}
- local function getspecific(k) return specific[k] end
- local function register_specific(k, alloc)
- assert(not specific[k], k)
- local d = nil
- local v = datasource[k]
- if v then
- d = unpack(v)
- elseif alloc then
- d = alloc()
- end
- local f = rawget(self, 'set_'..k)
- local function get() return d end
- local function save()
- assert(f, string.format("attempt to call a nil value(field 'set_%s')", k))
- f(packstring(d))
- end
- specific[k] = { get=get, save=save, runtime={} }
- return d
- end
- -- Ok, let's go on
- self.loadfrom = loadfrom
- self.pack = pack
- self.packall = packall
- self.dispatch = dispatch
- self.monitor = monitor
- self.getspecific = getspecific
- self.register_specific = register_specific
- self.backups_all = backups_all
- self.__index = self
- return setmetatable(self, mt)
- end
- return spawn
|