Ver código fonte

Merge branch '360test' of https://gitee.com/wangwenfan/congkong into 360test

# Conflicts:
#	script/common/ProtoID.lua
flowerpig 7 meses atrás
pai
commit
0c0c57126c

+ 28 - 2
script/common/InnerHandler.lua

@@ -875,6 +875,10 @@ function LW_ANOTHERWORLDBATTLE_GATHER(fd, msg)
     AnotherWorldBattleCS.N2C_Gather(msg)
 end
 
+function WL_ANOTHERWORLDBATTLE_GATHER(fd, msg)
+    AnotherWorldBattleNS.C2N_Gather_End(msg)
+end
+
 
 function LW_ANOTHERWORLDBATTLE_POINT_ISCAN_CHALLENGE(fd, msg)
     if _G.is_middle ~= true then return end
@@ -885,9 +889,9 @@ function WL_ANOTHERWORLDBATTLE_POINT_ISCAN_CHALLENGE(fd, msg)
 end
 
 
-function LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_WIN(fd, msg)
+function LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_END(fd, msg)
     if _G.is_middle ~= true then return end
-    AnotherWorldBattleCS.N2C_Point_Challenge_Win(msg)
+    AnotherWorldBattleCS.N2C_Point_Challenge_End_Handle(msg)
 end
 
 
@@ -898,4 +902,26 @@ end
 
 function WL_ANOTHERWORLDBATTLE_ISSUEREWARD(fd, msg)
     AnotherWorldBattleNS.C2N_IssueReward(msg)
+end
+
+
+function LW_ANOTHERWORLDBATTLE_UPDATE_PLAYER(fd, msg)
+    if _G.is_middle ~= true then return end
+    AnotherWorldBattleCS.N2C_Update_Player_Data(msg)
+end
+
+
+function LW_ANOTHERWORLDBATTLE_UPDATE_UNION(fd, msg)
+    if _G.is_middle ~= true then return end
+    AnotherWorldBattleCS.N2C_Update_Union_Data(msg)
+end
+
+
+
+function LW_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP(fd, msg)
+    if _G.is_middle ~= true then return end
+    AnotherWorldBattleCS.N2C_Update_Point_Lineup(msg)
+end
+function WL_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP(fd, msg)
+    AnotherWorldBattleNS.C2N_Update_Point_Lineup(msg)
 end

+ 49 - 4
script/common/InnerProto.lua

@@ -1065,7 +1065,7 @@ WL_ANOTHERWORLDBATTLE_JOIN = {
 }
 
 
--- 查询公会所在分组的所有城池信息
+-- 查询所有城池信息
 LW_ANOTHERWORLDBATTLE_ALLCITY_QUERY = {
   {"sourceServerId",          "int"},
   {"playerUuid",              "string"},
@@ -1076,9 +1076,12 @@ WL_ANOTHERWORLDBATTLE_ALLCITY_QUERY  = {
   {"cityArr",                   "table"},   -- 公会所在分组的所有城池数据
   {"myUnionBaseCityId",          "int"},   -- 公会出生点城池Id
   {"myOccupyCityArr",            "table"}, -- 公会占领的城池信息
+  {"hasPointNum",                 "int"},  -- 玩家当前占领的据点数量
+  {"challengeTimes",            "int"},   -- 公会出生点城池Id
+  {"lastTime",                  "int"},   -- 公会出生点城池Id
 }
 
--- 查询公会所在分组的单个城池的详细信息
+-- 查询单个城池的详细信息
 LW_ANOTHERWORLDBATTLE_CITYDETAILED_QUERY = {
   {"sourceServerId",          "int"},
   {"playerUuid",              "string"},
@@ -1164,6 +1167,12 @@ LW_ANOTHERWORLDBATTLE_GATHER = {
   {"playerUuid",              "string"},
   {"myUnionId",               "string"},
   {"targetCityId",            "int"},
+  {"opType",                  "int"},
+}
+WL_ANOTHERWORLDBATTLE_GATHER = {
+  {"playerUuid",              "string"},
+  {"targetCityId",            "int"},
+  {"opType",                  "int"},
 }
 
 
@@ -1182,13 +1191,14 @@ WL_ANOTHERWORLDBATTLE_POINT_ISCAN_CHALLENGE = {
   {"pointInfo",               "table"},
 }
 
--- 挑战据点胜利
-LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_WIN = {
+-- 挑战据点结束
+LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_END = {
   {"sourceServerId",          "int"},
   {"playerUuid",              "string"},
   {"myUnionId",               "string"},
   {"targetCityId",            "int"},
   {"targetPointIdx",          "int"},
+  {"challengeRes",            "int"},
   {"playerShowInfo",          "table"},
 }
 
@@ -1203,4 +1213,39 @@ WL_ANOTHERWORLDBATTLE_POINT_LOSE = {
 -- 发奖
 WL_ANOTHERWORLDBATTLE_ISSUEREWARD = {
   {"unionOccupyInfo",          "table"},
+}
+
+
+-- 玩家数据更新
+LW_ANOTHERWORLDBATTLE_UPDATE_PLAYER = {
+  {"playerUuid",              "string"},
+  {"updateData",               "table"},
+  {"myUnionId",              "string"},
+}
+
+-- 公会数据更新
+LW_ANOTHERWORLDBATTLE_UPDATE_UNION = {
+  {"myUnionId",              "string"},
+  {"updateData",               "table"},
+}
+
+-- 更换据点防守阵容
+LW_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP = {
+  {"sourceServerId",          "int"},
+  {"playerUuid",              "string"},
+  {"heroArr",                 "table"},
+  {"targetCityId",            "int"},
+  {"targetPointIdx",          "int"},
+  {"formation",		            "short"},--阵法
+	{"heroList"	,			          "table"},--上阵英雄
+	{"helpList"	,			          "table"},--辅助对象
+}
+-- 更换据点防守阵容
+WL_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP = {
+  {"playerUuid",              "string"},
+  {"targetCityId",            "int"},
+  {"targetPointIdx",          "int"},
+  {"formation",		            "short"},--阵法
+	{"heroList"	,			          "table"},--上阵英雄
+	{"helpList"	,			          "table"},--辅助对象
 }

+ 6 - 1
script/common/InnerProtoID.lua

@@ -153,9 +153,14 @@ _ENV[150] = 'WL_ANOTHERWORLDBATTLE_PLAYERRANK_QUERY'
 _ENV[151] = 'LW_ANOTHERWORLDBATTLE_GATHER'
 _ENV[152] = 'LW_ANOTHERWORLDBATTLE_POINT_ISCAN_CHALLENGE'
 _ENV[153] = 'WL_ANOTHERWORLDBATTLE_POINT_ISCAN_CHALLENGE'
-_ENV[154] = 'LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_WIN'
+_ENV[154] = 'LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_END'
 _ENV[155] = 'WL_ANOTHERWORLDBATTLE_POINT_LOSE'
 _ENV[156] = 'WL_ANOTHERWORLDBATTLE_JOIN'
 _ENV[157] = 'WL_ANOTHERWORLDBATTLE_ISSUEREWARD'
+_ENV[158] = 'LW_ANOTHERWORLDBATTLE_UPDATE_PLAYER'
+_ENV[159] = 'LW_ANOTHERWORLDBATTLE_UPDATE_UNION'
+_ENV[160] = 'WL_ANOTHERWORLDBATTLE_GATHER'
+_ENV[161] = 'LW_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP'
+_ENV[162] = 'WL_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP'
 
 

+ 7 - 1
script/common/Lang.lua

@@ -829,14 +829,20 @@ AB_UNION_NOT_TOPTWO = [[公会排名前二才能参加]]
 AB_NOT_TOPTWO_MANAGER = [[会长/副会长才能报名]]
 
 
-
+AB_CANNOT_OPERATION = [[参加了异界之战, 不能进行该操作]]
 AB_NOT_OPEN_TIME = [[不在开启阶段]]
+AB_NOT_BATTLE_TIME = [[不在战斗阶段]]
 AB_UNION_NUM_EXCEED = [[参加公会数量超出]]
 AB_UNION_NO_JOIN = [[当前公会没有参加]]
 AB_NOT_TOPTWO_MANGER = [[会长/副会长才能报名]]
 AB_NOT_OCCUPY_POINT = [[玩家没有占领据点]]
+AB_NOT_OCCUPY_TARGET_POINT = [[玩家没有占领该据点]]
 AB_GATHER_CD = [[集结冷却中]]
+AB_CITY_NO_GATHER = [[没有在本城池发起集结]]
 AB_CITY_NOT_ADDJION = [[城池不相邻]]
 AB_JOINED = [[已报名]]
+AB_OCCUPY_POINT_MAX = [[当前占据的据点已达上限]]
+AB_HERO_IN_OTHER_POINT= [[英雄在其他据点上阵了]]
+AB_UPDATE_LINEUP_SUCC= [[更换防守阵容成功]]
 
 AB_MIYAO_NOT_ENOUG = [[秘钥不足]]

+ 1 - 1
script/common/Log.lua

@@ -81,7 +81,7 @@ function init()
     --[[战区争霸-战斗]] LOGID_OSS_AREABATTLE_BATTLE = lua_log.reg("log/oss_areaBattle_battle","",300)
     --[[战区争霸-奖励]] LOGID_OSS_AREABATTLE_AWARD = lua_log.reg("log/oss_areaBattle_award","",300)
 
-    --[[精灵日志]] LOGID_OSS_ELF = lua_log.reg("log/oss_elf","playerUuid, sourceId, opType, elfUuid, elfId, elfCnt, elfLv, elfStar",300)
+    --[[异界之战日志]] LOGID_OSS_ANOTHERWORLDBATTLE = lua_log.reg("log/oss_anotherWorldBattle", "", 300)
 
 end
 init()

+ 5 - 1
script/common/ProtoID.lua

@@ -1710,10 +1710,14 @@ _ENV[1740]="CG_AB_GARHER"
 _ENV[1741]="CG_AB_POINT_CHAllENGE"
 _ENV[1742]="CG_AB_GetState"
 _ENV[1743]="GC_AB_GetState"
-
 _ENV[1744]="CG_AB_TREASURE_QUERY"
 _ENV[1745]="GC_AB_TREASURE_QUERY"
 _ENV[1746]="CG_AB_TREASURE_LOTTERY"
 _ENV[1747]="GC_AB_TREASURE_LOTTERY"
 _ENV[1748]="CG_DRILL_ONE_CLICK_SAODANG"
 _ENV[1749]="GC_DRILL_ONE_CLICK_SAODANG"
+_ENV[1750]="CG_AB_UPDATE_LINEUP"
+_ENV[1751]="GC_AB_GARHER"
+_ENV[1752]="CG_CHAT_AB_GATHER"
+
+

+ 51 - 0
script/common/Util.lua

@@ -126,6 +126,57 @@ function printTable(tb, step)
 	end
 end
 
+
+function serialize(val, name, skipmap, depth, buf)
+    skipmap = skipmap or {}      -- 用来检测循环引用
+    depth   = depth   or 0
+    buf     = buf     or {}
+    local indent = string.rep("  ", depth)
+
+    local t = type(val)
+    if t == "string" then
+        table.insert(buf, string.format("%q", val))
+    elseif t == "number" or t == "boolean" or t == "nil" then
+        table.insert(buf, tostring(val))
+    elseif t == "table" then
+        -- 循环引用检测
+        if skipmap[val] then
+            table.insert(buf, skipmap[val])
+            return buf
+        end
+        skipmap[val] = string.format("<%s>", name or "table")
+
+        table.insert(buf, "{\n")
+        local idx = 1
+        for k, v in pairs(val) do
+            -- 拼 key
+            if type(k) == "string" and k:match("^[%a_][%w_]*$") then
+                table.insert(buf, indent .. "  " .. k .. " = ")
+            else
+                table.insert(buf, indent .. "  [" )
+                serialize(k, nil, skipmap, 0, buf)
+                table.insert(buf, "] = ")
+            end
+            -- 拼 value
+            serialize(v, nil, skipmap, depth + 1, buf)
+            table.insert(buf, ",\n")
+        end
+        table.insert(buf, indent .. "}")
+    elseif t == "function" then
+        table.insert(buf, string.format("<function:%s>", tostring(val)))
+    elseif t == "userdata" then
+        table.insert(buf, string.format("<userdata:%s>", tostring(val)))
+    elseif t == "thread" then
+        table.insert(buf, string.format("<thread:%s>", tostring(val)))
+    else
+        table.insert(buf, "<??>")
+    end
+    return buf
+end
+
+
+
+
 -- 判断是否同一天
 function isSameDay(time1)
 	if not time1 then

+ 2 - 0
script/core/ObjHuman.lua

@@ -338,6 +338,8 @@ function onZhandouliUpdate(human)
 	if human.db.unionUuid then
 		UnionLogic = UnionLogic or require("union.UnionLogic")
 		UnionLogic.UpdateMemberPower(human)
+
+		AnotherWorldBattleNS.PlayerPowerChange(human)
 	end
 
 end

+ 1 - 2
script/module/anotherWorldBattle/AnotherWordTreasure.lua

@@ -41,7 +41,7 @@ local function getTreasureLv(human)
 
     for _, treasureCfg in ipairs(AnotherWorldBattleConfig.treasureLv) do
         if lotteryTimes >= treasureCfg.condLotteryNum then
-            lotteryTimes = treasureCfg.treasureLv
+            treasureLv = treasureCfg.treasureLv
         end
     end
 
@@ -107,7 +107,6 @@ function AB_Treasure_Query(human)
     msgRet.lotteryTimes = getData(human)
     msgRet.nextLvCondTimes = 0
 
-
     local maxLv = #AnotherWorldBattleConfig.treasureLv
     local nextLv = nowLv + 1
     if nextLv >= maxLv then

+ 465 - 269
script/module/anotherWorldBattle/AnotherWorldBattleCS.lua

@@ -72,14 +72,14 @@ local function isRunning()
 end
 
 
-
 -- 进入新一轮的处理
 local function newRoundHandle()
     local stage = AnotherWorldBattleDB.GetStage()
 
     -- 上一轮奖励没有发放, 在新一轮开始时, 先发奖
     if stage == AnotherWorldBattleDefine.AB_STATE_AWARD then
-        -- AwardPrizesHandle()
+        IssueRewardManager()
+        return AnotherWorldBattleDB.UpdateStage(AnotherWorldBattleDefine.AB_STATE_END)
     end
 
     -- 重置数据
@@ -200,7 +200,6 @@ local function grouping()
 
     AnotherWorldBattleDB.UpdateGroupArray(newGroupArray)
 end
-
 -- 给各个分组中的公会随机分配出生点
 local function randomBaseCity()
     local baseCityIdArr = {}
@@ -228,39 +227,53 @@ local function randomBaseCity()
     end
 end
 
-
--- 统计单个公会的占领情况, 用于发放奖励
-local function genUnionOccupyInfo(unionId, union)
+-- 统计公会的占领情况, 用于发放奖励
+local function genUnionOccupyInfo(unionId, union, playerListData)
     local occupyTb = {
-        occupyCityArr = {}, -- 曾占领, 当前还占领的城池列表
+        occupyCityArr = {}, -- 当前还占领的城池列表
+        point2CityIdArr = {}, -- 曾占领/当前还占领的据点的所属城池Id列表
         occuoyPointNum = 0,
         playerUuidArr = {},
+        unionId = unionId,
     }
 
     local now = os.time()
     local tbl = occupyTb.occupyCityArr
-    tbl[#tbl+1] = { union.baseCityId, { {union.baseCityStartTime, union.baseCityEndTime or now} }, true }
-
+    tbl[#tbl+1] = union.baseCityId
 
+    local tbl2 = occupyTb.point2CityIdArr
     for cityId, cityIno in pairs(union.occupCityList or {}) do
-        if cityIno.isOccupy or cityIno.occupyTimeArr then
-            -- 更新目前还占领的城池的占领结束时间
-            local lastTimeTb = cityIno.occupyTimeArr[#cityIno.occupyTimeArr]
-            if #lastTimeTb == 1 then
-                lastTimeTb[2] = now
+        if cityIno.isOccupy then
+            tbl[#tbl+1] = cityId
+        end
+
+        for _, pointInfo in pairs(cityIno.occupyPointList) do
+            if pointInfo.playerUuid then
+                occupyTb.occuoyPointNum = occupyTb.occuoyPointNum + 1
+
+                -- 更新据点最新占领时间段的结束时间
+                local occupyTimeArr = pointInfo.occupyTimeArr
+                local lastTimeTb = occupyTimeArr[#occupyTimeArr]
+                if #lastTimeTb == 1 then
+                    occupyTimeArr[#occupyTimeArr][2] = now
+                end
             end
 
-            tbl[#tbl+1] = { cityId, cityIno.occupyTimeArr, cityIno.isOccupy }
+            tbl2[#tbl2+1] = {cityId, pointInfo.occupyTimeArr}
         end
+    end
 
-        for _,_ in pairs(cityIno.occupyPointList) do
-            occupyTb.occuoyPointNum = occupyTb.occuoyPointNum + 1
-        end
+    -- 出生点算5个据点
+    local baseCiyuTimeArr = { {union.baseCityStartTime, union.baseCityEndTime or now } }
+    for i=1, AnotherWorldBattleDefine.AB_POINT_MAX_NUM do
+        tbl2[#tbl2+1] = {union.baseCityId,  baseCiyuTimeArr}
     end
 
-    local tbl2 = occupyTb.playerUuidArr
-    for playerUuid in pairs(union.playerList) do
-        tbl2[#tbl2+1] = playerUuid
+
+    for playerUuid, playerInfo in pairs(playerListData) do
+        if playerInfo.unionId == unionId then
+            occupyTb.playerUuidArr[#occupyTb.playerUuidArr+1] = playerUuid
+        end
     end
 
     -- 防止本次没有正常发放奖励,后续补发时, 结束时间异常的情况
@@ -278,35 +291,27 @@ local function issueReward(sourceServerId, occupyInfo)
     InnerMsg.sendMsg(fd, msgData)
 end
 
-
 -- 奖励发放管理函数
-local function issueRewardManager()
+function IssueRewardManager()
     local delay_sec = 0
     local unionList = AnotherWorldBattleDB.GetUnionList()
+    local playerListData = AnotherWorldBattleDB.GetPlayerList()
 
     for unionId, union in pairs(unionList) do
-        local occupyInfo = genUnionOccupyInfo(unionId, union)
+        local occupyInfo = genUnionOccupyInfo(unionId, union, playerListData)
         delay_sec = delay_sec + 5
         Timer.addLater(delay_sec, issueReward, union.serverId, occupyInfo)
     end
 end
 
-
-
-function oneMin()
-    if _G.is_middle ~= true then return end
-
-    if not isOpen() then
-        return
-    end
-
-    -- 与 onHour() 处理错开
-    if Util.getMin() == 0 then
-        return
-    end
-
+-- 检测活动各阶段及相关处理
+local function timedStageHandle()
     -- 处于报名阶段
-    if table.find(AnotherWorldBattleDefine.AB_JOIN_WDAY_AREA, wDay) then
+    -- if table.find(AnotherWorldBattleDefine.AB_JOIN_WDAY_AREA, wDay) then
+    --     joinStageCheck()
+    -- end
+
+    if wDay == AnotherWorldBattleDefine.AB_JOIN_WDAY then
         joinStageCheck()
     end
 
@@ -324,7 +329,7 @@ function oneMin()
             -- 给各个分组中的公会随机分配出生点
             randomBaseCity()
 
-            -- 最后更新活动阶段
+            -- 改为战斗阶段
             return AnotherWorldBattleDB.UpdateStage(AnotherWorldBattleDefine.AB_STATE_BATTLE)
         end
     end
@@ -334,75 +339,53 @@ function oneMin()
     if wDay == AnotherWorldBattleDefine.AB_BATTLE_WDAY_AREA[2] and now >= (toDayStartTime + AnotherWorldBattleDefine.AB_BATTLE_END_SEC) then
         local stage = AnotherWorldBattleDB.GetStage()
 
-        if stage == AnotherWorldBattleDefine.AB_STATE_BATTLE then
+        if stage == AnotherWorldBattleDefine.AB_STATE_BATTLE or stage == AnotherWorldBattleDefine.AB_STATE_AWARD then
             -- 改为发奖阶段
             AnotherWorldBattleDB.UpdateStage(AnotherWorldBattleDefine.AB_STATE_AWARD)
 
             -- 开始发奖
-            issueRewardManager()
+            IssueRewardManager()
 
             -- 改为结束阶段
             return AnotherWorldBattleDB.UpdateStage(AnotherWorldBattleDefine.AB_STATE_END)
         end
-
     end
 end
 
-function onHour(hour)
-    if _G.is_middle ~= true then return end
 
-    if hour == 0 or not wDay then
-        updateWDay()
-    end
+
+function oneMin()
+    if _G.is_middle ~= true then return end
 
     if not isOpen() then
         return
     end
 
-        -- 处于报名阶段
-    if table.find(AnotherWorldBattleDefine.AB_JOIN_WDAY_AREA, wDay) then
-        joinStageCheck()
+    -- 与 onHour() 处理错开
+    if Util.getMin() == 0 then
+        return
     end
 
-    local now = os.time()
-
-    -- 报名阶段 -> 战斗阶段
-    if wDay >= AnotherWorldBattleDefine.AB_BATTLE_WDAY_AREA[1] and wDay <= AnotherWorldBattleDefine.AB_BATTLE_WDAY_AREA[2] then
-        local stage = AnotherWorldBattleDB.GetStage()
-        local toDayStartTime = getTodayStartTime()
-
-        if stage == AnotherWorldBattleDefine.AB_STATE_JOIN and now >= (toDayStartTime + AnotherWorldBattleDefine.AB_START_SEC) then
-            -- 分组
-            grouping()
+    timedStageHandle()
+end
 
-            -- 给各个分组中的公会随机分配出生点
-            randomBaseCity()
+function onHour(hour)
+    if _G.is_middle ~= true then return end
 
-            -- 最后更新活动阶段
-            return AnotherWorldBattleDB.UpdateStage(AnotherWorldBattleDefine.AB_STATE_BATTLE)
-        end
+    if hour == 0 or not wDay then
+        updateWDay()
     end
 
-    -- 战斗阶段 -> 发奖阶段
-    local toDayStartTime = getTodayStartTime()
-    if wDay == AnotherWorldBattleDefine.AB_BATTLE_WDAY_AREA[2] and now >= (toDayStartTime + AnotherWorldBattleDefine.AB_BATTLE_END_SEC) then
-        local stage = AnotherWorldBattleDB.GetStage()
-
-        if stage == AnotherWorldBattleDefine.AB_STATE_BATTLE then
-            AnotherWorldBattleDB.UpdateStage(AnotherWorldBattleDefine.AB_STATE_AWARD)
-
-            -- 开始发奖
-            issueRewardManager()
-
-            -- 改为结束阶段
-            return AnotherWorldBattleDB.UpdateStage(AnotherWorldBattleDefine.AB_STATE_END)
-        end
-
+    if not isOpen() then
+        return
     end
+
+    timedStageHandle()
 end
 
 
 ------------------------------------C2N---------------------------------------------------
+
 -- 错误提示
 local function errTips(sourceServerId, playerUuid, errCode)
     local msgData = InnerMsg.wl.WL_ANOTHERWORLDBATTLE_TIPS
@@ -426,6 +409,22 @@ end
 
 ------------------------------------N2C---------------------------------------------------
 
+-- 获取自己公会的组Id
+local function getMyUnionGourpId(myUnionId)
+    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    return groupId
+end
+
+-- 获取自己公会/所在区服第一公会的组Id
+local function getGroupId(myUnionId, myServerId)
+    local groupId = getMyUnionGourpId(myUnionId)
+    if not groupId then
+        groupId = AnotherWorldBattleDB.GetGroupIdByServerId(myServerId)
+    end
+
+    return groupId
+end
+
 -- 统计单个服公会报名数量
 local function calcSvrUnionJoinNum(serverId)
     local num = 0
@@ -472,19 +471,22 @@ local function calcOccupyCityNum(occupCityList, cityLv)
     return num
 end
 
--- 统计公会占领的据点数量
-local function calcOccupyPointNum(occupCityList)
+-- 统计公会占领的据点所属城池数组
+local function calcOccupyPointArr(occupCityList)
+    local pointInfoArr = {}
+
     if not occupCityList then
-        return 0
+        return pointInfoArr
     end
 
-    local num = 0
     for cityId, occupyInfo in pairs(occupCityList) do
-        for _,_ in pairs(occupyInfo.occupyPointList) do
-            num = num + 1
+        for _, pointInfo in pairs(occupyInfo.occupyPointList) do
+            if pointInfo.playerUuid then
+                pointInfoArr[#pointInfoArr+1] = cityId
+            end
         end
     end
-    return num
+    return pointInfoArr
 end
 
 -- 获取公会占领的城池列表
@@ -526,67 +528,74 @@ local function isadJoin(cityIdArr, targetCityId)
     return false
 end
 
+-- 统计玩家占据的据点数量
+local function calcPlayerOccupyPointNum(playerUuid)
+    local playerOccupyPonitNum = 0
+    local playerData = AnotherWorldBattleDB.GetPlayerData(playerUuid)
+    if playerData and playerData.heroList then
+        for _, pointList in pairs(playerData.heroList) do
+            for _, _ in pairs(pointList) do
+                playerOccupyPonitNum = playerOccupyPonitNum + 1
+            end
+        end
+    end
+
+    return playerOccupyPonitNum
+end
+
+
 -- 检查某个据点是否能被玩家挑战
 local function isCanChallengePoint(targetCityId, targetPointIdx, myUnionId, playerUuid)
     -- 活动未开启
     if not isRunning() then
-        return false
+        return -1
     end
 
     -- 公会没有参加活动
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getMyUnionGourpId(myUnionId)
     if not groupId then
-        return false
+        return -2
     end
 
     local cityList = AnotherWorldBattleDB.GetCityListByGroupId(groupId)
     local tagetCityData = cityList[targetCityId]
     if not tagetCityData then
-        return false
-    end
-
-    -- 城池已被本公会占领
-    if tagetCityData.occupyUnion and tagetCityData.occupyUnion == myUnionId then
-        return false
+        return -3
     end
 
     local targetPointData = tagetCityData.pointArr[targetPointIdx]
     if not targetPointData then
-        return false
+        return -5
     end
 
+    -- 自己占领了该据点
+    if targetPointData.unionId and targetPointData.unionId == myUnionId and targetPointData.playerUuid == playerUuid then
+        return 2
+    end
+
+    -- 据点已被本公会占领
+    if tagetCityData.occupyUnion and tagetCityData.occupyUnion == myUnionId then
+        return -4
+    end
+
+
     -- 据点已被本公会占领
     if targetPointData.unionId and targetPointData.unionId == myUnionId then
-        return false
+        return -6
     end
 
     local myUnionData = AnotherWorldBattleDB.GetUnionData(myUnionId)
     if not myUnionData then
-        return false
+        return -7
     end
 
     -- 城池是否相邻
     local occupyCityArr = getUnionOccupyArr(myUnionId)
     if not isadJoin(occupyCityArr, targetCityId) then
-        return false
+        return -8
     end
 
-    -- 每个玩家最多占领据点数量是否超出
-    local playerOccupyPonitNum = 0
-    if myUnionData.playerList and myUnionData.playerList[playerUuid] then
-        local heroList = myUnionData.playerList[playerUuid].heroList
-        for cityId, pointList in pairs(heroList) do
-            for _, _ in pairs(pointList) do
-                playerOccupyPonitNum = playerOccupyPonitNum + 1
-            end
-        end
-    end
-
-    if playerOccupyPonitNum >= AnotherWorldBattleDefine.AB_PLAYER_OCCUPY_POINT_MAX_NUM then
-        return false
-    end
-
-    return true
+    return 1
 end
 
 -- 公会是否能报名
@@ -622,60 +631,73 @@ local function isCompleteOccupy(cityData, myUnionId)
     return true
 end
 
--- 查询玩家是否上榜
-local function getPlayerRank(playerRankList, playerUuid)
-    for _, rankData in ipairs(playerRankList) do
-        if rankData.playerUuid == playerUuid then
-            return true
-        end
+-- 获取玩家挑战次数相关数据
+local function getPlayerChallengeTimesInfo(playerUuid)
+    local playerData = AnotherWorldBattleDB.GetPlayerData(playerUuid)
+    if not playerData then
+        return AnotherWorldBattleDefine.AB_PLAYER_CHALLENGE_TIMES, 0
     end
 
-    return false
-end
+    local now = os.time()
+    local subSex = now - playerData.lastTime
+
+    if subSex >= AnotherWorldBattleDefine.AB_PLAYER_CHALLENGETIMES_SEC then
+        local addTimes = math.floor(subSex / AnotherWorldBattleDefine.AB_PLAYER_CHALLENGETIMES_SEC)
+        playerData.challengeTimes = math.min(playerData.challengeTimes + addTimes, AnotherWorldBattleDefine.AB_PLAYER_CHALLENGE_TIMES)
+        playerData.lastTime = playerData.lastTime + addTimes* AnotherWorldBattleDefine.AB_PLAYER_CHALLENGETIMES_SEC
 
--- 更新公会排行榜数据
-local function updateUnionRanktData(unionRankList, unionId, cityNum, pointNum)
-    for rank, rankData in ipairs(unionRankList) do
-        if rankData.unionId == unionId then
-            unionRankList[rank].occupyCityNum = unionRankList[rank].occupyCityNum + cityNum
-            unionRankList[rank].occupyPointNum = unionRankList[rank].occupyPointNum + pointNum
+        if playerData.challengeTimes == AnotherWorldBattleDefine.AB_PLAYER_CHALLENGE_TIMES then
+            playerData.lastTime = 0
         end
+
+        AnotherWorldBattleDB.UpdatePlayerData(playerUuid, playerData)
     end
+
+    return playerData.challengeTimes, playerData.lastTime
 end
 
--- 更新玩家排行榜数据
-local function updatePlayerRanktData(playerRankList, playerUuid, pointNum, pointWeight)
-    local playerRank = 0
-    for rank, rankData in ipairs(playerRankList) do
-        if rankData.playerUuid == playerUuid then
-            playerRank = rank
-        end
+-- 获取城池被占领状态
+local function getCityState(cityData)
+    local state = 0
+    if cityData.occupyUnion then
+        state = 1
+        return state
     end
 
-    if playerRank ~= 0 then
-        playerRankList[playerRank].pointNum = playerRankList[playerRank].pointNum + pointNum
-        playerRankList[playerRank].pointAllWeight = playerRankList[playerRank].pointAllWeight + pointWeight
-    end
-end
+    local occupyPlayerUuid
+    for _, pointInfo in ipairs(cityData.pointArr) do
+        if pointInfo.playerUuid then
+            if not occupyPlayerUuid then
+                occupyPlayerUuid = pointInfo.playerUuid
+            end
 
+            if pointInfo.playerUuid ~= occupyPlayerUuid then
+                state = 2
+                break
+            end
+        end
+    end
 
+    return state
+end
 
 
 -- 查询状态
 function N2C_Get_State(msg)
-    local sourceServerId = msg.sourceServerId
-
     local msgData = InnerMsg.wl.WL_ANOTHERWORLDBATTLE_GET_STATE
     msgData.playerUuid = msg.playerUuid
+    msgData.systemState = 0
+    msgData.joinState = 0
 
     local stage = AnotherWorldBattleDB.GetStage()
     msgData.systemState = stage
-    msgData.joinState = 0
 
     if stage == 0 then
         local lastRoundStartTime = AnotherWorldBattleDB.GetLastRoundStartTime()
         if lastRoundStartTime == 0 then
             msgData.systemState = 0
+        else
+            msgData.systemState = 3
         end
     end
 
@@ -686,6 +708,7 @@ function N2C_Get_State(msg)
         end
     end
 
+    local sourceServerId = msg.sourceServerId
     local num = calcSvrUnionJoinNum(sourceServerId)
     if num >= AnotherWorldBattleDefine.AB_SRV_UNION_MAX_NUM then
         msgData.joinState = 2
@@ -708,6 +731,7 @@ function N2C_Join(msg)
         return errTips(sourceServerId, playerUuid, AnotherWorldBattleDefine.ERR_CODE_8)
     end
 
+    -- 更新参赛列表数据
     local joinUnionArr = AnotherWorldBattleDB.GetJoinUnionArr()
     joinUnionArr = joinUnionArr or {}
     joinUnionArr[#joinUnionArr+1] = {
@@ -715,18 +739,15 @@ function N2C_Join(msg)
         power = unionInfo.power,
         serverId = sourceServerId
     }
-
     AnotherWorldBattleDB.UpdateJoinUnionArr(joinUnionArr)
 
-    local unionList = AnotherWorldBattleDB.GetUnionList()
-    unionList = unionList or {}
-    unionList[unionInfo.unionId] = {
+    -- 更新公会列表数据
+    local newUnionData = {
         serverId = sourceServerId,
         power = unionInfo.power,
         name = unionInfo.name,
     }
-
-    AnotherWorldBattleDB.UpdateUnionList(unionList)
+    AnotherWorldBattleDB.UpdateUnionData(unionInfo.unionId, newUnionData)
 
     -- 通知报名成功
     local msgData = InnerMsg.wl.WL_ANOTHERWORLDBATTLE_JOIN
@@ -739,15 +760,17 @@ end
 -- 查询所有城池信息
 function N2C_AllCity_Query(msg)
     local myUnionId = msg.myUnionId
-
     local msgData = InnerMsg.wl.WL_ANOTHERWORLDBATTLE_ALLCITY_QUERY
     msgData.cityArr = {}
     msgData.playerUuid = msg.playerUuid
     msgData.myUnionBaseCityId = 0
     msgData.myOccupyCityArr = {}
+    msgData.hasPointNum = 0
+    msgData.challengeTimes = 0
+    msgData.lastTime = 0
     local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
 
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getGroupId(myUnionId, msg.sourceServerId)
     if not groupId then
         -- 报名阶段, 或者活动开未开启过处于默认的结束状态
         local stage = AnotherWorldBattleDB.GetStage()
@@ -778,9 +801,15 @@ function N2C_AllCity_Query(msg)
                 cityArrMsg[cityId].occupyPointNum = cityArrMsg[cityId].occupyPointNum + 1
             end
         end
+
+        cityArrMsg[cityId].cityState = getCityState(cityInfo)
     end
 
     msgData.myOccupyCityArr = getUnionOccupyArr(myUnionId)
+    msgData.hasPointNum = calcPlayerOccupyPointNum(msg.playerUuid)
+    local challengeTimes, leftTime = getPlayerChallengeTimesInfo(msg.playerUuid)
+    msgData.challengeTimes = challengeTimes
+    msgData.lastTime = leftTime
 
     InnerMsg.sendMsg(fd, msgData)
 end
@@ -799,7 +828,7 @@ function N2C_CityDetailed_Query(msg)
     msgData.pointArr = {}
     msgData.gatherState = 0
 
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getGroupId(myUnionId, msg.sourceServerId)
     if not groupId then
         -- 报名阶段, 或者活动开未开启过处于默认的结束状态
         local stage = AnotherWorldBattleDB.GetStage()
@@ -816,25 +845,32 @@ function N2C_CityDetailed_Query(msg)
     end
 
 
-    local cityData = cityList[targetCityId]
-    local myUnionOccupyArr = getUnionOccupyArr(myUnionId)
+    local union = AnotherWorldBattleDB.GetUnionData(myUnionId)
+    local occupCityList = union and union.occupCityList
+    local myUnionOccupyArr = calcOccupyPointArr(occupCityList)
+    if union then
+        myUnionOccupyArr[#myUnionOccupyArr+1] = union.baseCityId
+    end
     msgData.myUnionOccupyArr = myUnionOccupyArr
 
-
+    local cityData = cityList[targetCityId]
     local pointArrMsg = msgData.pointArr
+
     for pointIdx, occupyInfo in ipairs(cityData.pointArr) do
         pointArrMsg[pointIdx] = {}
-        local bl = isCanChallengePoint(targetCityId, pointIdx, myUnionId, playerUuid)
-        pointArrMsg[pointIdx].isCanChallenge = bl and 1 or 0
+        local state = isCanChallengePoint(targetCityId, pointIdx, myUnionId, playerUuid)
+        pointArrMsg[pointIdx].state = state < 0 and 0 or state
 
         if occupyInfo.unionId and occupyInfo.playerUuid then
             local occupyUnionData = AnotherWorldBattleDB.GetUnionData(occupyInfo.unionId)
-            if occupyUnionData then
+            local occupyPlayerData = AnotherWorldBattleDB.GetPlayerData(occupyInfo.playerUuid)
+
+            if occupyUnionData and occupyPlayerData then
                 pointArrMsg[pointIdx].occupyUnionName = occupyUnionData.name
-                pointArrMsg[pointIdx].occupyPlayerName = occupyUnionData.playerList[occupyInfo.playerUuid].name
+                pointArrMsg[pointIdx].occupyPlayerName = occupyPlayerData.name
 
                 pointArrMsg[pointIdx].power = 0
-                local heroList = occupyUnionData.playerList[occupyInfo.playerUuid].heroList
+                local heroList = occupyPlayerData.heroList
                 if heroList and heroList[targetCityId] and heroList[targetCityId][pointIdx] then
                     pointArrMsg[pointIdx].power = calcHerosPower(heroList[targetCityId][pointIdx])
                 end
@@ -882,7 +918,7 @@ function N2C_PointDetailed_Query(msg)
     msgData.targetPointIdx = targetPointIdx
     msgData.pointInfo = {}
 
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getGroupId(myUnionId, msg.sourceServerId)
     if not groupId then
         -- 报名阶段, 或者活动开未开启过处于默认的结束状态
         local stage = AnotherWorldBattleDB.GetStage()
@@ -907,12 +943,7 @@ function N2C_PointDetailed_Query(msg)
 
     local pointInfoMsg = msgData.pointInfo
     if pointData.unionId and pointData.playerUuid then
-        local union = AnotherWorldBattleDB.GetUnionData(pointData.unionId)
-        if not union then
-            return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_4)
-        end
-
-        local playerData = union.playerList and union.playerList[pointData.playerUuid]
+        local playerData = AnotherWorldBattleDB.GetPlayerData(pointData.playerUuid)
         if not playerData then
             return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_4)
         end
@@ -936,12 +967,14 @@ function N2C_PointDetailed_Query(msg)
                 heroLv = heroInfo.heroLevel,
                 heroCamp = heroInfo.heroCamp,
                 heroIcon = heroInfo.heroIcon,
+                heroId = heroInfo.heroId,
+                heroQuality = heroInfo.heroQuality,
             }
         end
     end
 
-    local isCanChallenge = isCanChallengePoint(targetCityId, targetPointIdx, myUnionId, msg.playerUuid)
-    pointInfoMsg.isCanChallenge = isCanChallenge and 1 or 0
+    local state = isCanChallengePoint(targetCityId, targetPointIdx, myUnionId, msg.playerUuid)
+    pointInfoMsg.state = state < 0 and 0 or state
 
     InnerMsg.sendMsg(fd, msgData)
 end
@@ -949,7 +982,7 @@ end
 -- 查询公会出生点信息
 function N2C_BaseCity_Query(msg)
     local myUnionId = msg.myUnionId
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getGroupId(myUnionId, msg.sourceServerId)
     if not groupId then
         return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_3)
     end
@@ -966,8 +999,10 @@ function N2C_BaseCity_Query(msg)
     msgData.baseCityInfo = baseCityInfo
 
     baseCityInfo.cityId = union.baseCityId
-    baseCityInfo.occupyPointNum = calcOccupyPointNum(union.occupCityList)
-    baseCityInfo.myUnionOccupyArr = getUnionOccupyArr(myUnionId)
+    local pointInfoArr = calcOccupyPointArr(union.occupCityList)
+    baseCityInfo.occupyPointNum = #pointInfoArr
+    baseCityInfo.myUnionOccupyArr = calcOccupyPointArr(union.occupCityList)
+    baseCityInfo.myUnionOccupyArr[#baseCityInfo.myUnionOccupyArr+1] = baseCityInfo.cityId
     baseCityInfo.occupyCityLv2Num = calcOccupyCityNum(union.occupCityList, 2)
     baseCityInfo.occupyCityLv3Num = calcOccupyCityNum(union.occupCityList, 3)
     baseCityInfo.occupyCityLv4Num = calcOccupyCityNum(union.occupCityList, 4)
@@ -999,14 +1034,14 @@ function N2C_PlayerOccupyPoint_Query(msg)
     end
 
 
-    local playerList = union.playerList
-    if not playerList[playerUuid] then
+    local playerData = AnotherWorldBattleDB.GetPlayerData(playerUuid)
+    if not playerData then
         return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_5)
     end
 
-    local heroList = playerList[playerUuid].heroList
+    local heroList = playerData.heroList
     if not heroList then
-        return errTips(msg.sourceServerId, playerUuid, AnotherWorldBattleDefine.ERR_CODE_4)
+        return errTips(msg.sourceServerId, playerUuid, AnotherWorldBattleDefine.ERR_CODE_5)
     end
 
 
@@ -1020,14 +1055,16 @@ function N2C_PlayerOccupyPoint_Query(msg)
                 heroArr = {},
             }
 
-            local TargetHeroArr = occupyPointArrMsg[#occupyPointArrMsg].heroArr
+            local targetHeroArr = occupyPointArrMsg[#occupyPointArrMsg].heroArr
             for _, heroInfo in ipairs(heroInfoArr) do
-                TargetHeroArr[#TargetHeroArr+1] = {
+                targetHeroArr[#targetHeroArr+1] = {
                     heroBody = heroInfo.heroBody,
                     heroStar = heroInfo.heroStar,
                     heroLv = heroInfo.heroLevel,
                     heroCamp = heroInfo.heroCamp,
                     heroIcon = heroInfo.heroIcon,
+                    heroId = heroInfo.heroId,
+                    heroQuality = heroInfo.heroQuality
                 }
             end
         end
@@ -1039,7 +1076,7 @@ end
 -- 查询公会排行榜
 function N2C_UnionRank_Query(msg)
     local myUnionId = msg.myUnionId
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getGroupId(myUnionId, msg.sourceServerId)
     if not groupId then
         return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_3)
     end
@@ -1051,19 +1088,14 @@ function N2C_UnionRank_Query(msg)
     msgData.unionRankArr = {}
 
     for rank, randkData in ipairs(unionRankList) do
-        if rank > AnotherWorldBattleDefine.AB_RANK_MAX_NUM then
-            break
-        end
-
-        local unionName = AnotherWorldBattleDB.GetUnionName(randkData.unionId)
         msgData.unionRankArr[rank] = {
-            name = unionName,
+            name = randkData.name,
             power = randkData.power,
             cityNum = randkData.occupyCityNum,
             pointNum = randkData.occupyPointNum,
         }
 
-        if randkData.unionId == myUnionId then
+        if randkData.guildId == myUnionId then
             msgData.myUnionRank = rank
         end
     end
@@ -1075,7 +1107,7 @@ end
 -- 查询玩家排行榜
 function N2C_PlayerRank_Query(msg)
     local myUnionId = msg.myUnionId
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getGroupId(myUnionId, msg.sourceServerId)
     if not groupId then
         return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_3)
     end
@@ -1091,15 +1123,14 @@ function N2C_PlayerRank_Query(msg)
             break
         end
 
-        local playerName = AnotherWorldBattleDB.GetPlayerName(randkData.unionId, randkData.playerUuid)
-        msgData.unionRankArr[rank] = {
-            name = playerName,
+        msgData.playerRankArr[rank] = {
+            name = randkData.name,
             power = randkData.power,
-            pointNum = randkData.occupyPointNum,
+            pointNum = randkData.pointNum,
             pointWeight = randkData.pointAllWeight,
         }
 
-        if randkData.playerUuid == msg.playerUuid then
+        if randkData.playerId == msg.playerUuid then
             msgData.myRank = rank
         end
     end
@@ -1118,7 +1149,7 @@ function N2C_Gather(msg)
         return errTips(sourceServerId, playerUuid, AnotherWorldBattleDefine.ERR_CODE_1)
     end
 
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getMyUnionGourpId(myUnionId)
     if not groupId then
         return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_3)
     end
@@ -1129,25 +1160,52 @@ function N2C_Gather(msg)
         return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_3)
     end
 
-    local now = os.time()
-    if myUnionData.gatherInfo then
-        local gatherTime = myUnionData.gatherInfo.gatherTime
-        if now - gatherTime < AnotherWorldBattleDefine.AB_GATHER_CD_SEC then
-            return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_6)
+    local gatherInfo = myUnionData.gatherInfo
+    if msg.opType == 1 then --集结
+        -- 集结冷却时间判断
+        local now = os.time()
+        if gatherInfo then
+            local gatherTime = gatherInfo.gatherTime
+            if now - gatherTime < AnotherWorldBattleDefine.AB_GATHER_CD_SEC then
+                return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_6)
+            end
+        end
+
+        -- 城池是否相邻判断
+        local occupCityyArr = getUnionOccupyArr(myUnionId)
+        if not isadJoin(occupCityyArr, targetCityId) then
+            return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_7)
+        end
+
+        myUnionData.gatherInfo = myUnionData.gatherInfo or {}
+        myUnionData.gatherInfo.gatherTime = now
+        myUnionData.gatherInfo.gatherCity = targetCityId
+    else
+        -- 取消集结
+
+        if not gatherInfo then
+            return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_9)
+        end
+
+        if targetCityId ~= gatherInfo.gatherCity then
+            return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_9)
         end
-    end
 
-    local occupCityyArr = getUnionOccupyArr(myUnionId)
-    if not isadJoin(occupCityyArr, targetCityId) then
-        return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_7)
+        gatherInfo.gatherCity = 0
     end
 
-    myUnionData.gatherInfo = myUnionData.gatherInfo or {}
-    myUnionData.gatherInfo.gatherTime = now
-    myUnionData.gatherInfo.gatherCity = targetCityId
     AnotherWorldBattleDB.UpdateUnionData(myUnionId, myUnionData)
 
+    -- 推送城池数据给客户端,刷新界面
     N2C_CityDetailed_Query(msg)
+
+    -- 发给本地服, 用于在公会聊天频道生成链接
+    local msgData = InnerMsg.wl.WL_ANOTHERWORLDBATTLE_GATHER
+    msgData.playerUuid = msg.playerUuid
+    msgData.targetCityId = targetCityId
+    msgData.opType = msg.opType
+    local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
+    InnerMsg.sendMsg(fd, msgData)
 end
 
 -- 查询据点是否可以被挑战
@@ -1157,12 +1215,17 @@ function N2C_Try_Challengde_Point(msg)
     local targetCityId = msg.targetCityId
     local targetPointIdx = msg.targetPointIdx
 
-    local isCanChallenge = isCanChallengePoint(targetCityId, msg.targetPointIdx, msg.myUnionId, playerUuid)
-    if not isCanChallenge then
+    local state = isCanChallengePoint(targetCityId, msg.targetPointIdx, msg.myUnionId, playerUuid)
+    if state ~= 1 then
         return
     end
 
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local occupyPointNum = calcPlayerOccupyPointNum(msg.playerUuid)
+    if occupyPointNum >= AnotherWorldBattleDefine.AB_PLAYER_OCCUPY_POINT_MAX_NUM then
+        return errTips(msg.sourceServerId, playerUuid, AnotherWorldBattleDefine.ERR_CODE_10)
+    end
+
+    local groupId = getMyUnionGourpId(myUnionId)
     local cityList = AnotherWorldBattleDB.GetCityListByGroupId(groupId)
     local targetPointData = cityList[targetCityId].pointArr[targetPointIdx]
 
@@ -1189,7 +1252,7 @@ function N2C_Try_Challengde_Point(msg)
 end
 
 -- 玩家挑战据点胜利
-function N2C_Point_Challenge_Win(msg)
+local function challenge_Win(msg)
     local playerUuid = msg.playerUuid
     local myUnionId = msg.myUnionId
     local targetCityId = msg.targetCityId
@@ -1200,7 +1263,7 @@ function N2C_Point_Challenge_Win(msg)
         return
     end
 
-    local groupId = AnotherWorldBattleDB.GetUnionGroupId(myUnionId)
+    local groupId = getMyUnionGourpId(myUnionId)
     if not groupId then
         return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_3)
     end
@@ -1213,9 +1276,9 @@ function N2C_Point_Challenge_Win(msg)
     local cityList = AnotherWorldBattleDB.GetCityListByGroupId(groupId)
     local cityData = cityList[targetCityId]
     local pointData = cityData.pointArr[targetPointIdx]
-    local unionRankList = AnotherWorldBattleDB.GetUnionRankList(groupId)
-    local playerRankList = AnotherWorldBattleDB.GetPlayerRankList(groupId)
 
+    local now = os.time()
+    local cityNum, pointNum = 0, 1
     local pointWeight = AnotherWorldBattleConfig.city[targetCityId].pointWeight
 
     -- 防守方是真实玩家
@@ -1224,8 +1287,6 @@ function N2C_Point_Challenge_Win(msg)
         local defUnionData = AnotherWorldBattleDB.GetUnionData(pointData.unionId)
         local defOccupCityList = defUnionData.occupCityList
 
-        local cityNum, pointNum = 0, -1
-
         -- 防守方之前占领了城池
         if defOccupCityList[targetCityId].isOccupy then
 
@@ -1233,23 +1294,28 @@ function N2C_Point_Challenge_Win(msg)
             defOccupCityList[targetCityId].isOccupy = false
 
             -- 更新防守方对该城池的最后占领时间
-            local defOccupyTimeArr = defOccupCityList[targetCityId].occupyTimeArr
-            defOccupyTimeArr[#defOccupyTimeArr][2] = os.time()
+            local defOccupyPointList = defOccupCityList[targetCityId].occupyPointList
+            local defPointInfo = defOccupyPointList[targetPointIdx]
+            local defOccupyTimeArr = defPointInfo.occupyTimeArr
+            defOccupyTimeArr[#defOccupyTimeArr][2] = now
 
             -- 删除防守方的该据点的占领者
-            local defOccupyPointList = defOccupCityList[targetCityId].occupyPointList
-            defOccupyPointList[targetCityId] = nil
+            defPointInfo.playerUuid = nil
 
             -- 删除防守方玩家的防守阵容数据
-            local defPlayData = defUnionData.playerList[pointData.playerUuid]
-            defPlayData.heroList[targetCityId][targetPointIdx] = nil
+            local defPlayData = AnotherWorldBattleDB.GetPlayerData(pointData.playerUuid)
+            if defPlayData then
+                defPlayData.heroList[targetCityId][targetPointIdx] = nil
+                AnotherWorldBattleDB.UpdatePlayerData(pointData.playerUuid, defPlayData)
+            end
 
             cityNum = -1
         end
 
-        -- 更新排行榜数据
-        updateUnionRanktData(unionRankList, pointData.unionId, cityNum, pointNum)
-        updatePlayerRanktData(playerRankList, pointData.playerUuid, pointNum, -pointWeight)
+        -- 更新防守方公会的排行榜数据
+        AnotherWorldBattleDB.UpdateUnionRankList(groupId, pointData.unionId, cityNum, pointNum)
+        -- 更新防守方玩家的排行榜数据
+        AnotherWorldBattleDB.UpdatePlayerRankList(groupId, playerUuid, -pointNum, -pointWeight)
 
         -- 通知玩家
         pointLose(defUnionData.serverId, pointData.playerUuid, targetCityId, targetPointIdx)
@@ -1262,75 +1328,205 @@ function N2C_Point_Challenge_Win(msg)
     pointData.unionId = myUnionId
     pointData.playerUuid = playerUuid
 
-    -- 更新进攻方公会数据——据点占有者
+    -- 更新进攻方公会数据—— 据点占有者, 最新的据点占有时间
     myUnionData.occupCityList = myUnionData.occupCityList or {}
     local occupCityList = myUnionData.occupCityList
     occupCityList[targetCityId] = occupCityList[targetCityId] or {}
     occupCityList[targetCityId].occupyPointList = occupCityList[targetCityId].occupyPointList or {}
-    occupCityList[targetCityId].occupyPointList[targetPointIdx] = playerUuid
+    occupCityList[targetCityId].occupyPointList[targetPointIdx] = occupCityList[targetCityId].occupyPointList[targetPointIdx] or {}
+    local atkPointInfo = occupCityList[targetCityId].occupyPointList[targetPointIdx]
+    atkPointInfo.playerUuid = playerUuid
+    atkPointInfo.occupyTimeArr = atkPointInfo.occupyTimeArr or {}
+    atkPointInfo.occupyTimeArr[#atkPointInfo.occupyTimeArr+1] = { now }
 
     --更新进攻者的展示数据
-    myUnionData.playerList = myUnionData.playerList or {}
-    myUnionData.playerList[playerUuid] = myUnionData.playerList[playerUuid] or {}
-    local playerData = myUnionData.playerList[playerUuid]
-    playerData.name = playerShowInfo.name
-    playerData.lv = playerShowInfo.lv
-    playerData.head = playerShowInfo.head
-    playerData.headFrame = playerShowInfo.headFrame
-    playerData.power = playerShowInfo.power
-
-    playerData.heroList = playerData.heroList or {}
-    playerData.heroList[targetCityId] = playerData.heroList[targetCityId] or {}
-    playerData.heroList[targetCityId][targetPointIdx] = playerShowInfo.heroArr
-
-
-    -- 更新公会排行榜数据: 进攻方公会占领据点数量+1
-    updateUnionRanktData(unionRankList, myUnionId, 0, 1)
-
-    local bl = getPlayerRank(playerRankList, playerUuid)
-    if not bl then -- 如果玩家是第一次挑战据点, 则把玩家加入到玩家排行榜中
-        playerRankList[#playerRankList+1] = {
-            unionId = myUnionId,
-            playerUuid = playerUuid,
-            pointNum = 1,
-            pointAllWeight = pointWeight,
-            power = playerData.power
-        }
-    else
-        updatePlayerRanktData(playerRankList, playerUuid, 1, pointWeight)
-    end
+    local atkPlayerData = AnotherWorldBattleDB.GetPlayerData(playerUuid)
+    atkPlayerData = atkPlayerData or {}
+    atkPlayerData.name = playerShowInfo.name
+    atkPlayerData.lv = playerShowInfo.lv
+    atkPlayerData.head = playerShowInfo.head
+    atkPlayerData.headFrame = playerShowInfo.headFrame
+    atkPlayerData.power = playerShowInfo.power
+    atkPlayerData.unionId = myUnionId
+    -- 更新挑战次数
+    atkPlayerData.challengeTimes = (atkPlayerData.challengeTimes or AnotherWorldBattleDefine.AB_PLAYER_CHALLENGE_TIMES) - 1
+    if not atkPlayerData.lastTime or atkPlayerData.lastTime == 0 then
+        atkPlayerData.lastTime = os.time()
+    end
+    -- 增加防守阵容数据
+    atkPlayerData.heroList = atkPlayerData.heroList or {}
+    atkPlayerData.heroList[targetCityId] = atkPlayerData.heroList[targetCityId] or {}
+    atkPlayerData.heroList[targetCityId][targetPointIdx] = playerShowInfo.heroArr
+
+    cityNum = 0
 
     -- 进攻方完全占领城池了
     if isCompleteOccupy(cityData, myUnionId) then
-
         -- 更新城池的占领公会
         cityData.occupyUnion = myUnionId
 
         -- 更新进攻方公会对该城池的占领状态
         occupCityList[targetCityId].isOccupy = true
 
-        -- 增加进攻方公会对该城池的占领开始时间戳
-        local now = os.time()
-        occupCityList[targetCityId].occupyTimeArr = occupCityList[targetCityId].occupyTimeArr or {}
-        local occupyTimeArr = occupCityList[targetCityId].occupyTimeArr
-        occupyTimeArr[#occupyTimeArr+1] = { now }
-
         -- 如果占领的是发起集结的城池, 那么取消集结
         if myUnionData.gatherInfo and myUnionData.gatherInfo.gatherCity == targetCityId then
             myUnionData.gatherInfo.gatherCity = 0
         end
 
-        -- 更新公会排行榜数据
-        updateUnionRanktData(unionRankList, myUnionId, 1, 0)
+        cityNum = 1
     end
 
     -- 更新进攻方公会数据
     AnotherWorldBattleDB.UpdateUnionData(myUnionId, myUnionData)
+    -- 更新进攻方玩家数据
+    AnotherWorldBattleDB.UpdatePlayerData(playerUuid, atkPlayerData)
+
+    -- 更新进攻方公会的排行榜数据
+    AnotherWorldBattleDB.UpdateUnionRankList(groupId, myUnionId, cityNum, pointNum)
+    -- 更新进攻方玩家的排行榜数据
+    AnotherWorldBattleDB.UpdatePlayerRankList(groupId, playerUuid, pointNum, pointWeight)
+
 
     -- 更新城池数据
     AnotherWorldBattleDB.UpdateCityList(groupId, cityList)
+end
+-- 玩家挑战据点失败
+local function challenge_Fail(msg)
+    local playerUuid = msg.playerUuid
+    local myUnionId = msg.myUnionId
 
-    -- 更新公会/个人排行榜
-    AnotherWorldBattleDB.UpdateUnionRankList(groupId, unionRankList)
-    AnotherWorldBattleDB.UpdatePlayerRankList(groupId, playerRankList)
+    local groupId = getMyUnionGourpId(myUnionId)
+    if not groupId then
+        return
+    end
+
+    local playerData = AnotherWorldBattleDB.GetPlayerData(playerUuid)
+    playerData = playerData or {}
+    playerData.name = playerData.name
+    playerData.lv = playerData.lv
+    playerData.power = playerData.power
+    playerData.unionId = myUnionId
+    playerData.challengeTimes = (playerData.challengeTimes or AnotherWorldBattleDefine.AB_PLAYER_CHALLENGE_TIMES) - 1
+    if not playerData.lastTime or playerData.lastTime == 0 then
+        playerData.lastTime = os.time()
+    end
+    AnotherWorldBattleDB.UpdatePlayerData(playerUuid, playerData)
+
+    -- 加入个人排行榜
+    AnotherWorldBattleDB.UpdatePlayerRankList(groupId, playerUuid, 0, 0)
+end
+
+--挑战据点结束的处理函数
+function N2C_Point_Challenge_End_Handle(msg)
+    if msg.challengeRes == CombatDefine.RESULT_WIN then
+        challenge_Win(msg)
+    else
+        challenge_Fail(msg)
+    end
+end
+
+
+-- 玩家数据更新
+function N2C_Update_Player_Data(msg)
+    if not isRunning() then
+        return
+    end
+
+    local playerUuid = msg.playerUuid
+    local playerData = AnotherWorldBattleDB.GetPlayerData(playerUuid)
+    if not playerData then
+        return
+    end
+
+    local groupId = getMyUnionGourpId(playerData.unionId)
+    if not groupId then
+        return
+    end
+
+    local isUpdatePower = false
+    for k,v in pairs(msg.updateData) do
+        if k == "power" then
+            isUpdatePower = true
+        end
+
+        playerData[k] = v
+    end
+
+    AnotherWorldBattleDB.UpdatePlayerData(playerUuid, playerData)
+
+    -- 如果是战力更新, 更新玩家排行榜
+    if isUpdatePower then
+        AnotherWorldBattleDB.UpdatePlayerRankList(groupId, playerUuid, 0, 0, playerData.power)
+    end
+
+end
+
+-- 公会数据更新
+function N2C_Update_Union_Data(msg)
+    if not isRunning() then
+        return
+    end
+
+    local myUnionId = msg.myUnionId
+    local unionData = AnotherWorldBattleDB.GetUnionData(myUnionId)
+    if not unionData then
+        return
+    end
+
+    local groupId = getMyUnionGourpId(myUnionId)
+    if not groupId then
+        return
+    end
+
+    local isUpdatePower = false
+    for k,v in pairs(msg.updateData) do
+        if k == "power" then
+            isUpdatePower = true
+        end
+        unionData[k] = v
+    end
+
+    AnotherWorldBattleDB.UpdateUnionData(myUnionId, unionData)
+
+    -- 如果是战力更新, 更新公会排行榜
+    if isUpdatePower then
+        AnotherWorldBattleDB.UpdateUnionRankList(groupId, myUnionId, 0, 0, unionData.power)
+    end
+end
+
+-- 更新玩家据点防守阵容数据
+function N2C_Update_Point_Lineup(msg)
+    if not isRunning() then
+        return
+    end
+
+    local playerUuid = msg.playerUuid
+    local playerData = AnotherWorldBattleDB.GetPlayerData(playerUuid)
+    if not playerData or not playerData.heroList then
+        return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_5)
+    end
+
+    local groupId = getMyUnionGourpId(playerData.unionId)
+    if not groupId then
+        return
+    end
+
+    local targetCityId, targetPointIdx = msg.targetCityId, msg.targetPointIdx
+    local heroList = playerData.heroList
+    if not heroList[targetCityId] or not heroList[targetCityId][targetPointIdx] then
+        return errTips(msg.sourceServerId, msg.playerUuid, AnotherWorldBattleDefine.ERR_CODE_5)
+    end
+
+    heroList[targetCityId][targetPointIdx] = msg.heroArr
+    AnotherWorldBattleDB.UpdatePlayerData(playerUuid, playerData)
+
+    local msgData = InnerMsg.wl.WL_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP
+    msgData.playerUuid = playerUuid
+    msgData.targetCityId = targetCityId
+    msgData.targetPointIdx = targetPointIdx
+    msgData.formation = msg.formation
+    msgData.heroList = msg.heroList
+    msgData.helpList = msg.helpList
+    local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
+    InnerMsg.sendMsg(fd, msgData)
 end

+ 801 - 159
script/module/anotherWorldBattle/AnotherWorldBattleDB.lua

@@ -31,45 +31,48 @@ AnotherWorldBattleData = {
     --         occupCityList = { -- 城池列表(包括曾占领过, 当前成功占领, 当前只占领过一个或多个据点)
     --             [cityId1] = {
     --                 isOccupy = false, --当前是否占领
-    --                 occupyTimeArr = { {startTime1, endTime1}, {startTime2, endTime2} },
     --                 occupyPointList = { --占领本城池中的据点列表
-    --                     [pointId1] = playerUuid,
-    --                     [pointId2] = playerUuid,
+    --                     [pointId1] = { playerUuid = "",  occupyTimeArr = { {startTime1, endTime1}, {startTime2, endTime2}}, },
     --                 },
     --             },
     --         },
-
-    --         playerList = {
-    --             [playerUuid] = {
-    --                 name = "",
-    --                 lv = 200,
-    --                 head = 1234,
-    --                 headFrame = 1234,
-    --                 power = 999,
-    --                 heroList = {
-    --                     [cityId] = {
-    --                         [pointIdx] = {
-    --                             {
-    --                                 heroUuid = "sdgjdjdj",
-    --                                 heroStar = 111,
-    --                                 heroLevel = 111,
-    --                                 heroCamp =  1,
-    --                                 heroBody = 111,
-    --                                 heroIcon = 111,
-    --                                 heroPower = 11111,
-    --                             },
-    --                         },
-    --                     },
-
-    --                 }
-    --             },
-    --             },
     --         gatherInfo = { --集结信息
     --             gatherTime = 0,
     --             gatherCity = 123,
     --         },
     --     },
     -- },
+
+    -- playerList = {
+    --     [playerUuid] = {
+    --         name = "",
+    --         lv = 200,
+    --         head = 1234,
+    --         headFrame = 1234,
+    --         power = 999,
+    --         challengeTimes = 10,
+    --         lastTime = nil, -- 上一次更新的时间戳
+    --         unionId = "",
+    --         heroList = {
+    --             [cityId] = {
+    --                 [pointIdx] = {
+    --                     {
+    --                         heroUuid = "sdgjdjdj",
+    --                         heroStar = 111,
+    --                         heroLevel = 111,
+    --                         heroCamp =  1,
+    --                         heroBody = 111,
+    --                         heroIcon = 111,
+    --                         heroPower = 11111,
+    --                         heroId = 111,
+    --                         heroQuality = 1,
+    --                     },
+    --                 },
+    --             },
+
+    --         }
+    --     },
+    -- }
 }
 
 -- 所有分组的城池信息, 启动服务器后生成, 用于快速获取城池信息
@@ -90,21 +93,14 @@ Group_2_CityList = {
 }
 
 -- 所有分组的公会排行榜, 启动服务器后生成
-Group_2_UnionRankList = {
-    -- [group1] = {
-    --     {unionId =  "123", occupyCityNum = 1, occupyPointNum = 0, power = 999},
-    --     {unionId =  "456", occupyCityNum = 0, occupyPointNum = 0, power = 999},
-    -- },
-
-}
+Group_2_UnionRankList = {}
 
 -- 所有分组的玩家排行榜, 启动服务器后生成
-Group_2_PlayerRankList = {
-    -- [group1] = {
-    --     {unionId = '1244', playerUuid =  "123", pointNum = 2, pointAllWeight = 999, power = 999},
-    --     {unionId = '1244', playerUuid =  "777", pointNum = 1, pointAllWeight = 888, power = 999},
-    -- },
+Group_2_PlayerRankList = {}
 
+-- 区服Id - 公会列表 映射表
+Server_2_UnionArr = {
+    -- [serverId] = {unionId1, unionId2},
 }
 
 -- 公会 - 所属分组 映射表
@@ -165,6 +161,7 @@ local function genCityList(net, unionIdArr)
                 return unionId
             end
         end
+        return nil
     end
 
 
@@ -173,84 +170,635 @@ local function genCityList(net, unionIdArr)
             local unionInfo = AnotherWorldBattleData.unionList[unionId]
             if unionInfo and unionInfo.occupCityList and unionInfo.occupCityList[targetCityId] then
                 local pointList = unionInfo.occupCityList[targetCityId].occupyPointList
-                if pointList and pointList[targetPointIdx] then
-                    return unionId, pointList[targetPointIdx]
+                if pointList and pointList[targetPointIdx] and pointList[targetPointIdx].playerUuid then
+                    return unionId, pointList[targetPointIdx].playerUuid
                 end
             end
         end
+        return nil, nil
     end
 
 
     for cityId, cityCfg in ipairs(AnotherWorldBattleConfig.city) do
-        net[cityId] = { pointArr = {} }
+        local cityEntry = { pointArr = {} }
+        net[cityId] = cityEntry
 
         local unionId = getUnionByCityId(cityId)
         if unionId then
-            net[cityId].occupyUnion = unionId
+            cityEntry.occupyUnion = unionId
         end
 
-        local pointArr = net[cityId].pointArr
+        local pointArr = cityEntry.pointArr
         for i=1, AnotherWorldBattleDefine.AB_POINT_MAX_NUM do
-            pointArr[i] = {}
             local unionId1, playerUuid = getPointOccupyPlayer(cityId, i)
             if unionId1 and playerUuid then
-                pointArr[i].unionId = unionId1
-                pointArr[i].playerUuid = playerUuid
+                pointArr[i] = {
+                    unionId = unionId1,
+                    playerUuid = playerUuid
+                }
+            else
+                pointArr[i] = {}
             end
         end
     end
 end
 
--- 公会排行榜排序算法
-local function unionRankSortFunc(unionRankList)
-    table.sort(unionRankList, function (a, b)
-        if a.occupyCityNum > b.occupyCityNum then
+-- 工会排行榜
+local function createGuildRank()
+    local state = {
+        guilds = {},           -- {[guildId] = {id, name, power, occupyCityNum, occupyPointNum, ...}}
+        sortedGuilds = {},     -- 排序后的工会数组
+        isDirty = true,
+        maxSize = 8
+    }
+    
+    -- 创建接口表
+    local interface = {}
+    
+    -- 计算组合键
+    local function getGuildSortKey(occupyCityNum, occupyPointNum, power)
+        return occupyCityNum * 100000000000000000000 +  -- 10^20
+               occupyPointNum * 1000000000000 +         -- 10^12
+               power
+    end
+    
+    -- 使用组合键进行比较
+    local function compareGuilds(a, b)
+        local keyA = getGuildSortKey(a.occupyCityNum, a.occupyPointNum, a.power)
+        local keyB = getGuildSortKey(b.occupyCityNum, b.occupyPointNum, b.power)
+        
+        if keyA ~= keyB then
+            return keyA > keyB  -- 组合键大的排名高
+        end
+        
+        -- 组合键相同,按ID排序
+        return a.id < b.id
+    end
+    
+    local function quickSort(arr, left, right)
+        if left >= right then return end
+        
+        local pivot = arr[math.floor((left + right) / 2)]
+        local i, j = left, right
+        
+        while i <= j do
+            while compareGuilds(arr[i], pivot) do i = i + 1 end
+            while compareGuilds(pivot, arr[j]) do j = j - 1 end
+            
+            if i <= j then
+                arr[i], arr[j] = arr[j], arr[i]
+                i = i + 1
+                j = j - 1
+            end
+        end
+        
+        quickSort(arr, left, j)
+        quickSort(arr, i, right)
+    end
+    
+    local function refreshRank()
+        -- 收集所有工会到数组
+        local guildArray = {}
+        for _, guild in pairs(state.guilds) do
+            table.insert(guildArray, guild)
+        end
+        
+        -- 使用快速排序
+        if #guildArray > 0 then
+            quickSort(guildArray, 1, #guildArray)
+        end
+        
+        -- 只保留前8名
+        state.sortedGuilds = {}
+        for i = 1, math.min(state.maxSize, #guildArray) do
+            state.sortedGuilds[i] = {
+                guildId = guildArray[i].id,
+                rank = i,
+                power = guildArray[i].power,
+                name = guildArray[i].name,
+                occupyCityNum = guildArray[i].occupyCityNum,
+                occupyPointNum = guildArray[i].occupyPointNum
+            }
+        end
+        
+        state.isDirty = false
+    end
+
+    -- 定义接口函数
+    function interface.updateGuild(guildId, name, power, occupyCityNum, occupyPointNum)
+        if not state.guilds[guildId] then
+            state.guilds[guildId] = {
+                id = guildId, 
+                name = name, 
+                power = power,
+                occupyCityNum = occupyCityNum or 0,
+                occupyPointNum = occupyPointNum or 0
+            }
+        else
+            state.guilds[guildId].power = power
+            state.guilds[guildId].occupyCityNum = occupyCityNum or state.guilds[guildId].occupyCityNum
+            state.guilds[guildId].occupyPointNum = occupyPointNum or state.guilds[guildId].occupyPointNum
+            if name then
+                state.guilds[guildId].name = name
+            end
+        end
+        state.isDirty = true
+    end
+
+    function interface.updateOccupyCityNum(guildId, occupyCityNum)
+        if state.guilds[guildId] then
+            state.guilds[guildId].occupyCityNum = occupyCityNum
+            state.isDirty = true
+        end
+    end
+
+    function interface.updateOccupyPointNum(guildId, occupyPointNum)
+        if state.guilds[guildId] then
+            state.guilds[guildId].occupyPointNum = occupyPointNum
+            state.isDirty = true
+        end
+    end
+
+    function interface.updatePower(guildId, power)
+        if state.guilds[guildId] then
+            state.guilds[guildId].power = power
+            state.isDirty = true
+        end
+    end
+
+    function interface.disbandGuild(guildId)
+        if state.guilds[guildId] then
+            state.guilds[guildId] = nil
+            state.isDirty = true
             return true
-        elseif a.occupyCityNum == b.occupyCityNum then
-            if a.occupyPointNum > b.occupyCityNum then
-                return true
-            elseif a.occupyPointNum == b.occupyCityNum then
-                return a.power > b.power
+        end
+        return false
+    end
+
+    function interface.getRankList()
+        if state.isDirty then
+            refreshRank()
+        end
+        return state.sortedGuilds
+    end
+
+    function interface.getGuildRank(guildId)
+        if state.isDirty then
+            refreshRank()
+        end
+        
+        for i, guild in ipairs(state.sortedGuilds) do
+            if guild.guildId == guildId then
+                return i
+            end
+        end
+        return nil
+    end
+
+    function interface.getGuildDetail(guildId)
+        if state.isDirty then
+            refreshRank()
+        end
+        
+        for i, guild in ipairs(state.sortedGuilds) do
+            if guild.guildId == guildId then
+                return {
+                    rank = i,
+                    guildId = guild.guildId,
+                    name = guild.name,
+                    power = guild.power,
+                    occupyCityNum = guild.occupyCityNum,
+                    occupyPointNum = guild.occupyPointNum
+                }
+            end
+        end
+        return nil
+    end
+
+    function interface.hasGuild(guildId)
+        return state.guilds[guildId] ~= nil
+    end
+
+    function interface.getTotalGuilds()
+        return tableCount(state.guilds)
+    end
+
+    function interface._getState()
+        return {
+            totalGuilds = tableCount(state.guilds),
+            isDirty = state.isDirty
+        }
+    end
+
+    return interface
+end
+
+-- 玩家排行榜
+local function createPlayerRank()
+    local state = {
+        players = {},           -- {[playerId] = {id, name, power, pointNum, pointAllWeight, ...}}
+        rankArray = {},         -- 排行榜数组,按组合键排序
+        playerIndex = {},       -- {[playerId] = 在rankArray中的索引}
+        candidateMap = {},      -- 候选玩家 {[playerId] = true}
+        maxSize = AnotherWorldBattleDefine.AB_RANK_MAX_NUM,
+        size = 0
+    }
+    
+    -- 创建接口表
+    local interface = {}
+    
+    -- 计算组合键
+    local function getPlayerSortKey(pointNum, pointAllWeight, power)
+        return pointNum * 10000000000000000 +    -- 10^16
+               pointAllWeight * 10000000000 +    -- 10^10
+               power
+    end
+
+    -- 使用组合键进行比较
+    local function comparePlayers(a, b)
+        local keyA = getPlayerSortKey(a.pointNum, a.pointAllWeight, a.power)
+        local keyB = getPlayerSortKey(b.pointNum, b.pointAllWeight, b.power)
+
+        if keyA ~= keyB then
+            return keyA > keyB  -- 组合键大的排名高
+        end
+        
+        -- 组合键相同,按ID排序
+        return a.id < b.id
+    end
+
+    -- 二分查找插入位置(使用组合键)
+    local function findInsertPosition(playerData)
+        local left, right = 1, state.size
+        local key = getPlayerSortKey(playerData.pointNum, playerData.pointAllWeight, playerData.power)
+        
+        while left <= right do
+            local mid = math.floor((left + right) / 2)
+            local midPlayer = state.rankArray[mid]
+            local midKey = getPlayerSortKey(midPlayer.pointNum, midPlayer.pointAllWeight, midPlayer.power)
+            
+            if key > midKey then
+                right = mid - 1
             else
-                return false
+                left = mid + 1
+            end
+        end
+        
+        return left
+    end
+    
+    -- 插入玩家到排行榜
+    local function insertToRank(playerData)
+        if state.size == 0 then
+            state.rankArray[1] = playerData
+            state.playerIndex[playerData.id] = 1
+            state.size = 1
+            return
+        end
+        
+        local pos = findInsertPosition(playerData)
+        
+        -- 向后移动元素
+        for i = state.size, pos, -1 do
+            state.rankArray[i + 1] = state.rankArray[i]
+            state.playerIndex[state.rankArray[i].id] = i + 1
+        end
+        
+        -- 插入新元素
+        state.rankArray[pos] = playerData
+        state.playerIndex[playerData.id] = pos
+        state.size = state.size + 1
+        
+        -- 如果超过最大大小,移除最后一个
+        if state.size > state.maxSize then
+            local removedPlayer = state.rankArray[state.maxSize + 1]
+            if removedPlayer then
+                state.playerIndex[removedPlayer.id] = nil
+                state.candidateMap[removedPlayer.id] = true
+            end
+            state.size = state.maxSize
+        end
+    end
+    
+    -- 从排行榜移除玩家
+    local function removeFromRank(playerId)
+        local index = state.playerIndex[playerId]
+        if not index then return false end
+        
+        -- 向前移动元素
+        for i = index, state.size - 1 do
+            state.rankArray[i] = state.rankArray[i + 1]
+            state.playerIndex[state.rankArray[i].id] = i
+        end
+        
+        state.rankArray[state.size] = nil
+        state.playerIndex[playerId] = nil
+        state.size = state.size - 1
+        return true
+    end
+    
+    -- 调整玩家在排行榜中的位置
+    local function adjustPlayerPosition(playerId)
+        local currentIndex = state.playerIndex[playerId]
+        if not currentIndex then return end
+        
+        local playerData = state.players[playerId]
+        if not playerData then return end
+        
+        -- 先移除,再重新插入(确保位置正确)
+        removeFromRank(playerId)
+        insertToRank(playerData)
+    end
+
+    -- 检查候选玩家
+    local function checkCandidates()
+        if state.size < state.maxSize then
+            -- 排行榜未满,找到最佳候选加入
+            local bestCandidate = nil
+            local bestKey = -1
+            
+            for playerId, _ in pairs(state.candidateMap) do
+                local player = state.players[playerId]
+                if player then
+                    local key = getPlayerSortKey(player.pointNum, player.pointAllWeight, player.power)
+                    if key > bestKey then
+                        bestCandidate = playerId
+                        bestKey = key
+                    elseif key == bestKey and player.id < bestCandidate then
+                        bestCandidate = playerId
+                        bestKey = key
+                    end
+                end
+            end
+            
+            if bestCandidate then
+                state.candidateMap[bestCandidate] = nil
+                insertToRank(state.players[bestCandidate])
             end
         else
-            return false
+            -- 检查候选是否应该替换最后一名
+            local lastPlayer = state.rankArray[state.size]
+            local lastKey = getPlayerSortKey(lastPlayer.pointNum, lastPlayer.pointAllWeight, lastPlayer.power)
+            local bestCandidate = nil
+            local bestKey = lastKey
+            
+            for playerId, _ in pairs(state.candidateMap) do
+                local player = state.players[playerId]
+                if player then
+                    local key = getPlayerSortKey(player.pointNum, player.pointAllWeight, player.power)
+                    if key > bestKey then
+                        bestCandidate = playerId
+                        bestKey = key
+                    elseif key == bestKey and player.id < bestCandidate then
+                        bestCandidate = playerId
+                        bestKey = key
+                    end
+                end
+            end
+            
+            if bestCandidate then
+                state.candidateMap[bestCandidate] = nil
+                state.candidateMap[lastPlayer.id] = true
+                removeFromRank(lastPlayer.id)
+                insertToRank(state.players[bestCandidate])
+            end
         end
-    end)
-end
+    end
 
--- 个人排行榜排序算法
-local function playerRankSortFunc(playerRankList)
-    table.sort(playerRankList, function (a, b)
-        if a.pointNum > b.pointNum then
-            return true
-        elseif a.pointNum == b.pointNum then
-            if a.pointAllWeight > b.pointAllWeight then
-                return true
-            elseif a.pointAllWeight == b.pointAllWeight then
-                return a.power > b.power
+    -- 完全移除玩家(包括从候选集)
+    local function removePlayerCompletely(playerId)
+        -- 从排行榜移除
+        removeFromRank(playerId)
+        
+        -- 从候选集移除
+        state.candidateMap[playerId] = nil
+        
+        -- 从玩家数据移除
+        state.players[playerId] = nil
+        
+        return true
+    end
+
+    -- 定义接口函数
+    function interface.updatePlayer(playerId, name, power, pointNum, pointAllWeight)
+        local playerData = state.players[playerId]
+        
+        if not playerData then
+            -- 新玩家
+            playerData = {
+                id = playerId, 
+                name = name, 
+                power = power,
+                pointNum = pointNum or 0,
+                pointAllWeight = pointAllWeight or 0
+            }
+            state.players[playerId] = playerData
+            
+            if state.size < state.maxSize then
+                insertToRank(playerData)
             else
-                return false
+                -- 检查是否能直接进入排行榜
+                local lastPlayer = state.rankArray[state.size]
+                local lastKey = getPlayerSortKey(lastPlayer.pointNum, lastPlayer.pointAllWeight, lastPlayer.power)
+                local newKey = getPlayerSortKey(pointNum or 0, pointAllWeight or 0, power)
+                
+                if newKey > lastKey or (newKey == lastKey and playerId < lastPlayer.id) then
+                    state.candidateMap[lastPlayer.id] = true
+                    removeFromRank(lastPlayer.id)
+                    insertToRank(playerData)
+                else
+                    state.candidateMap[playerId] = true
+                end
             end
         else
-            return false
+            -- 已有玩家
+            playerData.power = power
+            playerData.pointNum = pointNum or playerData.pointNum
+            playerData.pointAllWeight = pointAllWeight or playerData.pointAllWeight
+            if name then
+                playerData.name = name
+            end
+            
+            local currentIndex = state.playerIndex[playerId]
+            
+            if currentIndex then
+                -- 玩家在排行榜中,需要调整位置
+                adjustPlayerPosition(playerId)
+            else
+                -- 玩家不在排行榜中,检查候选集
+                if state.candidateMap[playerId] then
+                    if state.size < state.maxSize then
+                        state.candidateMap[playerId] = nil
+                        insertToRank(playerData)
+                    else
+                        local lastPlayer = state.rankArray[state.size]
+                        local lastKey = getPlayerSortKey(lastPlayer.pointNum, lastPlayer.pointAllWeight, lastPlayer.power)
+                        local newKey = getPlayerSortKey(playerData.pointNum, playerData.pointAllWeight, playerData.power)
+                        
+                        if newKey > lastKey or (newKey == lastKey and playerId < lastPlayer.id) then
+                            state.candidateMap[lastPlayer.id] = true
+                            state.candidateMap[playerId] = nil
+                            removeFromRank(lastPlayer.id)
+                            insertToRank(playerData)
+                        end
+                    end
+                end
+            end
+        end
+    end
+
+    function interface.updatePointNum(playerId, pointNum)
+        if state.players[playerId] then
+            state.players[playerId].pointNum = pointNum
+            
+            local currentIndex = state.playerIndex[playerId]
+            if currentIndex then
+                adjustPlayerPosition(playerId)
+            else
+                -- 不在排行榜中,检查候选集
+                if state.candidateMap[playerId] then
+                    checkCandidates()
+                end
+            end
         end
-    end)
+    end
+
+    function interface.updatePointAllWeight(playerId, pointAllWeight)
+        if state.players[playerId] then
+            state.players[playerId].pointAllWeight = pointAllWeight
+            
+            local currentIndex = state.playerIndex[playerId]
+            if currentIndex then
+                adjustPlayerPosition(playerId)
+            else
+                -- 不在排行榜中,检查候选集
+                if state.candidateMap[playerId] then
+                    checkCandidates()
+                end
+            end
+        end
+    end
+
+    function interface.updatePower(playerId, power)
+        if state.players[playerId] then
+            state.players[playerId].power = power
+            
+            local currentIndex = state.playerIndex[playerId]
+            if currentIndex then
+                adjustPlayerPosition(playerId)
+            else
+                -- 不在排行榜中,检查候选集
+                if state.candidateMap[playerId] then
+                    checkCandidates()
+                end
+            end
+        end
+    end
+
+    function interface.removePlayer(playerId)
+        return removePlayerCompletely(playerId)
+    end
+
+    function interface.getRankList()
+        checkCandidates()  -- 每次获取时检查候选
+        
+        local result = {}
+        for i = 1, state.size do
+            local player = state.rankArray[i]
+            table.insert(result, {
+                playerId = player.id,
+                name = player.name,
+                rank = i,
+                power = player.power,
+                pointNum = player.pointNum,
+                pointAllWeight = player.pointAllWeight
+            })
+        end
+        return result
+    end
+
+    function interface.getPlayerRank(playerId)
+        local index = state.playerIndex[playerId]
+        return index
+    end
+
+    function interface.getPlayerDetail(playerId)
+        local index = state.playerIndex[playerId]
+        if index then
+            local player = state.rankArray[index]
+            return {
+                rank = index,
+                playerId = player.id,
+                name = player.name,
+                power = player.power,
+                pointNum = player.pointNum,
+                pointAllWeight = player.pointAllWeight
+            }
+        end
+        return nil
+    end
+
+    function interface.hasPlayer(playerId)
+        return state.players[playerId] ~= nil
+    end
+
+    function interface.getTotalPlayers()
+        return tableCount(state.players)
+    end
+
+    function interface.batchUpdate(updates)
+        for _, update in ipairs(updates) do
+            if update.playerId then
+                interface.updatePlayer(
+                    update.playerId,
+                    update.name,
+                    update.power,
+                    update.pointNum, 
+                    update.pointAllWeight
+                )
+            end
+        end
+    end
+
+    function interface._getState()
+        return {
+            totalPlayers = tableCount(state.players),
+            rankSize = state.size,
+            candidateCount = tableCount(state.candidateMap)
+        }
+    end
+
+    return interface
+end
+
+-- 辅助函数:计算表的元素数量
+function tableCount(t)
+    local count = 0
+    for _ in pairs(t) do count = count + 1 end
+    return count
+end
+
+
+-- 辅助函数:计算表的元素数量
+function tableCount(t)
+    local count = 0
+    for _ in pairs(t) do count = count + 1 end
+    return count
 end
 
+
 -- 生成公会排行榜
-local function genGroupUnionRankList(net, unionIdArr)
+local function genGroupUnionRankList(unionRank, unionIdArr)
     local function getUnionRankVal(union)
         local occupyCityNum, occupyPointNum, power = 0, 0, 0
         power = union.power or 0
 
-        for _,v in pairs(union.occupCityList or {}) do
+        for _, v in pairs(union.occupCityList or {}) do
             if v.isOccupy then
                 occupyCityNum = occupyCityNum + 1
             end
 
-            for _,_ in pairs(v.occupyPointList or {}) do
+            for _, _ in pairs(v.occupyPointList or {}) do
                 occupyPointNum = occupyPointNum + 1
             end
         end
@@ -259,57 +807,44 @@ local function genGroupUnionRankList(net, unionIdArr)
     end
 
     for _, unionId in ipairs(unionIdArr) do
-        local unionInfo = AnotherWorldBattleData.unionList[unionId]
-        if unionInfo then
-            local occupyCityNum, occupyPointNum, power = getUnionRankVal(unionInfo)
-            net[#net+1] = {
-                unionId = unionId,
-                occupyCityNum = occupyCityNum,
-                occupyPointNum = occupyPointNum,
-                power = power
-            }
+        local unionData = AnotherWorldBattleData.unionList[unionId]
+        if unionData then
+            local occupyCityNum, occupyPointNum, power = getUnionRankVal(unionData)
+            unionRank.updateGuild(unionId, unionData.name, power, occupyCityNum, occupyPointNum )
         end
     end
-
-    unionRankSortFunc(net)
-
-    -- while #net > AnotherWorldBattleDefine.AB_RANK_MAX_NUM do
-    --     table.remove(net)
-    -- end
 end
 
 -- 生成个人排行榜
-local function genGroupPlayerRankList(net, unionIdArr)
-    local playerList = {}
+local function genGroupPlayerRankList(playerRank, unionIdArr, playerListData)
+    local playerArr = {}
 
-    for _, unionId in ipairs(unionIdArr) do
-        local unionInfo = AnotherWorldBattleData.unionList[unionId]
-        if unionInfo and unionInfo.occupCityList then
-            for cityId, v in pairs(unionInfo.occupCityList) do
-                for pointId, playerUuid in pairs(v.occupyPointList or {}) do
-                    playerList[playerUuid] = playerUuid[playerUuid] or { playerUuid = playerUuid, pointNum = 0, pointAllWeight = 0, power = 0, unionId = unionId}
-                    playerList[playerUuid].pointNum = playerList[playerUuid].pointNum + 1
-
-                    local cityCfg = AnotherWorldBattleConfig.city[cityId]
-                    playerList[playerUuid].pointAllWeight = playerList[playerUuid].pointAllWeight + cityCfg.pointWeight
+    local function insertPlayerArr(unionId)
+        if not playerListData then
+            return
+        end
 
-                    if unionInfo.playerList and unionInfo.playerList[playerUuid] then
-                        playerList[playerUuid].power = unionInfo.playerList[playerUuid].power or 0
+        for playerUuid, playerInfo in pairs(playerListData) do
+            if playerInfo.unionId == unionId then
+                local pointNum, pointAllWeight = 0, 0
+                for cityId, pointList in pairs(playerInfo.heroList or {}) do
+                    for _, _ in pairs(pointList) do
+                        pointNum = pointNum + 1
+                        local cityCfg = AnotherWorldBattleConfig.city[cityId]
+                        pointAllWeight = pointAllWeight + (cityCfg and cityCfg.pointWeight or 0)
                     end
                 end
+
+                playerArr[#playerArr+1] = {playerId = playerUuid, name = playerInfo.name, power = playerInfo.power, pointNum = pointNum, pointAllWeight = pointAllWeight}
             end
         end
     end
 
-    for _, playerRankInfo in pairs(playerList) do
-        net[#net+1] = playerRankInfo
+    for _, unionId in ipairs(unionIdArr) do
+        insertPlayerArr(unionId)
     end
 
-    playerRankSortFunc(net)
-
-    -- while #net > AnotherWorldBattleDefine.AB_RANK_MAX_NUM do
-    --     table.remove(net)
-    -- end
+    playerRank.batchUpdate(playerArr)
 end
 
 -- 生成 "公会-公会所属分组Id" 映射表
@@ -319,6 +854,19 @@ local function genUnion2GroupList(groupId, unionIdArr)
     end
 end
 
+-- 生成 "serverId - 公会Array" 映射表
+local function genServer2UnionArr(unionRank)
+    local rankList = unionRank.getRankList()
+    for _, rankInfo in ipairs(rankList) do
+        local unionId = rankInfo.guildId
+        local unionInfo = AnotherWorldBattleData.unionList[unionId]
+        if unionInfo then
+            local serverId = unionInfo.serverId
+            Server_2_UnionArr[serverId] = Server_2_UnionArr[serverId] or {}
+            Server_2_UnionArr[serverId][#Server_2_UnionArr[serverId]+1] = unionId
+        end
+    end
+end
 
 -- 生成各组的缓存数据
 local function genGroupCache()
@@ -326,26 +874,30 @@ local function genGroupCache()
         return
     end
 
+    local playerListData = AnotherWorldBattleData.playerList
+
     for groupId, unionIdArr in ipairs(AnotherWorldBattleData.groupArray) do
         -- 城池
         Group_2_CityList[groupId] = {}
         genCityList(Group_2_CityList[groupId], unionIdArr)
 
         -- 公会排行榜
-        Group_2_UnionRankList[groupId] = {}
+        Group_2_UnionRankList[groupId] = createGuildRank()
         genGroupUnionRankList(Group_2_UnionRankList[groupId], unionIdArr)
 
+        -- "serverId -- unionIdArray" 映射表
+        genServer2UnionArr(Group_2_UnionRankList[groupId])
+
         -- 个人排行榜
-        Group_2_PlayerRankList[groupId] = {}
-        genGroupPlayerRankList(Group_2_PlayerRankList[groupId], unionIdArr)
+        Group_2_PlayerRankList[groupId] = createPlayerRank()
+        genGroupPlayerRankList(Group_2_PlayerRankList[groupId], unionIdArr, playerListData)
 
-        -- 公会-公会所属分组  映射表
+        -- "公会-公会所属分组"  映射表
         genUnion2GroupList(groupId, unionIdArr)
     end
 end
 
 
-
 function initAfterStart()
     if _G.is_middle ~= true then return end
 
@@ -360,12 +912,14 @@ function ResetData()
     Group_2_UnionRankList = {}
     Group_2_PlayerRankList = {}
     Union_2_Group = {}
+    Server_2_UnionArr = {}
 
     AnotherWorldBattleData.lastRoundStartTime = os.time()
     -- AnotherWorldBattleData.stage = AnotherWorldBattleDefine.AB_STATE_JOIN
     AnotherWorldBattleData.joinUnionArr = nil
     AnotherWorldBattleData.groupArray = nil
     AnotherWorldBattleData.unionList = nil
+    AnotherWorldBattleData.playerList = nil
 
     dbUpdate._id = AnotherWorldBattleData._id
     LuaMongo.update(DB.db_anotherWorldBattle, dbUpdate, AnotherWorldBattleData)
@@ -373,9 +927,28 @@ end
 
 
 
+-- 获取公会所在分组的Id
+function GetUnionGroupId(unionId)
+    return Union_2_Group[unionId]
+end
+
+-- 当自己公会没有参赛时, 获取本服第一个公会所在分组Id
+function GetGroupIdByServerId(serverId)
+    local unionArr = Server_2_UnionArr[serverId]
+    if unionArr and unionArr[1] then
+        local unionId = unionArr[1]
+        return GetUnionGroupId(unionId)
+    end
+end
+
+
+
+
+-- 获取活动当前阶段
 function GetStage()
     return AnotherWorldBattleData.stage
 end
+-- 更新活动当前阶段
 function UpdateStage(newStage)
     AnotherWorldBattleData.stage = newStage
     updateValue("stage", newStage)
@@ -386,6 +959,7 @@ function UpdateStage(newStage)
 end
 
 
+-- 获取活动上一轮的开始时间
 function GetLastRoundStartTime()
     return AnotherWorldBattleData.lastRoundStartTime
 end
@@ -395,96 +969,164 @@ function UpdateLastRoundStartTime(newTime)
 end
 
 
+-- 获取参赛公会列表
 function GetJoinUnionArr()
     return AnotherWorldBattleData.joinUnionArr
 end
-
+-- 更新参赛公会列表
 function UpdateJoinUnionArr(newJoinUnionArr)
     AnotherWorldBattleData.joinUnionArr = newJoinUnionArr
     updateValue("joinUnionArr", newJoinUnionArr)
 end
 
 
+-- 获取分组列表
 function GetGroupArray()
     return AnotherWorldBattleData.groupArray
 end
-
+-- 更新分组列表
 function UpdateGroupArray(newGroupArray)
     AnotherWorldBattleData.groupArray = newGroupArray
     updateValue("groupArray", newGroupArray)
 end
 
 
-function GetUnionList()
-    return AnotherWorldBattleData.unionList
-end
-
-function UpdateUnionList(newUnionList) -- 待确定
-    AnotherWorldBattleData.unionList = newUnionList
-    updateValue("unionList", newUnionList)
-end
-
-
 
+-- 获取公会名字
 function GetUnionName(unionId)
     return AnotherWorldBattleData.unionList and AnotherWorldBattleData.unionList[unionId].name or ""
 end
-
+-- 获取某个公会数据
 function GetUnionData(unionId)
     return AnotherWorldBattleData.unionList and AnotherWorldBattleData.unionList[unionId]
 end
+-- 更新某个公会数据
+function UpdateUnionData(unionId, newUnionData)
+    if not AnotherWorldBattleData.unionList then
+        AnotherWorldBattleData.unionList = {}
+        -- updateValue("unionList", AnotherWorldBattleData.unionList)
+    end
 
-function UpdateUnionData(unionId, NewUnionData)
-    AnotherWorldBattleData.unionList[unionId] = NewUnionData
-    updateValue("unionList"..".".. unionId, NewUnionData)  --待确认
+    AnotherWorldBattleData.unionList[unionId] = newUnionData
+    updateValue("unionList"..".".. unionId, newUnionData)
 end
 
+-- 获取公会列表
+function GetUnionList()
+    return AnotherWorldBattleData.unionList
+end
 
 
 
 
-function GetPlayerName(unionId, playerUuid)
-    if AnotherWorldBattleData.unionList and AnotherWorldBattleData.unionList[unionId] then
-        local playerList = AnotherWorldBattleData.unionList[unionId].playerList
-        if playerList and playerList[playerUuid] then
-            return playerList[playerUuid].name
-        end
+-- 获取玩家名字
+function GetPlayerName(playerUuid)
+    local playerListData = AnotherWorldBattleData.playerList
+    if playerListData and playerListData[playerUuid] then
+        return playerListData[playerUuid].name or ""
     end
 
     return ""
 end
-
-
--- 获取公会所在分组的Id
-function GetUnionGroupId(unionId)
-    return Union_2_Group[unionId]
+-- 获取玩家数据
+function GetPlayerData(playerUuid)
+    return AnotherWorldBattleData.playerList and AnotherWorldBattleData.playerList[playerUuid]
+end
+-- 更新玩家数据
+function UpdatePlayerData(playerUuid, newPlayerData)
+    if not AnotherWorldBattleData.playerList then
+        AnotherWorldBattleData.playerList = {}
+        -- updateValue("playerList", AnotherWorldBattleData.playerList)
+    end
+    AnotherWorldBattleData.playerList[playerUuid] = newPlayerData
+    updateValue("playerList".. "." .. playerUuid, newPlayerData)
+end
+-- 获取公会列表
+function GetPlayerList()
+    return AnotherWorldBattleData.playerList
 end
 
--- 根据分组Id, 获取本组的城池数据
+
+-- 获取城池数据
 function GetCityListByGroupId(groupId)
     return Group_2_CityList[groupId]
 end
-
+-- 更新城池数据
 function UpdateCityList(groupId, newCityList)
     Group_2_CityList[groupId] = newCityList
 end
 
--- 根据分组Id, 获取本组的公会排行数据
+
+
+-- 获取公会排行数据
 function GetUnionRankList(groupId)
-    return Group_2_UnionRankList[groupId]
+    local unionRank = Group_2_UnionRankList[groupId]
+    if unionRank then
+        return unionRank.getRankList()
+    end
 end
-
-function UpdateUnionRankList(groupId, newRankList)
-    Group_2_UnionRankList[groupId] = newRankList
-    unionRankSortFunc(Group_2_UnionRankList[groupId])
+-- 更新公会的排行榜数据, cityVal, pointVal为变化的值
+function UpdateUnionRankList(groupId, unionId, cityVal, pointVal, newPower)
+    local unionRank = Group_2_UnionRankList[groupId]
+    if unionRank then
+        local unionRankInfo = unionRank.getGuildDetail(unionId)
+        unionRankInfo.occupyCityNum = unionRankInfo.occupyCityNum + cityVal
+        unionRankInfo.occupyPointNum = unionRankInfo.occupyPointNum + pointVal
+        if newPower then
+            unionRankInfo.power = newPower
+        end
+        unionRank.updateGuild(unionId, unionRankInfo.name, unionRankInfo.power, unionRankInfo.occupyCityNum, unionRankInfo.occupyPointNum)
+    end
 end
 
 
--- 根据分组Id, 获取本组的玩家排行数据
+
+-- 生成玩家用于排名的数据
+local function genPlayerRankVal(playerUuid)
+    local playerListData = AnotherWorldBattleData.playerList
+    local name, power, pointNum, pointAllWeight = "", 0, 0, 0
+
+    if playerListData and playerListData[playerUuid] then
+        power = playerListData[playerUuid].power or 0
+        name = playerListData[playerUuid].name or ""
+
+        for cityId, pointList in pairs(playerListData[playerUuid].heroList or {}) do
+            for _, _ in pairs(pointList) do
+                pointNum = pointNum + 1
+                local cityCfg = AnotherWorldBattleConfig.city[cityId]
+                pointAllWeight = pointAllWeight + (cityCfg and cityCfg.pointWeight or 0)
+            end
+        end
+    end
+
+    return name, power, pointNum, pointAllWeight
+end
+-- 获取玩家排行数据
 function GetPlayerRankList(groupId)
-    return Group_2_PlayerRankList[groupId]
+    local playerRank = Group_2_PlayerRankList[groupId]
+    if playerRank then
+        return playerRank.getRankList()
+    end
 end
-function UpdatePlayerRankList(groupId, newRankList)
-    Group_2_PlayerRankList[groupId] = newRankList
-    playerRankSortFunc(Group_2_PlayerRankList[groupId])
+-- 更新玩家排行数据, pointVal, pointWeightVal为变化的值
+function UpdatePlayerRankList(groupId, playerUuid, pointVal, pointWeightVal, newPower)
+    local playerRank = Group_2_PlayerRankList[groupId]
+    if playerRank then
+        local playerRankData = playerRank.getPlayerDetail(playerUuid)
+        if not playerRankData then
+            playerRankData = {}
+            local name, power, pointNum, pointAllWeight = genPlayerRankVal(playerUuid)
+            playerRankData.name = name
+            playerRankData.power = power
+            playerRankData.pointNum = pointNum
+            playerRankData.pointAllWeight = pointAllWeight
+        else
+            playerRankData.pointNum = playerRankData.pointNum + pointVal
+            playerRankData.pointAllWeight = playerRankData.pointAllWeight + pointWeightVal
+            if newPower then
+                playerRankData.power = newPower
+            end
+        end
+        playerRank.updatePlayer(playerUuid, playerRankData.name, playerRankData.power, playerRankData.pointNum, playerRankData.pointAllWeight)
+    end
 end

+ 14 - 5
script/module/anotherWorldBattle/AnotherWorldBattleDefine.lua

@@ -9,11 +9,12 @@ AB_STATE_AWARD = 3     -- 发奖阶段标识
 
 AB_SUB_DAY = 9  -- 两次活动之间相隔的天数
 
-AB_OPEN_WDAY_AREA = {7, 4}      -- 功能时间范围, 周六 ~ 下周周三
+AB_OPEN_WDAY_AREA = {7, 4}      -- 活动开启时间范围, 周六 ~ 下周周三
 
-AB_JOIN_WDAY_AREA = {7, 1}      -- 报名时间范围, 周六 ~ 周日
+AB_JOIN_WDAY = 7
+-- AB_JOIN_WDAY_AREA = {7, 1}      -- 报名时间范围, 周六 ~ 周日
 
-AB_BATTLE_WDAY_AREA = {2, 4}    -- 战斗时间范围, 周一 ~ 周三
+AB_BATTLE_WDAY_AREA = {1, 4}    -- 战斗时间范围, 周日 ~ 周三
 
 
 AB_START_SEC = 600          -- 10*60, 用于与当天0点时间戳计算报名/战斗阶段开始时间
@@ -30,10 +31,13 @@ AB_GROUP_UNION_NUM = 8      -- 每8个公会为一组
 
 AB_POINT_MAX_NUM = 5        -- 每个城池最大据点数量
 
-AB_PLAYER_OCCUPY_POINT_MAX_NUM = 10  -- 每个玩家最多占领据点数量
+AB_PLAYER_OCCUPY_POINT_MAX_NUM = 15  -- 每个玩家最多占领据点数量
 
 AB_RANK_MAX_NUM = 50        -- 公会/个人排行榜最大上榜数量
 
+AB_PLAYER_CHALLENGE_TIMES = 10  -- 玩家初始时挑战次数
+AB_PLAYER_CHALLENGETIMES_SEC = 3600  -- 每一个小时恢复一次挑战次数
+
 
 AB_AWARD_MAIL_ID = 7030        -- 奖励发放邮件Id
 AB_LOSE_POINT_MAIL_ID = 7031   -- 玩家失去据点后通知邮件Id
@@ -51,9 +55,14 @@ ERR_CODE_5 = 5      -- 玩家没有占领过据点
 ERR_CODE_6 = 6      -- 集结冷却中
 ERR_CODE_7 = 7      -- 城池不相邻
 ERR_CODE_8 = 8      -- 公会已报名
+ERR_CODE_9 = 9      -- 没有在本城池发起集结
+ERR_CODE_10 = 10    -- 当前占据的据点已达上限
 
 
 
 
 AB_MAIL_FAIL_TAG = "fail"
-AB_MAIL_SUCC_TAG = "succ"
+AB_MAIL_SUCC_TAG = "succ"
+
+
+AB_DEF_NAME_STR = "防守者"

+ 368 - 155
script/module/anotherWorldBattle/AnotherWorldBattleNS.lua

@@ -38,8 +38,6 @@ local RoleHeadLogic = require("role.RoleHeadLogic")
 local MailManager = require("mail.MailManager")
 local Log = require("common.Log")
 local Timer = require("core.Timer")
-local CommonDB = require("common.CommonDB")
-local RoleSystemExcel = require("excel.roleSystem")
 local Grid = require("bag.Grid")
 local UnionLogic = require("union.UnionLogic")
 local BillboardLogic = require("billboard.BillboardLogic")
@@ -53,30 +51,30 @@ local HeroExcel = require("excel.hero")
 local MiddleCommonLogic = require("middle.MiddleCommonLogic")
 local CombatImpl = require("combat.CombatImpl")
 local RoleAttr = require("role.RoleAttr")
-local RoleDefine = require("role.RoleDefine")
 
 
-local function writeLog(str)
-    
+local function writeLog(logStr)
+    Log.write(Log.LOGID_OSS_ANOTHERWORLDBATTLE, logStr)
 end
 
-local function sendMail(mailId, receiverUuid, itemArray)
+local function sendMail(mailId, receiverUuid, itemArray, extraInfo)
     if not mailId or not receiverUuid then
         return
     end
 
+    local v1,v2,v3,v4,v5 = extraInfo and extraInfo[1] or 0,  extraInfo and extraInfo[2] or 0, extraInfo and extraInfo[3] or 0, extraInfo and extraInfo[4] or 0, extraInfo and extraInfo[5] or 0
     local mailCfg = MailExcel.mail[mailId]
-    local content = mailCfg.content
+    local content = Util.format(mailCfg.content, v1,v2,v3,v4,v5)
     MailManager.add(MailManager.SYSTEM, receiverUuid, mailCfg.title, content, itemArray, mailCfg.senderName or "GM")
 end
 
-
 local function createRewardQueue()
     local issueRewardQueue = {
         playerArray = {},
         insertMaxNum = 100, -- 一次最多插入数据库的邮件数量
         repeatMaxTimes = 3, -- 重试次数
-        repeatTb = {}
+        repeatTb = {},
+        extraInfo = {},
     }
 
     function issueRewardQueue:add(playerInfo)
@@ -91,7 +89,7 @@ local function createRewardQueue()
             local playerInfo = table.remove(self.playerArray)
             local uuid = playerInfo[1]
 
-            local ok, err = pcall(sendMail, AnotherWorldBattleDefine.AB_AWARD_MAIL_ID, uuid, playerInfo[2])
+            local ok, err = pcall(sendMail, AnotherWorldBattleDefine.AB_AWARD_MAIL_ID, uuid, playerInfo[2], issueRewardQueue.extraInfo)
             if not ok then
                 if not self.repeatTb[uuid] or self.repeatTb[uuid] < self.repeatMaxTimes then
                     issueRewardQueue:add(playerInfo)
@@ -116,13 +114,7 @@ local function createRewardQueue()
 end
 
 
-
-
-
-
-
-
--- 获取当天属于星期几
+-- 获取当天是星期几
 local function getWDay()
     return Util.getWeekDay()
 end
@@ -142,14 +134,18 @@ local function calcMonsterPower(monsterOutID)
     return power
 end
 
--- 计算多个城池每分钟产出道具数量之和
-local function calcCitysAward(cityIdArr)
+-- 根据据点所属城池,计算多个据点每分钟产出道具数量之和
+local function calcPointAward(cityIdArr)
     local myUnionAwardNum = 0
-
     if cityIdArr then
         for _, cityId in ipairs(cityIdArr) do
             local targetCityCfg = AnotherWorldBattleConfig.city[cityId]
-            myUnionAwardNum = myUnionAwardNum + targetCityCfg.cityAward[2]
+            if targetCityCfg.isBaseCity == 1 then
+                myUnionAwardNum = myUnionAwardNum + targetCityCfg.cityAward[2] * AnotherWorldBattleDefine.AB_POINT_MAX_NUM
+            else
+                myUnionAwardNum = myUnionAwardNum + targetCityCfg.cityAward[2]
+            end
+
         end
     end
 
@@ -190,6 +186,8 @@ local function getHeroInfo(human, targetHeroUuid)
             heroBody  = heroCfg.body,
             heroIcon  = heroGrid.head or heroCfg.head,
             heroPower = heroGrid.zhandouli,
+            heroId = heroGrid.id,
+            heroQuality = heroCfg.grade,
         }
 
         return heroInfo
@@ -235,10 +233,6 @@ local function generateShowInfo(human)
     return showInfo
 end
 
-
-
-
-
 -- 阵容数据检查,如果不在 "活动开启且战斗阶段" 则清空
 local function formationDataCheeck(human)
     if not human.db.anotherWorlBattle then
@@ -296,15 +290,18 @@ local function sendDefHeroArr(human)
 end
 
 -- 是否是防守阵容中的英雄
-local function isDefHero(human, checkHeroUuid)
+local function isDefHero(human, checkHeroUuid, excludeCityId, excludePointIdx)
     if not human.db.anotherWorlBattle then
         return false
     end
 
-    for _, pointList in pairs(human.db.anotherWorlBattle.formation) do
-        for _, combatData in pairs(pointList) do
-            local heroList = combatData.list
+    for cityId, pointList in pairs(human.db.anotherWorlBattle.formation) do
+        for pointIdx, combatData in pairs(pointList) do
+            if (excludeCityId and excludeCityId == cityId) and (excludePointIdx and excludePointIdx == pointIdx) then
+                break
+            end
 
+            local heroList = combatData.list
             for _, heroUuid in pairs(heroList) do
                 if heroUuid == checkHeroUuid then
                     return true
@@ -345,33 +342,115 @@ local function isBattleStage()
     return false
 end
 
-function IsRun(joinTime)
-    if not isBattleStage() then
-        return false
+-- 生成奖励发放对象列表
+local function genAwardObjArr(unionOccupyInfo)
+    local function calcMinute(timeArr)
+        local minuteVal = 0
+        for _, timeTb in ipairs(timeArr or {}) do
+            local sec = timeTb[2] - timeTb[1]
+            if sec > 0 then
+                minuteVal = minuteVal + sec
+            end
+        end
+
+        return math.floor(minuteVal / 60)
+    end
+
+    if not unionOccupyInfo.playerUuidArr or #unionOccupyInfo.playerUuidArr <= 0 then
+        return
     end
 
-    if joinTime then
-        local diffDays = Util.diffDay(joinTime)
+    local itemList = {}
+    local occupyCityInfo = {0,0,0,0,0}
 
-        -- 
-        if diffDays == 5 then
-            local now = os.time()
-            local toDayStartTime = Util.getDayStartTime(now)
-            if now < toDayStartTime  + AnotherWorldBattleDefine.AB_BATTLE_END_SEC then
-                return false
+    local item_185_Id = 185
+    local item_185_Num = 0
+    item_185_Num = item_185_Num + (unionOccupyInfo.occuoyPointNum or 0) -- 待优化
+
+    -- 额外奖励
+    for _, cityId in ipairs(unionOccupyInfo.occupyCityArr) do
+        local cityCfg = AnotherWorldBattleConfig.city[cityId]
+
+        if cityCfg then
+            if cityCfg.isBaseCity == 1 then
+                item_185_Num = item_185_Num + 20
+                occupyCityInfo[1] = occupyCityInfo[1] + 1
+            else
+                if cityCfg.cityLv == 2 then
+                    item_185_Num = item_185_Num + 2
+                    occupyCityInfo[2] = occupyCityInfo[2] + 1
+                elseif cityCfg.cityLv == 3 then
+                    item_185_Num = item_185_Num + 3
+                    occupyCityInfo[3] = occupyCityInfo[3] + 1
+                elseif cityCfg.cityLv == 4 then
+                    item_185_Num = item_185_Num + 5
+                    occupyCityInfo[4] = occupyCityInfo[4] + 1
+                elseif cityCfg.cityLv == 5 then
+                    item_185_Num = item_185_Num + 20
+                    occupyCityInfo[5] = occupyCityInfo[5] + 1
+                end
             end
         end
+    end
+
+    -- 占领据点每分钟的奖励
+    for _, pointInfo in ipairs(unionOccupyInfo.point2CityIdArr) do
+        local cityId = pointInfo[1]
+        local occupyTimeArr = pointInfo[2]
+        local cityCfg = AnotherWorldBattleConfig.city[cityId]
+
+        local totalMinVal = calcMinute(occupyTimeArr)
+        if totalMinVal > 0 then
+            local itemId, itemNum = cityCfg.cityAward[1], cityCfg.cityAward[2]
+            itemList[itemId] = totalMinVal * itemNum
+        end
+    end
 
-        -- < 5天说明处于本轮活动的开启时间
-        if diffDays > 5 and diffDays <= AnotherWorldBattleDefine.AB_SUB_DAY then
+
+    if item_185_Num > 0 then
+        itemList[item_185_Id] = item_185_Num
+    end
+
+    local itemArr = {}
+    for itemId, itemNum in pairs(itemList) do
+        itemArr[#itemArr+1] = { itemId, itemNum }
+    end
+
+    local awardObjArr = {}
+    for _, playerUuid in ipairs(unionOccupyInfo.playerUuidArr) do
+        awardObjArr[#awardObjArr+1] = {playerUuid, itemArr}
+    end
+
+    return awardObjArr, occupyCityInfo
+end
+
+
+
+-- 活动是否处于开启中
+function IsRuning(joinTime)
+    local wDay = getWDay()
+    if not table.find(AnotherWorldBattleDefine.AB_OPEN_WDAY_AREA, wDay) then
+        return false
+    end
+
+    local diffDays = Util.diffDay(joinTime)
+    -- 活动最后一天, 如果当前时间 >  结束时间则标识活动结束
+    if diffDays == 5 then
+        local now = os.time()
+        local toDayStartTime = Util.getDayStartTime(now)
+        if now > (toDayStartTime + AnotherWorldBattleDefine.AB_BATTLE_END_SEC) then
             return false
         end
     end
 
+    -- < 5天说明处于本轮活动的开启时间
+    if diffDays > 5 then
+        return false
+    end
+
     return true
 end
 
-
 --检测上阵英雄
 function checkUpdatePos(human, msg)
     local heroList = Util.split(msg.heroList, ",")
@@ -388,10 +467,30 @@ function checkUpdatePos(human, msg)
 end
 
 -- 公会战力更新
-function UnionPowerChange(unionId)
+function UnionPowerChange(unionId, newPower)
     if not isBattleStage() then
         return
     end
+
+    local msgData = InnerMsg.lw.LW_ANOTHERWORLDBATTLE_UPDATE_UNION
+    msgData.myUnionId = unionId
+    msgData.updateData = {}
+    msgData.updateData.power = newPower
+    InnerMsg.sendMsg(0, msgData)
+end
+
+-- 玩家战力更新
+function PlayerPowerChange(human)
+    if not isBattleStage() then
+        return
+    end
+
+    local msgData = InnerMsg.lw.LW_ANOTHERWORLDBATTLE_UPDATE_PLAYER
+    msgData.playerUuid = human.db._id
+    msgData.myUnionId = human.db.unionUuid
+    msgData.updateData = {}
+    msgData.updateData.power = human.db.zhandouli
+    InnerMsg.sendMsg(0, msgData)
 end
 
 
@@ -430,19 +529,22 @@ function AB_Join(human)
     -- end
 
     local wDay = getWDay()
-    if not table.find(AnotherWorldBattleDefine.AB_JOIN_WDAY_AREA, wDay) then
+    -- if not table.find(AnotherWorldBattleDefine.AB_JOIN_WDAY_AREA, wDay) then
+    --     msgRet.Joinstate = 5
+    --     return Msg.send(msgRet, human.fd)
+    -- end
+
+    if wDay ~= AnotherWorldBattleDefine.AB_JOIN_WDAY then
         msgRet.Joinstate = 5
         return Msg.send(msgRet, human.fd)
     end
 
-
     -- 公会排名前二才能参加
     if not isTopTwoUnion(human) then
         msgRet.Joinstate = 2
         return Msg.send(msgRet, human.fd)
     end
 
-
     -- 会长/副会长才能报名
     if not UnionLogic.IsTopTwoManager(human, unionId) then
         return Broadcast.sendErr(human, Lang.AB_NOT_TOPTWO_MANGER)
@@ -500,7 +602,7 @@ function AB_CityDetailed_Query(human, targetCityId)
     InnerMsg.sendMsg(0, msgData)
 end
 
--- 查询某个城池的某个据点的相信信息
+-- 查询某个城池的某个据点的详细信息
 function AB_PointDetailed_Query(human, targetCityId, targetPointIdx)
     if not AnotherWorldBattleConfig.city[targetCityId] then
         return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
@@ -562,11 +664,15 @@ function AB_PlayerRank_Query(human)
 end
 
 -- 发起集结
-function AB_Gather(human, targetCityId)
+function AB_Gather(human, targetCityId, opType)
     if not AnotherWorldBattleConfig.city[targetCityId] then
         return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
     end
 
+    if opType ~= 1 and opType ~= 2 then
+        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
+    end
+
     local unionId = human.db.unionUuid
     if not unionId then
         return Broadcast.sendErr(human, Lang.AB_NO_UNION)
@@ -582,6 +688,7 @@ function AB_Gather(human, targetCityId)
     msgData.playerUuid = human.db._id
     msgData.myUnionId = human.db.unionUuid
     msgData.targetCityId = targetCityId
+    msgData.opType = opType
 
     InnerMsg.sendMsg(0, msgData)
 end
@@ -603,8 +710,35 @@ function AB_Try_Challenge_Point(human, targetCityId, targetPointIdx)
     InnerMsg.sendMsg(0, msgData)
 end
 
--- 战斗胜利
-local function challenge_Win(human, args)
+-- 战斗结束
+local function challenge_End(human, args)
+    local cityId = args.cityId
+    local pointIdx = args.pointIdx
+
+    local msgData = InnerMsg.lw.LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_END
+    msgData.sourceServerId = Config.SVR_INDEX
+    msgData.playerUuid = human.db._id
+    msgData.myUnionId = human.db.unionUuid
+    msgData.targetCityId = cityId
+    msgData.targetPointIdx = pointIdx
+    msgData.challengeRes = args.challengeRes
+
+    -- 挑战没有胜利
+    if args.challengeRes ~= CombatDefine.RESULT_WIN then
+        -- 说明之前已经在跨服上保存玩家的基础数据了
+        if human.db.anotherWorlBattle then
+            return
+        end
+
+        msgData.playerShowInfo = {
+            name = human.db.name,
+            lv = human.db.lv,
+            power = human.db.zhandouli,
+        }
+        return InnerMsg.sendMsg(0, msgData)
+    end
+
+
     if not human.db.anotherWorlBattle then
         human.db.anotherWorlBattle = {
             startTime = os.time(),
@@ -614,8 +748,6 @@ local function challenge_Win(human, args)
 
     -- 把当前战斗阵容数据保存到当前模块,作为防守阵容
     local combatData = CombatPosLogic.getCombatHeroDB(human, CombatDefine.COMBAT_TYPE35)
-    local cityId = args.cityId
-    local pointIdx = args.pointIdx
     local formationData = human.db.anotherWorlBattle.formation or {}
     formationData[cityId] = formationData[cityId] or {}
     formationData[cityId][pointIdx] = Util.copyTable(combatData)
@@ -624,12 +756,6 @@ local function challenge_Win(human, args)
     sendDefHeroArr(human)
 
     --同步到跨服
-    local msgData = InnerMsg.lw.LW_ANOTHERWORLDBATTLE_POINT_CHALLENGE_WIN
-    msgData.sourceServerId = Config.SVR_INDEX
-    msgData.playerUuid = human.db._id
-    msgData.myUnionId = human.db.unionUuid
-    msgData.targetCityId = cityId
-    msgData.targetPointIdx = pointIdx
     msgData.playerShowInfo = generateShowInfo(human)
     InnerMsg.sendMsg(0, msgData)
 
@@ -637,6 +763,59 @@ local function challenge_Win(human, args)
     CombatPosLogic.cleanCombatHeros(human, CombatDefine.COMBAT_TYPE35)
 end
 
+-- 更换据点的防守阵容
+function AB_Update_Lineup(human, msg)
+    if not isBattleStage() then
+        return Broadcast.sendErr(human, Lang.AB_NOT_BATTLE_TIME)
+    end
+
+    local anotherWorlBattle = human.db.anotherWorlBattle
+    if not anotherWorlBattle or not anotherWorlBattle.formation then
+        return Broadcast.sendErr(human, Lang.AB_NOT_OCCUPY_POINT)
+    end
+
+    local cityId = msg.cityId
+    local pointIdx = msg.pointIdx
+    local formationData = anotherWorlBattle.formation
+    if not formationData[cityId] or not formationData[cityId][pointIdx] then
+        return Broadcast.sendErr(human, Lang.AB_NOT_OCCUPY_TARGET_POINT)
+    end
+
+    local res, heroList, helpList = CombatPosLogic.CheckUpdatePos(human, msg)
+    if not res then
+        return Broadcast.sendErr(human, Lang.COMBAT_POS__ERR)
+    end
+
+    local len = 0
+    local heroArr = {}
+    for i = 1, CombatDefine.COMBAT_HERO_CNT do
+        local uuid = heroList[i] or ""
+        if uuid ~= "0" and uuid ~= "" then
+            if isDefHero(human, uuid, cityId, pointIdx) then
+                return Broadcast.sendErr(human, Lang.AB_HERO_IN_OTHER_POINT)
+            end
+
+            len = len + 1
+            heroArr[len] = getHeroInfo(human, uuid)
+        end
+    end
+
+    if len == 0 then
+        return
+    end
+
+    local msgData = InnerMsg.lw.LW_ANOTHERWORLDBATTLE_UPDATE_POINT_LINEIP
+    msgData.sourceServerId = Config.SVR_INDEX
+    msgData.playerUuid = human.db._id
+    msgData.heroArr = heroArr
+    msgData.targetCityId = cityId
+    msgData.targetPointIdx = pointIdx
+    msgData.formation = msg.formation
+    msgData.heroList = heroList
+    msgData.helpList = helpList
+
+    InnerMsg.sendMsg(0, msgData)
+end
 
 
 
@@ -667,6 +846,10 @@ function C2N_ErrTips(msg)
         tips = Lang.AB_CITY_NOT_ADDJION
     elseif errCode == AnotherWorldBattleDefine.ERR_CODE_8 then
         tips = Lang.AB_JOINED
+    elseif errCode == AnotherWorldBattleDefine.ERR_CODE_9 then
+        tips = Lang.AB_CITY_NO_GATHER
+    elseif errCode == AnotherWorldBattleDefine.ERR_CODE_10 then
+        tips = Lang.AB_OCCUPY_POINT_MAX
     end
 
     Broadcast.sendErr(human, tips)
@@ -702,8 +885,9 @@ end
 
 -- 报名成功
 function C2N_Join_Succ(msg)
+    local now = os.time()
     local unionId = msg.myUnionId
-    UnionLogic.Join_AB_Succ(unionId)
+    UnionLogic.UpdateJoinAbTime(unionId, now)
 
 
     local human = ObjHuman.onlineUuid[msg.playerUuid]
@@ -716,7 +900,6 @@ function C2N_Join_Succ(msg)
     Msg.send(msgRet, human.fd)
 end
 
-
 -- 跨服返回的所有城池数据
 function C2N_AllCity_Query(msg)
     local human = ObjHuman.onlineUuid[msg.playerUuid]
@@ -726,24 +909,27 @@ function C2N_AllCity_Query(msg)
 
     local msgRet = Msg.gc.GC_AB_ALLCITY_QUERY
     msgRet.myBaseCityId = msg.myUnionBaseCityId
-    local cityArrMsg = msgRet.cityArr
-    cityArrMsg[0] = 0
-
-    local useCfg = false
-    local cityData = msg.cityArr
-    if #msg.cityArr <= 0 then
-        useCfg = true
-        cityData = AnotherWorldBattleConfig.city
+    msgRet.hasPointNum = msg.hasPointNum
+    msgRet.challengeTimes = msg.challengeTimes
+    local now = os.time()
+    msgRet.leftTime = msg.lastTime
+    if msgRet.leftTime ~= 0 then
+        msgRet.leftTime = (msg.lastTime + AnotherWorldBattleDefine.AB_PLAYER_CHALLENGETIMES_SEC) - now
     end
 
-    for cityId, cityInfo in ipairs(cityData) do
+    msgRet.cityArr[0] = 0
+    local cityArrMsg = msgRet.cityArr
+
+    for cityId, cityInfo in ipairs(msg.cityArr) do
         cityArrMsg[0] = cityId
         local cityCfg = AnotherWorldBattleConfig.city[cityId]
         cityArrMsg[cityId].cityId = cityId
         cityArrMsg[cityId].cityName = cityCfg.cityName
         cityArrMsg[cityId].cityLv = cityCfg.cityLv
-        cityArrMsg[cityId].occupyPointNum = useCfg and 0 or cityInfo.occupyPointNum
-        cityArrMsg[cityId].occupyUnionName = (useCfg and "" or cityInfo.occupyUnionName) or ""
+        cityArrMsg[cityId].occupyPointNum = cityInfo.occupyPointNum or 0
+        cityArrMsg[cityId].occupyUnionName = cityInfo.occupyUnionName or ""
+        cityArrMsg[cityId].cityState = cityInfo.cityState
+
         cityArrMsg[cityId].adJoinCityArr[0] = #cityCfg.adJoinCityArr
         for i, cId in ipairs(cityCfg.adJoinCityArr) do
             cityArrMsg[cityId].adJoinCityArr[i] = cId
@@ -771,9 +957,9 @@ function C2N_CityDetailed_Query(msg)
     msgRet.cityId = msg.targetCityId
     msgRet.cityLv = cityCfg.cityLv
     msgRet.cityIconId = cityCfg.cityIconId
-    Grid.makeItem(msgRet.cityAward, cityCfg.cityAward[1], cityCfg.cityAward[2])
+    Grid.makeItem(msgRet.cityAward, cityCfg.cityAward[1], cityCfg.cityAward[2] * AnotherWorldBattleDefine.AB_POINT_MAX_NUM )
 
-    local myUnionAwardNum = calcCitysAward(msg.myUnionOccupyArr)
+    local myUnionAwardNum = calcPointAward(msg.myUnionOccupyArr)
     Grid.makeItem(msgRet.myUnionAward, cityCfg.cityAward[1], myUnionAwardNum)
 
     -- 活动没有进入战斗阶段时, 使用默认数据
@@ -789,12 +975,12 @@ function C2N_CityDetailed_Query(msg)
             msgRet.pointArr[pointIdx].occupyUnionName = pointInfo.occupyUnionName
             msgRet.pointArr[pointIdx].occupyPlayerName = pointInfo.occupyPlayerName
             msgRet.pointArr[pointIdx].power = pointInfo.power
-            msgRet.pointArr[pointIdx].isCanChallenge = pointInfo.isCanChallenge
+            msgRet.pointArr[pointIdx].state = pointInfo.state
         else
             msgRet.pointArr[pointIdx].occupyUnionName = ""
-            msgRet.pointArr[pointIdx].occupyPlayerName = "防守者".. pointIdx  --待改
+            msgRet.pointArr[pointIdx].occupyPlayerName = AnotherWorldBattleDefine.AB_DEF_NAME_STR.. pointIdx
             msgRet.pointArr[pointIdx].power = calcMonsterPower(cityCfg.pointMonsterId)
-            msgRet.pointArr[pointIdx].isCanChallenge = pointInfo.isCanChallenge
+            msgRet.pointArr[pointIdx].state = pointInfo.state
         end
 
     end
@@ -819,7 +1005,7 @@ function C2N_PointDetailed_Query(msg)
 
     local pointInfo = msg.pointInfo
     local msgRet = Msg.gc.GC_AB_POINT_DETAILEDINFO_QUERY
-    msgRet.isCanChallenge = pointInfo.isCanChallenge or 0
+    msgRet.state = pointInfo.state
 
     if pointInfo.name then
         msgRet.name = pointInfo.name
@@ -835,9 +1021,11 @@ function C2N_PointDetailed_Query(msg)
             msgRet.heroArr[i].heroLv = heroInfo.heroLv
             msgRet.heroArr[i].heroCamp = heroInfo.heroCamp
             msgRet.heroArr[i].heroIcon = heroInfo.heroIcon
+            msgRet.heroArr[i].heroId = heroInfo.heroId
+            msgRet.heroArr[i].heroQuality = heroInfo.heroQuality
         end
     else
-        msgRet.name = "防守者" .. msg.targetPointIdx -- 待改
+        msgRet.name = AnotherWorldBattleDefine.AB_DEF_NAME_STR .. msg.targetPointIdx
         msgRet.head = getDefaultShowId(1, msg.targetPointIdx)
         msgRet.headFrame = getDefaultShowId(2, msg.targetPointIdx)
         msgRet.defLv = 200
@@ -859,6 +1047,8 @@ function C2N_PointDetailed_Query(msg)
             msgRet.heroArr[idx].heroLv = monsterInfo[2]
             msgRet.heroArr[idx].heroCamp = mcf.camp
             msgRet.heroArr[idx].heroIcon = mcf.head
+            msgRet.heroArr[idx].heroId = monsterID
+            msgRet.heroArr[idx].heroQuality = mcf.heroQuality or 1
         end
     end
 
@@ -877,9 +1067,9 @@ function C2N_BaseCity_Query(msg)
 
     local cityCfg = AnotherWorldBattleConfig.city[baseCityInfo.cityId]
     msgRet.cityIconId = cityCfg.cityIconId
-    Grid.makeItem(msgRet.cityAward, cityCfg.cityAward[1], cityCfg.cityAward[2])
+    Grid.makeItem(msgRet.cityAward, cityCfg.cityAward[1], cityCfg.cityAward[2] * AnotherWorldBattleDefine.AB_POINT_MAX_NUM)
 
-    local myUnionAwardNum = calcCitysAward(baseCityInfo.myUnionOccupyArr)
+    local myUnionAwardNum = calcPointAward(baseCityInfo.myUnionOccupyArr)
     Grid.makeItem(msgRet.myUnionAward, cityCfg.cityAward[1], myUnionAwardNum)
 
     msgRet.cityIconId = baseCityInfo.occupyPointNum
@@ -899,16 +1089,18 @@ function C2N_PlayerOccupyPoint_Query(msg)
     end
 
     local msgRet = Msg.gc.GC_AB_MY_OCCUPY_POINT_QUERY
-    local myPointArr = msg.myPointArr
+    local myPointArr = msgRet.myPointArr
     myPointArr[0] = 0
 
     for idx, pointInfo in ipairs(msg.occupyPointArr) do
         myPointArr[0] = idx
         local cityCfg = AnotherWorldBattleConfig.city[pointInfo.cityId]
         myPointArr[idx].cityIconId = cityCfg.cityIconId
+        myPointArr[idx].cityName = cityCfg.cityName
         myPointArr[idx].cityLv = cityCfg.cityLv
         myPointArr[idx].pointIdx = pointInfo.pointIdx
         myPointArr[idx].power = pointInfo.power
+        myPointArr[idx].cityId = pointInfo.cityId
 
         myPointArr[idx].heroArr[0] = #pointInfo.heroArr
         for heroIdx, heroInfo in ipairs(pointInfo.heroArr) do
@@ -918,12 +1110,31 @@ function C2N_PlayerOccupyPoint_Query(msg)
             hero.heroLv = heroInfo.heroLv
             hero.heroCamp = heroInfo.heroCamp
             hero.heroIcon = heroInfo.heroIcon
+            hero.heroId = heroInfo.heroId
+            hero.heroQuality = heroInfo.heroQuality
         end
     end
 
     Msg.send(msgRet, human.fd)
 end
 
+-- 跨服返回集结/取消集结成功
+function C2N_Gather_End(msg)
+    local human = ObjHuman.onlineUuid[msg.playerUuid]
+    if not human then
+        return
+    end
+
+    local targetCityId = msg.targetCityId
+    local cityCfg = AnotherWorldBattleConfig.city[targetCityId]
+    local msgRet = Msg.gc.GC_AB_GARHER
+    msgRet.cityId = targetCityId
+    msgRet.cityName = cityCfg.cityName
+    msgRet.opType = msg.opType
+
+    Msg.send(msgRet, human.fd)
+end
+
 --跨服返回公会排行榜数据
 function C2N_UnionRank_Query(msg)
     local human = ObjHuman.onlineUuid[msg.playerUuid]
@@ -934,15 +1145,31 @@ function C2N_UnionRank_Query(msg)
     local msgRet = Msg.gc.GC_AB_UNION_RANK_QUERY
     msgRet.unionRankArr[0] = 0
     msgRet.myUnionRank = msg.myUnionRank
+    msgRet.myData = { name = "", power = 0, cityNum = 0, pointNum = 0 }
 
     for rank, rankdData in ipairs(msg.unionRankArr) do
         msgRet.unionRankArr[0] = rank
         msgRet.unionRankArr[rank] = {
             name = rankdData.name,
             power = rankdData.power,
-            cityNum = rankdData.occupyCityNum,
-            pointNum = rankdData.occupyPointNum,
+            cityNum = rankdData.cityNum,
+            pointNum = rankdData.pointNum,
         }
+
+        if rank == msg.myUnionRank then
+            msgRet.myData.name = rankdData.name
+            msgRet.myData.power = rankdData.power
+            msgRet.myData.cityNum = rankdData.cityNum
+            msgRet.myData.pointNum = rankdData.pointNum
+        end
+    end
+
+    if msgRet.myData.power == 0 then
+        local unionId = human.db.unionUuid
+        local queryFiles = {name = 1, zhandouli = 1}
+        local unionInfo = UnionLogic.GetUnionData(unionId, queryFiles)
+        msgRet.myData.name = unionInfo and unionInfo.name or ""
+        msgRet.myData.power = unionInfo and unionInfo.zhandouli or 0
     end
 
     Msg.send(msgRet, human.fd)
@@ -958,15 +1185,26 @@ function C2N_PlayerRank_Query(msg)
     local msgRet = Msg.gc.GC_AB_PLAYER_RANK_QUERY
     msgRet.playerRankArr[0] = 0
     msgRet.myRank = msg.myRank
+    msgRet.myData = {
+        name = human.db.name,
+        power = human.db.zhandouli,
+        pointNum = 0,
+        pointWeight = 0,
+    }
 
     for rank, rankdData in ipairs(msg.playerRankArr) do
         msgRet.playerRankArr[0] = rank
         msgRet.playerRankArr[rank] = {
             name = rankdData.name,
             power = rankdData.power,
-            pointNum = rankdData.occupyPointNum,
+            pointNum = rankdData.pointNum,
             pointWeight = rankdData.pointWeight,
         }
+
+        if rank == msg.myRank then
+            msgRet.myData.pointNum = rankdData.pointNum
+            msgRet.myData.pointWeight = rankdData.pointWeight
+        end
     end
 
     Msg.send(msgRet, human.fd)
@@ -1030,7 +1268,8 @@ function C2N_Point_Lose(msg)
 
     -- 发邮件
     local mailCfg = MailExcel.mail[AnotherWorldBattleDefine.AB_LOSE_POINT_MAIL_ID]
-    MailManager.add(MailManager.SYSTEM, msg.playerUuid, mailCfg.title, mailCfg.content, nil, mailCfg.senderName or "GM")
+    local content = Util.format(mailCfg.content, losePointIdx)
+    MailManager.add(MailManager.SYSTEM, msg.playerUuid, mailCfg.title, content, nil, mailCfg.senderName or "GM")
 
     -- 把最新的防守阵容数据推给客户端
     if human.fd then
@@ -1038,87 +1277,56 @@ function C2N_Point_Lose(msg)
     end
 end
 
-
-local function genAwardObjArr(unionOccupyInfo)
-    local function calcMins(timeArr)
-        local minuteVal = 0
-        for _, timeTb in ipairs(timeArr or {}) do
-            local sec = timeTb[2] - timeTb[1]
-            if sec > 0 then
-                minuteVal = minuteVal + math.floor(sec / 60)
-            end
+-- 跨服通知可以更换据点的防守阵容数据
+function C2N_Update_Point_Lineup(msg)
+    local human = ObjHuman.onlineUuid[msg.playerUuid]
+    if not human then
+        local db = RoleDBLogic.getDb(msg.playerUuid)
+        if not db then
+            return
         end
-
-        return minuteVal
+        human = {}
+        human.db = db
     end
 
-    if not unionOccupyInfo.playerUuidArr or #unionOccupyInfo.playerUuidArr <= 0 then
-        return
+    local anotherWorlBattle = human.db.anotherWorlBattle
+    if not anotherWorlBattle or not anotherWorlBattle.formation then
+        return Broadcast.sendErr(human, Lang.AB_NOT_OCCUPY_POINT)
     end
 
-    local itemList = {}
-    local item_185_Id = 185
-    local item_185_Num = 0
-    item_185_Num = item_185_Num + (unionOccupyInfo.occuoyPointNum or 0) -- 待优化
-
-    for _, cityInfo in ipairs(unionOccupyInfo.occupyCityArr) do
-        local cityId = cityInfo[1]
-        local occupyTimeArr = cityInfo[2]
-        local isOccupy = cityInfo[3]
-        local cityCfg = AnotherWorldBattleConfig.city[cityId]
-
-        local totalMinVal = calcMins(occupyTimeArr)
-        if totalMinVal > 0 then
-            local itemId, itemNum = cityCfg.cityAward[1], cityCfg.cityAward[2]
-            itemList[itemId] = totalMinVal * itemNum
-        end
-
-        if cityCfg and isOccupy then
-            if cityCfg.isBaseCity == 1 then
-                item_185_Num = item_185_Num + 20
-            else
-                if cityCfg.cityLv == 2 then
-                    item_185_Num = item_185_Num + 2
-                elseif cityCfg.cityLv == 3 then
-                    item_185_Num = item_185_Num + 3
-                elseif cityCfg.cityLv == 4 then
-                    item_185_Num = item_185_Num + 5
-                elseif cityCfg.cityLv == 5 then
-                    item_185_Num = item_185_Num + 20
-                end
-            end
-        end
+    local cityId = msg.targetCityId
+    local pointIdx = msg.targetPointIdx
+    if not anotherWorlBattle.formation[cityId] or not anotherWorlBattle.formation[cityId][pointIdx] then
+        return
     end
 
-    if item_185_Num > 0 then
-        itemList[item_185_Id] = item_185_Num
-    end
+    local pointLinupData = anotherWorlBattle.formation[cityId][pointIdx]
+    pointLinupData.list = msg.heroList
+    pointLinupData.helpList = msg.helpList
+    pointLinupData.formation = msg.formation
 
-    local itemArr = {}
-    for itemId, itemNum in pairs(itemList) do
-        itemArr[#itemArr+1] = { itemId, itemNum }
-    end
-
-    local awardObjArr = {}
-    for _, playerUuid in ipairs(unionOccupyInfo.playerUuidArr) do
-        awardObjArr[#awardObjArr+1] = {playerUuid, itemArr}
+    if not human.fd then
+        ObjHuman.save(human)
     end
 
-    return awardObjArr
+    sendDefHeroArr(human)
+    Broadcast.sendCenter(human, Lang.AB_UPDATE_LINEUP_SUCC)
 end
 
-
--- 发奖
+-- 跨服通知给玩家发奖
 function C2N_IssueReward(msg)
-    local awardObjArr = genAwardObjArr(msg.unionOccupyInfo)
+    -- 删除公会参加异界之战活动时间
+    UnionLogic.UpdateJoinAbTime(msg.unionId, nil)
 
+    -- 发奖
+    local awardObjArr, occupyCityInfo = genAwardObjArr(msg.unionOccupyInfo)
     if awardObjArr then
         local issueRewardQueue = createRewardQueue()
+        issueRewardQueue.extraInfo = occupyCityInfo
 
         for _, obj in ipairs(awardObjArr) do
             issueRewardQueue:add(obj)
         end
-
         issueRewardQueue:insertDB()
     end
 end
@@ -1176,17 +1384,15 @@ function onFightBegin(human, cbParam, combatType, param)
         return
     end
 
-    local attrList = {
-        [RoleDefine.HURT_RATE] = 1000,
-        [RoleDefine.JIANSHANG_RATE] = 1000,
-    }
+    local gatherAttrs = AnotherWorldBattleConfig.var[1].gatherAttrs
 
     for index = 1, CombatDefine.COMBAT_HERO_CNT do
         local atkPos = CombatLogic.getPos(CombatDefine.ATTACK_SIDE, index)
         local atkObj = CombatImpl.objList[atkPos]
 
         if atkObj then
-            for attrId, attrVal in pairs(attrList) do
+            for _, atrrTb in ipairs(gatherAttrs) do
+                local attrId, attrVal = atrrTb[1], atrrTb[2]
                 atkObj.sysAttr[attrId] = (atkObj.sysAttr[attrId] or 0) + attrVal
             end
             atkObj.isSysAttrChange = true
@@ -1195,9 +1401,16 @@ function onFightBegin(human, cbParam, combatType, param)
 end
 
 function onFightEnd(human, result, type, cbParam, combatInfo)
-    if result == CombatDefine.RESULT_WIN then
-        challenge_Win(human, {cityId = human.AB_Battle_Cache.cityId, pointIdx = human.AB_Battle_Cache.pointIdx})
-    end
+    -- if result == CombatDefine.RESULT_WIN then
+    --     challenge_Win(human, {cityId = human.AB_Battle_Cache.cityId, pointIdx = human.AB_Battle_Cache.pointIdx})
+    -- end
+    local args = {
+        cityId = human.AB_Battle_Cache.cityId,
+        pointIdx = human.AB_Battle_Cache.pointIdx,
+        challengeRes = result
+    }
 
     human.AB_Battle_Cache = nil
+
+    challenge_End(human, args)
 end

+ 5 - 1
script/module/anotherWorldBattle/Handler.lua

@@ -43,13 +43,17 @@ function CG_AB_PLAYER_RANK_QUERY(human, msg)
 end
 
 function CG_AB_GARHER(human, msg)
-    AnotherWorldBattleNS.AB_Gather(human, msg.cityId)
+    AnotherWorldBattleNS.AB_Gather(human, msg.cityId, msg.opType)
 end
 
 function CG_AB_POINT_CHAllENGE(human, msg)
     AnotherWorldBattleNS.AB_Try_Challenge_Point(human, msg.cityId, msg.pointIdx)
 end
 
+function CG_AB_UPDATE_LINEUP(human, msg)
+    AnotherWorldBattleNS.AB_Update_Lineup(human, msg)
+end
+
 
 -------------------------------------------------异界寻宝------------------------------------------
 

+ 34 - 8
script/module/anotherWorldBattle/Proto.lua

@@ -9,6 +9,7 @@ AB_CITY_INFO = {
     {"occupyPointNum",  1,      "byte"},    -- 我方占领该城池的据点数量
     {"occupyUnionName", 1,      "string"},  -- 占领城池的公会名字, 没有则为 ""
     {"adJoinCityArr",   4,      "int"},     -- 与当前城池相邻的城池Id列表
+    {"cityState",       1,      "byte"},    -- 城池被占领状态, 0-全是npc, 1-被同一个公会占领 2-被不同公会占领
 }
 
 
@@ -16,7 +17,7 @@ AB_POINT_BASE_INFO = {
     {"occupyUnionName",  1,      "string"},  -- 占领据点的玩家的公会名字, 没有则为 ""
     {"occupyPlayerName", 1,      "string"},  -- 占领据点的玩家名字
     {"power",            1,      "double"},  -- 防守者战力
-    {"isCanChallenge",   1,      "byte"},    -- 是否能挑战
+    {"state",            1,      "byte"},    -- 0为不能挑战,1为可以挑战,2为可以防守布阵
 }
 
 
@@ -26,6 +27,8 @@ AB_HERO_BASE_INFO = {
     {"heroLv",          1,      "int"},     -- 英雄等级
     {"heroCamp",        1,      "int"},     -- 英雄种族
     {"heroIcon",        1,      "int"},     -- 英雄头像
+    {"heroId",          1,      "int"},     -- 英雄Id
+    {"heroQuality",     1,      "byte"},    -- 英雄品质
 }
 
 
@@ -37,6 +40,7 @@ AB_PLAYER_OCCUPY_POINT_INFO = {
     {"pointIdx",        1,      "byte"},    -- 据点索引
     {"power",           1,      "double"},  -- 防守战力
     {"heroArr",         6,      AB_HERO_BASE_INFO},   -- 防守者英雄阵容数据
+    {"cityId",          1,      "int"},    -- 城池Id
 }
 
 
@@ -78,7 +82,10 @@ CG_AB_ALLCITY_QUERY = {}
 GC_AB_ALLCITY_QUERY = {
     {"cityArr",            50,      AB_CITY_INFO}, -- 所有城池数据数组
     {"myBaseCityId",       1,      "short"},     -- 自己公会的出生点, 没有则为0
-    {"myOccupyCityArr",    43,     "short"},     -- 自己公会占领的城池列表
+    {"myOccupyCityArr",    41,     "short"},     -- 自己公会占领的城池列表
+    {"hasPointNum",        1,      "byte"},      -- 玩家当前占领的据点数量
+    {"challengeTimes",     1,      "byte"},      -- 玩家当前挑战次数
+    {"leftTime",           1,      "int"},       -- 距离下一次增加挑战次数的秒数, 挑战次数达到最大/玩家公会没有参加时, 该值为0
 }
 
 
@@ -92,7 +99,7 @@ GC_AB_CITY_DETAILED_QUERY = {
     {"cityLv",          1,      "byte"},    -- 城池等级
     {"cityIconId",      1,      "int"},     -- 城池造型 Id
     {"cityAward",       1,      ItemData},  -- 城池普通情况下每分钟产出道具信息
-    {"myUnionAward",    1,      ItemData},  -- 我方占领所有城池累计每分钟产出道具信息, 没有占领城池则数量为0
+    {"myUnionAward",    1,      ItemData},  -- 我方占领所有据点累计每分钟产出道具信息, 没有占领城池则数量为0
     {"pointArr",        5,      AB_POINT_BASE_INFO}, -- 城池据点信息
     {"gatherState",     1,      "byte"},    -- 0-不能集结, 1-可集结, 2-已集结
 }
@@ -111,7 +118,7 @@ GC_AB_POINT_DETAILEDINFO_QUERY = {
     {"headFrame",       1,      "int"},     -- 防守者头像框
     {"defLv",           1,      "int"},     -- 防守者等级
     {"heroArr",         6,      AB_HERO_BASE_INFO},     -- 防守者英雄阵容数据
-    {"isCanChallenge",  1,      "byte"},    -- 是否能挑战
+    {"state",           1,      "byte"},    -- 0为不能挑战,1为可以挑战,2为可以防守布阵
 }
 
 
@@ -135,7 +142,7 @@ GC_AB_BASECITY_QUERY = {
 -- 查询玩家占领的据点
 CG_AB_MY_OCCUPY_POINT_QUERY = {}
 GC_AB_MY_OCCUPY_POINT_QUERY = {
-    {"myPointArr",      10,     AB_PLAYER_OCCUPY_POINT_INFO},     -- 玩家占领的据点数据
+    {"myPointArr",      15,     AB_PLAYER_OCCUPY_POINT_INFO},     -- 玩家占领的据点数据
 }
 
 
@@ -152,8 +159,9 @@ GC_AB_DEF_HERO_QUERY = {
 -- 查询公会排行榜
 CG_AB_UNION_RANK_QUERY = {}
 GC_AB_UNION_RANK_QUERY = {
-    {"unionRankArr",           50,      AB_UNION_RANK_INFO},  -- 所有排行榜数据
+    {"unionRankArr",           8,      AB_UNION_RANK_INFO},  -- 所有排行榜数据
     {"myUnionRank",            1,      "byte"},             -- 我的公会排名
+    {"myData",                 1,      AB_UNION_RANK_INFO},  -- 我的公会排名
 }
 
 
@@ -163,11 +171,18 @@ CG_AB_PLAYER_RANK_QUERY = {}
 GC_AB_PLAYER_RANK_QUERY = {
     {"playerRankArr",           50,      AB_PLAYER_RANK_INFO},  -- 所有排行榜数据
     {"myRank",                  1,      "byte"},             -- 我的排名
+    {"myData",                  1,      AB_PLAYER_RANK_INFO},  -- 我的排名
 }
 
--- 发起集结
+-- 发起/取消集结
 CG_AB_GARHER = {
-    {"cityId",          1,      "int"},     -- 集结的目标城池Id
+    {"cityId",          1,      "int"},     -- 目标城池Id
+    {"opType",          1,      "byte"},    -- 操作类型, 1-集结, 2-取消集结
+}
+GC_AB_GARHER = {
+    {"cityId",          1,      "int"},     -- 目标城池Id
+    {"cityName",        1,      "string"},  -- 城池名字
+    {"opType",          1,      "byte"},    -- 操作类型, 1-集结, 2-取消集结
 }
 
 
@@ -177,6 +192,17 @@ CG_AB_POINT_CHAllENGE = {
     {"pointIdx",        1,      "byte"},    -- 据点索引
 }
 
+-- 更换某个据点的防守阵容
+CG_AB_UPDATE_LINEUP = {
+    {"type",	    1,		"byte"},--阵容类型
+	{"formation",	1,	    "short"},--阵法
+	{"heroList"	,	1,		"string"},--上阵英雄
+	{"helpList"	,	1,		"string"},--辅助对象
+    {"cityId",      1,      "int"},     -- 城池Id
+    {"pointIdx",    1,      "byte"},    -- 据点索引
+}
+
+
 
 
 -- 异界寻宝查询

+ 9 - 0
script/module/chat/ChatUnion.lua

@@ -52,4 +52,13 @@ function chatUnionRedBag(human)
     content.msg = str
 
     return ChatLogic.chat(human, content, ChatHandler.CHAT_UNION_RED_BAG)
+end
+
+-- Òì½çÖ®Õ½¼¯½á
+function chatUnionGather(human, str)
+    local content = {}
+    content.msgType = ChatHandler.CHAT_TYPE_UNION
+    content.msg = str
+
+    return ChatLogic.chat(human, content, ChatHandler.CHAT_UNION_AB_HATHER)
 end

+ 5 - 0
script/module/chat/Handler.lua

@@ -14,6 +14,7 @@ local HeroExcel = require("excel.hero")
 local RoleLogic = require("role.RoleLogic")
 local CharRecord = require("chat.ChatRecord")
 local MiddleCommonLogic = require("middle.MiddleCommonLogic")
+local ChatUnion = require("chat.ChatUnion")
 local Config = require("Config")
 
 -- 聊天频道
@@ -32,6 +33,7 @@ CHAT_UNION_FIGHT    = 1         -- 公会战
 CHAT_UNION_ECTYPE   = 2         -- 公会副本
 CHAT_UNION_RED_BAG  = 3         -- 公会红包
 CHAT_UNION_ZHAOMU   = 4         -- 公会招募
+CHAT_UNION_AB_HATHER  = 8		-- 公会异界之战集结
 CHAT_HERO_SHARE     = 5         -- 英雄聊天分享
 CHAT_FIGHT_SHARE    = 6         -- 战斗记录聊天分享
 CHAT_ITEM_SHARE     = 7         -- 道具聊天分享
@@ -190,3 +192,6 @@ function CG_CHAT_FRIEND_RECORD_DEL(human,msg)
     CharRecord.delFriendChatRecord(human,msg.uuid)
 end
 
+function CG_CHAT_AB_GATHER(human,msg)
+	ChatUnion.chatUnionGather(human, msg.str)
+end

+ 5 - 0
script/module/chat/Proto.lua

@@ -143,4 +143,9 @@ CG_CHAT_FRIEND_RECORD_DEL = {
 -- 登录发送聊天未读总数
 GC_CHAT_NOT_READ_ALL = {
     {"notRead",1,"int"},                -- 所有频道未读总数
+}
+
+-- 公会集结异界之战
+CG_CHAT_AB_GATHER = {
+    {"str",       	1,   "string"},
 }

+ 2 - 2
script/module/combat/CombatPosLogic.lua

@@ -150,7 +150,7 @@ end
 
 
 -- 可否更新阵容
-local function checkUpdatePos(human, msg)
+function CheckUpdatePos(human, msg)
     if msg.type == CombatDefine.COMBAT_TYPE4 then
         if not JjcGodWarLogic.checkCanPos(human) then return end
     end
@@ -250,7 +250,7 @@ end
 -- 更新上阵信息
 function updatePos(human, msg)
 	local combatType = msg.type
-	local canUpdate,heroList,helpList = checkUpdatePos(human,msg)
+	local canUpdate,heroList,helpList = CheckUpdatePos(human,msg)
 	if not canUpdate then
 		return Broadcast.sendErr(human, Lang.COMBAT_POS__ERR)
 	end

+ 43 - 4
script/module/union/UnionLogic.lua

@@ -78,12 +78,18 @@ UNION_CHANGE_OP_3 = 3     -- 解散公会
 local AnotherWorldBattleNS
 
 -- 如果异界之战处于战斗阶段,并且本公会参加了, 则不能做踢人等操作
-local function getAbState(union)
+local function isCanOperation(union)
     if not union.joinAnotherWorldBattleTi then
         return true
     end
-    
+
     AnotherWorldBattleNS = AnotherWorldBattleNS or require("anotherWorldBattle.AnotherWorldBattleNS")
+    local isRun = AnotherWorldBattleNS.IsRuning(union.joinAnotherWorldBattleTi)
+    if isRun then
+        return false
+    end
+
+    return true
 end
 
 
@@ -462,6 +468,11 @@ function dismissUnion(human)
     --     return Broadcast.sendErr(human, Lang.UNION_IS_WARRING)
     -- end
 
+    local res = isCanOperation(union)
+    if not res then
+        return Broadcast.sendErr(human, Lang.AB_CANNOT_OPERATION)
+    end
+
     UnionDBLogic.delUnion(union._id)
     onLeaveUnion(union._id, human.db._id, nil, MailDefine.MAIL_ID_UNION_DISMISS) 
     if not human.db.leaveUnionLimit then
@@ -516,6 +527,12 @@ function applyJoinUnion(human, unionUuid)
             end
         end
 	else
+    
+        local res = isCanOperation(union)
+        if not res then
+            return
+        end
+
 		-- 自动同意
 		human.db.unionUuid = union._id
         isJoin = true
@@ -561,6 +578,11 @@ function agreeJoinUnion(human, uuid, isArgee)
     end
     local isJoin = false
     if isArgee == 1 then
+        local res = isCanOperation(union)
+        if not res then
+            return Broadcast.sendErr(human, Lang.AB_CANNOT_OPERATION)
+        end
+
         local config = getUnionConfig(union.lv)
         if union.curCnt >= config.maxCnt then -- 人数满了
             return Broadcast.sendErr(human, Lang.UNION_CNT_IS_OVER)
@@ -644,6 +666,11 @@ function expelPlayer(human, uuid)
         return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_OTHER)
     end
 
+    local res = isCanOperation(union)
+    if not res then
+        return Broadcast.sendErr(human, Lang.AB_CANNOT_OPERATION)
+    end
+
     UnionDBLogic.delUnionMember(union, uuid, true)
     onLeaveUnion(union._id, uuid, 2, MailDefine.MAIL_ID_UNION_LEAVE)
     sendMemberUpdate(union)
@@ -667,6 +694,12 @@ function leaveUnion(human)
         return Broadcast.sendErr(human, Lang.UNION_LEVEL_ERR_LEADER)
     end
 
+    local res = isCanOperation(union)
+    if not res then
+        return Broadcast.sendErr(human, Lang.AB_CANNOT_OPERATION)
+    end
+
+
     UnionDBLogic.delUnionMember(union, human.db._id)
     onLeaveUnion(union._id, human.db._id)
     if not human.db.leaveUnionLimit then
@@ -1425,15 +1458,21 @@ end
 function UpdateMemberPower(human)
     local union = UnionDBLogic.getUnion(human.db.unionUuid)
     UnionDBLogic.MemberPowerChange(union)
+
+    local union = UnionDBLogic.getUnion(human.db.unionUuid)
+    if union.joinAnotherWorldBattleTi then
+        AnotherWorldBattleNS = AnotherWorldBattleNS or require("anotherWorldBattle.AnotherWorldBattleNS")
+        AnotherWorldBattleNS.UnionPowerChange(human.db.unionUuid, union.zhandouli)
+    end
 end
 
 -- 成功报名异界之战
-function Join_AB_Succ(unionId)
+function UpdateJoinAbTime(unionId, newTime)
     local union = UnionDBLogic.getUnion(unionId)
     if not union then
         return
     end
 
-    union.joinAnotherWorldBattleTi = os.time()
+    union.joinAnotherWorldBattleTi = newTime
     UnionDBLogic.updateUnionData(union)
 end

+ 14 - 14
script/module/yunying/YunYingLogic.lua

@@ -108,7 +108,7 @@ local function initYYInfo(yyID, config)
         if YYFUNCINFO[funcID] then
            -- 如果 funcID 已经存在,说明可能是在热更新时重复初始化,或者配置有重复
            -- 先清理旧的,然后继续初始化
-           print("WARNING: funcID "..funcID.." already exists in YYFUNCINFO, clearing old data")
+        --    print("WARNING: funcID "..funcID.." already exists in YYFUNCINFO, clearing old data")
            YYFUNCINFO[funcID] = nil
         end
 
@@ -254,7 +254,7 @@ function handleAbs7MiddleReturn(fd,msg)
             if now >= config.realStartTime and now < config.realEndTime then
                 config.actId = turns[1] or 0
                 config.adIcon = ad[1] or 0
-                print("handleAbs7 act is started!!",Config.SVR_INDEX,msg.funcID,config.actId)
+                -- print("handleAbs7 act is started!!",Config.SVR_INDEX,msg.funcID,config.actId)
                 actStart = true
             end
         end
@@ -525,19 +525,19 @@ function sendGroupList(human, panelID)
     end
     
     if not actID or actID < 1 then
-        print("[sendGroupList] not found actID for panelID="..panelID)
+        -- print("[sendGroupList] not found actID for panelID="..panelID)
         return
     end
     
     -- 通过运营ID获取运营信息
     YYInfo = ID2YYInfo[actID]
     if not YYInfo then
-        print("[sendGroupList] YYInfo not found for actID="..actID..", panelID="..panelID)
+        -- print("[sendGroupList] YYInfo not found for actID="..actID..", panelID="..panelID)
         return
     end
     
     if not isOpen(YYInfo, human, true) then
-        print("[sendGroupList] YYInfo not open for actID="..actID..", panelID="..panelID)
+        -- print("[sendGroupList] YYInfo not open for actID="..actID..", panelID="..panelID)
         return
     end
 
@@ -553,7 +553,7 @@ function sendGroupList(human, panelID)
         local funcConfig = getFuncConfig(funcID)
         
         if not funcConfig then
-            print("[sendGroupList] funcConfig is nil for funcID="..funcID)
+            -- print("[sendGroupList] funcConfig is nil for funcID="..funcID)
             goto continue
         end
         
@@ -562,8 +562,8 @@ function sendGroupList(human, panelID)
             goto continue
         end
 
-        print("[sendGroupList] processing funcID="..funcID..", panelID="..funcConfig.panelID..", requestPanelID="..panelID..", isMainPanel="..tostring(isMainPanel))
-        print("[sendGroupList] YYInfo.moduleList[funcID]="..tostring(YYInfo.moduleList[funcID]))
+        -- print("[sendGroupList] processing funcID="..funcID..", panelID="..funcConfig.panelID..", requestPanelID="..panelID..", isMainPanel="..tostring(isMainPanel))
+        -- print("[sendGroupList] YYInfo.moduleList[funcID]="..tostring(YYInfo.moduleList[funcID]))
 
         local state = false
         local endTime = nil
@@ -579,19 +579,19 @@ function sendGroupList(human, panelID)
                     state = false
                 end
                 if not state then
-                    print("[sendGroupList] funcID="..funcID.." isOpen returned false/nil, panelID="..funcConfig.panelID)
+                    -- print("[sendGroupList] funcID="..funcID.." isOpen returned false/nil, panelID="..funcConfig.panelID)
                 else
-                    print("[sendGroupList] funcID="..funcID.." isOpen returned true, panelID="..funcConfig.panelID)
+                    -- print("[sendGroupList] funcID="..funcID.." isOpen returned true, panelID="..funcConfig.panelID)
                 end
                 if endTime then
                    leftTime = endTime - os.time()
                 end
             else
-                print("[sendGroupList] funcID="..funcID.." moduleList is nil or isOpen is nil, setting state=true")
+                -- print("[sendGroupList] funcID="..funcID.." moduleList is nil or isOpen is nil, setting state=true")
                 state = true
             end
         else
-            print("[sendGroupList] player lv="..human.db.lv.." < openLv="..funcConfig.openLv.." for funcID="..funcID)
+            -- print("[sendGroupList] player lv="..human.db.lv.." < openLv="..funcConfig.openLv.." for funcID="..funcID)
         end
 
         if state then
@@ -615,13 +615,13 @@ function sendGroupList(human, panelID)
             net.panelID = funcConfig.panelID
             net.effect = funcConfig.effect
             net.param = funcID
-            print("[sendGroupList] added funcID="..funcID.." to list, panelID="..panelID)
+            -- print("[sendGroupList] added funcID="..funcID.." to list, panelID="..panelID)
         end
         
         ::continue::
     end
     
-    print("[sendGroupList] sending list with count="..msgRet.list[0]..", panelID="..panelID)
+    -- print("[sendGroupList] sending list with count="..msgRet.list[0]..", panelID="..panelID)
     Msg.send(msgRet, human.fd)
 end