-- 公用函数,不要加载其他模块数据 local asset = require "model.asset" local util = require "util" local skynet = require "skynet" local logger = require "logger" local math_floor = math.floor local table_insert = table.insert local M = {} function M.tlength(list) list = list or {} local s = 0 for k, v in pairs(list) do s = s + 1; end return s end -- 表格式序列号 function M.tqueue(obj) local temp = {} if not obj then return temp end for _, v in pairs(obj) do table.insert(temp, v) end return temp end function M.optimize_array(a) if a and next(a) then return a end end -- 合并奖励 function M.merge_award(t) local temp = {} for _, v in ipairs(t or {}) do local id, num = v.id, v.num if not temp[id] then temp[id] = {id = id, num = 0} end temp[id].num = temp[id].num + num end return M.tqueue(temp) end -- 合并支付 function M.merge_pay(t) return M.merge_award(t) end -- 合并两个表,注意这里只是浅拷贝 function M.merge2list(l1, l2) local temp = l1 or {} for _, v in ipairs(l2 or {}) do table_insert(l1, v) end return temp end -- 合并两个表,注意这里只是浅拷贝 function M.award_multiplier(list, times) local temp = list or {} for _, v in ipairs(temp) do v.num = math_floor(v.num * times) end return temp end --根据id判断物品类型 function M.goods_type(id) if id >= 0 and id < 20000 then return GOODS_HERO elseif id >=20000 and id < 30000 then return GOODS_CARD elseif id >=30000 and id < 40000 then return GOODS_BOX elseif id >= 100000 and id < 150000 then return GOODS_MONEY elseif id >= 150000 and id < 160000 then return GOODS_DEBRIS elseif id >= 200000 and id < 300000 then return GOODS_EQUIP end return GOODS_NONE end function M.goods_check(id) local gtype = M.goods_type(id) if gtype == GOODS_MONEY then if not asset.GoodsConfig_proto[id] then return STD_ERR.COMMON_UNKNOWN_CURRENCY -- 未知的货币 end elseif gtype == GOODS_CARD then if not asset.CardSkillConfig_proto[id] then return STD_ERR.COMMON_UNKNOWN_CARD -- 未知的技能卡牌 end elseif gtype == GOODS_HERO then if not asset.RoleConfig_proto[id] then return STD_ERR.COMMON_UNKNOWN_HERO -- 未知的角色 end elseif gtype == GOODS_DEBRIS then if not asset.CardConsumeConfig_proto[id] then return STD_ERR.COMMON_UNKNOWN_DEBRIS -- 未知的碎片 end elseif gtype == GOODS_EQUIP then if not asset.ArmorConfig_proto[id] then return STD_ERR.COMMON_UNKNOWN_EQUIP -- 未知的装备 end else return STD_ERR.COMMON_UNKNOWN_GOODS -- 未注册的物品 end return 0 end function M.city_skill_type(id) return math.floor(id/100) end function M.city_skill_level(id) return id%100 end -- 深拷贝 function M.scopy(obj) if type(obj) ~= 'table' then return obj end local tmp = {} for k,v in pairs(obj) do tmp[M.scopy(k)] = M.scopy(v) end return tmp end -- 奖励库生成奖励函数 function M.get_award(id, name, cur_times) local list = {} local name = name or "AwardConfig_proto" local conf_list = assert(asset[name], name) local conf = conf_list[id] if not conf then return STD_ERR.COMMON_CONF_ERR -- 配置异常 end if cur_times and conf.single and conf.single[1] ~= 0 and conf.replace then local replace = 0 for k, v in ipairs(conf.single) do if v == cur_times then replace = conf.replace[k] or 0 break end end if replace ~= 0 then conf = conf_list[replace] if not conf then return STD_ERR.COMMON_CONF_ERR -- 配置异常 end end end local quality = conf.quality if conf.weightsCount > 0 then local size = #conf.library local all = 0 for i = 1, size do all = all + (conf.weights[i] or 0) end if all <= 0 then return STD_ERR.COMMON_CONF_ERR -- 配置异常 end for i = 1, conf.weightsCount do local r = util.rand(1, all) for pos = 1, size do if r <= (conf.weights[pos] or 0) then local id = conf.library[pos] local min = conf.weightsMin[pos] or 0 local max = conf.weightsMax[pos] or 0 local num = min if min > max then max, min = min, max end if max ~= min then num = util.rand(min, max) end if num > 0 then table_insert(list, {id = id, num = num, quality = quality}) end break else r = r - (conf.weights[pos] or 0) end end end end if conf.oddsCount and conf.oddsCount > 0 then local size = #conf.reward for i = 1, conf.oddsCount do for pos = 1, size do local r = conf.odds[pos] or 0 local id = conf.reward[pos] local b = false if r >= MAXRAND then b = true elseif r > 0 then b = util.rand(1, MAXRAND) <= r end if b then local min = conf.oddsMin[pos] or 0 local max = conf.oddsMax[pos] or 0 local num = min if min > max then max, min = min, max end if max ~= min then num = util.rand(min, max) end if num > 0 then table_insert(list, {id = id, num = num, quality = quality}) end end end end end return 0, list end -- 洗牌算法 function M.table_rand(list) local size = #list if size <= 1 then return list end for i = 1, size do local randnum = util.rand(1, size) local temp = list[i] list[i] = list[randnum] list[randnum] = temp end return list end function M.get_hero_quality(id) return math_floor(id%100) end function M.get_hero_type(id) return math_floor(id/100) end function M.get_equip_type(id) return math_floor(id/100) end function M.get_equip_quality(id) return math_floor(id%100) end --[[ @desc: 解析时间字符串, 返回utc时间 ]] function M.split(str) local chunks = {str:match("(%d+)%/(%d+)%/(%d+)%/(%d+)%/(%d+)%/(%d+)")} assert(#chunks == 6) local year, month, day, hour, min, sec = table.unpack(chunks) return os.time({ year=year, month=month, day=day, hour=hour, min=min, sec=sec }) end --[[ @desc: 生成时间字符串 ]] function M.time_str(utc_time) local date_table = os.date("*t",utc_time) local str_table = { date_table.year, "/",date_table.month, "/",date_table.day, "/",date_table.hour, "/",date_table.min, "/",date_table.sec, } return table.concat(str_table) end --[[ @desc: 等价于redis的keys命令 优点:不会造成reids锁住造成的CPU飙升 缺点:查询时间变长(可忽略级) @return: { [1~n] = key} ]] local function _redis_keys_func(redis_obj,match_key,can_wait) local scan_func = function(cursor,match_key,key_temp) local ret = redis_obj:scan(cursor,"match", match_key,"count",100 ) if ret[2] then for _,v in ipairs(ret[2]) do key_temp[v] = true end end return tonumber(ret[1]) end local cursor = 0 local key_temp = {} if can_wait then while true do cursor = scan_func(cursor,match_key,key_temp) if cursor == 0 then break end skynet.sleep(0) end else while true do cursor = scan_func(cursor,match_key,key_temp) if cursor == 0 then break end end end local keys = {} for k,v in pairs(key_temp) do table_insert(keys,k) end return keys end function M.redis_keys(redis_obj,match_key) return _redis_keys_func(redis_obj,match_key,false) end function M.redis_keys_wait(redis_obj,match_key) return _redis_keys_func(redis_obj,match_key,true) end function M.get_ret_func(THIS) return function(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 end return M