role.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. local skynet = require "skynet"
  2. local schema = require "model.schema"
  3. local logger = require "logger"
  4. local asset = require "model.asset"
  5. local reward = require "model.reward"
  6. local common_fun = require "model.common_fun"
  7. local stringify = require "stringify"
  8. local embattle
  9. local mailbox
  10. local namecenter
  11. local shengtian
  12. local math_max = math.max
  13. local math_min = math.min
  14. local table_insert = table.insert
  15. local MAX_STM = 100
  16. local currency
  17. local module_name = "role"
  18. local _M = schema.new(module_name, {
  19. login_tims = 0; -- 登录次数
  20. re_stm = 0;
  21. first = false;
  22. })
  23. local REQUEST = {}
  24. local CMD = {}
  25. local MODULE = {}
  26. local THIS = {}
  27. local function func_ret(fname, character, args)
  28. local f = THIS[fname]
  29. if not f then
  30. logger.error("func_ret not fname:%s !!!", fname)
  31. return {errno = STD_ERR.COMMON_SYS_ERR}
  32. end
  33. local errno, ret = f(character, args)
  34. if errno ~= 0 then
  35. return {errno = errno}
  36. end
  37. ret = ret or {}
  38. ret.errno = 0
  39. return ret
  40. end
  41. function MODULE.list_request_interests() return REQUEST end
  42. function MODULE.list_command_interests() return CMD end
  43. -- TODO: 解析/升级模块数据
  44. function MODULE.parse(character)
  45. local d = _M.load(character)
  46. end
  47. -- TODO: 侦听事件
  48. function MODULE.monitor(character)
  49. local d = _M.assert_get(character)
  50. local reset_stm = THIS.reset_stm(d, character)
  51. character.monitor('timer.sec', function(_, ti)
  52. reset_stm(ti)
  53. end)
  54. character.monitor("currency_add", function(_, id, num)
  55. if id == CURRENCY_ID_ROLE_EXP then
  56. THIS.role_add_exp(character, num)
  57. end
  58. end)
  59. character.monitor("role_level", function(_, pre, cur)
  60. shengtian = shengtian or require "service.loginserver.shengtian"
  61. if character.login_args.channel== "shengtian" then
  62. local content = {
  63. account = character.account,
  64. uid = character.uid,
  65. name = character.nickname,
  66. server = character.sid,
  67. level = character.level,
  68. power = character.power,
  69. }
  70. shengtian.upload(2, content)
  71. end
  72. end)
  73. end
  74. -- TODO: 类似泰利的 prepare 接口
  75. function MODULE.launch(character)
  76. local d = _M.assert_get(character)
  77. currency = currency or require "model.currency"
  78. embattle = embattle or require "model.embattle"
  79. namecenter = skynet.localname(".namecenter")
  80. end
  81. -- TODO: 与客户端同步数据
  82. function MODULE.ready(character)
  83. local d = _M.assert_get(character)
  84. if not d.first then
  85. THIS.first_login(d, character)
  86. d.first = true
  87. end
  88. d.login_tims = math_max(0, d.login_tims) + 1
  89. _M.persist(character)
  90. end
  91. -- TODO: 玩家下线时的处理
  92. function MODULE.saybye(character)
  93. end
  94. -- -- TODO: 在这定义网络请求的处理代码
  95. -- function REQUEST.echo(character, args)
  96. -- end
  97. function MODULE.stm_change(character)
  98. local u = _M.assert_runtime(character)
  99. u.stm_change = true
  100. end
  101. function THIS.check_stm_change(d, character, bsend)
  102. local d = d or _M.assert_get(character)
  103. local bfull = THIS.check_stm_full(d, character)
  104. local change = false
  105. -- 满了且有重置时间
  106. if bfull and d.re_stm > 0 then
  107. d.re_stm = 0
  108. change = true
  109. end
  110. -- 没满也没有重置时间
  111. if not bfull and d.re_stm <= 0 then
  112. d.re_stm = os.time()
  113. change = true
  114. end
  115. if change or bsend then
  116. local time = d.re_stm
  117. if time > 0 then
  118. local conf = assert(asset.DataConfig_proto[1], "DataConfig_proto[1]")
  119. local one_time = conf.data1
  120. time = time + one_time
  121. end
  122. character.send("city_change", {currency = {id = CURRENCY_ID_STM, num = currency.get_money(character, CURRENCY_ID_STM)}, time = time})
  123. if change then
  124. _M.persist(character)
  125. end
  126. end
  127. return false
  128. end
  129. function THIS.check_stm_full(d, character)
  130. local d = d or _M.assert_get(character)
  131. local num = THIS.max_stm(d, character) - currency.get_money(character, CURRENCY_ID_STM)
  132. return num <= 0, num
  133. end
  134. function THIS.max_stm(d, character)
  135. return asset.DataConfig_proto[2].data3
  136. end
  137. function THIS.first_login(d, character)
  138. local DataConf = asset.DataConfig_proto[2]
  139. local errno, award_list = common_fun.get_award(DataConf.data2)
  140. if errno ~= 0 then
  141. return errno
  142. end
  143. if not award_list or not next(award_list) then
  144. return STD_ERR.COMMON_CONF_ERR -- 配置异常
  145. end
  146. -- 发奖励
  147. local desc = {
  148. module="first_login",
  149. brief="首次登录",
  150. context= "首次登录",
  151. mailgen={subject=2, body=""},
  152. notify={
  153. flags="first_login"
  154. },
  155. detail=award_list
  156. }
  157. reward(character, desc)
  158. embattle.first_battle(character)
  159. -- mailbox = mailbox or require "model.mailbox"
  160. -- local desc = {
  161. -- module = "首次登录",
  162. -- brief = "首次登录",
  163. -- context = "首次登录",
  164. -- }
  165. -- mailbox.send(character, 3, "", {}, desc)
  166. -- currency.add_money(character, CURRENCY_ID_STM, MAX_STM)
  167. end
  168. function THIS.reset_stm(d, character)
  169. local conf = assert(asset.DataConfig_proto[1], "DataConfig_proto[1]")
  170. local one_time = conf.data1
  171. local one_add = conf.data2
  172. local u = _M.assert_runtime(character)
  173. u.stm_change = true
  174. u.stm_send = true
  175. return function (ti)
  176. if d.re_stm > 0 then
  177. if d.re_stm + one_time <= ti then
  178. local bfull, max_add = THIS.check_stm_full(d, character)
  179. if not bfull then
  180. local times = math.floor((ti - d.re_stm) / one_time)
  181. local add_num = times * one_add
  182. if add_num >= max_add then
  183. currency.add_money(character, CURRENCY_ID_STM, max_add)
  184. d.re_stm = 0
  185. else
  186. currency.add_money(character, CURRENCY_ID_STM, add_num)
  187. d.re_stm = d.re_stm + times * one_time
  188. end
  189. else
  190. d.re_stm = 0
  191. end
  192. u.stm_change = true
  193. u.stm_send = true
  194. _M.persist(character)
  195. end
  196. end
  197. if u.stm_change then
  198. THIS.check_stm_change(d, character, u.stm_send)
  199. u.stm_change = false
  200. u.stm_send = false
  201. end
  202. end
  203. end
  204. function THIS.role_get_client_data(character)
  205. local level = character.level
  206. local exp = character.exp
  207. local conf = asset.RanksLevelConfig_proto[level+1]
  208. if not conf then
  209. exp = 0
  210. else
  211. exp = math_min(conf.exp, exp)
  212. end
  213. return {level = level, exp = exp}
  214. end
  215. function THIS.role_add_exp(character, num)
  216. local conf = asset.RanksLevelConfig_proto[character.level+1]
  217. if not conf then
  218. character.set_exp(0)
  219. else
  220. if num > 0 then
  221. character.set_exp(character.exp + num)
  222. end
  223. end
  224. end
  225. function THIS.role_get_data(character, args)
  226. return 0, THIS.role_get_client_data(character)
  227. end
  228. function THIS.role_upgrade(character, args)
  229. local exp = character.exp
  230. local level = character.level
  231. local award_list = {}
  232. while true do
  233. local conf = asset.RanksLevelConfig_proto[level+1]
  234. if not conf then
  235. exp = 0
  236. break
  237. end
  238. if exp > conf.exp then
  239. exp = exp - conf.exp
  240. level = level + 1
  241. for i = 1, #conf.award, 2 do
  242. local id = conf.award[i]
  243. local num = conf.award[i+1]
  244. if id and num and id > 0 and num > 0 then
  245. table_insert(award_list, {id = id, num = num})
  246. else
  247. break
  248. end
  249. end
  250. else
  251. break
  252. end
  253. end
  254. if level ~= character.level then
  255. if next(award_list) then
  256. local desc = {
  257. module="role",
  258. brief="队伍等级提升",
  259. context= string.format("队伍等级提升%d=>%d", character.level, level),
  260. mailgen={subject=2, body=""},
  261. notify={
  262. flags="role_upgrade"
  263. },
  264. detail=award_list
  265. }
  266. reward(character, desc)
  267. end
  268. local pre = character.level
  269. character.set_level(level)
  270. character.set_exp(exp)
  271. character.dispatch("role_level", pre, level)
  272. _M.persist(character)
  273. end
  274. return 0, THIS.role_get_client_data(character)
  275. end
  276. function THIS.role_rename(character, args)
  277. local name = args.name
  278. if not name then
  279. return STD_ERR.COMMON_PARM_ERR -- 参数异常
  280. end
  281. if name == character.nickname then
  282. return STD_ERR.COMMON_PARM_ERR -- 参数异常
  283. end
  284. local length = string.len(name)
  285. if length <=1 or length >21 then
  286. return STD_ERR.COMMON_PARM_ERR -- 参数异常
  287. end
  288. if string.match(name, "[%p]") then
  289. return -- 参数异常
  290. end
  291. if os.time() - character.rename_time < 48*HOUR_SEC then
  292. return STD_ERR.COMMON_PARM_ERR -- 参数异常
  293. end
  294. local errno = skynet.call(namecenter, "lua", "rename", character.nickname, name, character.uid)
  295. if errno ~= 0 then
  296. return errno
  297. end
  298. local oldname = character.nickname
  299. character.set_nickname(name)
  300. character.set_rename_time(os.time())
  301. skynet.call(namecenter, "lua", "unlock_name", oldname)
  302. return 0, {name = args.name, time = character.rename_time}
  303. end
  304. function REQUEST.role_get_data(character, args)
  305. return func_ret("role_get_data", character, args)
  306. end
  307. function REQUEST.role_upgrade(character, args)
  308. return func_ret("role_upgrade", character, args)
  309. end
  310. function REQUEST.role_rename(character, args)
  311. return func_ret("role_rename", character, args)
  312. end
  313. function CMD.ban_rank(character, ban)
  314. if character.ban_rank ~= ban then
  315. character.set_ban_rank(ban)
  316. end
  317. end
  318. return MODULE