-- 资源 local code = require "code" local gameConst = require("const.gameConst") local util_user = require("utils.util_user") local timeUtil = require("utils.timeUtil") local resAdapt = require("adapt.resAdapt") local moduleData = require("data.module") local MODULE_NAME = "bag" local root = {} -- 玩家资源初始化(新手物品初始化) function root:init(uid) local lastInitTime = self:_get_last_init_time(uid) -- 仅初始化1次 if lastInitTime > 0 then return end local initConfig = resAdapt:get_init_conf() local initItems = {} for _, v in ipairs(initConfig) do table.arry_merge(initItems, v.items) end if #initItems > 0 then self:update_items(uid, initItems, "init") end local curTime = timeUtil.now(uid) self:_set_last_init_time(uid, curTime) end -- 请求获取背包信息 function root:get_info(uid) log.info("get_info uid:%s", uid) local itemList = moduleData:hget_json(uid, MODULE_NAME, "itemList") or {} local isUpdate = false local curTime = timeUtil.now(uid) for i = #(itemList or {}), 1, -1 do local item = itemList[i] if item.expTime and curTime > item.expTime then -- 已经过期 isUpdate = true item.count = 0 end if item.count == 0 then isUpdate = true table.remove(itemList, i) end end if isUpdate then -- 存储 moduleData:hset(uid, MODULE_NAME, "itemList", itemList) end return itemList end --[[ 请求增减资源列表 返回的是 DataResUpdateItem 列表 ]] function root:update_items(uid, items, reason) -- log.info("update_items uid:%s items:%s reason:%s", uid, tostring(items), tostring(reason)) local itemList = moduleData:hget_json(uid, MODULE_NAME, "itemList") or {} local list = {} for _, v in ipairs(items) do local updateItems = self:_update_item(uid, itemList, v.id, v.count, v.bid) if updateItems then table.arry_merge(list, updateItems) end end -- 存储 moduleData:hset(uid, MODULE_NAME, "itemList", itemList) -- 推送 self:_on_res_update(uid, list, reason) -- 事件 self:_dispatch_event(uid, list) -- 日志-资源变化 self:_log_resource(uid, list, reason) return list end -- 判断资源是否足够 function root:is_enough(uid, items) -- 求和 local tempMap = {} for _, v in ipairs(items) do if not tempMap[v.id] then tempMap[v.id] = v.count else tempMap[v.id] = tempMap[v.id] + v.count end end local itemList = moduleData:hget_json(uid, MODULE_NAME, "itemList") or {} local ret = true for k, v in pairs(tempMap) do local item = table.key_find(itemList, "id", k) if not item or not item.count or item.count < v then ret = false break end end return ret end function root:is_enough_by_bid(uid, items) -- 求和 local tempMap = {} for _, v in ipairs(items) do if not tempMap[v.bid] then tempMap[v.bid] = v.count else tempMap[v.bid] = tempMap[v.bid] + v.count end end local itemList = moduleData:hget_json(uid, MODULE_NAME, "itemList") or {} local ret = true for k, v in pairs(tempMap) do local item = table.key_find(itemList, "bid", k) if not item or not item.count or item.count < v then ret = false break end end return ret end --[[ 增加资源 返回的是 DataResUpdateItem 列表 ]] function root:add_items(uid, items, reason) return self:update_items(uid, items, reason) end --[[ 消耗资源。资源不足也会消耗,消耗到0为止 返回的是 DataResUpdateItem 列表 ]] function root:consume_items(uid, items, reason) local tempList = {} for _, v in ipairs(items) do table.insert(tempList, {id = v.id, count = -v.count, bid = v.bid}) end return self:update_items(uid, tempList, reason) end -- 获取资源数量 function root:get_item_count(uid, itemId) -- log.info("get_item_count uid:%s itemId:%s", uid, itemId) local itemList = moduleData:hget_json(uid, MODULE_NAME, "itemList") or {} local item = table.key_find(itemList, "id", itemId) or {} return item.count or 0 end -- 获取资源数量 function root:get_item_by_bid(uid, bid) -- log.info("get_item_by_bid uid:%s bid:%s", uid, bid) local itemList = moduleData:hget_json(uid, MODULE_NAME, "itemList") or {} local item = table.key_find(itemList, "bid", bid) or {} return item end -- 已获得类型物品ID列表 function root:get_own_type_item_id_list(uid, resType) if uid == nil or resType == nil then return end local resIdList = {} local itemList = moduleData:hget_json(uid, MODULE_NAME, "itemList") or {} for k, v in ipairs(itemList) do if resAdapt:is_type(v.id, resType) then table.insert(resIdList, v.id) end end return resIdList end ---------------------------------------- -- 以下是私有方法 ---------------------------------------- -- 获取新的bid function root:_new_bid(uid) local lastBid = moduleData:hget_int(uid, MODULE_NAME, "lastBid") or 0 lastBid = lastBid + 1 moduleData:hset(uid, MODULE_NAME, "lastBid", lastBid) return lastBid end -- 最后初始化资源的时间戳 function root:_get_last_init_time(uid) return moduleData:hget_int(uid, MODULE_NAME, "lastInitTime") or 0 end function root:_set_last_init_time(uid, timestamp) moduleData:hset(uid, MODULE_NAME, "lastInitTime", timestamp) end function root:_AddExpirationTime(resConfing, uid) -- 计算失效时间/过期时间,expiration time ==> expTime; local expTime if resConfing then local curTime = timeUtil.now(uid) if resConfing.activeDays then expTime = curTime + (expTime or 0) + 86400 * tonumber(resConfing.activeDays) end if resConfing.termOfValidity then expTime = curTime + (expTime or 0) + tonumber(resConfing.termOfValidity) end end return expTime end function root:_AddItemByBid(uid, itemList, itemId, count, bid, resConfing, composite) local item if count > 0 and composite then local newBid = self:_new_bid(uid) item = { id = itemId, count = 0, bid = newBid } table.insert(itemList, item) else -- 不可叠加的物品只能通过bid来获取,但只有装备是通过bid来获取. item = table.key_find(itemList, "bid", bid) if not item and not bid then item = table.key_find(itemList, "id", itemId) end end -- 都没有获取到,就新建一个. if not item then local newBid = self:_new_bid(uid) item = { id = itemId, count = 0, bid = newBid } table.insert(itemList, item) end local oldCount = item.count or 0 local newCount = oldCount + count newCount = math.max(newCount, 0) item.count = newCount item.expTime = self:_AddExpirationTime(resConfing, uid) return {{id = itemId, deltaCount = count, count = newCount, bid = item.bid}} end -- 更新单个资源 function root:_update_item(uid, itemList, itemId, count, bid) local conf = resAdapt:get_item_conf(itemId) if not conf then log.error("更新资源异常,未找到[%s]资源配置", tostring(itemId)) return end return self:_AddItemByBid(uid, itemList, itemId, count, bid, conf, conf.enableComposite) end -- 推送资源变化 function root:_on_res_update(uid, updateItems, reason) local msg = { reason = reason, items = updateItems } util_user:user_proto_notify(uid, "on_res_update", msg) end -- 资源变化事件 function root:_dispatch_event(uid, updateItems) for _, v in ipairs(updateItems) do local conf = resAdapt:get_item_conf(v.id) or {} local evtParams = { times = 1, id = v.id, count = math.abs(v.deltaCount), add = v.deltaCount, type = conf.type, bId = v.bid, totalCount = v.count } util_user:user_dispatch_event(uid, gameConst.EVENT_ID.RES, evtParams) end end -- 资源变化事件 function root:_log_resource(uid, updateItems, reason) for _, v in ipairs(updateItems) do util_user:log_resource(uid, reason, v.id, v.deltaCount, v.count) end end return root