From a573a1cf90e06715a3da3ed76427e5b2794c06a8 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 31 十二月 2024 14:50:55 +0800
Subject: [PATCH] 10350 【后端】【越南】【英文】【BT】【砍树】跨服竞技场优化(跨服排位)

---
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py |  444 +++++++++++++++++++++++++++++++------------------------
 1 files changed, 252 insertions(+), 192 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
index 1dc3178..294786f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
@@ -38,6 +38,7 @@
 import datetime
 import random
 import time
+import json
 
 Def_CrossChampionshipPlayerMax = 64 # 最大玩家数
 Def_CrossChampionshipPlayerWFCount = 8 # 胜负排位所需玩家数
@@ -52,6 +53,7 @@
 value3:playerIDA        玩家IDA
 value4:playerIDB        玩家IDB
 value5:winPlayerID      获胜玩家ID
+strValue3:battleDict    镜像PK场次结果 {"玩家ID":[[第1场胜负,加积分,...], ...], ...}
 '''
 
 Def_RecType_CrossChampionshipGuess = ShareDefine.Def_UniversalGameRecType_CrossChampionshipGuess
@@ -238,6 +240,7 @@
         self.playerIDA = 0
         self.playerIDB = 0
         self.winPlayerID = 0
+        self.playerBatDict = {} # 镜像PK场次结果 {"玩家ID":[[第1场胜负,加积分,...], ...], ...}
         
         # 不存档
         self.roomID = 0
@@ -247,7 +250,7 @@
     
     def GetString(self):
         return {"overTime":self.overTime, "zoneID":self.zoneID, "groupMark":self.groupMark, "battleNum":self.battleNum,
-                "playerIDA":self.playerIDA, "playerIDB":self.playerIDB, "winPlayerID":self.winPlayerID}
+                "playerIDA":self.playerIDA, "playerIDB":self.playerIDB, "winPlayerID":self.winPlayerID, "playerBatDict":self.playerBatDict}
         
     def SetAttr(self, attrDict):
         for k, v in attrDict.items():
@@ -287,7 +290,24 @@
             GameWorld.Log("无该跨服排位争霸赛对战场次信息: groupMark=%s,battleNum=%s" % (groupMark, battleNum))
             
         # 不可能执行的代码,方便 . 出提示代码
-        if False:
+        if not battle and False:
+            battle = ChampionshipBattle()
+        return battle
+    
+    def GetBattleByPlayerID(self, groupMark, playerID):
+        battle = None
+        if groupMark in self.battleInfo:
+            battleDict = self.battleInfo[groupMark]
+            for bat in battleDict.values():
+                if playerID == bat.playerIDA or playerID == bat.playerIDB:
+                    battle = bat
+                    break
+                
+        if not battle:
+            GameWorld.Log("无该跨服排位争霸赛对战场次信息: groupMark=%s,playerID=%s" % (groupMark, playerID))
+            
+        # 不可能执行的代码,方便 . 出提示代码
+        if not battle and False:
             battle = ChampionshipBattle()
         return battle
     
@@ -331,6 +351,19 @@
     
     # 机器人
     if not obj or not hasattr(obj, "playerName"):
+        return
+    
+    packDataObj = PyDataManager.GetDBPlayerPackDataManager().GetPlayerPackObj(playerID)
+    # 如果有打包数据,以打包数据为准
+    if packDataObj:
+        obj.accID = packDataObj.accID
+        obj.playerName = packDataObj.playerName
+        obj.job = packDataObj.job
+        obj.lv = packDataObj.lv
+        obj.fightPower = packDataObj.fightPower
+        obj.realmLV = packDataObj.realmLV
+        obj.face = packDataObj.face
+        obj.facePic = packDataObj.facePic
         return
     
     if playerID < 10000:
@@ -448,7 +481,11 @@
         playerIDA = recData.GetValue3()
         playerIDB = recData.GetValue4()
         winPlayerID = recData.GetValue5()
-        
+        strValue3 = recData.GetStrValue3()
+        try:
+            playerBatDict = eval(strValue3) if strValue3 else {}
+        except:
+            playerBatDict = {}
         #if not playerIDA and not playerIDB:
         #    continue
         
@@ -466,6 +503,7 @@
             battle.playerIDA = playerIDA
             battle.playerIDB = playerIDB
             battle.winPlayerID = winPlayerID
+            battle.playerBatDict = playerBatDict
             pkZoneMgr.AddBattle(groupMark, battleNum, battle)
             GameWorld.Log("分组玩家: zoneID=%s,groupMark=%s,battleNum=%s,playerIDA=%s,playerIDB=%s,winPlayerID=%s" 
                           % (zoneID, groupMark, battleNum, playerIDA, playerIDB, winPlayerID))
@@ -608,6 +646,9 @@
                 recData.SetValue3(batObj.playerIDA)
                 recData.SetValue4(batObj.playerIDB)
                 recData.SetValue5(batObj.winPlayerID)
+                strValue3 = "%s" % batObj.playerBatDict
+                strValue3 = strValue3.replace(" ", "")
+                recData.SetStrValue3(strValue3)
                 
     GameWorld.Log("保存跨服排位玩家竞猜记录!")
     universalRecMgr.Delete(Def_RecType_CrossChampionshipGuess)
@@ -852,14 +893,14 @@
     PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipErrorDo, 1)
     return "OK"
 
-def OnMinuteProcess(curMinute):
+def OnMinuteProcess(curMinute=None):
     if not GameWorld.IsCrossServer():
         return
     
     Dispose_CrossChampionshipState()
     
     # 每半小时存档一次
-    if curMinute % 30 == 0:
+    if curMinute != None and curMinute % 30 == 0:
         SaveChampionshipData()
     return
 
@@ -1085,31 +1126,32 @@
     
     # 生成参赛玩家名单: 取跨服PK所有分区 championshipSeason 赛季的数据
     if championshipSeason:
-        crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()
+        crossBillboardMgr = PyDataManager.GetCrossBillboardManager()
         for zoneID in hisZoneIDList:
-            billboardList = crossPKBillboardMgr.GetCrossPKBillboardInfo(zoneID, championshipSeason)[0]
-            GameWorld.Log("zoneID=%s,billboardListLen=%s" % (zoneID, len(billboardList)))
-            if not billboardList:
+            groupValue1, groupValue2 = zoneID, championshipSeason
+            billboardObj = crossBillboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_CrossRealmPK, groupValue1, groupValue2)
+            billboardDataLen = billboardObj.GetCount()
+            GameWorld.Log("zoneID=%s,championshipSeason=%s,billboardDataLen=%s" % (zoneID, championshipSeason, billboardDataLen))
+            if not billboardDataLen:
                 # 没有玩家上榜的不处理
                 continue
             pkZoneMgr = champMgr.GetChampPKZoneMgr(zoneID, True)
-            battlePlayerList = billboardList[:Def_CrossChampionshipPlayerMax]
-            for num, billboardData in enumerate(battlePlayerList, 1):
-                playerID = billboardData.PlayerID
+            for index in range(Def_CrossChampionshipPlayerMax):
+                if index >= billboardDataLen:
+                    break
+                billboardData = billboardObj.At(index)
+                playerID = billboardData.ID
+                
                 batPlayer = ChampionshipBatPlayer()
                 batPlayer.zoneID = zoneID
                 batPlayer.playerID = playerID
-                batPlayer.playerName = billboardData.PlayerName
-                batPlayer.job = billboardData.Job
-                batPlayer.fightPower = billboardData.FightPower
-                batPlayer.realmLV = billboardData.RealmLV
                 pkZoneMgr.playerDict[playerID] = batPlayer
                 
                 getPlayer = pkZoneMgr.GetBatPlayer(playerID)
                 dataDict = {"zoneID":zoneID, "playerID":playerID, "accID":getPlayer.accID, "fightPower":getPlayer.fightPower}
                 DR_CrossChampionshipPK("StartPlayer", dataDict)
                 
-                GameWorld.Log("    AddBattlePlayer num=%s,playerID=%s,accID=%s,fightPower=%s" % (num, playerID, getPlayer.accID, getPlayer.fightPower))
+                GameWorld.Log("    AddBattlePlayer index=%s,playerID=%s,accID=%s,fightPower=%s" % (index, playerID, getPlayer.accID, getPlayer.fightPower))
                 
     GameWorld.Log("=============================================================")
     Send_CrossServerMsg_ChampionshipState(newAct=True)
@@ -1369,52 +1411,7 @@
 
 def DoCrossChampionshipStartEnter(state):
     ## 开启进场处理逻辑
-    if state not in ShareDefine.CrossChampionshipEnterStateInfo:
-        return
-    groupMark = ShareDefine.CrossChampionshipEnterStateInfo[state]
-    mapIndex = 0
-    mapIDList = IpyGameDataPY.GetFuncEvalCfg("CrossChamFB", 3)
-    GameWorld.Log("跨服排位争霸赛开启进场副本: groupMark=%s,mapIDList=%s" % (groupMark, mapIDList))
-    champMgr = GetChampionshipMgr()
-    pkZoneIDList = champMgr.GetChampPKZoneIDList()
-    for zoneID in pkZoneIDList:
-        pkZoneMgr = champMgr.GetChampPKZoneMgr(zoneID)
-        if not pkZoneMgr:
-            continue
-        if groupMark not in pkZoneMgr.battleInfo:
-            GameWorld.Log("该跨服排位争霸赛分区没有对战组! zoneID=%s,groupMark=%s" % (zoneID, groupMark), zoneID)
-            continue
-        if mapIndex >= len(mapIDList):
-            GameWorld.ErrLog("该跨服排位争霸赛分区没有分配对战地图! zoneID=%s,mapIndex=%s" % (zoneID, mapIndex), zoneID)
-            continue
-        mapID = mapIDList[mapIndex]
-        mapIndex += 1
-        copyMapID = 0
-        copyPropertyList = []
-        battleDict = pkZoneMgr.battleInfo[groupMark]
-        for battleNum in battleDict.keys():
-            batObj = pkZoneMgr.GetBattle(groupMark, battleNum)
-            if not batObj:
-                continue
-            roomID = GetChampionshipPKRoomID(zoneID, groupMark, battleNum)
-            copyPropertyList.append([copyMapID, roomID])
-            batObj.mapID = mapID
-            batObj.roomID = roomID
-            batObj.copyMapID = copyMapID
-            
-            # 添加开启分线数据
-            realMapID = mapID
-            copyMapObj = PlayerFB.CrossCopyMapInfo(zoneID, ChConfig.Def_FBMapID_CrossChampionship, 0)
-            copyMapObj.realMapID = realMapID
-            copyMapObj.copyMapID = copyMapID
-            key = (realMapID, copyMapID)
-            PyGameData.g_crossDynamicLineCopyMapInfo[key] = copyMapObj
-            GameWorld.Log("    对战房间! zoneID=%s,groupMark=%s,battleNum=%s,playerIDA=%s,playerIDB=%s,roomID=%s,mapID=%s,copyMapID=%s" 
-                          % (zoneID, groupMark, battleNum, batObj.playerIDA, batObj.playerIDB, roomID, mapID, copyMapID))
-            copyMapID += 1
-            
-        PlayerFB.SendMapOpenFBEx(mapID, copyPropertyList)
-        
+    # 改为镜像战斗,废弃开地图房间
     return
 
 def Sync_CrossChampionshipDataToClientServer(serverGroupID=0):
@@ -1549,6 +1546,21 @@
         GameWorld.Log("子服重置跨服排位争霸赛对战数据! dbID=%s,ID=%s,PKZoneIDList=%s,prePKZoneIDList=%s" % (dbID, ID, PKZoneIDList, prePKZoneIDList))
         for zoneID in PKZoneIDList:
             champMgr.GetChampPKZoneMgr(zoneID)
+            
+    OnMapServerInitOK()
+    return
+
+def OnMapServerInitOK():
+    # 通知地图服务器状态
+    
+    if GameWorld.IsCrossServer():
+        return
+    
+    State = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipState)
+    StateError = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipStateError)
+    
+    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossChampionshipState, State)
+    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossChampionshipStateError, StateError)
     return
 
 def CrossServerMsg_ChampionshipPlayer(msgData):
@@ -1575,7 +1587,8 @@
                     pkZoneMgr.playerDict[playerID] = batPlayer
                 batPlayer.SetAttr(attrDict)
                 
-        if isSync:
+    if isSync:
+        for zoneID in zoneBatPlayerInfo.keys():
             Sync_ChampionshipPKZoneGroupInfo(zoneID)
             
     return
@@ -1702,95 +1715,84 @@
     
     return
 
-def OnRequestChampionshipVSRoom(playerID, serverGroupID):
-    ## 请求进入排位对战房间
-    
-    stateError = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipStateError)
-    if stateError:
-        GameWorld.ErrLog("跨服排位状态已经异常无法进入! stateError=%s" % stateError, playerID)
-        return
-    
-    state = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipState)
-    if state not in ShareDefine.CrossChampionshipEnterStateInfo:
-        GameWorld.ErrLog("当前状态非跨服排位战斗状态无法进入: state=%s" % state, playerID)
-        return
-    groupMark = ShareDefine.CrossChampionshipEnterStateInfo[state]
-    
-    mapPosList = IpyGameDataPY.GetFuncEvalCfg("CrossChamFB", 2)
-    if not mapPosList:
-        GameWorld.ErrLog("没有配置跨服排位对战地图进入坐标! CrossChamFB 数值2")
-        return
-    
-    roomID = 0
-    vsRoomDict = {}
-    
-    champMgr = GetChampionshipMgr()
-    for zoneID in champMgr.GetChampPKZoneIDList():
-        pkZoneMgr = champMgr.GetChampPKZoneMgr(zoneID)
-        if not pkZoneMgr:
-            continue
-        if groupMark not in pkZoneMgr.battleInfo:
-            continue
-        battleDict = pkZoneMgr.battleInfo[groupMark]
-        for battleNum in battleDict.keys():
-            batObj = pkZoneMgr.GetBattle(groupMark, battleNum)
-            if not batObj:
-                continue
-            
-            if playerID == batObj.playerIDA:# or batObj.playerIDA == 496607:
-                factionIndex = 0
-            elif playerID == batObj.playerIDB:# or batObj.playerIDB == 489566:
-                factionIndex = 1
-            else:
-                continue
-            
-            if not batObj.mapID:
-                GameWorld.ErrLog("该跨服排位对战没有分配对战地图,无法进入! groupMark=%s,battleNum=%s" % (groupMark, battleNum), playerID)
-                return
-            roomID = batObj.roomID
-            realMapID = batObj.mapID
-            copyMapID = batObj.copyMapID
-            key = (realMapID, copyMapID)
-            if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
-                GameWorld.ErrLog("该跨服排位对战没有分配对战地图线路,无法进入! groupMark=%s,battleNum=%s,realMapID=%s,copyMapID=%s" 
-                                 % (groupMark, battleNum, realMapID, copyMapID), playerID)
-                return
-            copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]
-            if copyMapObj.openState != IPY_PlayerDefine.fbosOpen:
-                GameWorld.Log("该跨服排位对战分配的地图线路非开启状态,无法进入! groupMark=%s,battleNum=%s,realMapID=%s,copyMapID=%s,openState=%s" 
-                              % (groupMark, battleNum, realMapID, copyMapID, copyMapObj.openState), playerID)
-                return
-            
-            posX, posY = mapPosList[factionIndex] if len(mapPosList) > factionIndex else mapPosList[0]
-            
-            registerMap = ChConfig.Def_FBMapID_CrossChampionship
-            dataMapID = realMapID
-            
-            vsRoomDict = {roomID:{playerID:{"regMapInfo":[registerMap, realMapID, dataMapID, copyMapID, posX, posY]}}}
-            GameWorld.Log("玩家请求跨服排位对战组: zoneID=%s,groupMark=%s,battleNum=%s,roomID=%s" 
-                          % (zoneID, groupMark, battleNum, roomID), playerID)
-            break
-        
-    if not roomID or not vsRoomDict:
-        GameWorld.ErrLog("找不到玩家跨服排位对战组: state=%s,groupMark=%s" % (state, groupMark), playerID)
-        return
-    PlayerFB.Send_CrossServerMsg_EnterVSRoomRet(vsRoomDict, [serverGroupID])
-    return
+#def OnRequestChampionshipVSRoom(playerID, serverGroupID):
+#    ## 请求进入排位对战房间
+#    
+#    stateError = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipStateError)
+#    if stateError:
+#        GameWorld.ErrLog("跨服排位状态已经异常无法进入! stateError=%s" % stateError, playerID)
+#        return
+#    
+#    state = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipState)
+#    if state not in ShareDefine.CrossChampionshipEnterStateInfo:
+#        GameWorld.ErrLog("当前状态非跨服排位战斗状态无法进入: state=%s" % state, playerID)
+#        return
+#    groupMark = ShareDefine.CrossChampionshipEnterStateInfo[state]
+#    
+#    mapPosList = IpyGameDataPY.GetFuncEvalCfg("CrossChamFB", 2)
+#    if not mapPosList:
+#        GameWorld.ErrLog("没有配置跨服排位对战地图进入坐标! CrossChamFB 数值2")
+#        return
+#    
+#    roomID = 0
+#    vsRoomDict = {}
+#    
+#    champMgr = GetChampionshipMgr()
+#    for zoneID in champMgr.GetChampPKZoneIDList():
+#        pkZoneMgr = champMgr.GetChampPKZoneMgr(zoneID)
+#        if not pkZoneMgr:
+#            continue
+#        if groupMark not in pkZoneMgr.battleInfo:
+#            continue
+#        battleDict = pkZoneMgr.battleInfo[groupMark]
+#        for battleNum in battleDict.keys():
+#            batObj = pkZoneMgr.GetBattle(groupMark, battleNum)
+#            if not batObj:
+#                continue
+#            
+#            if playerID == batObj.playerIDA:# or batObj.playerIDA == 496607:
+#                factionIndex = 0
+#            elif playerID == batObj.playerIDB:# or batObj.playerIDB == 489566:
+#                factionIndex = 1
+#            else:
+#                continue
+#            
+#            if not batObj.mapID:
+#                GameWorld.ErrLog("该跨服排位对战没有分配对战地图,无法进入! groupMark=%s,battleNum=%s" % (groupMark, battleNum), playerID)
+#                return
+#            roomID = batObj.roomID
+#            realMapID = batObj.mapID
+#            copyMapID = batObj.copyMapID
+#            key = (realMapID, copyMapID)
+#            if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
+#                GameWorld.ErrLog("该跨服排位对战没有分配对战地图线路,无法进入! groupMark=%s,battleNum=%s,realMapID=%s,copyMapID=%s" 
+#                                 % (groupMark, battleNum, realMapID, copyMapID), playerID)
+#                return
+#            copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]
+#            if copyMapObj.openState != IPY_PlayerDefine.fbosOpen:
+#                GameWorld.Log("该跨服排位对战分配的地图线路非开启状态,无法进入! groupMark=%s,battleNum=%s,realMapID=%s,copyMapID=%s,openState=%s" 
+#                              % (groupMark, battleNum, realMapID, copyMapID, copyMapObj.openState), playerID)
+#                return
+#            
+#            posX, posY = mapPosList[factionIndex] if len(mapPosList) > factionIndex else mapPosList[0]
+#            
+#            registerMap = ChConfig.Def_FBMapID_CrossChampionship
+#            dataMapID = realMapID
+#            
+#            vsRoomDict = {roomID:{playerID:{"regMapInfo":[registerMap, realMapID, dataMapID, copyMapID, posX, posY]}}}
+#            GameWorld.Log("玩家请求跨服排位对战组: zoneID=%s,groupMark=%s,battleNum=%s,roomID=%s" 
+#                          % (zoneID, groupMark, battleNum, roomID), playerID)
+#            break
+#        
+#    if not roomID or not vsRoomDict:
+#        GameWorld.ErrLog("找不到玩家跨服排位对战组: state=%s,groupMark=%s" % (state, groupMark), playerID)
+#        return
+#    PlayerFB.Send_CrossServerMsg_EnterVSRoomRet(vsRoomDict, [serverGroupID])
+#    return
 
 def GetChampionshipPKRoomID(zoneID, groupMark, battleNum): return int("%d%03d%02d" % (zoneID, groupMark, battleNum))
-def MapServer_CrossChampionshipPKOver(infoList, tick):
-    ## 收到MapServer副本跨服排位PK结果同步
-    
-    roomID, winnerID, loserID, roundWinnerIDList, overType = infoList
-    zoneID = roomID / 100000
-    groupMark = roomID % 100000 / 100
-    battleNum = roomID % 100
-    GameWorld.Log("=== 收到MapServer_跨服排位PK战斗结果: zoneID=%s,groupMark=%s,battleNum=%s,roomID=%s,winnerID=%s,loserID=%s,roundWinnerIDList=%s,overType=%s" 
-                  % (zoneID, groupMark, battleNum, roomID, winnerID, loserID, roundWinnerIDList, overType), roomID)
-    DoBattleOverLogic(zoneID, groupMark, battleNum, winnerID, loserID, roundWinnerIDList, overType)
-    return
 
-def DoBattleOverLogic(zoneID, groupMark, battleNum, winnerID=0, loserID=0, roundWinnerIDList=None, overType=0):
+def DoBattleOverLogic(zoneID, groupMark, battleNum):
     ## 执行对战结算逻辑
     
     if not zoneID:
@@ -1809,10 +1811,7 @@
     if not battleObj:
         return
     
-    if roundWinnerIDList == None:
-        roundWinnerIDList = []
-        
-    roomID = battleObj.roomID
+    roomID = GetChampionshipPKRoomID(zoneID, groupMark, battleNum) # 改版后roomID没用了,仅作为日志输出用
     if battleObj.overTime:
         GameWorld.ErrLog("跨服排位PK对战已经结算过了,不重复结算! zoneID=%s,groupMark=%s,battleNum=%s,winPlayerID=%s,overTime=%s" 
                          % (zoneID, groupMark, battleNum, battleObj.winPlayerID, GameWorld.ChangeTimeNumToStr(battleObj.overTime)), roomID)
@@ -1821,11 +1820,30 @@
     playerIDA = battleObj.playerIDA
     playerIDB = battleObj.playerIDB
     roomPlayerIDList = [playerIDA, playerIDB]
-    GameWorld.Log("结算跨服排位PK战斗结果: zoneID=%s,groupMark=%s,battleNum=%s,playerIDA=%s,playerIDB=%s,roomPlayerIDList=%s" 
+    GameWorld.Log("结算跨服排位PK胜负结果: zoneID=%s,groupMark=%s,battleNum=%s,playerIDA=%s,playerIDB=%s,roomPlayerIDList=%s" 
                   % (zoneID, groupMark, battleNum, playerIDA, playerIDB, roomPlayerIDList), roomID)
     
+    winnerID, loserID = 0, 0
     if playerIDA and playerIDB:
-        if not winnerID and not loserID:
+        totalScoreDict = {}
+        for batPlayerID, batRetList in battleObj.playerBatDict.items():
+            for retInfo in batRetList:
+                if not retInfo or len(retInfo) < 2:
+                    continue
+                addScore = retInfo[1]
+                totalScoreDict[batPlayerID] = totalScoreDict.get(batPlayerID, 0) + addScore
+        playerScoreA = totalScoreDict.get(playerIDA, 0)
+        playerScoreB = totalScoreDict.get(playerIDB, 0)
+        GameWorld.Log("    总积分: %s, %s" % (totalScoreDict, battleObj.playerBatDict), roomID)
+        if playerScoreA > playerScoreB:
+            winnerID = playerIDA
+            loserID = playerIDB
+            GameWorld.Log("    跨服排位赛玩家累计总分高者获胜! winner is playerIDA=%s,loserID=%s" % (playerIDA, loserID), roomID)
+        elif playerScoreB > playerScoreA:
+            winnerID = playerIDB
+            loserID = playerIDA
+            GameWorld.Log("    跨服排位赛玩家累计总分高者获胜! winner is playerIDB=%s,loserID=%s" % (playerIDB, loserID), roomID)
+        else: # 平分
             playerA = pkZoneMgr.GetBatPlayer(playerIDA)
             playerB = pkZoneMgr.GetBatPlayer(playerIDB)
             fightPowerA = playerA.fightPower if playerA else 0
@@ -1843,18 +1861,7 @@
                 winnerID, loserID = roomPlayerIDList
                 GameWorld.Log("    跨服排位赛对战地图没有玩家参与或没有胜负玩家,战力相同随机玩家获胜! fightPowerA=%s(%s) = fightPowerB=%s(%s),winnerID=%s,loserID=%s" 
                               % (fightPowerA, playerIDA, fightPowerB, playerIDB, winnerID, loserID), roomID)
-        elif not loserID:
-            for roomPlayerID in roomPlayerIDList:
-                if roomPlayerID != winnerID:
-                    loserID = roomPlayerID
-                    GameWorld.Log("    跨服排位赛对战地图没有失败玩家,默认对方为失败玩家! loserID=%s" % loserID, roomID)
-                    break
                 
-        if not winnerID or winnerID not in roomPlayerIDList or loserID not in roomPlayerIDList:
-            GameWorld.ErrLog("跨服排位赛PK房间胜负玩家异常,不结算! roomID=%s,winnerID=%s,loserID=%s,roomPlayerIDList=%s" 
-                             % (roomID, winnerID, loserID, roomPlayerIDList), roomID)
-            return
-        
     elif playerIDA:
         winnerID = playerIDA
         loserID = playerIDB
@@ -1874,9 +1881,6 @@
     winner = pkZoneMgr.GetBatPlayer(winnerID)
     loser = pkZoneMgr.GetBatPlayer(loserID)
     
-    winnerName = winner.playerName if winner else str(winnerID)
-    loserName = loser.playerName if loser else str(loserID)
-    
     # 决赛可获取最终名次
     playerRankInfo = {}
     if groupMark == 2:
@@ -1894,8 +1898,7 @@
     wAwardItemList, fAwardItemList = [], []
     if wfAwardItemList and len(wfAwardItemList) == 2:
         wAwardItemList, fAwardItemList = wfAwardItemList
-                
-    timeStr = GameWorld.GetCurrentDataTimeStr()
+        
     # 结算
     for playerID in [winnerID, loserID]:
         if not playerID:
@@ -1904,15 +1907,15 @@
         if playerID == winnerID:
             addItemList = wAwardItemList
             mailTypeKey = "CrossChampionshipPKWin%s" % groupMark
-            tagPlayerID, tagPlayerName = loserID, loserName
+            tagPlayerID = loserID
         else:
             addItemList = fAwardItemList
             mailTypeKey = "CrossChampionshipPKLose%s" % groupMark
-            tagPlayerID, tagPlayerName = winnerID, winnerName
+            tagPlayerID = winnerID
             
         rank = playerRankInfo.get(playerID, 0)
-        GameWorld.Log("    结算跨服排位赛玩家奖励: zoneID=%s,roomID=%s,groupMark=%s,battleNum=%s,rank=%s,tagPlayerID=%s" 
-                           % (zoneID, roomID, groupMark, battleNum, rank, tagPlayerID), playerID)
+        GameWorld.Log("    结算跨服排位赛玩家奖励: zoneID=%s,groupMark=%s,battleNum=%s,rank=%s,tagPlayerID=%s,addItemList=%s" 
+                           % (zoneID, groupMark, battleNum, rank, tagPlayerID, addItemList), playerID)
         if rank:
             paramList = [rank]
         else:
@@ -1920,30 +1923,84 @@
         playerIDList = [playerID]
         PlayerCompensation.SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList, crossMail=True)
         
-        player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
-        if player:
-            overPack = ChPyNetSendPack.tagGCCrossChampionshipPKOver()
-            overPack.GroupMark = groupMark
-            overPack.TimeStr = timeStr
-            overPack.OverType = overType
-            overPack.WinnerID = winnerID
-            overPack.LoserID = loserID
-            overPack.RoundWinnerID = roundWinnerIDList
-            overPack.RoundCount = len(overPack.RoundWinnerID)
-            overPack.TagName = tagPlayerName
-            overPack.TagNameLen = len(overPack.TagName)
-            overPack.Rank = rank
-            NetPackCommon.SendFakePack(player, overPack)
-            
     # 同步子服
     Send_CrossServerMsg_ChampionshipGroup(battleObj=battleObj)
     
     # 记录流向
     winnerInfo = winner.GetString() if winner else {}
     loserInfo = loser.GetString() if loser else {}
-    dataDict = {"roundWinnerIDList":roundWinnerIDList, "overType":overType, "winner":winnerInfo, "loser":loserInfo, 
+    dataDict = {"winner":winnerInfo, "loser":loserInfo, 
                 "battle":battleObj.GetString(), "playerRankInfo":playerRankInfo}
     DR_CrossChampionshipPK("PKRoomOver", dataDict)    
+    return True
+
+def ClientServerMsg_ChampionshipPKOver(serverGroupID, msgData):
+    ## 收到子服同步的镜像PK结果
+    playerID = msgData["playerID"]
+    tagPlayerID = msgData["tagPlayerID"]
+    funcLineID = msgData["funcLineID"]
+    isWin = msgData["isWin"]
+    addScore = msgData["addScore"]
+    baseScore = msgData["baseScore"]
+    hpScore = msgData["hpScore"]
+    timeScore = msgData["timeScore"]
+    pkCountMax = msgData["pkCountMax"]
+    
+    zoneID = funcLineID / 100
+    groupMark = funcLineID % 100
+    
+    groupMarkList = ShareDefine.CrossChampionshipEnterStateInfo.values()
+    if groupMark not in groupMarkList:
+        GameWorld.ErrLog("跨服排位镜像PK结果分组异常! groupMark=%s" % groupMark, playerID)
+        return
+    
+    champMgr = GetChampionshipMgr()
+    pkZoneMgr = champMgr.GetChampPKZoneMgr(zoneID)
+    if not pkZoneMgr:
+        return
+    battleObj = pkZoneMgr.GetBattleByPlayerID(groupMark, playerID)
+    if not battleObj:
+        GameWorld.ErrLog("跨服排位镜像PK结果玩家不在该排位分组中! zoneID=%s,groupMark=%s" % (zoneID, groupMark), playerID)
+        return
+    battleNum = battleObj.battleNum
+    playerIDA = battleObj.playerIDA
+    playerIDB = battleObj.playerIDB
+    roomPlayerIDList = [playerIDA, playerIDB]
+    # 有轮空的默认不用打
+    if playerID not in roomPlayerIDList or tagPlayerID not in roomPlayerIDList or not tagPlayerID or not playerIDA or not playerIDB:
+        GameWorld.ErrLog("跨服排位镜像PK结果玩家ID错误! zoneID=%s,groupMark=%s,playerID=%s,tagPlayerID=%s,roomPlayerIDList=%s" 
+                         % (zoneID, groupMark, playerID, tagPlayerID, roomPlayerIDList), playerID)
+        return
+    if playerID not in battleObj.playerBatDict:
+        battleObj.playerBatDict[playerID] = []
+    batRetList = battleObj.playerBatDict[playerID]
+    if len(batRetList) >= pkCountMax or not pkCountMax:
+        GameWorld.ErrLog("跨服排位镜像PK结果已达PK次数上限! zoneID=%s,groupMark=%s,playerID=%s,tagPlayerID=%s,batRetList=%s" 
+                         % (zoneID, groupMark, playerID, tagPlayerID, batRetList), playerID)
+        return
+    if battleObj.overTime:
+        GameWorld.ErrLog("跨服排位镜像PK胜负已经结算过了,不再更新PK结果! zoneID=%s,groupMark=%s,battleNum=%s,winPlayerID=%s,overTime=%s" 
+                         % (zoneID, groupMark, battleNum, battleObj.winPlayerID, GameWorld.ChangeTimeNumToStr(battleObj.overTime)), playerID)
+        return
+    
+    isWin = 1 if isWin else 0
+    batRetList.append([isWin, addScore, baseScore, hpScore, timeScore])
+    GameWorld.Log("跨服排位镜像PK结果: zoneID=%s,groupMark=%s,battleNum=%s,playerIDA=%s,playerIDB=%s,batCount=%s,isWin=%s,addScore=%s,baseScore=%s,hpScore=%s,timeScore=%s" 
+                  % (zoneID, groupMark, battleNum, playerIDA, playerIDB, len(batRetList), isWin, addScore, baseScore, hpScore, timeScore), playerID)
+    
+    # 是否都打完所有次数,是的话直接结算胜负
+    isAllOver = True
+    for roomPlayerID in roomPlayerIDList:
+        batList = battleObj.playerBatDict.get(roomPlayerID, [])
+        if len(batList) < pkCountMax:
+            isAllOver = False
+            break
+    if isAllOver:
+        if DoBattleOverLogic(zoneID, groupMark, battleNum):
+            return
+        
+    # 同步子服
+    Send_CrossServerMsg_ChampionshipGroup(battleObj=battleObj)
     return
 
 def DoCrossChampionshipFinalOver():
@@ -2947,11 +3004,14 @@
             battleObj = pkZoneMgr.GetBattle(groupMark, battleNum)
             if not battleObj:
                 continue
+            battleRetDict = {str(k):v for k, v in battleObj.playerBatDict.items()}
             battlePack = ChPyNetSendPack.tagGCCrossChampionshipPKBattle()
             battlePack.BattleNum = battleNum
             battlePack.WinPlayerID = battleObj.winPlayerID
             battlePack.PlayerIDA = battleObj.playerIDA
             battlePack.PlayerIDB = battleObj.playerIDB
+            battlePack.BattleRet = json.dumps(battleRetDict, ensure_ascii=False).replace(" ", "")
+            battlePack.BattleRetLen = len(battlePack.BattleRet)
             groupPack.BattleList.append(battlePack)
         groupPack.BattleCount = len(groupPack.BattleList)
         clientPack.GroupList.append(groupPack)

--
Gitblit v1.8.0