common_fun.lua 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. -- 公用函数,不要加载其他模块数据
  2. local asset = require "model.asset"
  3. local util = require "util"
  4. local skynet = require "skynet"
  5. local logger = require "logger"
  6. local math_floor = math.floor
  7. local table_insert = table.insert
  8. local M = {}
  9. function M.tlength(list)
  10. list = list or {}
  11. local s = 0
  12. for k, v in pairs(list) do
  13. s = s + 1;
  14. end
  15. return s
  16. end
  17. -- 表格式序列号
  18. function M.tqueue(obj)
  19. local temp = {}
  20. if not obj then
  21. return temp
  22. end
  23. for _, v in pairs(obj) do
  24. table.insert(temp, v)
  25. end
  26. return temp
  27. end
  28. function M.optimize_array(a)
  29. if a and next(a) then
  30. return a
  31. end
  32. end
  33. -- 合并奖励
  34. function M.merge_award(t)
  35. local temp = {}
  36. for _, v in ipairs(t or {}) do
  37. local id, num = v.id, v.num
  38. if not temp[id] then
  39. temp[id] = {id = id, num = 0}
  40. end
  41. temp[id].num = temp[id].num + num
  42. end
  43. return M.tqueue(temp)
  44. end
  45. -- 合并支付
  46. function M.merge_pay(t)
  47. return M.merge_award(t)
  48. end
  49. -- 合并两个表,注意这里只是浅拷贝
  50. function M.merge2list(l1, l2)
  51. local temp = l1 or {}
  52. for _, v in ipairs(l2 or {}) do
  53. table_insert(l1, v)
  54. end
  55. return temp
  56. end
  57. -- 合并两个表,注意这里只是浅拷贝
  58. function M.award_multiplier(list, times)
  59. local temp = list or {}
  60. for _, v in ipairs(temp) do
  61. v.num = math_floor(v.num * times)
  62. end
  63. return temp
  64. end
  65. --根据id判断物品类型
  66. function M.goods_type(id)
  67. if id >= 0 and id < 20000 then
  68. return GOODS_HERO
  69. elseif id >=20000 and id < 30000 then
  70. return GOODS_CARD
  71. elseif id >=30000 and id < 40000 then
  72. return GOODS_BOX
  73. elseif id >= 100000 and id < 150000 then
  74. return GOODS_MONEY
  75. elseif id >= 150000 and id < 160000 then
  76. return GOODS_DEBRIS
  77. elseif id >= 200000 and id < 300000 then
  78. return GOODS_EQUIP
  79. end
  80. return GOODS_NONE
  81. end
  82. function M.goods_check(id)
  83. local gtype = M.goods_type(id)
  84. if gtype == GOODS_MONEY then
  85. if not asset.GoodsConfig_proto[id] then
  86. return STD_ERR.COMMON_UNKNOWN_CURRENCY -- 未知的货币
  87. end
  88. elseif gtype == GOODS_CARD then
  89. if not asset.CardSkillConfig_proto[id] then
  90. return STD_ERR.COMMON_UNKNOWN_CARD -- 未知的技能卡牌
  91. end
  92. elseif gtype == GOODS_HERO then
  93. if not asset.RoleConfig_proto[id] then
  94. return STD_ERR.COMMON_UNKNOWN_HERO -- 未知的角色
  95. end
  96. elseif gtype == GOODS_DEBRIS then
  97. if not asset.CardConsumeConfig_proto[id] then
  98. return STD_ERR.COMMON_UNKNOWN_DEBRIS -- 未知的碎片
  99. end
  100. elseif gtype == GOODS_EQUIP then
  101. if not asset.ArmorConfig_proto[id] then
  102. return STD_ERR.COMMON_UNKNOWN_EQUIP -- 未知的装备
  103. end
  104. else
  105. return STD_ERR.COMMON_UNKNOWN_GOODS -- 未注册的物品
  106. end
  107. return 0
  108. end
  109. function M.city_skill_type(id)
  110. return math.floor(id/100)
  111. end
  112. function M.city_skill_level(id)
  113. return id%100
  114. end
  115. -- 深拷贝
  116. function M.scopy(obj)
  117. if type(obj) ~= 'table' then
  118. return obj
  119. end
  120. local tmp = {}
  121. for k,v in pairs(obj) do
  122. tmp[M.scopy(k)] = M.scopy(v)
  123. end
  124. return tmp
  125. end
  126. -- 奖励库生成奖励函数
  127. function M.get_award(id, name, cur_times)
  128. local list = {}
  129. local name = name or "AwardConfig_proto"
  130. local conf_list = assert(asset[name], name)
  131. local conf = conf_list[id]
  132. if not conf then
  133. return STD_ERR.COMMON_CONF_ERR -- 配置异常
  134. end
  135. if cur_times and conf.single and conf.single[1] ~= 0 and conf.replace then
  136. local replace = 0
  137. for k, v in ipairs(conf.single) do
  138. if v == cur_times then
  139. replace = conf.replace[k] or 0
  140. break
  141. end
  142. end
  143. if replace ~= 0 then
  144. conf = conf_list[replace]
  145. if not conf then
  146. return STD_ERR.COMMON_CONF_ERR -- 配置异常
  147. end
  148. end
  149. end
  150. local quality = conf.quality
  151. if conf.weightsCount > 0 then
  152. local size = #conf.library
  153. local all = 0
  154. for i = 1, size do
  155. all = all + (conf.weights[i] or 0)
  156. end
  157. if all <= 0 then
  158. return STD_ERR.COMMON_CONF_ERR -- 配置异常
  159. end
  160. for i = 1, conf.weightsCount do
  161. local r = util.rand(1, all)
  162. for pos = 1, size do
  163. if r <= (conf.weights[pos] or 0) then
  164. local id = conf.library[pos]
  165. local min = conf.weightsMin[pos] or 0
  166. local max = conf.weightsMax[pos] or 0
  167. local num = min
  168. if min > max then
  169. max, min = min, max
  170. end
  171. if max ~= min then
  172. num = util.rand(min, max)
  173. end
  174. if num > 0 then
  175. table_insert(list, {id = id, num = num, quality = quality})
  176. end
  177. break
  178. else
  179. r = r - (conf.weights[pos] or 0)
  180. end
  181. end
  182. end
  183. end
  184. if conf.oddsCount and conf.oddsCount > 0 then
  185. local size = #conf.reward
  186. for i = 1, conf.oddsCount do
  187. for pos = 1, size do
  188. local r = conf.odds[pos] or 0
  189. local id = conf.reward[pos]
  190. local b = false
  191. if r >= MAXRAND then
  192. b = true
  193. elseif r > 0 then
  194. b = util.rand(1, MAXRAND) <= r
  195. end
  196. if b then
  197. local min = conf.oddsMin[pos] or 0
  198. local max = conf.oddsMax[pos] or 0
  199. local num = min
  200. if min > max then
  201. max, min = min, max
  202. end
  203. if max ~= min then
  204. num = util.rand(min, max)
  205. end
  206. if num > 0 then
  207. table_insert(list, {id = id, num = num, quality = quality})
  208. end
  209. end
  210. end
  211. end
  212. end
  213. return 0, list
  214. end
  215. -- 洗牌算法
  216. function M.table_rand(list)
  217. local size = #list
  218. if size <= 1 then
  219. return list
  220. end
  221. for i = 1, size do
  222. local randnum = util.rand(1, size)
  223. local temp = list[i]
  224. list[i] = list[randnum]
  225. list[randnum] = temp
  226. end
  227. return list
  228. end
  229. function M.get_hero_quality(id)
  230. return math_floor(id%100)
  231. end
  232. function M.get_hero_type(id)
  233. return math_floor(id/100)
  234. end
  235. function M.get_equip_type(id)
  236. return math_floor(id/100)
  237. end
  238. function M.get_equip_quality(id)
  239. return math_floor(id%100)
  240. end
  241. --[[
  242. @desc: 解析时间字符串, 返回utc时间
  243. ]]
  244. function M.split(str)
  245. local chunks = {str:match("(%d+)%/(%d+)%/(%d+)%/(%d+)%/(%d+)%/(%d+)")}
  246. assert(#chunks == 6)
  247. local year, month, day, hour, min, sec = table.unpack(chunks)
  248. return os.time({ year=year, month=month, day=day, hour=hour, min=min, sec=sec })
  249. end
  250. --[[
  251. @desc: 生成时间字符串
  252. ]]
  253. function M.time_str(utc_time)
  254. local date_table = os.date("*t",utc_time)
  255. local str_table = {
  256. date_table.year,
  257. "/",date_table.month,
  258. "/",date_table.day,
  259. "/",date_table.hour,
  260. "/",date_table.min,
  261. "/",date_table.sec,
  262. }
  263. return table.concat(str_table)
  264. end
  265. --[[
  266. @desc: 等价于redis的keys命令 优点:不会造成reids锁住造成的CPU飙升 缺点:查询时间变长(可忽略级)
  267. @return: { [1~n] = key}
  268. ]]
  269. local function _redis_keys_func(redis_obj,match_key,can_wait)
  270. local scan_func = function(cursor,match_key,key_temp)
  271. local ret = redis_obj:scan(cursor,"match", match_key,"count",100 )
  272. if ret[2] then
  273. for _,v in ipairs(ret[2]) do
  274. key_temp[v] = true
  275. end
  276. end
  277. return tonumber(ret[1])
  278. end
  279. local cursor = 0
  280. local key_temp = {}
  281. if can_wait then
  282. while true do
  283. cursor = scan_func(cursor,match_key,key_temp)
  284. if cursor == 0 then
  285. break
  286. end
  287. skynet.sleep(0)
  288. end
  289. else
  290. while true do
  291. cursor = scan_func(cursor,match_key,key_temp)
  292. if cursor == 0 then
  293. break
  294. end
  295. end
  296. end
  297. local keys = {}
  298. for k,v in pairs(key_temp) do
  299. table_insert(keys,k)
  300. end
  301. return keys
  302. end
  303. function M.redis_keys(redis_obj,match_key)
  304. return _redis_keys_func(redis_obj,match_key,false)
  305. end
  306. function M.redis_keys_wait(redis_obj,match_key)
  307. return _redis_keys_func(redis_obj,match_key,true)
  308. end
  309. function M.get_ret_func(THIS)
  310. return function(fname, character, args)
  311. local f = THIS[fname]
  312. if not f then
  313. logger.error("func_ret not fname:%s !!!", fname)
  314. return {errno = STD_ERR.COMMON_SYS_ERR}
  315. end
  316. local errno, ret = f(character, args)
  317. if errno ~= 0 then
  318. return {errno = errno}
  319. end
  320. ret = ret or {}
  321. ret.errno = 0
  322. return ret
  323. end
  324. end
  325. return M