local Lang = require("common.Lang") local Msg = require("core.Msg") local ObjHuman = require("core.ObjHuman") local ZhuanpanExcel = require("excel.zhuanpan") local ItemDefine = require("bag.ItemDefine") local BagLogic = require("bag.BagLogic") local Grid = require("bag.Grid") local Broadcast = require("broadcast.Broadcast") local RoleSystemLogic = require("roleSystem.RoleSystemLogic") local RoleSystemDefine = require("roleSystem.RoleSystemDefine") local ItemExcel = require("excel.item").item local Util = require("common.Util") local HeroExcel = require("excel.hero").hero local ChatPaoMaLogic = require("chat.ChatPaoMaLogic") local VipLogic = require("vip.VipLogic") local EquipLogic = require("equip.EquipLogic") local YunYingLogic = require("yunying.YunYingLogic") local TriggerDefine = require("trigger.TriggerDefine") local TriggerLogic = require("trigger.TriggerLogic") local WeekTaskLogic = require("dailyTask.WeekTaskLogic") local ClutterDataLogic = require("clutter.ClutterDataLogic") local ClutterDataDefine = require("clutter.ClutterDataDefine") local ZhuanpanGift = require("zhuanpan.ZhuanpanGift") local Log = require("common.Log") local DB = require("common.DB") local LuaMongo = _G.lua_mongo local MailManager = require("mail.MailManager") -- 允许的渠道 local ALLOW_CHANNELS = { [11] = true, [17] = true, -- 美团2楼 } DEFAULT_ZHUANPAN_TYPE_NORMAL = 1 -- 基础转盘 DEFAULT_ZHUANPAN_TYPE_GAOJI = 2 -- 高级转盘 DEFAULT_BUY_ZHUANPAN_CNT = 50 -- 购买许愿珠所需钻石 DEFAULT_FREE_REFRESH_TIME = 10800 -- 免费刷新的时间 ZHUAN_PAN_ITEM_KIND_CNT = 8 -- 转盘种类数量 DEFAULT_MAX_LUCK = 1000 REWARD_RECORD = { index={}, order={} } REWARD_RECORD_CNT = 15 function getLuckConfig(mainType) local config = nil if mainType == DEFAULT_ZHUANPAN_TYPE_NORMAL then config = ZhuanpanExcel.luck1 elseif mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then config = ZhuanpanExcel.luck2 end return config end function red(human, type) if not human.db.zhuanpan then return end local zhuanpan = human.db.zhuanpan[type] local config = getLuckConfig(type) if zhuanpan then local luck = zhuanpan.luck or 0 local luckStatus = zhuanpan.luckStatus for k, v in pairs(config) do if luck >= k then if luckStatus[k] == 1 then return true end end end end if zhuanpan.free == 1 then return true end end -- 转盘查询 function query(human, mainType) local zhuanpanConfig = ZhuanpanExcel[mainType] if not zhuanpanConfig then return end -- 高级转盘判断等级 local roleConfig = nil local flag, roleConfig = RoleSystemLogic.isOpen(human,RoleSystemDefine.ROLE_SYS_ID_501) if mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then if flag ~= true then return Broadcast.sendErr(human, Lang.ZHUANPAN_GAIJI_NEED_LV) end end local oldCnt = getCntByType(human, mainType) local oldLuck local tOldStatus = nil if human.db.zhuanpan and human.db.zhuanpan[mainType] then oldLuck = human.db.zhuanpan[mainType].luck if human.db.zhuanpan[mainType].luckStatus then tOldStatus = Util.copyTable(human.db.zhuanpan[mainType].luckStatus) end end -- 更新 update(human, mainType) -- 初始化 initDB(human, mainType, oldCnt,oldLuck, tOldStatus) local zuanpan = human.db.zhuanpan[mainType] local config = ZhuanpanExcel.define[mainType] local msgRet = Msg.gc.GC_ZHUANPAN_QUERY msgRet.type = mainType msgRet.isFirst = zuanpan.free == 1 and 1 or 0 local now = os.time() local ts1 = now - zuanpan.ts1 msgRet.refreshTime = 24 * 60 * 60 - ts1 msgRet.freeRefreshTime = DEFAULT_FREE_REFRESH_TIME - (now - zuanpan.ts2) if msgRet.freeRefreshTime < 0 then msgRet.freeRefreshTime = 0 end Grid.makeItem(msgRet.itemID, config.useItemID , 1) msgRet.itemCnt[0] = 2 msgRet.itemCnt[1] = config.useItemCnt1 msgRet.itemCnt[2] = config.useItemCnt2 msgRet.drawCnt = config.drawCnt2 Grid.makeItem(msgRet.zuanshiNeed, config.refreshCost[1][1], config.refreshCost[1][2]) msgRet.needLv = config and config.lv or 0 if mainType == DEFAULT_ZHUANPAN_TYPE_NORMAL then msgRet.needLv = ZhuanpanExcel.define[DEFAULT_ZHUANPAN_TYPE_GAOJI].lv elseif mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then msgRet.needLv = ZhuanpanExcel.define[DEFAULT_ZHUANPAN_TYPE_NORMAL].lv end msgRet.needVipLv = VipLogic.getPowerNeedLv(VipLogic.VIP_POWER15) for i = 1, ZHUAN_PAN_ITEM_KIND_CNT do local data = zuanpan[i] local dataID = data.id local tempConfig = zhuanpanConfig[dataID] Grid.makeItem(msgRet.list[i].item, data.itemID, data.itemCnt) msgRet.list[i].id = dataID msgRet.list[i].chance = tempConfig.chance msgRet.list[i].maxCnt = tempConfig.getCnt msgRet.list[i].getCnt = 0 if data.getCnt then msgRet.list[i].getCnt = data.getCnt end end local luckConfig = getLuckConfig(mainType) msgRet.luck = zuanpan.luck or 0 local len = 0 for k, v in pairs(luckConfig) do len = len + 1 local net = msgRet.luckList[len] net.id = k net.status = zuanpan.luckStatus[k] or 0 Grid.makeItem(net.item, v.reward[1] , v.reward[2]) end msgRet.luckList[0] = len len = 0 if REWARD_RECORD[mainType] then for k, v in ipairs(REWARD_RECORD[mainType]) do len = len + 1 local net = msgRet.record[len] net.id = k net.tips = v.tips net.timer = v.timer net.order = v.order end end msgRet.record[0] = len msgRet.list[0] = ZHUAN_PAN_ITEM_KIND_CNT len = 0 local totalWeight = 0 local chanceList = {} for k, v in pairs(zhuanpanConfig) do totalWeight = totalWeight + v.chance chanceList[k] = chanceList[k] or {} local rewardWeight = 0 for a, b in ipairs(v.rewardID) do rewardWeight = rewardWeight + b[3] end chanceList[k].totalWeight = rewardWeight end -- 大全重占比 local temp = {} for k, v in pairs(zhuanpanConfig) do local chance = chanceList[k] local scale = v.chance / totalWeight for a, b in ipairs(v.rewardID) do local itemID = b[1] if not temp[itemID] then local weight = b[3] / chance.totalWeight len = len + 1 local net = msgRet.chanceList[len] local itemConfig = ItemDefine.getConfig(itemID) if not itemConfig then print(itemID) end net.tips = itemConfig and itemConfig.name or "" net.chance = weight * scale * 100 temp[itemID] = 1 end end end msgRet.chanceList[0] = len local red1 = red(human, DEFAULT_ZHUANPAN_TYPE_NORMAL) msgRet.red1 = red1 == true and 1 or 0 local red2 = red(human, DEFAULT_ZHUANPAN_TYPE_GAOJI) msgRet.red2 = red2 == true and 1 or 0 Msg.send(msgRet, human.fd) end function refresh(human, mainType, needTime, bRefreshLuck) if not ZhuanpanExcel[mainType] then return end local oldCnt = getCntByType(human, mainType) local oldLuck local tOldStatus = nil if human.db.zhuanpan and human.db.zhuanpan[mainType] then oldLuck = human.db.zhuanpan[mainType].luck if human.db.zhuanpan[mainType].luckStatus and not bRefreshLuck then tOldStatus = Util.copyTable(human.db.zhuanpan[mainType].luckStatus) end end -- 更新 update(human, mainType) -- 初始化 initDB(human, mainType, oldCnt,oldLuck,tOldStatus) -- 判断是否免费 if needTime then local config = ZhuanpanExcel.define[mainType] local needCost = 0 local now = os.time() local ts2 = now - human.db.zhuanpan[mainType].ts2 local leftTime = DEFAULT_FREE_REFRESH_TIME - ts2 if leftTime > 0 then needCost = config.refreshCost[1][2] end -- 判断消耗 local cnt = BagLogic.getItemCnt(human, config.refreshCost[1][1]) if cnt < needCost then return end -- 扣消耗 if needCost > 0 then BagLogic.delItem(human, config.refreshCost[1][1], needCost, "zhuanpan_refresh") end -- 改db local dayStartTime = Util.getDayStartTime(now) human.db.zhuanpan[mainType].ts2 = now human.db.zhuanpan[mainType].ts1 = dayStartTime end addRandomReward(human, mainType) -- 通知客户端 if needTime then query(human, mainType) end end -- 刷新数据 function updateDaily(human) refresh(human, DEFAULT_ZHUANPAN_TYPE_NORMAL) refresh(human, DEFAULT_ZHUANPAN_TYPE_GAOJI) human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].free = 1 human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].freeCnt = 0 ZhuanpanGift.updateDaily(human) end -- 抽奖 function getReward(human, mainType, cnt) local config = ZhuanpanExcel.define[mainType] if not ZhuanpanExcel[mainType] then return end local needItemID = config.useItemID local needItemCnt = nil if cnt == 1 then needItemCnt = config.useItemCnt1 elseif cnt == config.drawCnt2 then needItemCnt = config.useItemCnt2 -- 多次抽奖需要达到指定vip等级 --[[local needVipLv = VipLogic.getPowerNeedLv(VipLogic.VIP_POWER15) if VipLogic.getVipLv(human) < needVipLv then return Broadcast.sendErr(human, Util.format(Lang.ROLE_VIP_ERROR2, needVipLv)) end]] end if needItemCnt == nil then return end local oldCnt = getCntByType(human, mainType) local oldLuck local tOldStatus = nil if human.db.zhuanpan and human.db.zhuanpan[mainType] then oldLuck = human.db.zhuanpan[mainType].luck if human.db.zhuanpan[mainType].luckStatus then tOldStatus = Util.copyTable(human.db.zhuanpan[mainType].luckStatus) end end -- 更新 update(human, mainType) -- 初始化 initDB(human, mainType, oldCnt,oldLuck, tOldStatus) local zhuanpan = human.db.zhuanpan[mainType] if not BagLogic.checkItemCnt(human, needItemID, needItemCnt) then return end -- 每日可抽取次数检测 -- local dayTimes = ClutterDataLogic.GetZhuanPanTimes(human) -- if dayTimes < cnt then -- return Broadcast.sendErr(human, Lang.JINBI_EXCHANGE_ERR_CNT) -- end -- --更新每次抽取次数 -- dayTimes = dayTimes - cnt -- 改为只更新次数 ClutterDataLogic.UpdateZhuanPanTimes(human, cnt) -- 扣消耗 BagLogic.delItem(human, needItemID, needItemCnt, "zhuanpan_get") local msgRet = Msg.gc.GC_ZHUANPAN_GET_REWARD msgRet.type = mainType msgRet.list[0] = cnt local len = 0 for i = 1, cnt do local result = getLuckDrawSingle(human, mainType) if result == nil then assert(nil) end -- 改db local data = zhuanpan[result] local zhuanpanConfig = ZhuanpanExcel[mainType] local tempConfig = zhuanpanConfig[data.id] local nowGetCnt = data.getCnt or 0 local maxGetCnt = tempConfig.getCnt if maxGetCnt ~= 0 then data.getCnt = nowGetCnt + 1 end -- 加道具 local itemID = data.itemID local itemCnt = data.itemCnt BagLogic.addItem(human, itemID, itemCnt, "zhuanpan_get") local itemConfig = ItemExcel[itemID] local heroConfig = HeroExcel[itemID] -- 存在部分 英雄配表里面的id 和装备配表重合了 if itemConfig and itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN and heroConfig and heroConfig.star == 5 then if mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then ChatPaoMaLogic.broadcast(human, ChatPaoMaLogic.PAOMA_TYPE_BROAD_TYPE11, tempConfig.grade, itemID) else ChatPaoMaLogic.broadcast(human, ChatPaoMaLogic.PAOMA_TYPE_BROAD_TYPE10, tempConfig.grade, itemID) end end if tempConfig.getCnt > 0 then if not REWARD_RECORD[mainType] then REWARD_RECORD[mainType] = {} end local record = REWARD_RECORD[mainType] local index = REWARD_RECORD.index[mainType] or 1 local order = REWARD_RECORD.order[mainType] or 1 record[index] = record[index] or {} record[index].tips = Util.format(Lang.ZHUANPAN_RECORD_TWO, human.db.name, ItemDefine.getValue(itemID,"name"), itemCnt) record[index].timer = os.time() record[index].order = order index = index + 1 if index > REWARD_RECORD_CNT then index = 1 end REWARD_RECORD.order[mainType] = order + 1 REWARD_RECORD.index[mainType] = index end msgRet.list[i] = data.id len = len + 1 if not ItemDefine.isEquip(itemID) then Grid.makeItem(msgRet.item[len], itemID, itemCnt) else EquipLogic.makeEquipItemOne(human, msgRet.item[len]) end end msgRet.item[0] = len -- 增加积分 local itemID = ItemDefine.ITEM_LUCK_ID local itemCnt = cnt * 10 BagLogic.addItem(human, itemID, itemCnt, "zhuanpan_back") msgRet.luckItem[0] = 1 Grid.makeItem(msgRet.luckItem[1], itemID, itemCnt) zhuanpan.cnt = zhuanpan.cnt or 0 zhuanpan.cnt = zhuanpan.cnt + cnt zhuanpan.luck = zhuanpan.luck or 0 zhuanpan.luck = zhuanpan.luck + cnt * 10 zhuanpan.luckStatus = zhuanpan.luckStatus or {} local luckConfig = getLuckConfig(mainType) -- 集火幸运值 奖励 local luckStatus = zhuanpan.luckStatus for k, v in pairs(luckConfig) do if zhuanpan.luck >= k then if luckStatus[k] == nil then luckStatus[k] = 1 end end end Msg.send(msgRet, human.fd) query(human, mainType) YunYingLogic.onCallBack(human, "onFindStar", cnt) TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_FINDSTAR, human.db._id, cnt) --周任务,寻星 WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_1, cnt) end -- 购买许愿珠 function buyCnt(human, mainType, cnt) if cnt < 1 then return end if mainType ~= DEFAULT_ZHUANPAN_TYPE_NORMAL then return end local needZuanshi = 50 * cnt -- 判断消耗 if not ObjHuman.checkRMB(human, needZuanshi) then return end -- 扣消耗 ObjHuman.decZuanshi(human, -needZuanshi, "zhuanpan_buy_cnt", ItemDefine.ITEM_BASE_QIYUANZHU_ID, cnt) -- 增加物品 BagLogic.addItem(human, ItemDefine.ITEM_BASE_QIYUANZHU_ID, cnt, "zhuanpan_buy_cnt") -- 通知客户端 local msgRet = Msg.gc.GC_BUY_ZHUANPAN_CNT Msg.send(msgRet, human.fd) end ------------------------------功能函数-------------------------------------- function addRandomReward(human, mainType) local zhuanpanConfig = ZhuanpanExcel[mainType] if not zhuanpanConfig then return end local nowLv = human.db.lv local itemID = nil local itemCnt = nil local cntIndex = 0 for i = 1, #zhuanpanConfig do local tempConfig = zhuanpanConfig[i] if not tempConfig then return end if mainType == DEFAULT_ZHUANPAN_TYPE_NORMAL then if nowLv >= tempConfig.minLv and nowLv <= tempConfig.maxLv then itemID, itemCnt = getRandomItem(human, tempConfig) if itemID and itemCnt then cntIndex = cntIndex + 1 human.db.zhuanpan[mainType][cntIndex] = {} human.db.zhuanpan[mainType][cntIndex].id = i human.db.zhuanpan[mainType][cntIndex].itemID = itemID human.db.zhuanpan[mainType][cntIndex].itemCnt = itemCnt end end elseif mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then itemID, itemCnt = getRandomItem(human, tempConfig) if itemID and itemCnt then cntIndex = cntIndex + 1 human.db.zhuanpan[mainType][cntIndex] = {} human.db.zhuanpan[mainType][cntIndex].id = i human.db.zhuanpan[mainType][cntIndex].itemID = itemID human.db.zhuanpan[mainType][cntIndex].itemCnt = itemCnt end end end end function getLuckDrawSingle(human, mainType) local zhuanpanConfig = ZhuanpanExcel[mainType] if not zhuanpanConfig then return end local totalWeight = 0 local recordData = nil for i = 1, ZHUAN_PAN_ITEM_KIND_CNT do local data = human.db.zhuanpan[mainType][i] local drawID = data.id local tempConfig = zhuanpanConfig[drawID] local nowGetCnt = data.getCnt or 0 local maxGetCnt = tempConfig.getCnt if maxGetCnt == 0 or maxGetCnt > nowGetCnt then totalWeight = totalWeight + tempConfig.chance end end local randNum = math.random(1,totalWeight) for i = 1, ZHUAN_PAN_ITEM_KIND_CNT do local data = human.db.zhuanpan[mainType][i] local drawID = data.id local tempConfig = zhuanpanConfig[drawID] local nowGetCnt = data.getCnt or 0 local maxGetCnt = tempConfig.getCnt if maxGetCnt == 0 or maxGetCnt > nowGetCnt then local tempWeight = tempConfig.chance if randNum <= tempWeight then return i end randNum = randNum - tempWeight end end end function initDB(human, mainType, cnt, oldluck, tOldStatus) if human.db.zhuanpan ~= nil and human.db.zhuanpan[mainType] ~= nil then return end local now = os.time() human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan[mainType] = {} local dayStartTime = Util.getDayStartTime(now) human.db.zhuanpan[mainType].ts1 = dayStartTime human.db.zhuanpan[mainType].ts2 = now - DEFAULT_FREE_REFRESH_TIME human.db.zhuanpan[mainType].cnt = cnt human.db.zhuanpan[mainType].luck = oldluck human.db.zhuanpan[mainType].free = 1 if tOldStatus then human.db.zhuanpan[mainType].luckStatus = tOldStatus else human.db.zhuanpan[mainType].luckStatus = {} end addRandomReward(human, mainType) end function update(human, mainType) if human.db.zhuanpan == nil or human.db.zhuanpan[mainType] == nil then return end if human.db.zhuanpan[mainType].ts1 then -- 防止前端 在结束倒计时结束 发送查询 , 这边还没有结束 返回一样的数据 local now = os.time() + 1 local ts1 = now - human.db.zhuanpan[mainType].ts1 local leftTime = 24 * 60 * 60 - ts1 if leftTime <= 0 then human.db.zhuanpan[mainType] = nil end end end function getRandomItem(human, tempConfig) local totalWeight = 0 for k, v in ipairs(tempConfig.rewardID) do totalWeight = totalWeight + v[3] end local random = math.random(1, totalWeight) for k, v in ipairs(tempConfig.rewardID) do local weight = v[3] local itemID = v[1] local itemCnt = v[2] if random <= weight then return itemID, itemCnt end random = random - weight end end function zhuanpanByGm(human,mainType,val) if not mainType and not val then return end if mainType == 0 or mainType > 2 or val < 5 then return end if human.db.zhuanpan[mainType] then local now = os.time() human.db.zhuanpan[mainType].ts1 = now - 24 * 60 * 60 + val end end function getCntByType(human, mainType) local num = 0 if human.db.zhuanpan and human.db.zhuanpan[mainType] then human.db.zhuanpan[mainType].cnt = human.db.zhuanpan[mainType].cnt or 0 num = human.db.zhuanpan[mainType].cnt end return num end function getLuck(human, msg) local mainType = msg.type local config = getLuckConfig(mainType) if not config then return end local zhuanpan = human.db.zhuanpan[mainType] if zhuanpan == nil then return end if zhuanpan.luck <= 0 then return end local luckStatus = zhuanpan.luckStatus if luckStatus == nil then luckStatus = {} zhuanpan.luckStatus = luckStatus end -- 收集所有可领取的奖励(status == 1) local itemList = {} local itemListLen = 0 -- 遍历所有配置的奖励,找到可领取的(status == 1) for k, v in pairs(config) do if luckStatus[k] == 1 then -- 标记为已领取 luckStatus[k] = 2 -- 添加奖励到背包 BagLogic.addItem(human, v.reward[1], v.reward[2], "zhuanpan_back") -- 收集到奖励列表 itemListLen = itemListLen + 1 itemList[itemListLen] = {v.reward[1], v.reward[2]} end end -- 如果没有可领取的奖励,直接返回 if itemListLen == 0 then return end -- 循环处理幸运值扣除和重新激活奖励(可能领取多轮) while true do -- 计算是否需要重新扣除幸运值 重新激活奖励 local luck = zhuanpan.luck local calc = true for k, v in pairs(config) do if luckStatus[k] == nil or luckStatus[k] ~= 2 then calc = false end end -- 如果所有奖励都已领取,扣除幸运值并重新激活 if calc == true then zhuanpan.luckStatus = {} luck = luck - DEFAULT_MAX_LUCK luck = luck < 0 and 0 or luck zhuanpan.luck = luck -- 重新激活幸运值奖励 luckStatus = zhuanpan.luckStatus for k, v in pairs(config) do if zhuanpan.luck >= k then if luckStatus[k] == nil then luckStatus[k] = 1 end end end -- 如果重新激活后还有可领取的奖励,继续循环领取 local hasMore = false for k, v in pairs(config) do if luckStatus[k] == 1 then hasMore = true -- 领取这个奖励 luckStatus[k] = 2 BagLogic.addItem(human, v.reward[1], v.reward[2], "zhuanpan_back") itemListLen = itemListLen + 1 itemList[itemListLen] = {v.reward[1], v.reward[2]} end end -- 如果没有更多可领取的奖励,退出循环 if not hasMore then break end else -- 不是所有奖励都已领取,退出循环 break end end -- 发送所有奖励列表 if itemListLen > 0 then BagLogic.sendItemGetList(human, itemList, "zhuanpan_back") end query(human, msg.type) end function isDot(human) local red1 = red(human, DEFAULT_ZHUANPAN_TYPE_NORMAL) if red1 then return true end --local red2 = red(human, DEFAULT_ZHUANPAN_TYPE_GAOJI) --if red2 then return true end return false end function getFree(human) local oldLuck local tOldStatus = nil if human.db.zhuanpan and human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL] then oldLuck = human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].luck if human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].luckStatus then tOldStatus = Util.copyTable(human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].luckStatus) end end initDB(human,DEFAULT_ZHUANPAN_TYPE_NORMAL,nil, oldLuck,tOldStatus) if human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].free ~= 1 then return end human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].free = 0 local zhuanpanConfig = ZhuanpanExcel.define[DEFAULT_ZHUANPAN_TYPE_NORMAL] local len = #zhuanpanConfig.freeCnt local totalWeight = 0 for i = 1,len do totalWeight = totalWeight + zhuanpanConfig.freeCnt[i][2] end local itemCnt = nil local randomWeight = math.random(1,totalWeight) for i = 1,len do if randomWeight < zhuanpanConfig.freeCnt[i][2] then itemCnt = zhuanpanConfig.freeCnt[i][1] break else randomWeight = randomWeight - zhuanpanConfig.freeCnt[i][2] end end if itemCnt then local item = {} item[1] = {zhuanpanConfig.useItemID,itemCnt} item[2] = zhuanpanConfig.freeitem[1] BagLogic.addItemList(human, item, "zhuanpan_get") else assert() end end -- 检查账号下是否有任何角色已领取每日固定奖励(账号级别判断) local function checkAccountDailyFixedReward(account) if not account then return false end local QueryByAccount = {account = account} local fields = {zhuanpan = 1} LuaMongo.find(DB.db_char, QueryByAccount, fields) while true do local data = {} if not LuaMongo.next(data) then break end if data.zhuanpan and data.zhuanpan.dailyFixedReward then local getTime = data.zhuanpan.dailyFixedReward.getTime if getTime and Util.isSameDay(getTime) then return true -- 账号下已有角色今日领取过 end end end return false -- 账号下没有角色今日领取过 end -- 获取账号下最早创建的角色注册日期(账号级别判断) local function getAccountEarliestCreateTime(account) if not account then return nil end local QueryByAccount = {account = account} local fields = {createTime = 1} LuaMongo.find(DB.db_char, QueryByAccount, fields) local earliestTime = nil while true do local data = {} if not LuaMongo.next(data) then break end if data.createTime then if not earliestTime or data.createTime < earliestTime then earliestTime = data.createTime end end end return earliestTime end -- 检查渠道17是否已超过注册后15天(基于当前角色注册时间) local function isChannel18Over15Days(human) if not human or not human.db or not human.db.createTime then return false end local createTime = human.db.createTime local registerDayStart = Util.getDayStartTime(createTime) local now = os.time() local todayDayStart = Util.getDayStartTime(now) -- 计算从注册日期到今天已经过了多少天(注册日期是第1天) local daysSinceRegister = math.floor((todayDayStart - registerDayStart) / 86400) + 1 -- 如果超过15天,则不能领取 return daysSinceRegister > 7 end -- 检查账号下是否有任何角色已领取一次性奖励(账号级别判断) local function checkAccountOnceReward(account) if not account then return false end local QueryByAccount = {account = account} local fields = {zhuanpan = 1} LuaMongo.find(DB.db_char, QueryByAccount, fields) while true do local data = {} if not LuaMongo.next(data) then break end if data.zhuanpan and data.zhuanpan.onceReward then local getTime = data.zhuanpan.onceReward.getTime if getTime then return true -- 账号下已有角色领取过 end end end return false -- 账号下没有角色领取过 end -- 检查账号下是否有任何角色已领取订阅奖励(账号级别判断) local function checkAccountSubscribeReward(account) if not account then return false end local QueryByAccount = {account = account} local fields = {zhuanpan = 1} LuaMongo.find(DB.db_char, QueryByAccount, fields) while true do local data = {} if not LuaMongo.next(data) then break end if data.zhuanpan and data.zhuanpan.subscribeReward then local getTime = data.zhuanpan.subscribeReward.getTime if getTime then return true -- 账号下已有角色领取过 end end end return false -- 账号下没有角色领取过 end -- 从newUniqueTag解析渠道ID (格式: "channelID|serverTag|account") local function getChannelIdFromNewUniqueTag(newUniqueTag) if not newUniqueTag then return nil end local parts = {} for part in string.gmatch(newUniqueTag, "([^|]+)") do table.insert(parts, part) end if #parts >= 1 then return tonumber(parts[1]) end return nil end -- 获取每日固定奖励配置(根据渠道ID) local function getDailyFixedRewardConfig(channelId) if channelId == 17 then -- 渠道17(美图2楼):[[101,20000],[111,5000]] return { {101, 20000}, {111, 5000} } else -- 渠道11(默认):[[102, 50]] return { {102, 50} } end end -- 每日固定奖励查询 function dailyFixedRewardQuery(human) local msgRet = Msg.gc.GC_ZHUANPAN_DAILY_FIXED_QUERY if not msgRet then Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardQuery] 错误: msgRet为nil") return end -- 每日更新检查 ObjHuman.updateDaily(human) local account = human.db.account local isReceived = false -- 先读取当日是否已领取(必须在 or {} 初始化之前读,否则可能被空表覆盖导致刚写入的 getTime 丢失) local getTime = nil if human.db.zhuanpan and human.db.zhuanpan.dailyFixedReward then getTime = human.db.zhuanpan.dailyFixedReward.getTime end if getTime and Util.isSameDay(getTime) then isReceived = true else isReceived = checkAccountDailyFixedReward(account) end Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardQuery] getTime=" .. tostring(getTime) .. ", isReceived=" .. tostring(isReceived) .. ", account=" .. tostring(account)) -- 初始化数据库(放在读取 getTime 之后,避免覆盖已有 dailyFixedReward 导致 isReceived 错误) human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.dailyFixedReward = human.db.zhuanpan.dailyFixedReward or {} -- 渠道17(美团2楼)需要满足: -- 1) 当日从2楼登录(mtFrom2floor == 1,且 mtFrom2floorDay 是今天) -- 2) 订阅奖励已领取且在7日有效期内 local newUniqueTag = human.db.newUniqueTag or human.newUniqueTag local channelId = getChannelIdFromNewUniqueTag(newUniqueTag) if channelId == 17 then -- 2楼登录状态(mtFrom2floor 可能为字符串;Util.isSameDay 同天返回 now 时间戳,否则 nil,转为布尔) local from2floorOk = false if tonumber(human.db.mtFrom2floor) == 1 and human.db.mtFrom2floorDay then from2floorOk = (Util.isSameDay(human.db.mtFrom2floorDay) and true or false) end -- 订阅相关状态(mtSubscribe 可能为字符串 "1",用 tonumber 统一判断) local isSubscribed = (tonumber(human.db.mtSubscribe) == 1) local zhuanpan = human.db.zhuanpan local hasSubscribeReward = zhuanpan and zhuanpan.subscribeReward and zhuanpan.subscribeReward.getTime local inValidPeriod = hasSubscribeReward and isSubscribeRewardInValidPeriod(human) Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardQuery] channelId=17 from2floorOk=" .. tostring(from2floorOk) .. ", mtFrom2floor=" .. tostring(human.db.mtFrom2floor) .. ", mtFrom2floorDay=" .. tostring(human.db.mtFrom2floorDay) .. ", isSubscribed=" .. tostring(isSubscribed) .. ", hasSubscribeReward=" .. tostring(hasSubscribeReward) .. ", inValidPeriod=" .. tostring(inValidPeriod)) if not isSubscribed then -- 未订阅:不可领取 msgRet.status = 3 -- 未激活(未订阅) elseif isReceived then -- 当日已领取:固定为 2,不因 mtFrom2floor 被置 0 而变成 0 msgRet.status = 2 -- 已领取(今日已领取) elseif not from2floorOk then -- 当天未从2楼进入:不可领取 msgRet.status = 0 else if not hasSubscribeReward or not inValidPeriod then -- 已订阅,但订阅奖励尚未领取,或已超过7日有效期 msgRet.status = 3 -- 未激活(订阅奖励未领或15天已满) else msgRet.status = 1 -- 可领取(已激活且在7日内,且今日未领) end end else -- 其他渠道保持原有逻辑 if isReceived then msgRet.status = 2 -- 已领取(账号级别) else msgRet.status = 1 -- 可领取 end end -- 根据渠道ID设置奖励物品 local newUniqueTag = human.db.newUniqueTag or human.newUniqueTag local channelId = getChannelIdFromNewUniqueTag(newUniqueTag) local rewardConfig = getDailyFixedRewardConfig(channelId or 11) -- 默认渠道11 Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardQuery] 查询奖励信息: rewardConfig",rewardConfig) -- 循环处理所有奖励物品 for i = 1, #rewardConfig do Grid.makeItem(msgRet.reward[i], rewardConfig[i][1], rewardConfig[i][2]) end msgRet.reward[0] = #rewardConfig -- 设置数组长度 Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardQuery] channelId=" .. tostring(channelId) .. ", status=" .. tostring(msgRet.status)) if human.fd then Msg.send(msgRet, human.fd) else Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardQuery] 错误: human.fd为nil,无法发送协议") end end -- 每日固定奖励领取 function dailyFixedRewardGet(human, channelId) if not ALLOW_CHANNELS[channelId] then Log.write( Log.LOGID_DEBUG, "[dailyFixedRewardGet] 渠道不匹配: channelId=" .. (channelId or "nil") .. ", 允许=11,16,18" ) return Broadcast.sendErr(human, "渠道不匹配") end -- 每日更新检查 ObjHuman.updateDaily(human) -- 初始化数据库 human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.dailyFixedReward = human.db.zhuanpan.dailyFixedReward or {} -- 账号级别判断:先检查当前角色的内存数据,再检查数据库 local account = human.db.account local isReceived = false -- 先检查当前角色的内存数据 local getTime = human.db.zhuanpan.dailyFixedReward.getTime if getTime and Util.isSameDay(getTime) then isReceived = true else -- 再检查账号下其他角色(数据库) isReceived = checkAccountDailyFixedReward(account) end if isReceived then Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardGet] 账号今日已领取: account="..(account or "nil")) return Broadcast.sendErr(human, "今日已领取") end -- 渠道17(美团2楼)额外条件: -- 1) 当日从2楼登录(mtFrom2floor == 1 且 mtFrom2floorDay 为今天) -- 2) 订阅奖励已领取且在7日有效期内 if channelId == 17 then -- 2楼登录状态(mtFrom2floor 可能为字符串,Util.isSameDay 同天返回时间戳,转为布尔) local from2floorOk = false if tonumber(human.db.mtFrom2floor) == 1 and human.db.mtFrom2floorDay then from2floorOk = (Util.isSameDay(human.db.mtFrom2floorDay) and true or false) end if not from2floorOk then Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardGet] 渠道17当日未从2楼进入,无法领取: account="..(account or "nil")) return Broadcast.sendErr(human, "条件不足,无法领取") end -- 订阅有效期检查(mtSubscribe 可能为字符串 "1") if tonumber(human.db.mtSubscribe) ~= 1 or not isSubscribeRewardInValidPeriod(human) then Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardGet] 渠道17订阅未激活或已过期,无法领取: account="..(account or "nil")) return Broadcast.sendErr(human, "订阅未激活或已过期") end end BagLogic.cleanMomentItemList() -- 根据渠道ID发放不同的奖励(循环处理所有奖励) local rewardConfig = getDailyFixedRewardConfig(channelId) for i = 1, #rewardConfig do BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, rewardConfig[i][1], rewardConfig[i][2]) end -- 复用已有的日志类型,避免未定义的logType导致断言 local success, err = pcall(function() BagLogic.addMomentItemList(human, "zhuanpan_once_reward") end) if not success then Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardGet] 错误: 添加到背包失败: "..(err or "unknown")) return Broadcast.sendErr(human, "发放奖励失败") end -- 记录领取时间 local nowTime = os.time() human.db.zhuanpan.dailyFixedReward.getTime = nowTime -- 渠道17:领取成功后,消耗当天的2楼登录资格,防止同日重复触发 if channelId == 17 then human.db.mtFrom2floor = 0 end Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardGet] 领取成功 account=" .. tostring(human.db.account) .. " channelId=" .. tostring(channelId) .. " getTime=" .. tostring(nowTime) .. " mtFrom2floor=" .. tostring(human.db.mtFrom2floor)) -- 领取成功后下发查询协议 local querySuccess, queryErr = pcall(function() dailyFixedRewardQuery(human) end) if not querySuccess then Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardGet] 错误: 发送查询协议失败: "..(queryErr or "unknown")) -- 即使查询协议发送失败,奖励已经发放,所以不返回错误 end -- Log.write(Log.LOGID_DEBUG, "[dailyFixedRewardGet] 领取完成") end -- 抖音渠道一次性奖励查询 function onceRewardQuery(human) local msgRet = Msg.gc.GC_ZHUANPAN_ONCE_REWARD_QUERY if not msgRet then Log.write(Log.LOGID_DEBUG, "[onceRewardQuery] 错误: msgRet为nil") return end -- 初始化数据库 human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.onceReward = human.db.zhuanpan.onceReward or {} -- 账号级别判断:先检查当前角色的内存数据,再检查数据库 local account = human.db.account local isReceived = false -- 先检查当前角色的内存数据 local getTime = human.db.zhuanpan.onceReward.getTime if getTime then isReceived = true else -- 再检查账号下其他角色(数据库) isReceived = checkAccountOnceReward(account) end if isReceived then msgRet.status = 2 -- 已领取(账号级别) else msgRet.status = 1 -- 可领取 end -- 设置奖励物品列表:[[102,500],[118,10],[111,100000]] local success, err = pcall(function() Grid.makeItem(msgRet.reward[1], 102, 500) Grid.makeItem(msgRet.reward[2], 118, 10) Grid.makeItem(msgRet.reward[3], 111, 100000) msgRet.reward[0] = 3 -- 设置数组长度 end) if not success then Log.write(Log.LOGID_DEBUG, "[onceRewardQuery] 错误: 设置奖励物品失败: "..tostring(err)) return end if human.fd then Msg.send(msgRet, human.fd) end end -- 抖音渠道一次性奖励领取 function onceRewardGet(human, channelId) if not ALLOW_CHANNELS[channelId] then Log.write( Log.LOGID_DEBUG, "[onceRewardGet] 渠道不匹配: channelId=" .. (channelId or "nil") .. ", 允许=11,12" ) return Broadcast.sendErr(human, "渠道不匹配") end -- 初始化数据库 human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.onceReward = human.db.zhuanpan.onceReward or {} -- 账号级别判断:先检查当前角色的内存数据,再检查数据库 local account = human.db.account local isReceived = false -- 先检查当前角色的内存数据 local getTime = human.db.zhuanpan.onceReward.getTime if getTime then isReceived = true else -- 再检查账号下其他角色(数据库) isReceived = checkAccountOnceReward(account) end if isReceived then Log.write(Log.LOGID_DEBUG, "[onceRewardGet] 账号已领取过,无法重复领取: account="..(account or "nil")) return Broadcast.sendErr(human, "已领取过,无法重复领取") end BagLogic.cleanMomentItemList() -- 发放奖励:[[102,500],[118,10],[111,100000]] BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, 102, 500) BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, 118, 10) BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, 111, 100000) local success, err = pcall(function() BagLogic.addMomentItemList(human, "zhuanpan_once_reward") end) if not success then Log.write(Log.LOGID_DEBUG, "[onceRewardGet] 错误: 添加到背包失败: "..(err or "unknown")) return Broadcast.sendErr(human, "发放奖励失败") end -- 记录领取时间(永久记录) human.db.zhuanpan.onceReward.getTime = os.time() local querySuccess, queryErr = pcall(function() onceRewardQuery(human) end) if not querySuccess then Log.write(Log.LOGID_DEBUG, "[onceRewardGet] 错误: 发送查询协议失败: "..(queryErr or "unknown")) -- 即使查询协议发送失败,奖励已经发放,所以不返回错误 end end -- 检查当前角色订阅奖励是否在7日有效期内(从订阅奖励领取时间起算) function isSubscribeRewardInValidPeriod(human) if not human or not human.db then return false end local zhuanpan = human.db.zhuanpan if not zhuanpan or not zhuanpan.subscribeReward or not zhuanpan.subscribeReward.getTime then return false end local activateTime = zhuanpan.subscribeReward.getTime local activateDayStart = Util.getDayStartTime(activateTime) local nowTs = os.time() local todayDayStart = Util.getDayStartTime(nowTs) -- 激活日为第1天,7日内有效 local daysSinceActivate = math.floor((todayDayStart - activateDayStart) / 86400) + 1 return daysSinceActivate <= 7 end -- 检查美团2楼玩家每日固定奖励领取情况(晚上11点调用) function checkMtFrom2floorDailyReward() if _G.is_middle == true then return end local QueryMtFrom2floor = {mtFrom2floor = 1} local fields = {zhuanpan = 1, createTime = 1, mtSubscribe = 1, account = 1} LuaMongo.find(DB.db_char, QueryMtFrom2floor, fields) local now = os.time() local todayDayStart = Util.getDayStartTime(now) local dailyMailSentCount = 0 local subscribeMailSentCount = 0 while true do local data = {} if not LuaMongo.next(data) then break end -- 检查是否在订阅有效期内(如果从未激活订阅奖励,视为未激活,不发每日固定奖励) if data.mtSubscribe ~= 1 then goto continue end local inValidPeriod = false if data.zhuanpan and data.zhuanpan.subscribeReward and data.zhuanpan.subscribeReward.getTime then local activateTime = data.zhuanpan.subscribeReward.getTime local activateDayStart = Util.getDayStartTime(activateTime) local daysSinceActivate = math.floor((todayDayStart - activateDayStart) / 86400) + 1 inValidPeriod = (daysSinceActivate <= 7) end -- 订阅奖励未激活或已过期,则不发每日固定奖励 if not inValidPeriod then goto continue end -- 检查今天是否已领取每日固定奖励 local hasReceivedToday = false if data.zhuanpan and data.zhuanpan.dailyFixedReward then local getTime = data.zhuanpan.dailyFixedReward.getTime if getTime and Util.isSameDay(getTime) then hasReceivedToday = true end end -- 如果今天没领取,发送邮件,并将 mtFrom2floor 置为0,防止当天再次通过登录触发 if not hasReceivedToday then local title = "每日固定奖励提醒" local content = "您今日尚未领取每日固定奖励,请及时领取!" local rewardItems = {{101, 20000}, {111, 5000}} -- 渠道17的奖励 local success, err = pcall(function() MailManager.add(MailManager.SYSTEM, data._id, title, content, rewardItems) -- 更新数据库:标记今日已通过邮件发放,并清除当天的2楼标记 local updateFields = { ["zhuanpan.dailyFixedReward.getTime"] = now, ["mtFrom2floor"] = 0, } LuaMongo.update(DB.db_char, {_id = data._id}, updateFields, false, false) end) if success then dailyMailSentCount = dailyMailSentCount + 1 Log.write(Log.LOGID_DEBUG, "[checkMtFrom2floorDailyReward] 发送每日固定奖励邮件并更新状态成功: uuid="..data._id) else Log.write(Log.LOGID_DEBUG, "[checkMtFrom2floorDailyReward] 发送每日固定奖励邮件或更新状态失败: uuid="..data._id..", err="..tostring(err)) end end -- 检查订阅奖励:如果已订阅(mtSubscribe == 1)且未领取,发送邮件 if data.mtSubscribe == 1 then -- 检查账号下是否已领取订阅奖励 local hasReceivedSubscribe = checkAccountSubscribeReward(data.account) if not hasReceivedSubscribe then local title = "订阅奖励提醒" local content = "您已订阅但尚未领取订阅奖励,请及时领取!" local rewardItems = {{101, 50000}, {112, 100}} -- 订阅奖励 local success, err = pcall(function() MailManager.add(MailManager.SYSTEM, data._id, title, content, rewardItems) end) if success then subscribeMailSentCount = subscribeMailSentCount + 1 Log.write(Log.LOGID_DEBUG, "[checkMtFrom2floorDailyReward] 发送订阅奖励邮件成功: uuid="..data._id) else Log.write(Log.LOGID_DEBUG, "[checkMtFrom2floorDailyReward] 发送订阅奖励邮件失败: uuid="..data._id..", err="..tostring(err)) end end end ::continue:: end Log.write(Log.LOGID_DEBUG, "[checkMtFrom2floorDailyReward] 检查完成,每日固定奖励邮件数量: "..dailyMailSentCount..", 订阅奖励邮件数量: "..subscribeMailSentCount) end -- 美团订阅奖励查询(同时接收并存储订阅状态) function subscribeRewardQuery(human, msg) local msgRet = Msg.gc.GC_ZHUANPAN_SUBSCRIBE_REWARD_QUERY if not msgRet then Log.write(Log.LOGID_DEBUG, "[subscribeRewardQuery] 错误: msgRet为nil") return end -- 如果前端上传了订阅状态,则进行存储 if msg and msg.mtSubscribe ~= nil then local val = tonumber(msg.mtSubscribe) or 0 -- 只从 0 -> 1,避免重复覆盖或回退 if val == 1 and human.db then human.db.mtSubscribe = human.db.mtSubscribe or 0 if human.db.mtSubscribe ~= 1 then human.db.mtSubscribe = 1 Log.write(Log.LOGID_DEBUG, "[subscribeRewardQuery] 更新订阅状态为1, account="..tostring(human.db.account)) end end end -- 初始化数据库 human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.subscribeReward = human.db.zhuanpan.subscribeReward or {} -- 检查是否订阅(mtSubscribe == 1) local isSubscribed = (human.db.mtSubscribe == 1) -- 账号级别判断:先检查当前角色的内存数据,再检查数据库 local account = human.db.account local isReceived = false if isSubscribed then -- 先检查当前角色的内存数据 local getTime = human.db.zhuanpan.subscribeReward.getTime if getTime then isReceived = true else -- 再检查账号下其他角色(数据库) isReceived = checkAccountSubscribeReward(account) end end if not isSubscribed then msgRet.status = 0 -- 不可领取(未订阅) elseif isReceived then msgRet.status = 2 -- 已领取 else msgRet.status = 1 -- 可领取 end -- 设置奖励物品列表:[[101,50000],[112,100]] local success, err = pcall(function() Grid.makeItem(msgRet.reward[1], 101, 50000) Grid.makeItem(msgRet.reward[2], 112, 100) msgRet.reward[0] = 2 -- 设置数组长度 end) if not success then Log.write(Log.LOGID_DEBUG, "[subscribeRewardQuery] 错误: 设置奖励物品失败: "..tostring(err)) return end if human.fd then Msg.send(msgRet, human.fd) end end -- 美团订阅奖励领取 function subscribeRewardGet(human, channelId) -- 检查渠道,只有渠道ID=17(美团2楼)才能领取 if not channelId or channelId ~= 17 then Log.write(Log.LOGID_DEBUG, "[subscribeRewardGet] 渠道不匹配: channelId="..(channelId or "nil")..", 需要=18") return Broadcast.sendErr(human, "渠道不匹配") end -- 检查是否订阅(mtSubscribe == 1) if human.db.mtSubscribe ~= 1 then Log.write(Log.LOGID_DEBUG, "[subscribeRewardGet] 未订阅: mtSubscribe="..(human.db.mtSubscribe or "nil")) return Broadcast.sendErr(human, "未订阅,无法领取") end -- 初始化数据库 human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.subscribeReward = human.db.zhuanpan.subscribeReward or {} -- 账号级别判断:先检查当前角色的内存数据,再检查数据库 local account = human.db.account local isReceived = false -- 先检查当前角色的内存数据 local getTime = human.db.zhuanpan.subscribeReward.getTime if getTime then isReceived = true else -- 再检查账号下其他角色(数据库) isReceived = checkAccountSubscribeReward(account) end if isReceived then Log.write(Log.LOGID_DEBUG, "[subscribeRewardGet] 账号已领取过,无法重复领取: account="..(account or "nil")) return Broadcast.sendErr(human, "已领取过,无法重复领取") end BagLogic.cleanMomentItemList() -- 发放奖励:[[101,50000],[112,100]] BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, 101, 50000) BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, 112, 100) -- 使用已存在的日志类型,避免日志定义缺失导致的断言 local success, err = pcall(function() BagLogic.addMomentItemList(human, "zhuanpan_once_reward") end) if not success then Log.write(Log.LOGID_DEBUG, "[subscribeRewardGet] 错误: 添加到背包失败: "..(err or "unknown")) return Broadcast.sendErr(human, "发放奖励失败") end -- 记录领取时间(永久记录) human.db.zhuanpan.subscribeReward.getTime = os.time() local querySuccess, queryErr = pcall(function() subscribeRewardQuery(human) end) if not querySuccess then Log.write(Log.LOGID_DEBUG, "[subscribeRewardGet] 错误: 发送订阅奖励查询协议失败: "..(queryErr or "unknown")) -- 即使查询协议发送失败,奖励已经发放,所以不返回错误 end -- 领取订阅奖励后,同时下发每日固定奖励查询协议 local dailyQuerySuccess, dailyQueryErr = pcall(function() dailyFixedRewardQuery(human) end) if not dailyQuerySuccess then Log.write(Log.LOGID_DEBUG, "[subscribeRewardGet] 错误: 发送每日固定奖励查询协议失败: "..(dailyQueryErr or "unknown")) -- 即使查询协议发送失败,奖励已经发放,所以不返回错误 end end -----------------------淘宝小程序桌面活动----------------------- -- 奖励配置(占位,按需修改) local TB_ENTER_REWARD = {{112, 100}} -- 桌面进入奖励(每日1次) local TB_SECOND_FLOOR_REWARD = {{127, 10}} -- 二楼进入奖励(每日1次) local TB_DESKTOP_REWARD = {{118, 5}} -- 添加桌面奖励(仅1次) -- 渠道校验:仅 pf == "tbMiniGame" 的玩家可参与 local function isTbMiniApp(human) return human.pf_info and human.pf_info.pf == "tbMiniGame" end -- 淘宝小程序桌面活动查询 -- status: 1=桌面进入 2=二楼进入 function tbminiappQuery(human, status) Log.write(Log.LOGID_DEBUG, "[tbminiappQuery] 收到请求 account=" .. tostring(human and human.db and human.db.account) .. " pf=" .. tostring(human and human.pf) .. " status=" .. tostring(status)) local msgRet = Msg.gc.GC_ZHUANPAN_TB_QUERY if not msgRet then Log.write(Log.LOGID_DEBUG, "[tbminiappQuery] 错误: msgRet为nil") return end if not isTbMiniApp(human) then Log.write(Log.LOGID_DEBUG, "[tbminiappQuery] 渠道不匹配 pf=" .. tostring(human and human.pf)) return Broadcast.sendErr(human, "渠道不匹配") end ObjHuman.updateDaily(human) human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.tbminiapp = human.db.zhuanpan.tbminiapp or {} local tb = human.db.zhuanpan.tbminiapp -- 是否已添加桌面 msgRet.isDesktopAdded = tb.desktopAdded and 1 or 0 -- 是否已领取添加桌面奖励(一次性) msgRet.isDesktopRewardReceived = (tb.desktopReward and tb.desktopReward.getTime) and 1 or 0 -- 是否已领取桌面进入奖励(每日1次) local enterTime = tb.enterReward and tb.enterReward.getTime msgRet.isEnterRewardReceived = (enterTime and Util.isSameDay(enterTime)) and 1 or 0 -- 是否已领取二楼进入奖励(每日1次) local floorTime = tb.floorReward and tb.floorReward.getTime msgRet.isFloorRewardReceived = (floorTime and Util.isSameDay(floorTime)) and 1 or 0 -- 填充奖励道具信息 local ok, err = pcall(function() Grid.makeItem(msgRet.enterReward, TB_ENTER_REWARD[1][1], TB_ENTER_REWARD[1][2]) Grid.makeItem(msgRet.floorReward, TB_SECOND_FLOOR_REWARD[1][1], TB_SECOND_FLOOR_REWARD[1][2]) Grid.makeItem(msgRet.desktopReward, TB_DESKTOP_REWARD[1][1], TB_DESKTOP_REWARD[1][2]) end) if not ok then Log.write(Log.LOGID_DEBUG, "[tbminiappQuery] 错误: Grid.makeItem失败: " .. tostring(err)) return end Log.write(Log.LOGID_DEBUG, "[tbminiappQuery] 准备发送" .. " isDesktopAdded=" .. tostring(msgRet.isDesktopAdded) .. " isDesktopRewardReceived=" .. tostring(msgRet.isDesktopRewardReceived) .. " isEnterRewardReceived=" .. tostring(msgRet.isEnterRewardReceived) .. " isFloorRewardReceived=" .. tostring(msgRet.isFloorRewardReceived) .. " fd=" .. tostring(human.fd)) if human.fd then Msg.send(msgRet, human.fd) Log.write(Log.LOGID_DEBUG, "[tbminiappQuery] 发送成功 account=" .. tostring(human.db.account)) else Log.write(Log.LOGID_DEBUG, "[tbminiappQuery] 错误: human.fd为nil,无法发送协议 account=" .. tostring(human.db.account)) end end -- 淘宝小程序添加桌面上报:记录添加状态 function tbminiappAddDesktop(human) if not isTbMiniApp(human) then return Broadcast.sendErr(human, "渠道不匹配") end human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.tbminiapp = human.db.zhuanpan.tbminiapp or {} human.db.zhuanpan.tbminiapp.desktopAdded = true Log.write(Log.LOGID_DEBUG, "[tbminiappAddDesktop] 添加桌面成功 account=" .. tostring(human.db.account)) local querySuccess, queryErr = pcall(function() tbminiappQuery(human, 0) end) if not querySuccess then Log.write(Log.LOGID_DEBUG, "[tbminiappAddDesktop] 错误: 发送查询协议失败: "..(queryErr or "unknown")) end end -- 淘宝小程序活动奖励领取 -- status: 1=桌面进入奖励(每日1次)2=二楼进入奖励(每日1次)3=添加桌面奖励(仅1次) function tbminiappRewardGet(human, status) if not isTbMiniApp(human) then return Broadcast.sendErr(human, "渠道不匹配") end ObjHuman.updateDaily(human) human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.tbminiapp = human.db.zhuanpan.tbminiapp or {} local tb = human.db.zhuanpan.tbminiapp local rewardConfig = nil if status == 1 then -- 桌面进入奖励(每日1次) local enterTime = tb.enterReward and tb.enterReward.getTime if enterTime and Util.isSameDay(enterTime) then Log.write(Log.LOGID_DEBUG, "[tbminiappRewardGet] 今日已领取桌面进入奖励 account=" .. tostring(human.db.account)) return Broadcast.sendErr(human, "今日已领取桌面进入奖励") end rewardConfig = TB_ENTER_REWARD elseif status == 2 then -- 二楼进入奖励(每日1次) local floorTime = tb.floorReward and tb.floorReward.getTime if floorTime and Util.isSameDay(floorTime) then Log.write(Log.LOGID_DEBUG, "[tbminiappRewardGet] 今日已领取二楼进入奖励 account=" .. tostring(human.db.account)) return Broadcast.sendErr(human, "今日已领取二楼进入奖励") end rewardConfig = TB_SECOND_FLOOR_REWARD elseif status == 3 then -- 添加桌面奖励(仅1次) if not tb.desktopAdded then Log.write(Log.LOGID_DEBUG, "[tbminiappRewardGet] 尚未添加桌面 account=" .. tostring(human.db.account)) return Broadcast.sendErr(human, "尚未添加桌面") end if tb.desktopReward and tb.desktopReward.getTime then Log.write(Log.LOGID_DEBUG, "[tbminiappRewardGet] 添加桌面奖励已领取 account=" .. tostring(human.db.account)) return Broadcast.sendErr(human, "添加桌面奖励已领取") end rewardConfig = TB_DESKTOP_REWARD else return Broadcast.sendErr(human, "无效的status参数") end -- 发放奖励 BagLogic.cleanMomentItemList() for _, v in ipairs(rewardConfig) do BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, v[1], v[2]) end local success, err = pcall(function() BagLogic.addMomentItemList(human, "zhuanpan_once_reward") end) if not success then Log.write(Log.LOGID_DEBUG, "[tbminiappRewardGet] 错误: 添加到背包失败: "..(err or "unknown")) return Broadcast.sendErr(human, "发放奖励失败") end -- 记录领取时间 local nowTime = os.time() if status == 1 then tb.enterReward = tb.enterReward or {} tb.enterReward.getTime = nowTime elseif status == 2 then tb.floorReward = tb.floorReward or {} tb.floorReward.getTime = nowTime elseif status == 3 then tb.desktopReward = tb.desktopReward or {} tb.desktopReward.getTime = nowTime end Log.write(Log.LOGID_DEBUG, "[tbminiappRewardGet] 领取成功 status=" .. tostring(status) .. " account=" .. tostring(human.db.account)) -- 下发查询协议 local querySuccess, queryErr = pcall(function() tbminiappQuery(human, 0) end) if not querySuccess then Log.write(Log.LOGID_DEBUG, "[tbminiappRewardGet] 错误: 发送查询协议失败: "..(queryErr or "unknown")) end end -----------------------游戏圈任务----------------------- -- 游戏圈任务配置 -- reward: {itemId, count} target: 完成目标数量 type: "once"永久/"daily"每日/"weekly"每周 local YOUXI_TASK_CONFIG = { [1] = { reward = {118, 10}, target = 1, taskType = "once" }, -- 首次加入游戏圈: 10连抽 [2] = { reward = {117, 1}, target = 1, taskType = "daily" }, -- 今日点赞1次: 金币100 [3] = { reward = {117, 1}, target = 1, taskType = "daily" }, -- 今日发表评论1次: 金币100 [4] = { reward = {117, 5}, target = 10, taskType = "weekly" }, -- 每周点赞10次: 金币100 [5] = { reward = {117, 5}, target = 20, taskType = "weekly" }, -- 每周发表评论20次: 金币100 } -- 获取本周一0点时间戳 local function getWeekStartTime() local now = os.time() local t = os.date("*t", now) local daysFromMonday = (t.wday - 2) % 7 -- wday: 1=Sun, 2=Mon local todayStart = Util.getDayStartTime(now) return todayStart - daysFromMonday * 86400 end -- 判断时间戳是否在本周(本周一0点)之后 local function isCurrentWeek(timestamp) if not timestamp then return false end return timestamp >= getWeekStartTime() end -- 更新每日 SDK 进度(当天自然日,同天取最大值;跨天把昨天 count 累加入本周合计) -- weekTotal 始终不含当天,getWeekProgress 统一加上今日 count local function updateDailyCount(field, newCount) field = field or {} local now = os.time() if field.dayTime and Util.isSameDay(field.dayTime) then -- 同一天:仅在 newCount > 0 时更新;weekTotal 不动(不含今天) if newCount > 0 then field.count = newCount end else -- 新的一天:把昨天的 count 累加到本周合计,重置今天的记录 local weekTotal = field.weekTotal or 0 if field.weekTime and isCurrentWeek(field.weekTime) then -- 同一周:把昨天(或更早今天之前)的 count 并入 weekTotal field.weekTotal = weekTotal + (field.count or 0) else -- 新的一周:重置,weekTotal 不含今天 field.weekTotal = 0 end field.count = newCount field.dayTime = now field.weekTime = now end return field end -- 获取本周累计进度:weekTotal(不含今天)+ 今日 count local function getWeekProgress(field) if not field then return 0 end local weekTotal = 0 if field.weekTime and isCurrentWeek(field.weekTime) then weekTotal = field.weekTotal or 0 end -- 今天的 count 始终不在 weekTotal 里,直接加上 if field.dayTime and Util.isSameDay(field.dayTime) then return weekTotal + (field.count or 0) end return weekTotal end -- 检查账号下是否有任何角色已领取指定游戏圈任务(账号级别判断) local function checkAccountYouxiTaskClaimed(account, taskId) if not account then return false end local config = YOUXI_TASK_CONFIG[taskId] if not config then return false end LuaMongo.find(DB.db_char, {account = account}, {zhuanpan = 1}) while true do local data = {} if not LuaMongo.next(data) then break end local yt = data.zhuanpan and data.zhuanpan.youxiTask if yt then if config.taskType == "once" then if yt.joinGetTime then return true end elseif config.taskType == "daily" then local field = (taskId == 2) and yt.dailyLike or yt.dailyComment if field and field.getTime and Util.isSameDay(field.getTime) then return true end elseif config.taskType == "weekly" then local field = (taskId == 4) and yt.dailyLike or yt.dailyComment if field and field.weekGetTime and isCurrentWeek(field.weekGetTime) then return true end end end end return false end -- 游戏圈任务查询(前端上传 SDK 数据,后端存储并计算进度) function youxiTaskQuery(human, msg) local msgRet = Msg.gc.GC_ZHUANPAN_YOUXI_TASK_QUERY if not msgRet then Log.write(Log.LOGID_DEBUG, "[youxiTaskQuery] 错误: msgRet为nil") return end human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.youxiTask = human.db.zhuanpan.youxiTask or {} local yt = human.db.zhuanpan.youxiTask -- 存储 SDK 上报数据并更新进度 if msg then -- 任务1:加入游戏圈(joinTime > 0 表示已加入) if msg.joinTime and msg.joinTime > 0 and not yt.joined then yt.joined = true end -- 任务2/4:点赞(count=0 时也需调用,以便跨天时将昨日 count 累入 weekTotal) if msg.likeCount ~= nil then yt.dailyLike = updateDailyCount(yt.dailyLike, msg.likeCount) end -- 任务3/5:评论(同上) if msg.commentCount ~= nil then yt.dailyComment = updateDailyCount(yt.dailyComment, msg.commentCount) end end local ok, err = pcall(function() for taskId = 1, 5 do local config = YOUXI_TASK_CONFIG[taskId] local taskData = msgRet.tasks[taskId] taskData.taskId = taskId taskData.target = config.target Grid.makeItem(taskData.reward, config.reward[1], config.reward[2]) if config.taskType == "once" then taskData.progress = yt.joined and 1 or 0 local claimed = yt.joinGetTime or checkAccountYouxiTaskClaimed(human.db.account, taskId) if claimed then taskData.status = 2 elseif yt.joined then taskData.status = 1 else taskData.status = 0 end elseif config.taskType == "daily" then local field = (taskId == 2) and yt.dailyLike or yt.dailyComment local dayCount = (field and field.dayTime and Util.isSameDay(field.dayTime)) and (field.count or 0) or 0 taskData.progress = math.min(dayCount, config.target) local getTime = field and field.getTime local claimed = (getTime and Util.isSameDay(getTime)) or checkAccountYouxiTaskClaimed(human.db.account, taskId) if claimed then taskData.status = 2 elseif dayCount >= config.target then taskData.status = 1 else taskData.status = 0 end elseif config.taskType == "weekly" then local field = (taskId == 4) and yt.dailyLike or yt.dailyComment local weekCount = getWeekProgress(field) taskData.progress = math.min(weekCount, config.target) local weekGetTime = field and field.weekGetTime local claimed = (weekGetTime and isCurrentWeek(weekGetTime)) or checkAccountYouxiTaskClaimed(human.db.account, taskId) if claimed then taskData.status = 2 elseif weekCount >= config.target then taskData.status = 1 else taskData.status = 0 end end end msgRet.tasks[0] = 5 end) if not ok then Log.write(Log.LOGID_DEBUG, "[youxiTaskQuery] 错误: " .. tostring(err)) return end if human.fd then Msg.send(msgRet, human.fd) end end -- 游戏圈任务领取(前端协议调用) -- taskId: 1-5 function youxiTaskGetReward(human, taskId) local config = YOUXI_TASK_CONFIG[taskId] if not config then Log.write(Log.LOGID_DEBUG, "[youxiTaskGetReward] 无效taskId=" .. tostring(taskId)) return Broadcast.sendErr(human, "无效的任务ID") end human.db.zhuanpan = human.db.zhuanpan or {} human.db.zhuanpan.youxiTask = human.db.zhuanpan.youxiTask or {} local yt = human.db.zhuanpan.youxiTask local now = os.time() -- 校验条件 & 重复领取(账号级别判断,同账号多角色共享) -- 先查当前角色内存,没有再查 DB 其他角色(与美团订阅奖励模式一致) local account = human.db.account if config.taskType == "once" then local claimed = yt.joinGetTime or checkAccountYouxiTaskClaimed(account, taskId) if claimed then return Broadcast.sendErr(human, "已领取过") end if not yt.joined then return Broadcast.sendErr(human, "尚未加入游戏圈") end elseif config.taskType == "daily" then local field = (taskId == 2) and yt.dailyLike or yt.dailyComment local getTime = field and field.getTime local claimed = (getTime and Util.isSameDay(getTime)) or checkAccountYouxiTaskClaimed(account, taskId) if claimed then return Broadcast.sendErr(human, "今日已领取") end local dayCount = (field and field.dayTime and Util.isSameDay(field.dayTime)) and (field.count or 0) or 0 if dayCount < config.target then return Broadcast.sendErr(human, "任务未完成") end elseif config.taskType == "weekly" then local field = (taskId == 4) and yt.dailyLike or yt.dailyComment local weekGetTime = field and field.weekGetTime local claimed = (weekGetTime and isCurrentWeek(weekGetTime)) or checkAccountYouxiTaskClaimed(account, taskId) if claimed then return Broadcast.sendErr(human, "本周已领取") end if getWeekProgress(field) < config.target then return Broadcast.sendErr(human, "任务未完成") end end -- 发放奖励 BagLogic.cleanMomentItemList() BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, config.reward[1], config.reward[2]) local success, err = pcall(function() BagLogic.addMomentItemList(human, "zhuanpan_once_reward") end) if not success then Log.write(Log.LOGID_DEBUG, "[youxiTaskGetReward] 发放奖励失败 task=" .. taskId .. " err=" .. tostring(err)) return Broadcast.sendErr(human, "发放奖励失败") end -- 记录领取时间 if config.taskType == "once" then yt.joinGetTime = now elseif config.taskType == "daily" then local key = (taskId == 2) and "dailyLike" or "dailyComment" yt[key] = yt[key] or {} yt[key].getTime = now elseif config.taskType == "weekly" then local key = (taskId == 4) and "dailyLike" or "dailyComment" yt[key] = yt[key] or {} yt[key].weekGetTime = now end Log.write(Log.LOGID_DEBUG, "[youxiTaskGetReward] 领取成功 task=" .. taskId .. " account=" .. tostring(human.db.account)) -- 领取后下发最新查询(不传 msg,不更新 SDK 数据) youxiTaskQuery(human, nil) end -- SDK 回调奖励发放(内部调用,与任务奖励独立) -- items: {{itemId, count}, ...} function youxiSdkReward(human, items) if not items or #items == 0 then Log.write(Log.LOGID_DEBUG, "[youxiSdkReward] items为空 account=" .. tostring(human.db.account)) return end BagLogic.cleanMomentItemList() for _, v in ipairs(items) do BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, v[1], v[2]) end local success, err = pcall(function() BagLogic.addMomentItemList(human, "zhuanpan_once_reward") end) if not success then Log.write(Log.LOGID_DEBUG, "[youxiSdkReward] 发放失败 err=" .. tostring(err) .. " account=" .. tostring(human.db.account)) else Log.write(Log.LOGID_DEBUG, "[youxiSdkReward] 发放成功 cnt=" .. #items .. " account=" .. tostring(human.db.account)) end end