Browse Source

同步30test

gitxsm 1 month ago
parent
commit
681b7472fa
33 changed files with 902 additions and 195 deletions
  1. 32 0
      script/common/CommonDB.lua
  2. 24 1
      script/common/InnerHandler.lua
  3. 31 0
      script/common/InnerProto.lua
  4. 4 0
      script/common/InnerProtoID.lua
  5. 2 0
      script/common/Lang.lua
  6. 4 0
      script/common/ProtoID.lua
  7. 1 1
      script/module/absAct/AbsActLogic.lua
  8. 23 23
      script/module/absAct/MangHeLogic.lua
  9. 17 8
      script/module/bag/Grid.lua
  10. 40 37
      script/module/battle/BattleGift.lua
  11. 4 1
      script/module/battle/BattleLogic.lua
  12. 2 0
      script/module/battle/Proto.lua
  13. 27 0
      script/module/combat/BeSkill.lua
  14. 36 0
      script/module/combat/CombatBuff.lua
  15. 34 0
      script/module/combat/TargetMode.lua
  16. 1 1
      script/module/drawCard/DrawCardLogic.lua
  17. 34 0
      script/module/equip/EquipLogicGrid.lua
  18. 29 11
      script/module/hero/HeroArtifacts.lua
  19. 32 18
      script/module/hero/HeroEquip.lua
  20. 19 3
      script/module/hero/HeroExclusiveWeapon.lua
  21. 16 2
      script/module/hero/HeroPubLogic.lua
  22. 18 3
      script/module/hero/HeroTianYuan.lua
  23. 2 2
      script/module/role/RoleAttr.lua
  24. 15 0
      script/module/scene/Handler.lua
  25. 61 42
      script/module/serverCommerce/ServerCommerceActBattleGroundCS.lua
  26. 3 0
      script/module/serverCommerce/ServerCommerceMiddle.lua
  27. 17 0
      script/module/talisman/TalismanLogic.lua
  28. 13 0
      script/module/zhuanpan/Handler.lua
  29. 21 0
      script/module/zhuanpan/Proto.lua
  30. 229 7
      script/module/zhuanpan/ZhuanpanLogic.lua
  31. 31 27
      webServer/src/channels/handlers/MiniappChannelHandler.ts
  32. 20 7
      webServer/src/controller/ApiController.ts
  33. 60 1
      webServer/src/mongo/mongodb.ts

+ 32 - 0
script/common/CommonDB.lua

@@ -42,6 +42,7 @@ KEY_COMMERCEACT_INFO = "commerceActInfo"				-- 跨服活动信息
 KEY_JJCLADDER_INFO = "jjcNewladderInfo"					-- 天梯赛信息
 KEY_COMMERCEACT_MIDDLE_INFO = "commerceMiddleActInfo"	-- 中心服跨服商业活动信息
 KEY_BAN_DATA = "banData"								-- 封禁数据
+KEY_DESKTOP_DATA = "desktopData"					-- 桌面添加数据(账号级)
 KEY_REBATE_DATA = "rebateData"							-- 渠道返利数据
 KEY_ANOTHERWORLDBATTLE_START_TI = "anotherWorldBattleStart" -- 最近一轮异界之战开启时间
 KEY_LEVELGIFT_GETRECORD = "levelGiftGetRecord"			-- 送万元充值/等级礼包领取记录
@@ -569,4 +570,35 @@ function SetCommerceMiddleAct_ByKey(nKey, tData)
 	db.commerceMiddleActInfo[nKey] = tData
 
 	updateValue(KEY_COMMERCEACT_MIDDLE_INFO, db.commerceMiddleActInfo)
+end
+
+-- 桌面添加数据(账号级,多区服共享)
+-- 结构:{ [newUniqueTag] = { ["channelId_platform"] = true, ... }, ... }
+
+local function makeDesktopAccountKey(channelId, serverId, account)
+	return tostring(channelId) .. "|" .. tostring(serverId) .. "|" .. tostring(account)
+end
+
+function GetDesktopData(channelId, serverId, account)
+	local data = db[KEY_DESKTOP_DATA]
+	if not data then return nil end
+	local accountKey = makeDesktopAccountKey(channelId, serverId, account)
+	return data[accountKey]
+end
+
+function SetDesktopData(channelId, serverId, account, platform)
+	local accountKey = makeDesktopAccountKey(channelId, serverId, account)
+	local platformKey = tostring(channelId) .. "_" .. tostring(platform)
+	local data = db[KEY_DESKTOP_DATA] or {}
+	data[accountKey] = data[accountKey] or {}
+	data[accountKey][platformKey] = true
+	db[KEY_DESKTOP_DATA] = data
+	updateValue(KEY_DESKTOP_DATA, data)
+end
+
+function IsDesktopAdded(channelId, serverId, account, platform)
+	local accountData = GetDesktopData(channelId, serverId, account)
+	if not accountData then return false end
+	local platformKey = tostring(channelId) .. "_" .. tostring(platform)
+	return accountData[platformKey] == true
 end

+ 24 - 1
script/common/InnerHandler.lua

@@ -23,6 +23,7 @@ local MiddleCommonLogic = require("middle.MiddleCommonLogic")
 local CommerceMiddle = require("serverCommerce.ServerCommerceMiddle")
 local MiddleCommonRank = require("middle.MiddleCommonRank")
 local BanLogic = require("scene.BanLogic")
+local ZhuanpanLogic = require("zhuanpan.ZhuanpanLogic")
 local JjcNewLadderMidder = require("jjcnewladder.jjcNewLadderMiddle")
 local RebateLogic = require("platform.RebateLogic")
 local ServerCommerceActPeakBettleMiddle = require("serverCommerce.ServerCommerceActPeakBettleMiddle")
@@ -1032,4 +1033,26 @@ function LW_ANOTHERWORLDBATTLE_UIONMORALE_DO(fd, msg)
 end
 function WL_ANOTHERWORLDBATTLE_UIONMORALE_DO(fd, msg)
     AnotherWorldBattleNS.C2N_MyUnionMoraleInfo_Response(msg)
-end
+end
+
+
+----------------------- 桌面添加开始 ---------------------------
+
+-- 普通服→中心服:上报添加桌面,中心服写入并返回最新状态
+function LW_DESKTOP_SET(fd, msg)
+    if _G.is_middle ~= true then return end
+    ZhuanpanLogic.CS_DesktopSet(msg)
+end
+
+-- 普通服→中心服:查询桌面状态
+function LW_DESKTOP_QUERY(fd, msg)
+    if _G.is_middle ~= true then return end
+    ZhuanpanLogic.CS_DesktopQuery(msg)
+end
+
+-- 中心服→普通服:查询结果回包,普通服转发给客户端
+function WL_DESKTOP_QUERY(fd, msg)
+    ZhuanpanLogic.NS_DesktopQueryResult(msg)
+end
+
+----------------------- 桌面添加结束 ---------------------------

+ 31 - 0
script/common/InnerProto.lua

@@ -750,6 +750,37 @@ WL_REBATE_OK = {
 }
 -------------------- 返利结束 -----------------------------------
 
+-------------------- 桌面添加开始 -----------------------------------
+
+-- 普通服→中心服:上报添加桌面(仅写入,无需回包)
+LW_DESKTOP_SET = {
+  {"nSrcServerID",  "int"},     -- 来源区服ID
+  {"channelId",     "int"},     -- 渠道ID
+  {"serverId",      "int"},     -- 区服ID
+  {"account",       "string"},  -- 账号
+  {"platform",      "string"},  -- 平台标识
+}
+
+-- 普通服→中心服:查询桌面状态
+LW_DESKTOP_QUERY = {
+  {"nSrcServerID",  "int"},     -- 来源区服ID(用于路由回包)
+  {"channelId",     "int"},     -- 渠道ID
+  {"serverId",      "int"},     -- 区服ID
+  {"account",       "string"},  -- 账号
+  {"platform",      "string"},  -- 平台标识
+}
+
+-- 中心服→普通服:查询结果回包
+WL_DESKTOP_QUERY = {
+  {"channelId",       "int"},     -- 渠道ID
+  {"serverId",        "int"},     -- 区服ID
+  {"account",         "string"},  -- 账号
+  {"platform",        "string"},  -- 平台标识
+  {"isDesktopAdded",  "int"},     -- 是否已添加 0否 1是
+}
+
+-------------------- 桌面添加结束 -----------------------------------
+
 
 --------------------------诸神圣域------------------------------------
 -- 普通服向跨服请求排行榜数据

+ 4 - 0
script/common/InnerProtoID.lua

@@ -189,3 +189,7 @@ _ENV[175] = 'LW_BATTLEGROUND_MATCHLIST_QUERY'
 _ENV[176] = 'WL_BATTLEGROUND_MATCHLIST_QUERY'
 _ENV[177] = 'LW_BATTLEGROUND_ACT_END'
 
+_ENV[178] = 'LW_DESKTOP_SET'       -- 普通服→中心服:上报添加桌面
+_ENV[179] = 'LW_DESKTOP_QUERY'     -- 普通服→中心服:查询桌面状态
+_ENV[180] = 'WL_DESKTOP_QUERY'     -- 中心服→普通服:查询结果回包
+

+ 2 - 0
script/common/Lang.lua

@@ -539,6 +539,8 @@ ABS_ARBORDAY_MAYI_DESC_4 = [[活动期间每进行一竞技场挑战可获得1
 ABS_ZHANBU_LUNPAN_ERR = [[占卜轮盘奖励已全部获取,无法再获取了]]
 ABS_SURPRISE_CHEST_GET_SUCESS = [[领取成功]]
 
+ABS_JYZH_NOT_OPEN = [[服务器≥5天且每周五维护后开启]]
+
 SKIN_CONF_ERR = [[配置错误]]
 SKIN_PARAM_ERR = [[参数错误]]
 

+ 4 - 0
script/common/ProtoID.lua

@@ -1827,3 +1827,7 @@ _ENV[1901]="CG_ZHUANPAN_YOUXI_TASK_QUERY"
 _ENV[1902]="GC_ZHUANPAN_YOUXI_TASK_QUERY"
 _ENV[1903]="CG_ZHUANPAN_YOUXI_TASK_GET"
 
+_ENV[1904]="CG_ZHUANPAN_DY_DESKTOP_SET"
+_ENV[1905]="CG_ZHUANPAN_DY_DESKTOP_QUERY"
+_ENV[1906]="GC_ZHUANPAN_DY_DESKTOP_QUERY"
+

+ 1 - 1
script/module/absAct/AbsActLogic.lua

@@ -300,7 +300,7 @@ function actDetailQuery(human, id)
   
     if startFlag == nil then
         checkAbsActClean(human, id)
-        return Broadcast.sendErr(human, Lang.ACT_NOT_START)
+        return --Broadcast.sendErr(human, Lang.ACT_NOT_START)
     end
 
     -- 确保活动数据已初始化

+ 23 - 23
script/module/absAct/MangHeLogic.lua

@@ -381,23 +381,23 @@ function mangHeGift(human, id, buyConf, isFirst, cnt, buyNum)
     AbsActLogic.checkAbsActClean(human, id)
     local config = AbsActExcel.mangHeGift[1]
     local buyCnt = human.db.absAct[id].buyCnt and human.db.absAct[id].buyCnt or 0
-    if config.cnt <= buyCnt then
-        return 
-    end
-
-    -- if buyCnt + buyNum >= config.cnt  then
-    --     return
+    -- if config.cnt <= buyCnt then
+    --     return 
     -- end
+
+    if buyCnt + buyNum > config.cnt  then
+        return Broadcast.sendErr(human, Lang.COPY_BUY_CNT_ERR_CNT)
+    end
     
-    -- human.db.absAct[id].buyCnt = buyCnt + buyNum
-    -- local tItemList = {}
-    -- for index, v in ipairs(config.reward) do
-    --     table.insert(tItemList, {v[1], v[2]*buyNum})
-    -- end
-    -- BagLogic.addItemList(human, tItemList, "abs_manghe")
+    human.db.absAct[id].buyCnt = buyCnt + buyNum
+    local tItemList = {}
+    for index, v in ipairs(config.reward) do
+        table.insert(tItemList, {v[1], v[2]*buyNum})
+    end
+    BagLogic.addItemList(human, tItemList, "abs_manghe")
 
-    human.db.absAct[id].buyCnt = buyCnt + 1
-    BagLogic.addItemList(human, config.reward, "abs_manghe")
+    -- human.db.absAct[id].buyCnt = buyCnt + 1
+    -- BagLogic.addItemList(human, config.reward, "abs_manghe")
     query(human, id)
 end
 
@@ -513,13 +513,13 @@ function isOpen(human, YYInfo, funcConfig)
     return AbsActLogic.isStarted(human, funcConfig.funcID)
 end
 
--- function GetRemainNum(human, nBuyID)
---     local config = AbsActExcel.mangHeGift[1]
---     if config.buyID ~= nBuyID then
---         return 0
---     end
+function GetRemainNum(human, nBuyID)
+    local config = AbsActExcel.mangHeGift[1]
+    if config.buyID ~= nBuyID then
+        return 0
+    end
 
---     AbsActLogic.checkAbsActClean(human, MANGHE_ABS_ID)
---     local buyCnt = human.db.absAct[MANGHE_ABS_ID].buyCnt and human.db.absAct[MANGHE_ABS_ID].buyCnt or 0
---     return buyCnt < config.cnt and (config.cnt - buyCnt) or 0
--- end
+    AbsActLogic.checkAbsActClean(human, MANGHE_ABS_ID)
+    local buyCnt = human.db.absAct[MANGHE_ABS_ID].buyCnt and human.db.absAct[MANGHE_ABS_ID].buyCnt or 0
+    return buyCnt < config.cnt and (config.cnt - buyCnt) or 0
+end

+ 17 - 8
script/module/bag/Grid.lua

@@ -11,9 +11,10 @@ local ItemDefine = require("bag.ItemDefine")
 local SuipianLogic = require("bag.SuipianLogic")
 local RoleAttr = require("role.RoleAttr")
 local EquipLogic = require("equip.EquipLogic")
+local EquipLogicGrid = require("equip.EquipLogicGrid")
 
 -- 填充装备,道具信息 
-function makeItem(net, itemID, itemCnt, shuijingAttrID, itemGrid, itemIndex, opFlag, equipQuality, gemBonus, sourceType, isShowEquipBaseAttrArea)
+function makeItem(net, itemID, itemCnt, shuijingAttrID, itemGrid, itemIndex, opFlag, equipQuality, gemBonus, sourceType, human)
 	local itemConfig = ItemDefine.getConfig(itemID)
 	net.id = itemConfig and itemID or 0 
 	net.cnt = itemConfig and itemCnt or 0
@@ -52,7 +53,7 @@ function makeItem(net, itemID, itemCnt, shuijingAttrID, itemGrid, itemIndex, opF
 
     makeItemSuipian(net, itemConfig)
     makeItemFuwen(net, itemID, itemConfig, itemGrid, itemIndex)
-    makeItemEquip(net, itemConfig, itemGrid, itemIndex, shuijingAttrID, equipQuality, gemBonus, isShowEquipBaseAttrArea)
+    makeItemEquip(net, itemConfig, itemGrid, itemIndex, shuijingAttrID, equipQuality, gemBonus, human)
 end
 
 function makeFuwenSkill(net, skillID, skillLockList)
@@ -143,7 +144,7 @@ function makeItemFuwen(net, itemID, itemConfig, fuwenGrid, fuwenIndex)
 	end
 end
 
-function makeItemEquip(net, itemConfig, equipGrid, equipIndex, shuijingAttrID, equipQuality, gemBonus, isShowEquipBaseAttrArea)
+function makeItemEquip(net, itemConfig, equipGrid, equipIndex, shuijingAttrID, equipQuality, gemBonus, human)
 	if itemConfig.mainType ~= ItemDefine.MAINTYPE_EQUIP then
 		return
 	end
@@ -332,26 +333,34 @@ function makeItemEquip(net, itemConfig, equipGrid, equipIndex, shuijingAttrID, e
 	net.equip[1].suit = net.equip[1].suit or {}
 	net.equip[1].suit[0] = 0
 	if itemConfig.suitIm then
+		local suitImTemp = itemConfig.suitIm
+		if itemConfig.jobSuitIm and next(itemConfig.jobSuitIm) then
+			suitImTemp = Util.copyTable(itemConfig.suitIm)
+			local jobId = EquipLogicGrid.GetEquipOwnerJob(human, equipGrid)
+			local attrInfo = itemConfig.jobSuitIm[jobId]
+			EquipLogicGrid.MergeEquipSuitIm(suitImTemp, attrInfo)
+		end
+
 		net.equip[1].suit = net.equip[1].suit or {}
 		net.equip[1].suit[0] = 1
 		net.equip[1].suit[1] = net.equip[1].suit[1] or {}
 		net.equip[1].suit[1].attr = net.equip[1].suit[1].attr or {}
-		net.equip[1].suit[1].attr[0] = #itemConfig.suitIm
+		net.equip[1].suit[1].attr[0] = #suitImTemp -- #itemConfig.suitIm
 
 		net.equip[1].suit[1].gemAttr[0] = 0
 		if gemBonus then
-			net.equip[1].suit[1].gemAttr[0] = #itemConfig.suitIm
+			net.equip[1].suit[1].gemAttr[0] = #suitImTemp -- #itemConfig.suitIm
 		end
 
 		for i=1,net.equip[1].suit[1].attr[0] do
 			net.equip[1].suit[1].attr[i] = net.equip[1].suit[1].attr[i] or {}
-			net.equip[1].suit[1].attr[i].key = itemConfig.suitIm[i][1]
-			net.equip[1].suit[1].attr[i].value = itemConfig.suitIm[i][2]
+			net.equip[1].suit[1].attr[i].key = suitImTemp[i][1] -- itemConfig.suitIm[i][1]
+			net.equip[1].suit[1].attr[i].value = suitImTemp[i][2] -- itemConfig.suitIm[i][2]
 
 
 			if gemBonus and (gemBonus[i+1] or gemBonus.sp_suit) then
 				net.equip[1].suit[1].gemAttr[i] = net.equip[1].suit[1].gemAttr[i] or {}
-				net.equip[1].suit[1].gemAttr[i].key = itemConfig.suitIm[i][1]
+				net.equip[1].suit[1].gemAttr[i].key = suitImTemp[i][1] -- itemConfig.suitIm[i][1]
 
 				if itemConfig.subType == ItemDefine.EQUIP_SUBTYPE_RING or itemConfig.subType == ItemDefine.EQUIP_SUBTYPE_AMULET then
 					net.equip[1].suit[1].gemAttr[i].value = gemBonus.sp_suit * 100

+ 40 - 37
script/module/battle/BattleGift.lua

@@ -163,46 +163,47 @@ end
 
 -- 外部调用,跨天处理
 function updateDaily(human)
-    -- local battleGiftData = getData(human)
-    -- if not battleGiftData then
-    --     calcBeforeVal(human)
-    --     updateRedDot(human)
-    --     return
-    -- end
+    local battleGiftData = getData(human)
+    if not battleGiftData then
+        calcBeforeVal(human)
+        updateRedDot(human)
+        return
+    end
 
-    -- resetData(human)
+    resetData(human)
 
-    -- updateRedDot(human)
+    updateRedDot(human)
 end
 
 -- 外部调用, 登录处理
 function onLogin(human)
-    -- local battleGiftData = getData(human)
-    -- if not battleGiftData then
-    --     calcBeforeVal(human)
-    --     updateRedDot(human)
-    -- end
+    local battleGiftData = getData(human)
+    if not battleGiftData then
+        calcBeforeVal(human)
+        updateRedDot(human)
+    end
 end
 
 -- 外部调用, 通关新的关卡
 function StageClearHandle(human, currentStage, stageType)
-    -- local val = getStageVal(stageType, currentStage)
-    -- if val > 0 then
-    --     addDailyStoreVal(human, val)
-    -- end
+    local val = getStageVal(stageType, currentStage)
+    if val > 0 then
+        addDailyStoreVal(human, val)
+        updateRedDot(human)
+    end
 end
 
 -- 外部调用, 入口处是否有红点
 function isDot(human)
-    -- local battleGiftData = getData(human)
-    -- if not battleGiftData then
-    --     return false
-    -- end
+    local battleGiftData = getData(human)
+    if not battleGiftData then
+        return false
+    end
 
-    -- local dailyStoreVal = battleGiftData.dailyStoreVal or 0
-    -- if dailyStoreVal <= 0 then
-    --     return false
-    -- end
+    local dailyStoreVal = battleGiftData.dailyStoreVal or 0
+    if dailyStoreVal <= 0 then
+        return false
+    end
 
     -- local dailyGetVal = battleGiftData.dailyGetVal or 0
     -- local dailyMaxVal = calclDailyMaxGetVal(human)
@@ -210,25 +211,25 @@ function isDot(human)
     --     return false
     -- end
 
-    -- return true
+    return true
 end
 
 -- 外部调用, 充值处理接口
 function charge(human, nAllPrice, buyID)
-    -- if not table.find(EliteDefine.BATTLEGIFT_BUYID_LIST, buyID) then
-    --     return
-    -- end
+    if not table.find(EliteDefine.BATTLEGIFT_BUYID_LIST, buyID) then
+        return
+    end
 
-    -- local battleGiftData = getData(human)
-    -- if battleGiftData and battleGiftData.buyIdList and table.find(battleGiftData.buyIdList, buyID) then
-    --     return
-    -- end
+    local battleGiftData = getData(human)
+    if battleGiftData and battleGiftData.buyIdList and table.find(battleGiftData.buyIdList, buyID) then
+        return
+    end
 
-    -- insertBuyIdList(human, buyID)
+    insertBuyIdList(human, buyID)
 
-    -- updateRedDot(human)
+    updateRedDot(human)
 
-    -- BattleGift_Query(human)
+    BattleGift_Query(human)
 end
 
 
@@ -250,6 +251,7 @@ function BattleGift_Query(human)
     msgRet.dailyStoreVal = battleGiftData and battleGiftData.dailyStoreVal or 0
     msgRet.dailyGetVal = battleGiftData and battleGiftData.dailyGetVal or 0
     msgRet.dailyMaxVal = calclDailyMaxGetVal(human)
+    msgRet.dailyLimitVal = 0
 
     local targetBuyId = 0
     for _, buyId in ipairs(EliteDefine.BATTLEGIFT_BUYID_LIST) do
@@ -259,6 +261,7 @@ function BattleGift_Query(human)
         end
     end
 
+    msgRet.dailyLimitVal = EliteDefine.BATTLEGIFT_BUYID_2_LIMIT[targetBuyId] or 0
     BuyLogic.fontBuyItem(human, msgRet.buyItem, targetBuyId)
 
     Msg.send(msgRet, human.fd)
@@ -293,7 +296,7 @@ function BattleGift_Get(human)
 
     local itemId = EliteDefine.BATTLEGIFT_2_ITEMID
     local itemCnt = math.floor(getVal / 100)
-    BagLogic.addItem(human, itemId, itemCnt, LOGTYPE)
+    BagLogic.addItemList(human, { {itemId, itemCnt} }, LOGTYPE)
 
     BattleGift_Query(human)
 

+ 4 - 1
script/module/battle/BattleLogic.lua

@@ -3515,6 +3515,9 @@ function mopupFight(human)
         return Broadcast.sendErr(human, Lang.BATTLE_MOPUP_CNT_OVER)
     end
 
+    local msgRet = Msg.gc.GC_BATTLE_MOPUP_FIGHT
+    msgRet.isDailyFirstMopup = human.db.mopupFreeCnt <= 0 and 1 or 0
+
     local bUseFree = false
     if not TequanShopLogic.isActiveMopup(human) then
         if human.db.mopupDoCnt >= BATTLE_MOPUP_CNT and 0 >= nNowAddFreeCnt then
@@ -3566,7 +3569,7 @@ function mopupFight(human)
 
     -- local config = BattleExcel.node[guajiID]
     local config = tBattleConfig.node[guajiID]
-    local msgRet = Msg.gc.GC_BATTLE_MOPUP_FIGHT
+    -- local msgRet = Msg.gc.GC_BATTLE_MOPUP_FIGHT
 
     local vipExpAdd =(VipLogic.getPowerArgs(human, VipLogic.VIP_POWER7) or 0) / 100
     local vipJinAdd =(VipLogic.getPowerArgs(human, VipLogic.VIP_POWER8) or 0) / 100

+ 2 - 0
script/module/battle/Proto.lua

@@ -248,6 +248,7 @@ GC_BATTLE_MOPUP_FIGHT = {
 	{"qingbao",	      1,	  "int"},	            --情报
     {"item",40,ItemData},
 	{"double",        1,      "byte"},
+	{"isDailyFirstMopup",     1,      "byte"}, 		-- 是否是当天的第一次扫荡, 0-不是, 1-是
 }
 
 -- 扫荡查询
@@ -487,6 +488,7 @@ GC_BATTLEGIFT_QUERY = {
 	{"dailyGetVal",		1,	    "int"},	       -- 当日已领礼金数量
 	{"dailyMaxVal",		1,	    "int"},	       -- 当日可领礼金数量
 	{"buyItem",     	1,      BuyItem},      -- 购买信息, BuyItem.buyID为0, 则表示所有购买项均已购买
+	{"dailyLimitVal",	1,	    "int"},	       -- 充值当前购买项后,增加的"每日可领取上限值"
 }
 
 -- 闯关礼金领取

+ 27 - 0
script/module/combat/BeSkill.lua

@@ -504,6 +504,29 @@ local function isCanRevive(obj, attacker , data)
 	return true
 end
 
+-- 连击检测
+local function comboCheck(targetObj, side)
+	if Skill.GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
+
+	for _,pos in ipairs(CombatDefine.SIDE2POS[side]) do
+		local obj = CombatImpl.objList[pos]
+		if obj and obj.beSkillList then
+			for _, skillInfo in ipairs(obj.beSkillList[BESKILL_TYPE72] or {}) do
+				local skillCfg = Skill.GetSkillConfig(skillInfo[1])
+				if skillCfg and skillCfg.cmd == "comboProb" then
+					local comboProbVal = skillCfg.beSkillArgs[1] or 0
+					local randval = math.random(0, 10000)
+					if comboProbVal >= randval then
+						CombatImpl.comboList[#CombatImpl.comboList + 1] = {targetObj, 1}
+					end
+				end
+			end
+		end
+    end
+end
+
+
+
 function onSkillID(obj,skillID)
 	--local skillConfig = SkillExcel[skillID]
 	local skillConfig = Skill.GetSkillConfig(skillID)
@@ -945,8 +968,12 @@ function onHit(attacker,targets,skillID)
 			end
 		end
 	end
+
+	comboCheck(attacker, side)
 end
 
+
+
 function onHp(obj, hurt, attackPos)
 	if obj.beSkillList[BESKILL_TYPE3] then
 		for _,v in ipairs(obj.beSkillList[BESKILL_TYPE3]) do

+ 36 - 0
script/module/combat/CombatBuff.lua

@@ -306,6 +306,37 @@ local function isMiankong(obj, cmd, attacker, skillKongRate)
 	end
 end
 
+-- 是否可能被禁止增加buff
+local function isBanBuff(obj, cmd)
+	initCombatBufferType()
+	if BUFFER_COMBAT_TYPE[cmd] and BUFFER_COMBAT_TYPE[cmd] == 2 then
+		local res, _, ind = isStatus(obj, { "linglun" })
+		if not res then
+			return false
+		end
+
+		local buffList = getBuffer(obj)
+		local buff = buffList[ind]
+		if not buff then
+			return false
+		end
+
+		local buffCfg = GetBuffConfig(buff.id)
+		if not buffCfg then
+			return false
+		end
+
+		local banProbVal = buffCfg.args[1] or 0
+		local randval = math.random(0, 10000)
+		if banProbVal >= randval then
+			return true
+		end
+	end
+
+	return false
+end
+
+
 function getStatus(obj)
 	return obj.bufferCmd or {}
 end
@@ -635,6 +666,11 @@ local function canAdd(obj, id, random, attacker, skillConfig)
 	-- 		return
 	-- 	end
 	-- end
+
+	if isBanBuff(obj, conf.cmd) then
+		return
+	end
+
 	return true
 end
 --根据cmd删除buff

+ 34 - 0
script/module/combat/TargetMode.lua

@@ -1401,6 +1401,39 @@ local function handler37(attacker,targetMode,skillTargets)
 end
 
 
+-- 从全体中根据职业选择
+--[[
+	@param2 = {
+		handlerID,
+		side    0: 全部双方  1:敌方 2: 己方
+		jobList    -- 职业集合
+		onjCnt 目标数量, 默认1
+	}
+]]
+local function handler38(attacker,targetMode,skillTargets)
+	local targetSide = getTargetSide(attacker,targetMode)
+	local jobList = targetMode[3] or {}
+	local cnt = targetMode[4] or 1
+
+	local targetList = {}
+	for _,pos in ipairs(CombatDefine.DEFAULT_TARGET_POS3[targetSide]) do
+		local obj = getObj(pos)
+		if canTarget(obj) and table.find(jobList, obj.job) then
+			targetList[#targetList+1] = obj
+		end
+	end
+
+
+	for _, obj in ipairs (targetList) do
+		if #targets >= cnt then
+			break
+		end
+
+		targets[#targets + 1] = obj
+	end
+end
+
+
 ------------------------------ 分界线 ------------------------------
 -- 目前是一样了,等策划配置好skill表后删掉 @mafei
 local function handler3(attacker,targetMode)
@@ -1446,5 +1479,6 @@ handler[34] = handler34	--从技能目标中根据职业选择
 handler[35] = handler35	--从全体中根据种族选择
 handler[36] = handler36	--按照属性X排序,选择前Y个目标, 且排除技能施放者,属性值需要比技能施放者高/低
 handler[37] = handler37 -- 在技能目标中选择友方/敌方
+handler[38] = handler38	--从全体中根据职业选择
 
 --对象选择器end

+ 1 - 1
script/module/drawCard/DrawCardLogic.lua

@@ -727,7 +727,7 @@ local function draw(human, id, op, actConfig, skip,isAct)
     local state, endTime, starTime = AbsActLogic.isStarted(human, NewHeroLogic.ABS_ACT_ID)
 
     if id == DRAWCARD_ID8 and not state then
-        return Broadcast.sendErr(human, Lang.DRILL_NOT_OPEN)
+        return Broadcast.sendErr(human, Lang.ABS_JYZH_NOT_OPEN)
     end
 
 

+ 34 - 0
script/module/equip/EquipLogicGrid.lua

@@ -7,6 +7,8 @@ local EquipExcel = require("excel.equip").equip
 -- local EquipLogic = require("equip.EquipLogic")
 local ItemDefine = require("bag.ItemDefine")
 local Util = require("common.Util")
+local HeroLogic = require("hero.HeroLogic")
+local HeroExcel = require("excel.hero")
 
 -- 装备品质
 EQUIP_COLOR_1 = 1   -- 绿
@@ -106,4 +108,36 @@ function createTempGrid(id, washAttr, washQuality)
    equip.attr = washAttr     --当前属性
    equip.quality = washQuality     --默认为1
    return equip
+end
+
+
+-- 获取穿戴装备的英雄的职业
+function GetEquipOwnerJob(human, equipGrid)
+   local jobId = 2 --默认是战士职业
+   if not human or not equipGrid or not equipGrid.putUuid then
+      return jobId
+   end
+
+   local heroGrid = HeroLogic.getHeroGridByUuid(human, equipGrid.putUuid)
+   if not heroGrid then
+      return jobId
+   end
+
+   local heroCfg = HeroExcel.hero[heroGrid.id]
+   if not heroCfg then
+      return jobId
+   end
+
+   jobId = heroCfg.job or 0
+
+   return jobId
+end
+
+-- 合并装备套装属性(用于装备等级>=15级的装备)
+function MergeEquipSuitIm(targetData, sourceData)
+   if not targetData or not sourceData or not next(sourceData) then
+      return
+   end
+
+   targetData[#targetData+1] = {sourceData[1], sourceData[2]}
 end

+ 29 - 11
script/module/hero/HeroArtifacts.lua

@@ -35,12 +35,21 @@ local HeroArtifactsConfig = require("excel.heroArtifacts")
 local Util = require("common.Util")
 local Lang = require("common.Lang")
 local Broadcast = require("broadcast.Broadcast")
+local TalismanLogic = require("talisman.TalismanLogic")
 
 local GiftLogic
 
 local LOGTAG = "Artifacts" --日志标识
 
 
+-- 获取来自秘宝的属性倍数加成
+local function getAttrMulFromTalisman(human)
+    local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.HeroArtifacts_LvAttr_Mul)
+    attrMul = attrMul / 100
+    return attrMul
+end
+
+
 local function initArtifactsData(heroGrid)
     heroGrid.artifacts = {
         level = 0,
@@ -187,10 +196,13 @@ local function populateActivateCostMsg(net)
 end
 
 -- 填充灵装当前等级/星级总加成属性协议结构数据
-local function populateTotalAttrMsg(net, n, tp)
+local function populateTotalAttrMsg(human, net, n, tp)
     local t
+    local attrMul = 1
     if tp == 1 then
         t = HeroArtifactsConfig.UpGradeLv
+        attrMul = getAttrMulFromTalisman(human)
+        attrMul = 1 + attrMul
     else
         t = HeroArtifactsConfig.UpGradeStar
     end
@@ -208,15 +220,18 @@ local function populateTotalAttrMsg(net, n, tp)
         len = len + 1
         net[0] = len
         net[len].key = attrId
-        net[len].value = n <= 0 and 0 or attrVal
+        net[len].value = (n <= 0 and 0 or attrVal) * attrMul
     end
 end
 
 -- 填充灵装下一等级/星级加成属性协议结构数据
-local function populateNextAttrMsg(net, n, tp, isMax)
+local function populateNextAttrMsg(human, net, n, tp, isMax)
     local t
+    local attrMul = 1
     if tp == 1 then
         t = HeroArtifactsConfig.UpGradeLv
+        attrMul = getAttrMulFromTalisman(human)
+        attrMul = 1 + attrMul
     else
         t = HeroArtifactsConfig.UpGradeStar
     end
@@ -227,7 +242,7 @@ local function populateNextAttrMsg(net, n, tp, isMax)
     for k,v in ipairs(attrArrCfg or {}) do
         net[0] = k
         net[k].key = v[1]
-        net[k].value = isMax and 0 or v[2]
+        net[k].value = (isMax and 0 or v[2]) * attrMul
     end
 end
 
@@ -529,9 +544,12 @@ function doCalcHero(human, heroGrid, addAttrs)
     local artifactsData = heroGrid.artifacts
 
     if artifactsData.level > 0 then
+        local attrMul = getAttrMulFromTalisman(human)
+        attrMul = 1 + attrMul
+
         local attrList = calcAttrs(HeroArtifactsConfig.UpGradeLv, artifactsData.level)
         for attrId, attrVal in pairs(attrList) do
-            RoleAttr.updateValue(attrId, attrVal, addAttrs)
+            RoleAttr.updateValue(attrId, attrVal * attrMul, addAttrs)
         end
     end
 
@@ -657,8 +675,8 @@ function HeroArtifacts_Base_Query(human, heroID, heroIndex)
     msgRet.redDotArr[2] = 0
 
     populateActivateCostMsg(msgRet.ActivateCost)
-    populateTotalAttrMsg(msgRet.nowLevelAttrs, currentLevel, 1)
-    populateTotalAttrMsg(msgRet.nowStarAttrs, currentStar, 2)
+    populateTotalAttrMsg(human, msgRet.nowLevelAttrs, currentLevel, 1)
+    populateTotalAttrMsg(human, msgRet.nowStarAttrs, currentStar, 2)
 
     if artifactsData and artifactsData.effectArr then
         populateEffectMsg(msgRet.effectArr, artifactsData.effectArr)
@@ -740,8 +758,8 @@ function HeroArtifacts_Lv_Query(human, heroID, heroIndex)
     local msgRet = Msg.gc.GC_HEROARTIFACTS_LV_QUERY
     msgRet.artifactsLv = currentLevel
     msgRet.artifactsLvMax = maxLevel
-    populateTotalAttrMsg(msgRet.nowLevelAttrs, currentLevel, 1)
-    populateNextAttrMsg(msgRet.nextLevelAttrs, nextLevel, 1, isMax)
+    populateTotalAttrMsg(human, msgRet.nowLevelAttrs, currentLevel, 1)
+    populateNextAttrMsg(human, msgRet.nextLevelAttrs, nextLevel, 1, isMax)
 
     local itemId, itemCnt = getNextStageCost(currentLevel, 1, isMax)
     Grid.makeItem(msgRet.cost, itemId, itemCnt)
@@ -815,8 +833,8 @@ function HeroArtifacts_Star_Query(human, heroID, heroIndex)
     local msgRet = Msg.gc.GC_HEROARTIFACTS_STAR_QUERY
     msgRet.artifactsStar = currentStar
     msgRet.artifactsStarMax = maxStar
-    populateTotalAttrMsg(msgRet.nowStarAttrs, currentStar, 2)
-    populateNextAttrMsg(msgRet.nextStarAttrs, nextStar, 2, isMax)
+    populateTotalAttrMsg(human, msgRet.nowStarAttrs, currentStar, 2)
+    populateNextAttrMsg(human, msgRet.nextStarAttrs, nextStar, 2, isMax)
 
     local itemId, itemCnt = getNextStageCost(currentStar, 2, isMax)
     Grid.makeItem(msgRet.cost, itemId, itemCnt)

+ 32 - 18
script/module/hero/HeroEquip.lua

@@ -16,6 +16,7 @@ local ItemExcel = require("excel.item").item
 local FuwenLogic = require("fuwen.FuwenLogic")
 local EquipLogic = require("equip.EquipLogic")
 local HeroGem = require("hero.HeroGem")
+local EquipLogicGrid = require("equip.EquipLogicGrid")
 
 function query(human, heroID, heroIndex)
 	local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
@@ -36,9 +37,9 @@ function query(human, heroID, heroIndex)
 		if equipGrid then
 			cnt = cnt + 1
 			if i == ItemDefine.EQUIP_SUBTYPE_SHUIJIN then -- 水晶比较特殊
-				Grid.makeItem(msgRet.equips[cnt], equipGrid.id, 1, heroGrid.shuijingAttrID)
+				Grid.makeItem(msgRet.equips[cnt], equipGrid.id, 1, heroGrid.shuijingAttrID, nil, nil, nil, nil, nil, nil, human)
 			else
-				Grid.makeItem(msgRet.equips[cnt], equipGrid.id, 1, nil, equipGrid, -1, Grid.getOpflagAtBag(heroGrid.equip[i].id),nil,suitBonusTbl)
+				Grid.makeItem(msgRet.equips[cnt], equipGrid.id, 1, nil, equipGrid, -1, Grid.getOpflagAtBag(heroGrid.equip[i].id), nil, suitBonusTbl, nil, human)
 			end
 		end
 
@@ -58,7 +59,7 @@ function query(human, heroID, heroIndex)
            heroGrid.fuwen[i].id ~= nil then
 			cnt = cnt + 1
             msgRet.fuwens[cnt].pos = i
-			Grid.makeItem(msgRet.fuwens[cnt].fuwen, heroGrid.fuwen[i].id, 1,nil,heroGrid.fuwen[i],-1, Grid.getOpflagAtBag(heroGrid.fuwen[i].id))
+			Grid.makeItem(msgRet.fuwens[cnt].fuwen, heroGrid.fuwen[i].id, 1, nil, heroGrid.fuwen[i], -1, Grid.getOpflagAtBag(heroGrid.fuwen[i].id), nil, nil, nil, human)
 		end
 
 		msgRet.fuwenGrid[i] = 1
@@ -104,7 +105,7 @@ function putOn(human, heroID, heroIndex, bagIndex, noCalc)
 	--获取宝石加成
 	local suitBonusTbl = HeroGem.suitAttrBonus(heroGrid)
 
-    Grid.makeItem(msgRet.equip, equipID, 1, nil, equipGrid, bagIndex, Grid.getOpflagAtBag(equipID), nil, suitBonusTbl)
+    Grid.makeItem(msgRet.equip, equipID, 1, nil, equipGrid, bagIndex, Grid.getOpflagAtBag(equipID), nil, suitBonusTbl, nil, human)
 
     if heroGrid.equip == nil or
         heroGrid.equip[pos] == nil then
@@ -210,7 +211,7 @@ function putOnHero(human, heroID, heroIndex, putHeroID, putHeroIndex, putHeroPos
 	--获取宝石加成
 	local suitBonusTbl = HeroGem.suitAttrBonus(heroGrid)
 
-    Grid.makeItem(msgRet.equip, equipID, 1, nil, equipGrid, bagIndex, Grid.getOpflagAtBag(equipID), nil, suitBonusTbl)
+    Grid.makeItem(msgRet.equip, equipID, 1, nil, equipGrid, bagIndex, Grid.getOpflagAtBag(equipID), nil, suitBonusTbl, nil, human)
 	
     --Grid.makeItem(msgRet.equip, equipID, 1, nil, equipGrid, 0, Grid.getOpflagAtBag(equipID))
     Msg.send(msgRet, human.fd)
@@ -295,7 +296,7 @@ function putOffQuick(human, heroID, heroIndex, noSendDy)
     end
 end
 
-function doCalcHero(obj,attrs)
+function doCalcHero(human, obj, attrs)
 	local equip = obj.equip
 	if not equip then return end
 	
@@ -386,6 +387,12 @@ function doCalcHero(obj,attrs)
 					if equipConfig.subType == ItemDefine.EQUIP_SUBTYPE_RING or equipConfig.subType == ItemDefine.EQUIP_SUBTYPE_AMULET then
 						equipSuitCntTable[equipConfig.suit].isSpEquip = 1
 					end
+
+					--等级 >= 15级的装备
+					if equipConfig.jobSuitIm and next(equipConfig.jobSuitIm) then
+						local jobId = EquipLogicGrid.GetEquipOwnerJob(human, equipGrid)
+						equipSuitCntTable[equipConfig.suit].jobId = jobId
+					end
 				end
 			end
 		end
@@ -397,9 +404,16 @@ function doCalcHero(obj,attrs)
 			if v.cnt > 1 then
 				local equipIDTemp = v.equipID
 				local equipConfigTemp = EquipExcel.equip[equipIDTemp]
-				for i = 1, #equipConfigTemp.suitIm do
-					local keyTemp = equipConfigTemp.suitIm[i][1]
-					local valTemp = equipConfigTemp.suitIm[i][2]
+				local suitImCfg = equipConfigTemp.suitIm
+				if v.jobId then
+					suitImCfg = Util.copyTable(equipConfigTemp.suitIm)
+					local attrInfo = equipConfigTemp.jobSuitIm[v.jobId]
+					EquipLogicGrid.MergeEquipSuitIm(suitImCfg, attrInfo)
+				end
+
+				for i = 1, #suitImCfg do
+					local keyTemp = suitImCfg[i][1]
+					local valTemp = suitImCfg[i][2]
 					if v.cnt > i then
 						-- 普通套装
 						if v.isSpEquip ~= 1 and (suitBonusTbl and suitBonusTbl[i+1]) then
@@ -457,7 +471,7 @@ function jihuoShuijing(human, heroID, heroIndex)
 	local msgRet = Msg.gc.GC_HERO_EQUIP_PUTON
 	msgRet.heroID = heroID
 	msgRet.heroIndex = heroIndex
-	Grid.makeItem(msgRet.equip, equipID, 1, heroGrid.shuijingAttrID)
+	Grid.makeItem(msgRet.equip, equipID, 1, heroGrid.shuijingAttrID, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 end
 
@@ -533,7 +547,7 @@ function shuijingTransDo(human, heroID, heroIndex)
 	human.tempAttrID = equipConfig.shuijingAttrID[indexTemp]
 
 	-- 通知客户端
-	Grid.makeItem(msgRet.equip, equipID, 1, human.tempAttrID)
+	Grid.makeItem(msgRet.equip, equipID, 1, human.tempAttrID, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 end
 
@@ -567,7 +581,7 @@ function shuijingTransSave(human, heroID, heroIndex)
 	local msgRet = Msg.gc.GC_HERO_EQUIP_PUTON
 	msgRet.heroID = heroID
 	msgRet.heroIndex = heroIndex
-	Grid.makeItem(msgRet.equip, equipID, 1, heroGrid.shuijingAttrID)
+	Grid.makeItem(msgRet.equip, equipID, 1, heroGrid.shuijingAttrID, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 	
 	local msgRet = Msg.gc.GC_SHUIJING_TRANS_SAVE
@@ -611,7 +625,7 @@ function shuijingUpLvQuery(human, mainType, heroID, heroIndex)
 	msgRet.equip[0] = 1
 	local attrID = heroGrid.shuijingAttrID
 	local tempAttrID = EquipExcel.shuijingAttr[attrID].lockNextID
-	Grid.makeItem(msgRet.equip[1], nextID, 1, tempAttrID)
+	Grid.makeItem(msgRet.equip[1], nextID, 1, tempAttrID, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 end
 
@@ -689,13 +703,13 @@ function shuijingUpLvDo(human, mainType, heroID, heroIndex)
 	local msgRet = Msg.gc.GC_HERO_EQUIP_PUTON
 	msgRet.heroID = heroID
 	msgRet.heroIndex = heroIndex
-	Grid.makeItem(msgRet.equip, nextID, 1, heroGrid.shuijingAttrID)
+	Grid.makeItem(msgRet.equip, nextID, 1, heroGrid.shuijingAttrID, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 	
 	local msgRet = Msg.gc.GC_SHUIJING_UPLV_DO
 	msgRet.heroID = heroID
 	msgRet.heroIndex = heroIndex
-	Grid.makeItem(msgRet.equip, nextID, 1, heroGrid.shuijingAttrID)
+	Grid.makeItem(msgRet.equip, nextID, 1, heroGrid.shuijingAttrID, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 end
 
@@ -724,7 +738,7 @@ function shenqiUpLvQuery(human, heroID, heroIndex)
 	msgRet.heroID = heroID
 	msgRet.heroIndex = heroIndex
 	msgRet.needExp = shenqiUpNeedConfig.needExp
-	Grid.makeItem(msgRet.equip, nextID, 1)
+	Grid.makeItem(msgRet.equip, nextID, 1, nil, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 end
 
@@ -811,7 +825,7 @@ function shenqiUpLvDo(human, heroID, heroIndex, equipIDList, equipCntList)
 	local msgRet = Msg.gc.GC_HERO_EQUIP_PUTON
 	msgRet.heroID = heroID
 	msgRet.heroIndex = heroIndex
-	Grid.makeItem(msgRet.equip, nextID, 1)
+	Grid.makeItem(msgRet.equip, nextID, 1, nil, nil, nil, nil, nil, nil, nil, human)
 	Msg.send(msgRet, human.fd)
 	
 	local msgRet = Msg.gc.GC_SHENQI_UPLV_DO
@@ -819,7 +833,7 @@ function shenqiUpLvDo(human, heroID, heroIndex, equipIDList, equipCntList)
 	msgRet.heroIndex = heroIndex
 	if backCnt > 0 then 
 		msgRet.equip[0] = 1
-		Grid.makeItem(msgRet.equip[1], HeroDefine.DEFAULT_SHENQI_UPLV_BACK,backCnt)
+		Grid.makeItem(msgRet.equip[1], HeroDefine.DEFAULT_SHENQI_UPLV_BACK, backCnt, nil, nil, nil, nil, nil, nil, nil, human)
 	else
 		msgRet.equip[0] = 0
 	end

+ 19 - 3
script/module/hero/HeroExclusiveWeapon.lua

@@ -13,6 +13,7 @@ local RoleDefine = require("role.RoleDefine")
 local ObjHuman = require("core.ObjHuman")
 local Config = require("excel.weapon").weapon
 local HeroExcel = require("excel.hero").hero
+local TalismanLogic = require("talisman.TalismanLogic")
 
 local GiftLogic
 
@@ -22,6 +23,14 @@ local LOGTAG = "HeroExclusiveWeapon" --日志标识
 local SSRGRADE = 4          -- SSR英雄的grade值
 
 
+-- 获取来自秘宝的属性倍数加成
+local function getAttrMulFromTalisman(human)
+    local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.HeroExclusiveWeapon_Attr_Mul)
+    attrMul = attrMul / 100
+    return attrMul
+end
+
+
 --获取英雄的专属武器配置
 local function getHeroWeaponCfg(heroID)
     for _, cfg in pairs(Config) do
@@ -113,7 +122,7 @@ end
 
 
 --专属武器加成
-function doCalcHero(heroGrid, addAttrs)
+function doCalcHero(human, heroGrid, addAttrs)
     if not heroGrid or not heroGrid.weaponLv then
         return
     end
@@ -124,8 +133,12 @@ function doCalcHero(heroGrid, addAttrs)
     end
 
     local nowWeaponLv = heroGrid.weaponLv
+
+    local attrMul = getAttrMulFromTalisman(human)
+    attrMul = 1 + attrMul
+
     for _, v in ipairs(cfg.normalAttrs) do
-        RoleAttr.updateValue(v[1], v[2] * nowWeaponLv, addAttrs)
+        RoleAttr.updateValue(v[1], v[2] * nowWeaponLv * attrMul, addAttrs)
     end
 end
 
@@ -248,6 +261,9 @@ function Query(human, heroID, heroIndex)
             costInfo[0] = len
         end
 
+        local attrMul = getAttrMulFromTalisman(human)
+        attrMul = 1 + attrMul
+
         --普通属性加成
         local normalAttrs = msgRet.normalAttrs
         local normalAttrsCfg = cfg.normalAttrs
@@ -255,7 +271,7 @@ function Query(human, heroID, heroIndex)
         for k, v in ipairs(normalAttrsCfg) do
             normalAttrs[k] = {}
             normalAttrs[k].key = v[1] or 0
-            normalAttrs[k].value = v[2] * nowWeaponLv
+            normalAttrs[k].value = v[2] * nowWeaponLv * attrMul
         end
 
         --特殊效果

+ 16 - 2
script/module/hero/HeroPubLogic.lua

@@ -25,6 +25,7 @@ local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
 local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
 local Grid = require("bag.Grid")
 local BagLogic = require("bag.BagLogic")
+local TalismanLogic = require("talisman.TalismanLogic")
 
 
 HERO_OP_UPSTAR      = 1     -- 升星/合成
@@ -34,6 +35,14 @@ HERO_OP_ADD         = 4     -- 获得
 
 local LOGTAG = "HeroPub"
 
+-- 获取来自秘宝的属性倍数加成
+local function getAttrMulFromTalisman(human)
+    local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.HeroPubLogic_Attr_Mul)
+    attrMul = attrMul / 100
+    return attrMul
+end
+
+
 local function initPubData(human)
     human.db.heroPubData = human.db.heroPubData or {}
     human.db.heroPubData.activateIdxList = human.db.heroPubData.activateIdxList or {}
@@ -345,6 +354,9 @@ local function respndAttrInfo(human)
     local heroPubData = getPubData(human)
     local nowMaxStar = calcAllHeroStar(human.pubHeroList)
 
+    local attrMul = getAttrMulFromTalisman(human)
+    attrMul = 1 + attrMul
+
     local msgRet = Msg.gc.GC_HEROPUB_ATTR_QUERY
     msgRet.star = nowMaxStar
     local attrList = msgRet.attrList
@@ -363,7 +375,7 @@ local function respndAttrInfo(human)
         local attrInfo = attrList[len].attrInfo
         for k ,v in ipairs(cfg.attrs) do
             attrInfo[k].key = v[1]
-            attrInfo[k].value = v[2]
+            attrInfo[k].value = v[2] * attrMul
 
             attrInfo[0] = k
         end
@@ -433,12 +445,14 @@ function doCalcHero(human, attrs)
         return
     end
 
+    local attrMul = getAttrMulFromTalisman(human)
+    attrMul = 1 + attrMul
 
     local activateIdxList = heroPubData.activateIdxList
     for k, v in ipairs(HeroPubCfg) do
         if activateIdxList[k] then
             for _, attrInfo in ipairs(v.attrs) do
-                RoleAttr.updateValue(attrInfo[1], attrInfo[2], attrs)
+                RoleAttr.updateValue(attrInfo[1], attrInfo[2] * attrMul, attrs)
             end
         end
     end

+ 18 - 3
script/module/hero/HeroTianYuan.lua

@@ -10,12 +10,21 @@ local RoleAttr = require("role.RoleAttr")
 local HeroTianYuanCfg = require("excel.heroTianYuan")
 local Broadcast = require("broadcast.Broadcast")
 local RoleDefine = require("role.RoleDefine")
+local TalismanLogic = require("talisman.TalismanLogic")
 
 local GiftLogic
 
 local LOGTAG = "HeroTianYuan" --日志标识
 
 
+-- 获取来自秘宝的属性倍数加成
+local function getAttrMulFromTalisman(human)
+    local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.HeroTianYuan_Attr_Mul)
+    attrMul = attrMul / 100
+    return attrMul
+end
+
+
 local function initData(heroGrid)
     heroGrid.tianYuanData = {
         pointIdx = 0,
@@ -221,8 +230,11 @@ function doCalcHero(human, heroGrid, tatgetAttrs)
     local nowPointIdx = heroGrid.tianYuanData.pointIdx or 0
     local sourceAttrs = calcData(nowStage, nowPointIdx, 1)
 
+    local attrMul = getAttrMulFromTalisman(human)
+    attrMul = 1 + attrMul
+
     for attrId, attrVal in pairs(sourceAttrs or {}) do
-        RoleAttr.updateValue(attrId, attrVal, tatgetAttrs)
+        RoleAttr.updateValue(attrId, attrVal * attrMul, tatgetAttrs)
     end
 end
 
@@ -268,6 +280,9 @@ function HeroTianYuan_Query(human, heroID, heroIndex)
     --     Grid.makeItem(msgRet.cost[i], itemId, itemCnt)
     -- end
 
+    local attrMul = getAttrMulFromTalisman(human)
+    attrMul = 1 + attrMul
+
     -- 总加成属性
     msgRet.attrs[0] = 0
     local attrs = calcData(nowStage, nowPointIdx, 1)
@@ -277,7 +292,7 @@ function HeroTianYuan_Query(human, heroID, heroIndex)
             len = len + 1
             msgRet.attrs[0] = len
             msgRet.attrs[len].key = attrId
-            msgRet.attrs[len].value = attrVal
+            msgRet.attrs[len].value = attrVal * attrMul
         end
     end
 
@@ -289,7 +304,7 @@ function HeroTianYuan_Query(human, heroID, heroIndex)
             msgRet.nextAttrs[0] = #nextAttrs
             for i, attrTb in ipairs(nextAttrs) do
                 msgRet.nextAttrs[i].key = attrTb[1]
-                msgRet.nextAttrs[i].value = attrTb[2]
+                msgRet.nextAttrs[i].value = attrTb[2] * attrMul
             end
         end
     end

+ 2 - 2
script/module/role/RoleAttr.lua

@@ -166,7 +166,7 @@ function calcHeroGrid(heroGrid, index, human)
 		SkinLogic.doCalcSkinHero(human,HERO_BASE_ATTRS)
 	end
 	BeSkill.doCalcHero(heroGrid, HERO_BASE_ATTRS) -- 被动技能属性
-	HeroEquip.doCalcHero(heroGrid, HERO_OTHER_ATTRS) -- 装备
+	HeroEquip.doCalcHero(human, heroGrid, HERO_OTHER_ATTRS) -- 装备
     FuwenLogic.doCalcHero(heroGrid, HERO_OTHER_ATTRS) -- 符文	
 	UnionTecLogic.doCalcHero(human, heroGrid, HERO_OTHER_ATTRS) -- 公会科技	
 	RoleHeadLogic.doCalcHero(human, HERO_OTHER_ATTRS) --称号
@@ -178,7 +178,7 @@ function calcHeroGrid(heroGrid, index, human)
 
 	TalismanLogic.doCalcHero(human, heroGrid, HERO_OTHER_ATTRS) --秘宝
 
-	HeroExclusiveWeapon.doCalcHero(heroGrid, HERO_OTHER_ATTRS) -- 专属武器
+	HeroExclusiveWeapon.doCalcHero(human, heroGrid, HERO_OTHER_ATTRS) -- 专属武器
 	WinnerRelicLogic.doCalcHero(human, heroGrid, HERO_OTHER_ATTRS) --圣者遗物
 
 	HeroPubLogic.doCalcHero(human, HERO_OTHER_ATTRS) --英雄酒馆

+ 15 - 0
script/module/scene/Handler.lua

@@ -102,6 +102,21 @@ function CG_TEST_PROTO(fd,msg)
 			appBanInfo = param.appBanInfo
 		}
 		BanLogic.Update_Ban_Info(banInfo)
+	elseif param.type == "deliverGoods" then
+		local uTag = RoleDBLogic.Generateuuid(param.channel_id, msg.account, msg.serverTag)
+		local human = ObjHuman.onlineNewUniqueTag[uTag]
+		if not human then
+			Log.write(Log.LOGID_DEBUG, "[deliverGoods] 玩家不在线 account=" .. tostring(msg.account) .. " orderId=" .. tostring(param.orderId))
+			return
+		end
+		local items = {}
+		if param.goods and #param.goods > 0 then
+			for _, good in ipairs(param.goods) do
+				table.insert(items, {good.Id, good.Num})
+			end
+		end
+		Log.write(Log.LOGID_DEBUG, "[deliverGoods] 开始发货 account=" .. tostring(msg.account) .. " orderId=" .. tostring(param.orderId) .. " itemCnt=" .. #items)
+		youxiSdkReward(human, items)
 	end
 end
 

+ 61 - 42
script/module/serverCommerce/ServerCommerceActBattleGroundCS.lua

@@ -21,7 +21,7 @@ local dbUpdate = {_id=nil}
 local dbUpdateField = {}
 
 local RANK_SHOW_NUM = 50    -- 排行榜显示的数量
-local notifyActEnd = false  -- 是否收到活动结束通知的标识
+local repeateServerIdList = {}
 
 local battleGroundData = {
     -- allAreaRankList = { -- 各个战区排行榜, 榜上的都是真实玩家
@@ -149,6 +149,12 @@ function BattleGround_InitAfterStart()
     loadData()
 end
 
+function onZero()
+    if next(repeateServerIdList) then
+        repeateServerIdList = {}
+    end
+end
+
 
 -- 通过本服Id获取所在战区Id
 local function getWarZoneServerIdx(sourceServerId)
@@ -157,6 +163,11 @@ local function getWarZoneServerIdx(sourceServerId)
     return nServerKey
 end
 
+-- 通服务器Id获取所在战区Id的最小服务器Id,最大服务器Id
+local function getWarZoneServerArea(sourceServerId)
+    local nServerKey = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(sourceServerId)
+    return MiddleConnect.MiddleConnect_GetWarZoneServer(nServerKey)
+end
 
 -- 生成一个战区排行榜
 local function genWarZoneRankList(warZoneServerIdx)
@@ -467,73 +478,81 @@ function BG_N2C_Lineup_Update(msg)
     updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx])
 end
 
+
+
 -- 活动结束
 function BG_N2C_Act_End(msg)
-    if notifyActEnd then
+    local warZoneServerIdMin, warZoneServerIdMax = getWarZoneServerArea(msg.sourceServerId)
+
+    if not warZoneServerIdMin or warZoneServerIdMin == 0 then
         return
     end
 
-    -- local logData = {
-    --     joinList = battleGroundData.joinList,
-    --     allAreaRankList = battleGroundData.allAreaRankList,
-    -- }
-
-    -- local logTb = Util.serialize(logData)
-    -- local logStr = table.concat(logTb)
-    -- writeLog(logStr)
-
-
-    local logTab1 = Util.serialize(battleGroundData.joinList)
-    local logStr1 = table.concat(logTab1)
-    Timer.addLater(40, writeLog, logStr1)
-
-    local logTab2 = Util.serialize(battleGroundData.allAreaRankList)
-    local logStr2 = table.concat(logTab2)
-    Timer.addLater(45, writeLog, logStr2)
-
+    if repeateServerIdList[warZoneServerIdMin] then
+        return
+    end
 
     -- 更新标识
-    notifyActEnd = true
+    repeateServerIdList[warZoneServerIdMin] = true
 
-    local fd_2_Rank = {}
+    local fd_2_PlayerList = {}
     local joinList = battleGroundData.joinList
-    local allAreaRankList = battleGroundData.allAreaRankList
+
+    local serverIdxMin = MiddleConnect.MiddleConnect_ConfServerID2TrueServerID(warZoneServerIdMin)
+    local serverIdxMax = MiddleConnect.MiddleConnect_ConfServerID2TrueServerID(warZoneServerIdMax)
 
     -- 参与玩家(包括在榜玩家)
-    for _, playerInfo in ipairs(joinList or {}) do
+    for k = #joinList, 1, -1 do
+        local playerInfo = joinList[k]
         local serverId = playerInfo[1]
-        local fd = MiddleManager.getFDBySvrIndex(serverId)
-        if fd then
-            fd_2_Rank[fd] = fd_2_Rank[fd] or {}
-            fd_2_Rank[fd][#fd_2_Rank[fd]+1] = {ServerCommerceActDefine.COMMERCEACT_NPC_CNT, playerInfo[2]}
+        if serverId >= serverIdxMin and serverId <= serverIdxMax then
+            local fd = MiddleManager.getFDBySvrIndex(serverId)
+            if fd then
+                fd_2_PlayerList[fd] = fd_2_PlayerList[fd] or {}
+                fd_2_PlayerList[fd][#fd_2_PlayerList[fd]+1] = {ServerCommerceActDefine.COMMERCEACT_NPC_CNT, playerInfo[2]}
+            end
+            table.remove(joinList, k)
         end
     end
 
     -- 在榜玩家
-    for _, rankList in pairs(allAreaRankList or {}) do
-        for _, player in pairs(rankList) do
-            local fd = MiddleManager.getFDBySvrIndex(player.serverId)
-            if fd then
-                fd_2_Rank[fd] = fd_2_Rank[fd] or {}
-                local idx = findVal(fd_2_Rank[fd], player.playerUuid)
-                if idx then
-                    fd_2_Rank[fd][idx][1] = player.rank
-                end
+    local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
+    for _, player in pairs(myWarZoneRankList or {}) do
+        local fd = MiddleManager.getFDBySvrIndex(player.serverId)
+        if fd then
+            fd_2_PlayerList[fd] = fd_2_PlayerList[fd] or {}
+            local idx = findVal(fd_2_PlayerList[fd], player.playerUuid)
+            if idx then
+                fd_2_PlayerList[fd][idx][1] = player.rank
             end
         end
     end
 
-    if next(fd_2_Rank) then
+    if battleGroundData.allAreaRankList and battleGroundData.allAreaRankList[warZoneServerIdMin] then
+        battleGroundData.allAreaRankList[warZoneServerIdMin] = nil
+    end
+
+    if next(fd_2_PlayerList) then
+        -- 写日志
+        local logTab2 = Util.serialize(fd_2_PlayerList)
+        local logStr2 = table.concat(logTab2)
+        Timer.addLater(45, writeLog, logStr2)
+
         local delay_sec = 0
-        for fd, rankArr in pairs(fd_2_Rank) do
+        for fd, rankArr in pairs(fd_2_PlayerList) do
             delay_sec = delay_sec + 3
             Timer.addLater(delay_sec, issueReward, fd, rankArr)
         end
 
-        -- 重置排行榜数据
-        battleGroundData.joinList = nil
+        -- 更新数据
+        if not next(battleGroundData.joinList) then
+            battleGroundData.joinList = nil
+        end
         updateValue("joinList", battleGroundData.joinList)
-        battleGroundData.allAreaRankList = nil
+
+        if not next(battleGroundData.allAreaRankList) then
+            battleGroundData.allAreaRankList = nil
+        end
         updateValue("allAreaRankList", battleGroundData.allAreaRankList)
     end
 end

+ 3 - 0
script/module/serverCommerce/ServerCommerceMiddle.lua

@@ -11,6 +11,7 @@ local ServerCommerceManger = require("serverCommerce.ServerCommerceManager")
 local ServerCommerceActDefine = require("serverCommerce.ServerCommerceActDefine")
 local ServerCommerceRank = require("serverCommerce.ServerCommerceActRank")
 local Log = require("common.Log")
+local ServerCommerceActBattleGroundCS = require("serverCommerce.ServerCommerceActBattleGroundCS")
 
 
 -- 缓存开服天数
@@ -188,6 +189,8 @@ function CommerceMiddle_OnZero()
         return
     end
 
+    ServerCommerceActBattleGroundCS.onZero()
+
     Timer.addLater(15, CommerceMiddle_GetOpen)
     print("[CommerceMiddle_OnZero] 整点定时去获取数据")
 end

+ 17 - 0
script/module/talisman/TalismanLogic.lua

@@ -60,6 +60,11 @@ OTHER_EFFECT_TBL = {
     ["WinnerRelic_Attr_Mul"] = "WinnerRelic_Attr_Mul", -- 圣遗物系统通用属性加成
     ["Elf_Attr_Mul"] = "Elf_Attr_Mul",              -- 精灵系统通用属性加成
     ["Moshou_LvAttr_Mul"] = "Moshou_LvAttr_Mul",    -- 守护凤凰系统等级加成属性的加成
+
+    ["HeroExclusiveWeapon_Attr_Mul"] = "HeroExclusiveWeapon_Attr_Mul",    -- 英雄专属武器系统加成
+    ["HeroTianYuan_Attr_Mul"] = "HeroTianYuan_Attr_Mul",                  -- 英雄天元系统加成
+    ["HeroArtifacts_LvAttr_Mul"] = "HeroArtifacts_LvAttr_Mul",            -- 英雄神威灵装系统加成
+    ["HeroPubLogic_Attr_Mul"] = "HeroPubLogic_Attr_Mul",                  -- 英雄酒馆系统加成
 }
 
 --是否开启本系统
@@ -190,6 +195,18 @@ function doCalcHero(human, heroGrid, addAttrs)
                 if singleAttr[1] == heroCfg.camp then
                     RoleAttr.updateValue(singleAttr[2], singleAttr[3], addAttrs)
                 end
+            elseif #singleAttr == 4 then
+                local bl = false
+                local tp = singleAttr[1]
+                if tp == 1 then -- 职业
+                    if heroCfg.job == singleAttr[2] then
+                        bl = true
+                    end
+                end
+
+                if bl then
+                    RoleAttr.updateValue(singleAttr[3], singleAttr[4], addAttrs)
+                end
             end
         end
     end

+ 13 - 0
script/module/zhuanpan/Handler.lua

@@ -98,4 +98,17 @@ end
 -- 游戏圈任务领取
 function CG_ZHUANPAN_YOUXI_TASK_GET(human, msg)
 	ZhuanpanLogic.youxiTaskGetReward(human, msg.taskId)
+end
+
+
+-----------------------添加桌面-----------------------
+
+-- 上报添加桌面
+function CG_ZHUANPAN_DY_DESKTOP_SET(human, msg)
+	ZhuanpanLogic.dyDesktopSetLocal(human, msg.channelId, msg.platform)
+end
+
+-- 查询桌面添加状态
+function CG_ZHUANPAN_DY_DESKTOP_QUERY(human, msg)
+	ZhuanpanLogic.dyDesktopQueryLocal(human, msg.channelId, msg.platform)
 end

+ 21 - 0
script/module/zhuanpan/Proto.lua

@@ -211,3 +211,24 @@ CG_ZHUANPAN_YOUXI_TASK_GET = {
 	{"taskId",  1,  "byte"},  -- 任务ID (1-5)
 }
 
+
+-----------------------添加桌面-----------------------
+
+-- 上报添加桌面(前端确认添加后调用)
+CG_ZHUANPAN_DY_DESKTOP_SET = {
+	{"channelId",  1,  "int"},     -- 渠道ID
+	{"platform",   1,  "string"},  -- 平台标识(如 "douyin"、"meituan" 等)
+}
+
+-- 查询桌面添加状态
+CG_ZHUANPAN_DY_DESKTOP_QUERY = {
+	{"channelId",  1,  "int"},     -- 渠道ID
+	{"platform",   1,  "string"},  -- 平台标识
+}
+
+GC_ZHUANPAN_DY_DESKTOP_QUERY = {
+	{"channelId",      1,  "int"},     -- 渠道ID
+	{"platform",       1,  "string"},  -- 平台标识
+	{"isDesktopAdded", 1,  "byte"},    -- 是否已添加桌面 0否 1是
+}
+

+ 229 - 7
script/module/zhuanpan/ZhuanpanLogic.lua

@@ -1,6 +1,10 @@
 local Lang  = require("common.Lang")
 local Msg = require("core.Msg")
 local ObjHuman = require("core.ObjHuman")
+local InnerMsg = require("core.InnerMsg")
+local Config = require("Config")
+local MiddleManager = require("middle.MiddleManager")
+local CommonDB = require("common.CommonDB")
 local ZhuanpanExcel = require("excel.zhuanpan")
 local ItemDefine = require("bag.ItemDefine")
 local BagLogic = require("bag.BagLogic")
@@ -1764,6 +1768,31 @@ local function getWeekProgress(field)
 	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
@@ -1802,7 +1831,8 @@ function youxiTaskQuery(human, msg)
 
 			if config.taskType == "once" then
 				taskData.progress = yt.joined and 1 or 0
-				if yt.joinGetTime then
+				local claimed = yt.joinGetTime or checkAccountYouxiTaskClaimed(human.db.account, taskId)
+				if claimed then
 					taskData.status = 2
 				elseif yt.joined then
 					taskData.status = 1
@@ -1815,7 +1845,8 @@ function youxiTaskQuery(human, msg)
 				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
-				if getTime and Util.isSameDay(getTime) then
+				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
@@ -1828,7 +1859,8 @@ function youxiTaskQuery(human, msg)
 				local weekCount = getWeekProgress(field)
 				taskData.progress = math.min(weekCount, config.target)
 				local weekGetTime = field and field.weekGetTime
-				if weekGetTime and isCurrentWeek(weekGetTime) then
+				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
@@ -1864,9 +1896,12 @@ function youxiTaskGetReward(human, taskId)
 	local yt = human.db.zhuanpan.youxiTask
 	local now = os.time()
 
-	-- 校验条件 & 重复领取
+	-- 校验条件 & 重复领取(账号级别判断,同账号多角色共享)
+	-- 先查当前角色内存,没有再查 DB 其他角色(与美团订阅奖励模式一致)
+	local account = human.db.account
 	if config.taskType == "once" then
-		if yt.joinGetTime then
+		local claimed = yt.joinGetTime or checkAccountYouxiTaskClaimed(account, taskId)
+		if claimed then
 			return Broadcast.sendErr(human, "已领取过")
 		end
 		if not yt.joined then
@@ -1875,7 +1910,9 @@ function youxiTaskGetReward(human, taskId)
 
 	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
+		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
@@ -1885,7 +1922,9 @@ function youxiTaskGetReward(human, taskId)
 
 	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
+		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
@@ -1923,6 +1962,189 @@ function youxiTaskGetReward(human, taskId)
 	youxiTaskQuery(human, nil)
 end
 
+-----------------------添加桌面(本地存储,账号级,同游戏圈写法)-----------------------
+
+-- 检查账号下所有角色是否已添加过桌面(查本服MongoDB)
+local function checkAccountDesktopAdded(account, channelId, platform)
+	if not account then return false end
+	local key = tostring(channelId) .. "_" .. tostring(platform)
+	LuaMongo.find(DB.db_char, {account = account}, {zhuanpan = 1})
+	while true do
+		local data = {}
+		if not LuaMongo.next(data) then break end
+		local da = data.zhuanpan and data.zhuanpan.desktopAdded
+		if da and da[key] then return true end
+	end
+	return false
+end
+
+-- 上报添加桌面
+function dyDesktopSetLocal(human, channelId, platform)
+	if not channelId or not platform or platform == "" then
+		return Broadcast.sendErr(human, "参数缺失")
+	end
+
+	human.db.zhuanpan = human.db.zhuanpan or {}
+	human.db.zhuanpan.desktopAdded = human.db.zhuanpan.desktopAdded or {}
+	local key = tostring(channelId) .. "_" .. tostring(platform)
+	human.db.zhuanpan.desktopAdded[key] = true
+
+	Log.write(Log.LOGID_DEBUG, "[dyDesktopSetLocal] 添加桌面 account=" .. tostring(human.db.account)
+		.. " channelId=" .. tostring(channelId) .. " platform=" .. tostring(platform))
+
+	local ok, err = pcall(function()
+		dyDesktopQueryLocal(human, channelId, platform)
+	end)
+	if not ok then
+		Log.write(Log.LOGID_DEBUG, "[dyDesktopSetLocal] 错误: 下发查询失败: " .. tostring(err))
+	end
+end
+
+-- 查询桌面添加状态
+function dyDesktopQueryLocal(human, channelId, platform)
+	if not channelId or not platform or platform == "" then
+		return Broadcast.sendErr(human, "参数缺失")
+	end
+
+	local msgRet = Msg.gc.GC_ZHUANPAN_DY_DESKTOP_QUERY
+	if not msgRet then return end
+
+	human.db.zhuanpan = human.db.zhuanpan or {}
+	human.db.zhuanpan.desktopAdded = human.db.zhuanpan.desktopAdded or {}
+	local key = tostring(channelId) .. "_" .. tostring(platform)
+
+	local added = human.db.zhuanpan.desktopAdded[key]
+	if not added then
+		added = checkAccountDesktopAdded(human.db.account, channelId, platform)
+	end
+
+	msgRet.channelId      = channelId
+	msgRet.platform       = platform
+	msgRet.isDesktopAdded = added and 1 or 0
+
+	Log.write(Log.LOGID_DEBUG, "[dyDesktopQueryLocal] account=" .. tostring(human.db.account)
+		.. " channelId=" .. tostring(channelId) .. " platform=" .. tostring(platform)
+		.. " isDesktopAdded=" .. tostring(msgRet.isDesktopAdded))
+
+	if human.fd then
+		Msg.send(msgRet, human.fd)
+	end
+end
+
+
+-----------------------添加桌面(跨服中心服存储,账号级多区服共享)-----------------------
+--
+---- 从 newUniqueTag 解析出 serverId 和 account(格式: "channelID|serverTag|account")
+--local function parseUniqueTag(newUniqueTag)
+--	local parts = {}
+--	for part in string.gmatch(newUniqueTag, "([^|]+)") do
+--		table.insert(parts, part)
+--	end
+--	return tonumber(parts[2]), parts[3]  -- serverId, account
+--end
+--
+---- 普通服:上报添加桌面 → 发消息给中心服写入
+--function dyDesktopSet(human, channelId, platform)
+--	if not channelId or not platform or platform == "" then
+--		return Broadcast.sendErr(human, "参数缺失")
+--	end
+--
+--	local newUniqueTag = human.db.newUniqueTag or human.newUniqueTag
+--	if not newUniqueTag then
+--		return Broadcast.sendErr(human, "账号标识缺失")
+--	end
+--	local serverId, account = parseUniqueTag(newUniqueTag)
+--
+--	local tMsg = InnerMsg.lw.LW_DESKTOP_SET
+--	tMsg.nSrcServerID = Config.SVR_INDEX
+--	tMsg.channelId    = channelId
+--	tMsg.serverId     = serverId or 0
+--	tMsg.account      = account or ""
+--	tMsg.platform     = platform
+--	InnerMsg.sendMsg(0, tMsg)
+--
+--	Log.write(Log.LOGID_DEBUG, "[dyDesktopSet] 发送中心服 channelId=" .. tostring(channelId)
+--		.. " serverId=" .. tostring(serverId) .. " account=" .. tostring(account) .. " platform=" .. tostring(platform))
+--end
+--
+---- 普通服:查询桌面添加状态 → 发消息给中心服查询
+--function dyDesktopQuery(human, channelId, platform)
+--	if not channelId or not platform or platform == "" then
+--		return Broadcast.sendErr(human, "参数缺失")
+--	end
+--
+--	local newUniqueTag = human.db.newUniqueTag or human.newUniqueTag
+--	if not newUniqueTag then
+--		return Broadcast.sendErr(human, "账号标识缺失")
+--	end
+--	local serverId, account = parseUniqueTag(newUniqueTag)
+--
+--	local tMsg = InnerMsg.lw.LW_DESKTOP_QUERY
+--	tMsg.nSrcServerID = Config.SVR_INDEX
+--	tMsg.channelId    = channelId
+--	tMsg.serverId     = serverId or 0
+--	tMsg.account      = account or ""
+--	tMsg.platform     = platform
+--	InnerMsg.sendMsg(0, tMsg)
+--
+--	Log.write(Log.LOGID_DEBUG, "[dyDesktopQuery] 发送中心服 channelId=" .. tostring(channelId)
+--		.. " serverId=" .. tostring(serverId) .. " account=" .. tostring(account) .. " platform=" .. tostring(platform))
+--end
+--
+---- 普通服:收到中心服查询回包,找到玩家下发 GC 协议
+--function NS_DesktopQueryResult(msg)
+--	-- 用三个字段重新拼出 newUniqueTag 来查找在线玩家
+--	local newUniqueTag = tostring(msg.channelId) .. "|" .. tostring(msg.serverId) .. "|" .. tostring(msg.account)
+--	local human = ObjHuman.onlineNewUniqueTag[newUniqueTag]
+--	if not human or not human.fd then
+--		Log.write(Log.LOGID_DEBUG, "[NS_DesktopQueryResult] 玩家不在线 newUniqueTag=" .. newUniqueTag)
+--		return
+--	end
+--
+--	local msgRet = Msg.gc.GC_ZHUANPAN_DY_DESKTOP_QUERY
+--	if not msgRet then return end
+--
+--	msgRet.channelId      = msg.channelId
+--	msgRet.platform       = msg.platform
+--	msgRet.isDesktopAdded = msg.isDesktopAdded
+--
+--	Msg.send(msgRet, human.fd)
+--end
+--
+---- 中心服:收到普通服上报,写入 MongoDB 后回包最新状态
+--function CS_DesktopSet(msg)
+--	CommonDB.SetDesktopData(msg.channelId, msg.serverId, msg.account, msg.platform)
+--
+--	Log.write(Log.LOGID_DEBUG, "[CS_DesktopSet] 写入完成 channelId=" .. tostring(msg.channelId)
+--		.. " serverId=" .. tostring(msg.serverId) .. " account=" .. tostring(msg.account) .. " platform=" .. tostring(msg.platform))
+--
+--	local tMsg = InnerMsg.wl.WL_DESKTOP_QUERY
+--	tMsg.channelId      = msg.channelId
+--	tMsg.serverId       = msg.serverId
+--	tMsg.account        = msg.account
+--	tMsg.platform       = msg.platform
+--	tMsg.isDesktopAdded = 1
+--
+--	local fd = MiddleManager.getFDBySvrIndex(msg.nSrcServerID)
+--	InnerMsg.sendMsg(fd, tMsg)
+--end
+--
+---- 中心服:收到普通服查询请求,读 MongoDB 后回包
+--function CS_DesktopQuery(msg)
+--	local added = CommonDB.IsDesktopAdded(msg.channelId, msg.serverId, msg.account, msg.platform)
+--
+--	local tMsg = InnerMsg.wl.WL_DESKTOP_QUERY
+--	tMsg.channelId      = msg.channelId
+--	tMsg.serverId       = msg.serverId
+--	tMsg.account        = msg.account
+--	tMsg.platform       = msg.platform
+--	tMsg.isDesktopAdded = added and 1 or 0
+--
+--	local fd = MiddleManager.getFDBySvrIndex(msg.nSrcServerID)
+--	InnerMsg.sendMsg(fd, tMsg)
+--end
+
+
 -- SDK 回调奖励发放(内部调用,与任务奖励独立)
 -- items: {{itemId, count}, ...}
 function youxiSdkReward(human, items)

+ 31 - 27
webServer/src/channels/handlers/MiniappChannelHandler.ts

@@ -9,6 +9,7 @@ import {PaymentHelper} from "../../utils/PaymentHelper";
 
 import Msg from "../../utils/msg";
 import axios from "axios";
+import { insertMailToPlayer } from "../../mongo/mongodb";
 
 const Order = require("../../model/OrderModel");
 const CryptoJS = require("crypto-js");
@@ -1484,7 +1485,7 @@ export class MiniappChannelHandler implements ChannelHandler {
     async deliverGoods(ctx: Context, config: ChannelConfig): Promise<LoginResult> {
         try {
             const body = ctx.request.body as any;
-            const { timestamp, nonce, signature, wxMsg } = body;
+            const { timestamp, nonce, signature, wxMsg,uid } = body;
 
             // 验证签名(签名算法1:SHA1)
             const verifyConfig = this.getChannel11Config('miniapp');
@@ -1501,48 +1502,51 @@ export class MiniappChannelHandler implements ChannelHandler {
             }
 
             const { OrderId, ToUserOpenid, GiftTypeId, GiftId, GoodsList, Zone, IsPreview } = miniGame;
-            if (!OrderId || !ToUserOpenid || !GoodsList) {
-                logger.error("游戏圈发货:缺少必要参数", { OrderId, ToUserOpenid });
+            if (!OrderId || !uid || !GoodsList) {
+                logger.error("游戏圈发货:缺少必要参数", { OrderId, uid });
                 return { code: 0, msg: "ok" };
             }
 
-            logger.info("游戏圈发货请求", { OrderId, ToUserOpenid, GiftTypeId, GiftId, Zone, IsPreview });
+            logger.info("游戏圈发货请求", { OrderId, ToUserOpenid, GiftTypeId, GiftId, Zone, IsPreview,uid });
 
             // 查询玩家最近登录的服务器
             const Server = require("../../model/ServerModel");
-            const serverList = await Server.getEnterServerListByUid(ToUserOpenid, 11);
+            const serverList = await Server.getEnterServerListByUid(uid, 11);
             if (!serverList || serverList.length === 0) {
-                logger.warn("游戏圈发货:未找到玩家服务器记录", { ToUserOpenid });
+                logger.warn("游戏圈发货:未找到玩家服务器记录", { uid });
                 return { code: 0, msg: "ok" };
             }
 
             // 取最近登录的服务器
             const serverInfo = serverList[0];
-            const url = serverInfo.wss || `ws://${serverInfo.ip}:${serverInfo.port}`;
-
-            const params = JSON.stringify({
-                type: "deliverGoods",
-                account: ToUserOpenid,
-                channel_id: 11,
-                orderId: OrderId,
-                giftTypeId: GiftTypeId,
-                giftId: GiftId,
-                goods: GoodsList,
-                zone: Zone,
-            });
 
-            logger.info("游戏圈发货 - 通知游戏服务器", { url, params });
+            // 将 GoodsList 转换为邮件道具格式 [[itemId, count], ...]
+            const items: Array<[number, number]> = (GoodsList as any[]).map(good => [
+                Number(good.Id),
+                Number(good.Num),
+            ]);
 
-            const sendMsg = new Msg();
-            sendMsg.connect(url, Account);
-            await new Promise<void>((resolve) => {
-                setTimeout(() => {
-                    sendMsg.CG_TEST_PROTO(ToUserOpenid, params, serverInfo.server_id);
-                    resolve();
-                }, 1000);
+            // newUniqueTag 格式与 Lua 保持一致:"channelId|serverId|account"
+            const newUniqueTag = `11|${serverInfo.server_id}|${uid}`;
+
+            logger.info("游戏圈发货 - 直接写邮件到DB", {
+                OrderId, uid, dbName: serverInfo.db_name, newUniqueTag, itemCnt: items.length,
             });
 
-            logger.info("游戏圈发货成功", { OrderId, ToUserOpenid });
+            const ok = await insertMailToPlayer(
+                serverInfo.db_name,
+                newUniqueTag,
+                "游戏圈礼物",
+                "您有一份游戏圈礼物待领取",
+                items,
+            );
+
+            if (!ok) {
+                logger.warn("游戏圈发货:邮件写入失败", { OrderId, uid });
+            } else {
+                logger.info("游戏圈发货成功", { OrderId,uid });
+            }
+
             return { code: 0, msg: "ok" };
 
         } catch (error) {

+ 20 - 7
webServer/src/controller/ApiController.ts

@@ -19,9 +19,10 @@ import {PaymentHelper} from "../utils/PaymentHelper";
 import {SignatureVerifier} from "../utils/SignatureVerifier";
 import {ChannelConfigManager} from "../utils/ChannelConfigManager";
 import {getRoleInfoByUidAndServerId} from "../mongo/mongodb";
+import {min} from "moment-timezone";
 
 // platform内存缓存,key: ip:device_no,TTL 5分钟
-const platformCache = new Map<string, {value: string; expireAt: number}>();
+const platformCache = new Map<string, { value: string; expireAt: number }>();
 const PLATFORM_CACHE_TTL = 60 * 1000; // 缓存1分钟
 
 function setPlatformCache(ip: string, platform: string) {
@@ -602,7 +603,7 @@ class ApiController {
                     // 发货成功
                     if (ctx.query.platform == "mtminiapp") {
                         ctx.body = {"code": 0, "msg": "ok"}
-                    }else {
+                    } else {
                         ctx.body = {errCode: 0};
                     }
                 } else {
@@ -797,8 +798,13 @@ class ApiController {
                         logger.error(`查询服务器${element.server_id}角色信息失败:`, error);
                     }
                 }
-                const sid = Number(element.server_id) || 1;
-                const minSid = Math.floor((sid - 1) / 10) * 10 + 1;
+                let minSid = 1
+                if (tag == 11) {
+                    const sid = Number(element.server_id) || 1;
+                    minSid = Math.floor((sid - 1) / 10) * 10 + 1;
+                }
+
+
                 data.push({
                     channel: channelConfig.name, //渠道固定
                     minSid: minSid, //最小服务器
@@ -844,10 +850,14 @@ class ApiController {
                         logger.error(`查询服务器${serverInfo.id}角色信息失败:`, error);
                     }
                 }
+                let minSid = 1
+                if (tag == 11) {
+                    minSid = Math.floor(((servers[0].sid || 1) - 1) / 10) * 10 + 1
+                }
 
                 data.push({
                     channel: channelConfig.name, //渠道固定
-                    minSid: Math.floor(((servers[0].sid || 1) - 1) / 10) * 10 + 1, //最小服务器
+                    minSid: minSid, //最小服务器
                     maxSid: servers.length, //最大服务器 这里会控制 服务器列表显示的数量
                     isNewAccount: isNewAccount, //1为新号 会弹出用户协议
                     //以下是最近登陆的服务器 (不可为空 如果没有参数可以填最后一个区)
@@ -896,7 +906,9 @@ class ApiController {
         // 所有组的minSid统一取最小值
         if (data.length > 0) {
             const globalMinSid = Math.min(...data.map(item => item.minSid));
-            data.forEach(item => { item.minSid = globalMinSid; });
+            data.forEach(item => {
+                item.minSid = globalMinSid;
+            });
         }
 
         // tag=11 时,找到第一个有角色的服,隐藏它之前的服;都没角色则只显示最新的1个服
@@ -1178,6 +1190,7 @@ class ApiController {
                 "VIP666",
                 "VIP777",
                 "VIP888",
+                "QINGMINGLB",
             ];
             let param: string = "";
 
@@ -1562,7 +1575,7 @@ class ApiController {
 
             // 验证必要参数
             const {serverId, gameServerId, serverName, startTime, channelId} = data;
-            
+
             if (!serverId || !gameServerId || !serverName || !startTime) {
                 logger.warn("mianyou开服同步失败: 缺少必要参数", {data});
                 ctx.body = ApiController.fail("缺少必要参数: serverId, gameServerId, serverName, startTime");

+ 60 - 1
webServer/src/mongo/mongodb.ts

@@ -110,4 +110,63 @@ async function getRoleInfoByUidAndServerId(newUniqueTag: string, dbName: string)
     }
 }
 
-export { getDb, getCollection, closeConnection, getRoleInfoById, connectToMongo, getGuildInfoById, getRoleInfoByUidAndServerId };
+/**
+ * 向玩家发送系统邮件(直接写入 MongoDB)
+ * @param dbName    游戏服数据库名,如 "ckwy_fy_S001"
+ * @param newUniqueTag  玩家唯一标识,格式 "channelId|serverId|account"
+ * @param title     邮件标题
+ * @param content   邮件内容
+ * @param items     道具列表,格式 [[itemId, count], ...]
+ * @returns 发送是否成功
+ */
+async function insertMailToPlayer(
+    dbName: string,
+    newUniqueTag: string,
+    title: string,
+    content: string,
+    items: Array<[number, number]>
+): Promise<boolean> {
+    try {
+        if (!client) {
+            await connectToMongo();
+        }
+        const database = client!.db(dbName);
+
+        // 通过 newUniqueTag 找到角色,取出 _id
+        const charCol = database.collection('char');
+        const charDoc = await charCol.findOne({ newUniqueTag });
+        if (!charDoc) {
+            console.warn(`[insertMailToPlayer] 找不到角色 newUniqueTag=${newUniqueTag} dbName=${dbName}`);
+            return false;
+        }
+
+        const receiverUuid = charDoc._id.toString();
+
+        const mailDoc: any = {
+            type: 1,                    // SYSTEM
+            receiverUuid,
+            title,
+            senderName: title,
+            head: 0,
+            content,
+            time: Math.floor(Date.now() / 1000),
+        };
+
+        if (items && items.length > 0) {
+            mailDoc.items = items;
+            mailDoc.flag = 1;           // 有道具未领取
+        } else {
+            mailDoc.get = 1;            // 无道具,直接已读
+        }
+
+        const mailCol = database.collection('mail');
+        await mailCol.insertOne(mailDoc);
+        console.log(`[insertMailToPlayer] 邮件发送成功 receiverUuid=${receiverUuid} itemCnt=${items.length}`);
+        return true;
+    } catch (error) {
+        console.error('[insertMailToPlayer] 发送邮件失败:', error);
+        return false;
+    }
+}
+
+export { getDb, getCollection, closeConnection, getRoleInfoById, connectToMongo, getGuildInfoById, getRoleInfoByUidAndServerId, insertMailToPlayer };