local skynet = require "skynet" local schema = require "model.schema" local logger = require "logger" local asset = require "model.asset" local reward = require "model.reward" local common_fun = require "model.common_fun" local stringify = require "stringify" local embattle local mailbox local namecenter local shengtian local math_max = math.max local math_min = math.min local table_insert = table.insert local MAX_STM = 100 local currency local module_name = "role" local _M = schema.new(module_name, { login_tims = 0; -- 登录次数 re_stm = 0; first = false; }) local REQUEST = {} local CMD = {} local MODULE = {} local THIS = {} local function func_ret(fname, character, args) local f = THIS[fname] if not f then logger.error("func_ret not fname:%s !!!", fname) return {errno = STD_ERR.COMMON_SYS_ERR} end local errno, ret = f(character, args) if errno ~= 0 then return {errno = errno} end ret = ret or {} ret.errno = 0 return ret end function MODULE.list_request_interests() return REQUEST end function MODULE.list_command_interests() return CMD end -- TODO: 解析/升级模块数据 function MODULE.parse(character) local d = _M.load(character) end -- TODO: 侦听事件 function MODULE.monitor(character) local d = _M.assert_get(character) local reset_stm = THIS.reset_stm(d, character) character.monitor('timer.sec', function(_, ti) reset_stm(ti) end) character.monitor("currency_add", function(_, id, num) if id == CURRENCY_ID_ROLE_EXP then THIS.role_add_exp(character, num) end end) character.monitor("role_level", function(_, pre, cur) shengtian = shengtian or require "service.loginserver.shengtian" if character.login_args.channel== "shengtian" then local content = { account = character.account, uid = character.uid, name = character.nickname, server = character.sid, level = character.level, power = character.power, } shengtian.upload(2, content) end end) end -- TODO: 类似泰利的 prepare 接口 function MODULE.launch(character) local d = _M.assert_get(character) currency = currency or require "model.currency" embattle = embattle or require "model.embattle" namecenter = skynet.localname(".namecenter") end -- TODO: 与客户端同步数据 function MODULE.ready(character) local d = _M.assert_get(character) if not d.first then THIS.first_login(d, character) d.first = true end d.login_tims = math_max(0, d.login_tims) + 1 _M.persist(character) end -- TODO: 玩家下线时的处理 function MODULE.saybye(character) end -- -- TODO: 在这定义网络请求的处理代码 -- function REQUEST.echo(character, args) -- end function MODULE.stm_change(character) local u = _M.assert_runtime(character) u.stm_change = true end function THIS.check_stm_change(d, character, bsend) local d = d or _M.assert_get(character) local bfull = THIS.check_stm_full(d, character) local change = false -- 满了且有重置时间 if bfull and d.re_stm > 0 then d.re_stm = 0 change = true end -- 没满也没有重置时间 if not bfull and d.re_stm <= 0 then d.re_stm = os.time() change = true end if change or bsend then local time = d.re_stm if time > 0 then local conf = assert(asset.DataConfig_proto[1], "DataConfig_proto[1]") local one_time = conf.data1 time = time + one_time end character.send("city_change", {currency = {id = CURRENCY_ID_STM, num = currency.get_money(character, CURRENCY_ID_STM)}, time = time}) if change then _M.persist(character) end end return false end function THIS.check_stm_full(d, character) local d = d or _M.assert_get(character) local num = THIS.max_stm(d, character) - currency.get_money(character, CURRENCY_ID_STM) return num <= 0, num end function THIS.max_stm(d, character) return asset.DataConfig_proto[2].data3 end function THIS.first_login(d, character) local DataConf = asset.DataConfig_proto[2] local errno, award_list = common_fun.get_award(DataConf.data2) if errno ~= 0 then return errno end if not award_list or not next(award_list) then return STD_ERR.COMMON_CONF_ERR -- 配置异常 end -- 发奖励 local desc = { module="first_login", brief="首次登录", context= "首次登录", mailgen={subject=2, body=""}, notify={ flags="first_login" }, detail=award_list } reward(character, desc) embattle.first_battle(character) -- mailbox = mailbox or require "model.mailbox" -- local desc = { -- module = "首次登录", -- brief = "首次登录", -- context = "首次登录", -- } -- mailbox.send(character, 3, "", {}, desc) -- currency.add_money(character, CURRENCY_ID_STM, MAX_STM) end function THIS.reset_stm(d, character) local conf = assert(asset.DataConfig_proto[1], "DataConfig_proto[1]") local one_time = conf.data1 local one_add = conf.data2 local u = _M.assert_runtime(character) u.stm_change = true u.stm_send = true return function (ti) if d.re_stm > 0 then if d.re_stm + one_time <= ti then local bfull, max_add = THIS.check_stm_full(d, character) if not bfull then local times = math.floor((ti - d.re_stm) / one_time) local add_num = times * one_add if add_num >= max_add then currency.add_money(character, CURRENCY_ID_STM, max_add) d.re_stm = 0 else currency.add_money(character, CURRENCY_ID_STM, add_num) d.re_stm = d.re_stm + times * one_time end else d.re_stm = 0 end u.stm_change = true u.stm_send = true _M.persist(character) end end if u.stm_change then THIS.check_stm_change(d, character, u.stm_send) u.stm_change = false u.stm_send = false end end end function THIS.role_get_client_data(character) local level = character.level local exp = character.exp local conf = asset.RanksLevelConfig_proto[level+1] if not conf then exp = 0 else exp = math_min(conf.exp, exp) end return {level = level, exp = exp} end function THIS.role_add_exp(character, num) local conf = asset.RanksLevelConfig_proto[character.level+1] if not conf then character.set_exp(0) else if num > 0 then character.set_exp(character.exp + num) end end end function THIS.role_get_data(character, args) return 0, THIS.role_get_client_data(character) end function THIS.role_upgrade(character, args) local exp = character.exp local level = character.level local award_list = {} while true do local conf = asset.RanksLevelConfig_proto[level+1] if not conf then exp = 0 break end if exp > conf.exp then exp = exp - conf.exp level = level + 1 for i = 1, #conf.award, 2 do local id = conf.award[i] local num = conf.award[i+1] if id and num and id > 0 and num > 0 then table_insert(award_list, {id = id, num = num}) else break end end else break end end if level ~= character.level then if next(award_list) then local desc = { module="role", brief="队伍等级提升", context= string.format("队伍等级提升%d=>%d", character.level, level), mailgen={subject=2, body=""}, notify={ flags="role_upgrade" }, detail=award_list } reward(character, desc) end local pre = character.level character.set_level(level) character.set_exp(exp) character.dispatch("role_level", pre, level) _M.persist(character) end return 0, THIS.role_get_client_data(character) end function THIS.role_rename(character, args) local name = args.name if not name then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end if name == character.nickname then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end local length = string.len(name) if length <=1 or length >21 then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end if string.match(name, "[%p]") then return -- 参数异常 end if os.time() - character.rename_time < 48*HOUR_SEC then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end local errno = skynet.call(namecenter, "lua", "rename", character.nickname, name, character.uid) if errno ~= 0 then return errno end local oldname = character.nickname character.set_nickname(name) character.set_rename_time(os.time()) skynet.call(namecenter, "lua", "unlock_name", oldname) return 0, {name = args.name, time = character.rename_time} end function REQUEST.role_get_data(character, args) return func_ret("role_get_data", character, args) end function REQUEST.role_upgrade(character, args) return func_ret("role_upgrade", character, args) end function REQUEST.role_rename(character, args) return func_ret("role_rename", character, args) end function CMD.ban_rank(character, ban) if character.ban_rank ~= ban then character.set_ban_rank(ban) end end return MODULE