role.lua 10 KB

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