#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package CrossRealmPK  
 | 
#  
 | 
# @todo:¿ç·þPK¾º¼¼³¡  
 | 
# @author hxp  
 | 
# @date 2018-12-21  
 | 
# @version 1.0  
 | 
#  
 | 
# ÏêϸÃèÊö: ¿ç·þPK¾º¼¼³¡  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#"""Version = 2018-12-21 18:00"""  
 | 
#-------------------------------------------------------------------------------  
 | 
  
 | 
import GameWorld  
 | 
import PlayerControl  
 | 
import CrossRealmMsg  
 | 
import CrossRealmPlayer  
 | 
import ChPyNetSendPack  
 | 
import NetPackCommon  
 | 
import IpyGameDataPY  
 | 
import ShareDefine  
 | 
import PyGameData  
 | 
import ChConfig  
 | 
  
 | 
import operator  
 | 
import random  
 | 
      
 | 
PKPlayerState_Matching = 0  
 | 
PKPlayerState_Fighting = 1  
 | 
  
 | 
class CrossPKPlayer():  
 | 
    ## ¿ç·þPKÍæ¼ÒÀà  
 | 
      
 | 
    def __init__(self):  
 | 
        self.accID = ""  
 | 
        self.playerID = 0  
 | 
        self.playerName = ""  
 | 
        self.playerJob = 0  
 | 
        self.playerLV = 0  
 | 
        self.maxHP = 0  
 | 
        self.fightPower = 0  
 | 
        self.pkScore = 0  
 | 
        self.danLV = 0  
 | 
        self.matchTick = 0  
 | 
        self.cWinCount = 0 # Á¬Ê¤´ÎÊý  
 | 
        self.ondayScore = 0 # ¹ýÌìʱµÄ»ý·Ö  
 | 
        self.serverGroupID = 0 # ËùÊô·þÎñÆ÷ID£¬Ò»¸ö·þÎñÆ÷IDÓɶà¸ö·þ×é³É  
 | 
        self.pkZoneID = 0 # ËùÊôÈüÇøID£¬Ò»¸öÈüÇøÓɶà¸ö·þÎñÆ÷ID×é³É  
 | 
        self.seasonID = 0 # Èü¼¾ID  
 | 
        return  
 | 
      
 | 
class CrossPKRoom():  
 | 
    ## ¿ç·þPK·¿¼äÀà  
 | 
      
 | 
    def __init__(self):  
 | 
        self.pkZoneID = 0  
 | 
        self.roomID = 0  
 | 
        self.mapID = 0  
 | 
        self.openTick = 0 # ¿ª·¿Ê±¼ä  
 | 
        self.readyTick = 0 # Íæ¼Ò¶¼×¼±¸ºÃµÄʱ¼ä  
 | 
        self.roomState = ShareDefine.Def_VsRoom_State_WaitPlayer # Ä¬ÈÏ״̬  
 | 
        self.roomPlayerIDList = [] # ¶ÔÕ½Íæ¼ÒIDÁÐ±í  
 | 
        self.readyPlayerIDList = [] # ÒѾ׼±¸ºÃµÄÍæ¼ÒIDÁÐ±í  
 | 
        self.isMapOpen = False # µØÍ¼ÊÇ·ñÒѾ¿ªÆô¸Ã·¿¼ä£¬Î´¿ªÆôµÄ·¿¼ä³¬Ê±ºó£¬±¾´ÎÆ¥ÅäÊÓΪÎÞЧ£¬ÓÐÍæ¼Ò½øµØÍ¼²Å»á¿ªÆô¸±±¾·ÖÏß  
 | 
        return  
 | 
      
 | 
################################################################################  
 | 
  
 | 
def OnPlayerLogin(curPlayer):  
 | 
    if not GameWorld.IsCrossServer():  
 | 
        __OnLoginNotifyPKOverInfo(curPlayer)  
 | 
    return  
 | 
  
 | 
## Íæ¼ÒÀëÏß´¦Àí  
 | 
def OnLeaveServer(curPlayer):      
 | 
    # ·¢ËÍÈ¡ÏûÆ¥Åä  
 | 
    SendCancelCrossRealmPKMatch(curPlayer, "PlayerDisconnect")  
 | 
    return  
 | 
  
 | 
def IsCrossRealmPKOpen():  
 | 
    ## ¿ç·þPKÆ¥ÅäÈüÊÇ·ñ¿ªÆô  
 | 
    return 1  
 | 
    return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState) == ChConfig.Def_Action_Open  
 | 
  
 | 
def ClientServerMsg_ServerInitOK(serverGroupID, tick):  
 | 
    ## ×Ó·þÆô¶¯³É¹¦  
 | 
    GameWorld.Log("ͬ²½¿ç·þPKÈü¼¾ÐÅÏ¢¼°×´Ì¬µ½×Ó·þ: serverGroupID=%s" % (serverGroupID))  
 | 
    seasonInfo = {"SeasonID":1, "SeasonState":1, "MatchState":1}  
 | 
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, [serverGroupID])  
 | 
    return  
 | 
  
 | 
def SendCancelCrossRealmPKMatch(curPlayer, reason):     
 | 
    ## ·¢ËÍÈ¡ÏûÆ¥Åä  
 | 
      
 | 
    # ¿ç·þ·þÎñÆ÷²»´¦Àí  
 | 
    if GameWorld.IsCrossServer():  
 | 
        return  
 | 
      
 | 
    # ·Ç»î¶¯Öв»´¦Àí  
 | 
    if not IsCrossRealmPKOpen():  
 | 
        return  
 | 
      
 | 
#    # Èç¹ûÊÇÒªµÇ½µ½¿ç·þ·þÎñÆ÷µÄ£¬²»·¢ËÍÈ¡Ïû  
 | 
#    if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IsLoginToMergeServer):  
 | 
#        GameWorld.DebugLog("±¾´ÎÀëÏßΪҪµÇ½¿ç·þ·þÎñÆ÷µÄ×Ô¶¯ÀëÏßÐÐΪ£¬²»·¢ËÍÈ¡ÏûÆ¥Å䣡", curPlayer.GetPlayerID())  
 | 
#        curPlayer.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)  
 | 
#        return  
 | 
  
 | 
    vsRoomID = curPlayer.GetVsRoomId()  
 | 
    if vsRoomID and PlayerControl.GetCrossRealmState(curPlayer) == 1:  
 | 
        GameWorld.DebugLog("Íæ¼Ò¿ç·þPK״̬£¬²»ÄÜÈ¡ÏûÆ¥Å䣡vsRoomID=%s" % vsRoomID, curPlayer.GetPlayerID())  
 | 
        return  
 | 
      
 | 
    dataMsg = {"accID":curPlayer.GetAccID(), # Õ˺Š 
 | 
               "playerID":curPlayer.GetPlayerID(), # Íæ¼ÒID  
 | 
               "playerName":curPlayer.GetName(), # ¿ç·þ×Ó·þÍæ¼ÒÃû  
 | 
               "reason":reason, # È¡ÏûÔÒò  
 | 
               "vsRoomID":vsRoomID, # ¶ÔÕ½·¿¼äID  
 | 
               }  
 | 
    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKCancel, dataMsg)  
 | 
    PlayerControl.SetVsRoomId(curPlayer, 0)  
 | 
    GameWorld.Log("·¢ËÍÈ¡Ïû¿ç·þPKÆ¥Åäµ½¿ç·þ·þÎñÆ÷£ºdataMsg=%s" % str(dataMsg), curPlayer.GetPlayerID())  
 | 
    return  
 | 
  
 | 
def ClientServerMsg_PKMatch(serverGroupID, playerInfoDict, tick):  
 | 
    ## ÇëÇóÆ¥Åä  
 | 
      
 | 
    if not GameWorld.IsMergeServer():  
 | 
        GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦Àí¿ç·þPKÆ¥ÅäÇëÇó£¡")  
 | 
        return  
 | 
      
 | 
    if not IsCrossRealmPKOpen():  
 | 
        GameWorld.Log("¿ç·þÆ¥ÅäPK»î¶¯Î´¿ªÆô£¬²»ÔÊÐíÇëÇóÆ¥Å䣡")  
 | 
        return  
 | 
      
 | 
    seasonID = playerInfoDict["seasonID"] # Èü¼¾ID  
 | 
    pkZoneID = playerInfoDict["pkZoneID"] # ËùÊôÈüÇø  
 | 
    accID = playerInfoDict["accID"] # ½ÇÉ«Õ˺Š 
 | 
    playerID = playerInfoDict["playerID"] # ½ÇÉ«ID  
 | 
    playerName = playerInfoDict["playerName"] # Íæ¼ÒÃû  
 | 
    job = playerInfoDict["playerJob"] # Ö°Òµ  
 | 
    playerLV = playerInfoDict["playerLV"] # Ö°Òµ  
 | 
    maxHP = playerInfoDict["maxHP"] # Ö°Òµ  
 | 
    fightPower = playerInfoDict["fightPower"] # Õ½¶·Á¦  
 | 
    pkScore = playerInfoDict["pkScore"] # µ±Ç°»ý·Ö  
 | 
    danLV = playerInfoDict["danLV"] # µ±Ç°¶Îλ  
 | 
    cWinCount = playerInfoDict["cWinCount"] # Á¬Ê¤´ÎÊý  
 | 
    ondayScore = playerInfoDict["ondayScore"] # ¹ýÌìʱµÄ»ý·Ö  
 | 
      
 | 
    zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  
 | 
#    if playerID in zoneMatchPlayerList:  
 | 
#        GameWorld.Log("Íæ¼ÒÕýÔÚÆ¥ÅäÖУ¬ÎÞ·¨Öظ´·¢ÆðÆ¥Å䣡playerID=%s,accID=%s" % (playerID, accID))  
 | 
#        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])  
 | 
#        return  
 | 
#    if playerID in PyGameData.g_crossPKPlayerDict:  
 | 
#        GameWorld.Log("Íæ¼ÒÕýÔÚÕ½¶·ÖУ¬ÎÞ·¨Öظ´·¢ÆðÆ¥Å䣡playerID=%s,accID=%s" % (playerID, accID))  
 | 
#        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, -2], [serverGroupID])  
 | 
#        return  
 | 
      
 | 
    pkPlayer = CrossPKPlayer()  
 | 
    pkPlayer.accID = accID  
 | 
    pkPlayer.playerID = playerID  
 | 
    pkPlayer.playerName = playerName  
 | 
    pkPlayer.playerJob = job  
 | 
    pkPlayer.playerLV = playerLV  
 | 
    pkPlayer.maxHP = maxHP  
 | 
    pkPlayer.pkScore = pkScore  
 | 
    pkPlayer.danLV = danLV  
 | 
    pkPlayer.fightPower = fightPower  
 | 
    pkPlayer.matchTick = tick  
 | 
    pkPlayer.cWinCount = cWinCount  
 | 
    pkPlayer.ondayScore = ondayScore  
 | 
    pkPlayer.serverGroupID = serverGroupID  
 | 
    pkPlayer.pkZoneID = pkZoneID  
 | 
    pkPlayer.seasonID = seasonID  
 | 
    PyGameData.g_crossPKPlayerDict[playerID] = pkPlayer  
 | 
      
 | 
    # ¼ÓÈëÈüÇøÆ¥ÅäÁÐ±í  
 | 
    zoneMatchPlayerList.append(playerID)  
 | 
    PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList  
 | 
      
 | 
    GameWorld.Log("Íæ¼Ò¼ÓÈëÆ¥Åä: seasonID=%s,pkZoneID=%s,serverGroupID=%s,accID=%s,playerID=%s,pkScore=%s,fightPower=%s,cWinCount=%s,len(zoneMatchPlayerList)=%s"   
 | 
                  % (seasonID, pkZoneID, serverGroupID, accID, playerID, pkScore, fightPower, cWinCount, len(zoneMatchPlayerList)))  
 | 
      
 | 
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])  
 | 
    return  
 | 
  
 | 
def ClientServerMsg_PKCancel(playerInfoDict, tick):  
 | 
    ## È¡ÏûÆ¥Åä  
 | 
      
 | 
    if not GameWorld.IsMergeServer():  
 | 
        GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦ÀíÈ¡Ïû¿ç·þPKÆ¥Å䣡")  
 | 
        return  
 | 
      
 | 
    # ·Ç»î¶¯Öв»´¦Àí  
 | 
    if not IsCrossRealmPKOpen():  
 | 
        return  
 | 
      
 | 
    accID = playerInfoDict["accID"] # ½ÇÉ«Õ˺Š 
 | 
    playerID = playerInfoDict["playerID"] # Íæ¼ÒID  
 | 
    reason = playerInfoDict["reason"] # È¡ÏûÔÒò  
 | 
    vsRoomID = playerInfoDict["vsRoomID"] # ËùÊô¶ÔÕ½·¿¼äID  
 | 
    if vsRoomID in PyGameData.g_crossPKRoomDict:  
 | 
        pkRoom = PyGameData.g_crossPKRoomDict[vsRoomID]  
 | 
        if pkRoom.isMapOpen or pkRoom.readyTick:  
 | 
            GameWorld.Log("¿ç·þ¶ÔÕ½·¿¼äÒѾ¿ªÆôÁËÏß·£¬»òÕßË«·½Êý¾Ý¶¼ÒÑ´«ÊäÍê±Ï£¬²»¿ÉÔÙÈ¡ÏûÆ¥Å䣡vsRoomID=%s" % vsRoomID)  
 | 
            return  
 | 
          
 | 
    GameWorld.Log("Íæ¼ÒÈ¡ÏûÆ¥Åä: reason=%s,accID=%s,playerID=%s,vsRoomID=%s" % (reason, accID, playerID, vsRoomID))  
 | 
      
 | 
    pkZoneID = 0  
 | 
    if playerID in PyGameData.g_crossPKPlayerDict:  
 | 
        pkPlayer = PyGameData.g_crossPKPlayerDict.pop(playerID)  
 | 
        pkZoneID = pkPlayer.pkZoneID  
 | 
        GameWorld.Log("    ÒƳýPKÍæ¼Ò: pkZoneID=%s,accID=%s,playerID=%s" % (pkZoneID, accID, playerID))  
 | 
          
 | 
    zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  
 | 
    if playerID in zoneMatchPlayerList:  
 | 
        zoneMatchPlayerList.remove(playerID)  
 | 
        GameWorld.Log("    ´ÓÆ¥Åä¶ÓÁÐÖÐɾ³ý£¬Æ¥Åä¶ÓÁÐÊ£ÓàÈËÊý=%s" % (len(zoneMatchPlayerList)))  
 | 
          
 | 
    #È¡ÏûËùÓдæÔÚ¸ÃÍæ¼ÒµÄ·¿¼ä£¬×Ó·þ²»Ò»¶¨ÖªµÀÍæ¼Òµ±Ç°×îÐÂËùÊô·¿¼äID£¬ ¹ÊÖ»ÄÜͨ¹ý±éÀúɾ³ýÒÑ¾ÎªÍæ¼Ò´´½¨µÄ·¿¼ä  
 | 
    for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():  
 | 
        if playerID not in pkRoom.roomPlayerIDList:  
 | 
            continue  
 | 
          
 | 
        for roomPlayerID in pkRoom.roomPlayerIDList:  
 | 
            if roomPlayerID == playerID:  
 | 
                GameWorld.Log("    ×Ô¼º²»´¦Àí: roomID=%s,playerID=%s" % (roomID, playerID))  
 | 
                continue  
 | 
              
 | 
            zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  
 | 
            zoneMatchPlayerList.append(roomPlayerID)  
 | 
            PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList  
 | 
            GameWorld.Log("    ½«Ö®Ç°Æ¥ÅäµÄ¶ÔÊÖÖØÐ¼ÓÈëÆ¥Åä¶ÓÁÐ: roomID=%s,roomPlayerID=%s,µ±Ç°Æ¥ÅäÈËÊý=%s"   
 | 
                          % (roomID, roomPlayerID, len(zoneMatchPlayerList)))  
 | 
              
 | 
        PyGameData.g_crossPKRoomDict.pop(roomID)  
 | 
        GameWorld.Log("    ÒƳý·¿¼ä: popRoomID=%s" % (roomID))  
 | 
        break  
 | 
      
 | 
    return  
 | 
  
 | 
def ClientServerMsg_PKPrepareOK(playerInfoDict, tick):  
 | 
    ## Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK  
 | 
      
 | 
    if not GameWorld.IsMergeServer():  
 | 
        GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦ÀíÈ¡Ïû¿ç·þPKÆ¥Å䣡")  
 | 
        return  
 | 
      
 | 
    accID = playerInfoDict["accID"] # Íæ¼ÒÕ˺Š 
 | 
    playerID = playerInfoDict["playerID"] # Íæ¼ÒID  
 | 
    vsRoomID = playerInfoDict["vsRoomID"] # ËùÊô¶ÔÕ½·¿¼äID  
 | 
    if playerID not in PyGameData.g_crossPKPlayerDict:  
 | 
        GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«ÕÒ²»µ½¸Ã¶ÔÕ½Íæ¼ÒÐÅÏ¢£¡vsRoomID=%s,playerID=%s" % (vsRoomID, playerID))  
 | 
        return  
 | 
    #pkPlayer = PyGameData.g_crossPKPlayerDict[playerID]  
 | 
          
 | 
    if vsRoomID not in PyGameData.g_crossPKRoomDict:  
 | 
        GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«ÕÒ²»µ½¸Ã¶ÔÕ½·¿¼ä(%s)£¡¿ÉÄܶÔÊÖÒÑÈ¡Ïû£¡" % vsRoomID)  
 | 
        return  
 | 
    vsRoom = PyGameData.g_crossPKRoomDict[vsRoomID]  
 | 
      
 | 
    if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:  
 | 
        GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«·¿¼ä״̬·ÇµÈ´ý״̬, state=%s£¡" % vsRoom.roomState)  
 | 
        return  
 | 
      
 | 
    if playerID not in vsRoom.readyPlayerIDList:  
 | 
        vsRoom.readyPlayerIDList.append(playerID)  
 | 
          
 | 
    GameWorld.Log("Íæ¼Ò¿ç·þPK×¼±¸Íê±Ï: accID=%s,playerID=%s,vsRoomID=%s" % (accID, playerID, vsRoomID))  
 | 
    return  
 | 
  
 | 
def __ReadyOKRoomPlayerProcess(tick):  
 | 
    ## Íæ¼Ò¿ç·þPKÒÑ×¼±¸ºÃµÄ·¿¼ä´¦Àí  
 | 
      
 | 
    #GameWorld.Log("===ÒÑ×¼±¸ºÃµÄ¶ÔÕ½·¿¼ä´¦Àí===")  
 | 
    serverGroupIDList = []  
 | 
    sendReadyOKRoomList = []  
 | 
    for roomID, vsRoom in PyGameData.g_crossPKRoomDict.items():  
 | 
          
 | 
        # ·ÇµÈ´ý״̬µÄ·¿¼ä²»´¦Àí  
 | 
        if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:  
 | 
            continue  
 | 
          
 | 
        if not vsRoom.roomPlayerIDList:  
 | 
            continue  
 | 
          
 | 
        pkZoneID = 0  
 | 
        isAllReady = True  
 | 
        roomGroupIDList = []  
 | 
        readyMemberDict = {} # ÒÑ×¼±¸ºÃµÄÍæ¼ÒÐÅÏ¢  
 | 
        for roomPlayerID in vsRoom.roomPlayerIDList:  
 | 
            if roomPlayerID not in vsRoom.readyPlayerIDList or roomPlayerID not in PyGameData.g_crossPKPlayerDict:  
 | 
                isAllReady = False  
 | 
                break  
 | 
            roomPlayer = PyGameData.g_crossPKPlayerDict[roomPlayerID]  
 | 
            pkZoneID = roomPlayer.pkZoneID  
 | 
            roomGroupIDList.append(roomPlayer.serverGroupID)  
 | 
            readyMemberDict[roomPlayerID] = {"ServerGroupID":roomPlayer.serverGroupID, "Name":roomPlayer.playerName,   
 | 
                                             "Job":roomPlayer.playerJob, "LV":roomPlayer.playerLV, "MaxHP":roomPlayer.maxHP}  
 | 
                      
 | 
        if not isAllReady:  
 | 
            continue  
 | 
        vsRoom.roomState = ShareDefine.Def_VsRoom_State_PrepareFight  
 | 
        vsRoom.readyTick = tick  
 | 
        GameWorld.Log("    ×¼±¸ºÃµÄ·¿¼ä: pkZoneID=%s,roomID=%s,mapID=%s,readyMemberDict=%s" % (pkZoneID, roomID, vsRoom.mapID, str(readyMemberDict)))  
 | 
          
 | 
        sendReadyOKRoomList.append([roomID, readyMemberDict])  
 | 
        serverGroupIDList += roomGroupIDList  
 | 
          
 | 
    # ½«ÒÑ×¼±¸ºÃµÄ·¿¼ä¹ã²¥µ½×Ó·þ  
 | 
    if sendReadyOKRoomList:  
 | 
        GameWorld.Log("    ÒÑ×¼±¸ºÃµÄ¶ÔÕ½·¿¼äÊý: %s" % len(sendReadyOKRoomList))  
 | 
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKReadyOKRoomList, sendReadyOKRoomList, serverGroupIDList)  
 | 
          
 | 
    return  
 | 
  
 | 
def OnPKMatchProcess(tick):  
 | 
    ## Íæ¼Ò¿ç·þPKÆ¥Å䶨ʱ´¦ÀíÂß¼  
 | 
      
 | 
    # ·Ç¿ç·þ·þÎñÆ÷²»´¦Àí¿ç·þPKÆ¥ÅäÂß¼  
 | 
    if not GameWorld.IsMergeServer():  
 | 
        return  
 | 
      
 | 
    if not IsCrossRealmPKOpen():  
 | 
        return  
 | 
      
 | 
    # Í¬²½×Ó·þÅÅÐаñ  
 | 
    #__SyncBillboardToClientServer(False, tick)  
 | 
      
 | 
    processTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 1) * 1000  
 | 
    processTickKey = "PKMatchLastTick"  
 | 
    lastProcessTick = GameWorld.GetGameWorld().GetDictByKey(processTickKey)  
 | 
    if tick - lastProcessTick < processTick:  
 | 
        return  
 | 
    GameWorld.GetGameWorld().SetDict(processTickKey, tick)  
 | 
      
 | 
    # ´¦Àí³¬Ê±µÄ·¿¼ä  
 | 
    __DoCheckRoomTimeout(tick)  
 | 
    # Í¨ÖªÒÑ×¼±¸ºÃµÄ·¿¼äÍæ¼Ò¿É½øÈë¿ç·þ  
 | 
    __ReadyOKRoomPlayerProcess(tick)  
 | 
      
 | 
    maxGroupCnt = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 2)  
 | 
    outTimeTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 3) * 1000  
 | 
      
 | 
    # Ã¿¸öÈüÇøµ¥¶ÀÆ¥Åä  
 | 
    for pkZoneID, matchPlayerIDList in PyGameData.g_crossPKZoneMatchPlayerDict.items():  
 | 
        matchPlayerCount = len(matchPlayerIDList)  
 | 
        if matchPlayerCount < 2:  
 | 
            #GameWorld.Log("Æ¥ÅäPKÈËÊý²»×㣬²»´¦Àí£¡pkZoneID=%s, ×ÜÈËÊý:%s" % (pkZoneID, matchPlayerCount))  
 | 
            continue  
 | 
          
 | 
        GameWorld.Log("¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¿ªÊ¼¿ç·þPKÆ¥Åä(pkZoneID=%s, ×ÜÈËÊý:%s)¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï" % (pkZoneID, matchPlayerCount))  
 | 
          
 | 
        matchPlayerList = []  
 | 
        for matchPlayerID in matchPlayerIDList:  
 | 
            if matchPlayerID not in PyGameData.g_crossPKPlayerDict:  
 | 
                continue  
 | 
            matchPlayerList.append(PyGameData.g_crossPKPlayerDict[matchPlayerID])  
 | 
        # °´Æ¥Åäʱ¼ä¡¢»ý·ÖÉýÐòÅÅÐò  
 | 
        matchTickSortList = sorted(matchPlayerList, key=operator.attrgetter("matchTick"))  
 | 
        scoreSortList = sorted(matchPlayerList, key=operator.attrgetter("pkScore"))  
 | 
          
 | 
        matchPlayerVSList = [] # ³É¹¦Æ¥ÅäÍæ¼Ò¶ÔÕ½ÁÐ±í  
 | 
          
 | 
        # ÓÅÏÈÆ¥ÅäµÈ´ý³¬Ê±Íæ¼Ò  
 | 
        __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick)  
 | 
          
 | 
        if len(matchPlayerVSList) < maxGroupCnt:  
 | 
            # ÔÙ°´»ý·Ö¶ÎÆ¥ÅäÍæ¼Ò  
 | 
            __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList)  
 | 
              
 | 
        # ¸ø³É¹¦Æ¥ÅäµÄÍæ¼Ò·ÇÅä¶ÔÕ½·¿¼ä  
 | 
        matchPlayerVSList = matchPlayerVSList[:maxGroupCnt]  
 | 
        __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick)  
 | 
        GameWorld.Log("==========Æ¥Åä½áÊø(×ÜÆ¥Åä¶ÓÎé:%s)==========" % len(matchPlayerVSList))  
 | 
    return  
 | 
  
 | 
  
 | 
def __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick):  
 | 
    '''Æ¥Åä³¬Ê±Íæ¼Ò  
 | 
        Æ¥ÅäÖеÄÍæ¼Ò°´»ý·ÖÅÅÐò£¬×îºóÒ»¸öĬÈÏÆ¥ÅäÉÏÒ»¸ö£¬µÚÒ»¸öĬÈÏÆ¥ÅäÏÂÒ»¸ö£¬ÆäËûÆ¥Åäǰºó»ý·Ö²î¾ø¶ÔÖµ½ÏСµÄÒ»¸ö  
 | 
    '''  
 | 
    GameWorld.Log(" ==ÓÅÏÈÆ¥Å䳬ʱµÈ´ýÍæ¼Ò==×î´óµÈ´ýʱ¼ä:%s, tick=%s" % (outTimeTick, tick))  
 | 
    GameWorld.Log(" scoreSortListLen=%s" % len(scoreSortList))  
 | 
    for i, matchPlayer in enumerate(matchTickSortList):          
 | 
        # Ö»ÓÐÒ»¸öÍæ¼Ò  
 | 
        if len(scoreSortList) <= 1:  
 | 
            GameWorld.Log("    µ±Ç°Íæ¼ÒÊý%s<=1£¬²»ÔÙÆ¥Å䣡" % len(scoreSortList))  
 | 
            break  
 | 
          
 | 
        if tick - matchPlayer.matchTick < outTimeTick:  
 | 
            GameWorld.Log("    i=%s,Íæ¼Òδ³¬Ê±£¬²»ÔÙÆ¥Å䣡" % (i))  
 | 
            break  
 | 
          
 | 
        GameWorld.Log("    i=%s,³¬Ê±Íæ¼Ò, %s-%s=%s >= outTimeTick(%s)"   
 | 
                      % (i, tick, matchPlayer.matchTick, tick - matchPlayer.matchTick, outTimeTick))  
 | 
        # ÒѾ±»Æ¥Åä×ßÁË  
 | 
        if matchPlayer not in scoreSortList:  
 | 
            GameWorld.Log("        ÒѾ±»Æ¥Åä×ßÁË£¡")  
 | 
            continue  
 | 
          
 | 
        outTimeIndex = scoreSortList.index(matchPlayer)  
 | 
        # ×îºóÒ»¸öĬÈÏÆ¥ÅäÉÏÒ»¸ö  
 | 
        if outTimeIndex == len(scoreSortList) - 1:   
 | 
            vsIndex = outTimeIndex - 1  
 | 
            GameWorld.Log("        ³¬Ê±Íæ¼Ò»ý·ÖÅÅÐòË÷Òý%s,×îºóÒ»¸ö,ĬÈÏÆ¥ÅäÉÏÒ»¸öË÷Òý%s£¡" % (outTimeIndex, vsIndex))  
 | 
        # µÚÒ»¸öĬÈÏÆ¥ÅäÏÂÒ»¸ö  
 | 
        elif outTimeIndex == 0:  
 | 
            vsIndex = outTimeIndex + 1  
 | 
            GameWorld.Log("        ³¬Ê±Íæ¼Ò»ý·ÖÅÅÐòË÷Òý%s,µÚÒ»¸ö,ĬÈÏÆ¥ÅäÏÂÒ»¸öË÷Òý%s£¡" % (outTimeIndex, vsIndex))  
 | 
        # ÆäËûÇé¿öÆ¥Åä»ý·Ö½Ï½üµÄÒ»¸ö  
 | 
        else:  
 | 
            preIndex = outTimeIndex - 1  
 | 
            nextIndex = outTimeIndex + 1  
 | 
            prePlayer = scoreSortList[preIndex]  
 | 
            nextPlayer = scoreSortList[nextIndex]  
 | 
            preDiff = abs(prePlayer.pkScore - matchPlayer.pkScore)  
 | 
            nextDiff = abs(matchPlayer.pkScore - nextPlayer.pkScore)  
 | 
            vsIndex = preIndex if preDiff <= nextDiff else nextIndex  
 | 
            GameWorld.Log("        ³¬Ê±Íæ¼Ò»ý·ÖÅÅÐòË÷Òý-»ý·Ö(%s-%s),ÉÏÒ»¸ö(%s-%s),ÏÂÒ»¸ö(%s-%s),preDiff=%s,nextDiff=%s,vsIndex=%s"   
 | 
                          % (outTimeIndex, matchPlayer.pkScore, preIndex, prePlayer.pkScore,  
 | 
                             nextIndex, nextPlayer.pkScore, preDiff, nextDiff, vsIndex))  
 | 
              
 | 
        if outTimeIndex > vsIndex:   
 | 
            scoreSortList.pop(outTimeIndex)  
 | 
            vsPlayer = scoreSortList.pop(vsIndex)  
 | 
        elif outTimeIndex < vsIndex:  
 | 
            vsPlayer = scoreSortList.pop(vsIndex)  
 | 
            scoreSortList.pop(outTimeIndex)  
 | 
        else:  
 | 
            continue  
 | 
          
 | 
        # ¼ÓÈë³É¹¦Æ¥ÅäÁÐ±í  
 | 
        matchPlayerVSList.append([matchPlayer, vsPlayer])  
 | 
          
 | 
    return  
 | 
  
 | 
def __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList):  
 | 
    ''' Æ¥Åä»ý·Ö·Ö¶ÎÍæ¼Ò  
 | 
            Æ¥ÅäÖеÄÍæ¼Ò°´¶Îλ»ý·Ö¹é×飬¹é×éºó£¬Ëæ»ú¶Îλ˳Ðò£¬Ã¿¸ö¶Îλ×éÖеÄÍæ¼ÒËæ»úÁ½Á½PK  
 | 
    '''  
 | 
    GameWorld.Log(" ==Æ¥Åä»ý·Ö·Ö¶ÎÍæ¼Ò== maxGroupCnt=%s,scoreSortListLen=%s" % (maxGroupCnt, len(scoreSortList)))  
 | 
    danPlayerListDict = {} # °´»ý·Ö·Ö¶ÎÁбí·ÖÉ¢Íæ¼Ò  
 | 
    for matchPlayer in scoreSortList:  
 | 
        danLV = matchPlayer.danLV  
 | 
        danPlayerList = danPlayerListDict.get(danLV, [])  
 | 
        danPlayerList.append(matchPlayer)  
 | 
        danPlayerListDict[danLV] = danPlayerList  
 | 
          
 | 
    # °´·Ö¶ÎÍæ¼ÒËæ»úÆ¥Åä  
 | 
    danList = danPlayerListDict.keys()  
 | 
    random.shuffle(danList) # ´òÂÒ¶Îλ˳Ðò  
 | 
      
 | 
    GameWorld.Log("    »ý·Ö·Ö¶Î¸öÊý: %s, %s" % (len(danList), danList))  
 | 
      
 | 
    # ÈÕÖ¾Êä³ö·Ö×éÃ÷ϸ  
 | 
    for danLV in danList:  
 | 
        strList = []  
 | 
        for player in danPlayerListDict[danLV]:  
 | 
            strList.append((player.playerID, player.pkScore, player.fightPower))  
 | 
        GameWorld.Log("        »ý·Ö¶Î×é, danLV=%s, %s" % (danLV, str(strList)))  
 | 
          
 | 
    doCount = 0  
 | 
    while len(matchPlayerVSList) < maxGroupCnt and doCount < maxGroupCnt:  
 | 
        doCount += 1  
 | 
        isMatchOK = False  
 | 
        for danLV in danList:  
 | 
            danPlayerList = danPlayerListDict[danLV]  
 | 
            danPlayerCount = len(danPlayerList)  
 | 
            if danPlayerCount < 2:  
 | 
                GameWorld.Log("    ¶ÎλÈËÊýÉÙÓÚ2¸ö£¬´Ë¶Îλ±¾ÂÖÂÖ¿Õ£¡doCount=%s,danLV=%s" % (doCount, danLV))  
 | 
                continue  
 | 
              
 | 
            vsIndexList = random.sample(xrange(danPlayerCount), 2) # Ëæ»úÈ¡Á½¸öË÷Òý¶ÔÕ½  
 | 
            vsIndexList.sort()  
 | 
            aPlayer = danPlayerList.pop(vsIndexList[1])  
 | 
            bPlayer = danPlayerList.pop(vsIndexList[0])  
 | 
              
 | 
            matchPlayerVSList.append([aPlayer, bPlayer])  
 | 
            isMatchOK = True  
 | 
            GameWorld.Log("    ³É¹¦Æ¥ÅäÍæ¼Ò: aPlayerID=%s,aScore=%s,aFP=%s VS bPlayerID=%s,bScore=%s,bFP=%s"   
 | 
                          % (aPlayer.playerID, aPlayer.pkScore, aPlayer.fightPower, bPlayer.playerID, bPlayer.pkScore, bPlayer.fightPower))  
 | 
              
 | 
            if len(matchPlayerVSList) >= maxGroupCnt:  
 | 
                GameWorld.Log("    ÒѾ´ïµ½×î´óÆ¥ÅäÊý! ÒÑÆ¥Åä¶ÔÕ½Êý=%s, ²»ÔÙÆ¥Å䣡doCount=%s" % (len(matchPlayerVSList), doCount))  
 | 
                break  
 | 
              
 | 
        if not isMatchOK:  
 | 
            GameWorld.Log("    ÒѾûÓÐÂú×ãÆ¥ÅäÌõ¼þµÄÍæ¼Ò! ²»ÔÙÆ¥Å䣡doCount=%s" % (doCount))  
 | 
            break  
 | 
          
 | 
    return  
 | 
  
 | 
def __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick):  
 | 
    ## ÉèÖöÔÕ½·¿¼ä  
 | 
      
 | 
    if not matchPlayerVSList:  
 | 
        return  
 | 
      
 | 
    vsRoomDict = {}  
 | 
    serverGroupIDList = []  
 | 
    zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  
 | 
      
 | 
    mapIDList = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 4)  
 | 
    GameWorld.Log("===¸øÅä¶ÔµÄÍæ¼Ò¿ª·¿¼ä(pkZoneID=%s,Åä¶ÔÊý:%s)===" % (pkZoneID, len(matchPlayerVSList)))  
 | 
    for aPlayer, bPlayer in matchPlayerVSList:  
 | 
          
 | 
        if not aPlayer or not bPlayer:  
 | 
            continue  
 | 
          
 | 
        aPlayerID = aPlayer.playerID  
 | 
        bPlayerID = bPlayer.playerID  
 | 
        if aPlayerID not in PyGameData.g_crossPKPlayerDict or bPlayerID not in PyGameData.g_crossPKPlayerDict:  
 | 
            GameWorld.ErrLog("Íæ¼ÒÆ¥ÅäÊý¾ÝÒì³££¡aPlayerID=%s,bPlayerID=%s" % (aPlayerID, bPlayerID))  
 | 
            continue  
 | 
          
 | 
        roomID = __GetNewRoomID()  
 | 
        if not roomID:  
 | 
            GameWorld.ErrLog("ÎÞ·¨´´½¨·¿¼ä£¡¸Ã·¿¼äÒѾ´æÔÚ£¡PyGameData.g_crossPKRoomID=%s" % PyGameData.g_crossPKRoomID)  
 | 
            continue  
 | 
        mapID = random.choice(mapIDList)  
 | 
          
 | 
        newRoom = CrossPKRoom()  
 | 
        newRoom.pkZoneID = pkZoneID  
 | 
        newRoom.roomID = roomID  
 | 
        newRoom.mapID = mapID  
 | 
        newRoom.openTick = tick  
 | 
        newRoom.roomPlayerIDList = [aPlayerID, bPlayerID]  
 | 
        PyGameData.g_crossPKRoomDict[roomID] = newRoom  
 | 
          
 | 
        aServerGroupID, bServerGroupID = aPlayer.serverGroupID, bPlayer.serverGroupID  
 | 
        GameWorld.Log("    ¿ª·¿:pkZoneID=%s,mapID=%s,roomID=%s,aPlayerID=%s,bPlayerID=%s" % (pkZoneID, mapID, roomID, aPlayerID, bPlayerID))  
 | 
        vsRoomDict[roomID] = [mapID, [[aServerGroupID, aPlayerID], [bServerGroupID, bPlayerID]]]  
 | 
          
 | 
        serverGroupIDList.append(aServerGroupID)  
 | 
        serverGroupIDList.append(bServerGroupID)  
 | 
          
 | 
        # ÒƳýÆ¥Åä¶ÓÁÐ  
 | 
        if aPlayerID in zoneMatchPlayerList:  
 | 
            zoneMatchPlayerList.remove(aPlayerID)  
 | 
        if bPlayerID in zoneMatchPlayerList:  
 | 
            zoneMatchPlayerList.remove(bPlayerID)  
 | 
        PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList  
 | 
          
 | 
    # ½«Æ¥Åä½á¹û¹ã²¥µ½×Ó·þ  
 | 
    if vsRoomDict:  
 | 
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchResult, vsRoomDict, serverGroupIDList)  
 | 
          
 | 
    return  
 | 
  
 | 
def __GetNewRoomID():  
 | 
    ## »ñȡз¿¼äID, ·¿¼äºÅÖ±½Ó×ÔÔö£¬Ò»¶¨²»»áÖØ¸´£¬³ý·Ç×ÔÔöÒ»ÂÖºó·¿¼äID»¹Ã»ÓÐÊÍ·Å  
 | 
    for _ in xrange(100):  
 | 
        newRoomID = PyGameData.g_crossPKRoomID + 1  
 | 
        if newRoomID > 65530:  
 | 
            newRoomID = 1  
 | 
        PyGameData.g_crossPKRoomID = newRoomID  
 | 
        if newRoomID not in PyGameData.g_crossPKRoomDict:  
 | 
            return newRoomID  
 | 
    return 0  
 | 
  
 | 
def __DoCheckRoomTimeout(tick):  
 | 
    ## ´¦Àí³¬Ê±µÄ·¿¼ä  
 | 
      
 | 
    timeoutRoomDict = {}  
 | 
    serverGroupIDList = []  
 | 
    #roomTimeout = IpyGameDataPY.GetFuncCfg("CheckRoomTimeout", 1) * 1000 # Õâ¸öʱ¼ä¾¡Á¿³¤µã£¬Ä¿Ç°ÔÝʱ²»È·¶¨Íæ¼Ò´Ó×¼±¸ºÃµ½½øÈëµ½µØÍ¼µÄʱ³¤  
 | 
    roomTimeout = 180 * 1000 # Õâ¸öʱ¼ä¾¡Á¿³¤µã£¬Ä¿Ç°ÔÝʱ²»È·¶¨Íæ¼Ò´Ó×¼±¸µ½½øÈëµ½µØÍ¼µÄʱ³¤  
 | 
    for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():  
 | 
        if pkRoom.isMapOpen or not pkRoom.readyTick:  
 | 
            continue  
 | 
        if tick - pkRoom.readyTick <= roomTimeout:  
 | 
            continue  
 | 
        pkZoneID = pkRoom.pkZoneID  
 | 
        GameWorld.Log("PK·¿¼äµÈ´ýÍæ¼Ò½øÀ´³¬Ê±£¬Ã»ÓÐÍæ¼Ò½øÀ´£¬¹Ø±Õ¸Ã·¿¼ä£¡pkZoneID=%s,roomID=%s,openTick=%s,readyTick=%s,tick=%s"   
 | 
                      % (pkZoneID, roomID, pkRoom.openTick, pkRoom.readyTick, tick))  
 | 
        roomPlayerInfo = []  
 | 
        for roomPlayerID in pkRoom.roomPlayerIDList:  
 | 
            pkPlayer = PyGameData.g_crossPKPlayerDict.pop(roomPlayerID, None)  
 | 
            if not pkPlayer:  
 | 
                continue  
 | 
            serverGroupID = pkPlayer.serverGroupID  
 | 
            GameWorld.Log("    ÒƳýÍæ¼Ò£¬Íæ¼ÒÐèÖØÐÂÊÖ¶¯Æ¥Å䣬serverGroupID=%s,roomPlayerID=%s" % (serverGroupID, roomPlayerID))  
 | 
            serverGroupIDList.append(serverGroupID)  
 | 
            roomPlayerInfo.append([serverGroupID, roomPlayerID])  
 | 
        timeoutRoomDict[roomID] = roomPlayerInfo  
 | 
        PyGameData.g_crossPKRoomDict.pop(roomID)  
 | 
          
 | 
    # ½«³¬Ê±·¿¼ä¹ã²¥µ½×Ó·þ  
 | 
    if timeoutRoomDict:  
 | 
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKTimeoutRoomList, timeoutRoomDict, serverGroupIDList)  
 | 
    return  
 | 
  
 | 
def MapServer_CrossPKRoomOpen(msgList):  
 | 
    roomID = msgList[0]  
 | 
    if roomID not in PyGameData.g_crossPKRoomDict:  
 | 
        GameWorld.ErrLog("MapServer_CrossPKRoomOpen => PK·¿¼ä²»´æÔÚ£¡roomID=%s" % roomID)  
 | 
        return  
 | 
    pkRoom = PyGameData.g_crossPKRoomDict[roomID]  
 | 
    pkRoom.isMapOpen = True  
 | 
    GameWorld.Log("MapServer_CrossPKRoomOpen => roomID=%s" % roomID)  
 | 
    return  
 | 
  
 | 
def MapServer_MergePKOver(infoList):  
 | 
    ## ÊÕµ½MapServer¸±±¾¿ç·þPK½á¹ûͬ²½  
 | 
      
 | 
    GameWorld.Log("ÊÕµ½MapServer_¿ç·þPKÕ½¶·½á¹û: %s" % str(infoList))  
 | 
      
 | 
    roomID, winnerID, loserID, roundWinnerIDList, overType = infoList  
 | 
      
 | 
    if roomID not in PyGameData.g_crossPKRoomDict:  
 | 
        GameWorld.ErrLog("¿ç·þPK·¿¼äÊý¾Ý²»´æÔÚ£¡roomID=%s" % roomID)  
 | 
        return  
 | 
    vsRoom = PyGameData.g_crossPKRoomDict.pop(roomID)  
 | 
    #vsRoom = PyGameData.g_crossPKRoomDict[roomID]  
 | 
    roomPlayerIDList = vsRoom.roomPlayerIDList  
 | 
    if not winnerID and not loserID:  
 | 
        GameWorld.ErrLog("µØÍ¼Ã»ÓнáËã¿ç·þPKʤ¸ºÍæ¼Ò£¬Ëæ»úÍæ¼Ò»ñʤ!")  
 | 
        if not roomPlayerIDList or len(roomPlayerIDList) != 2:  
 | 
            return  
 | 
        winnerID, loserID = roomPlayerIDList  
 | 
    elif not loserID:  
 | 
        for roomPlayerID in roomPlayerIDList:  
 | 
            if roomPlayerID != winnerID:  
 | 
                loserID = roomPlayerID  
 | 
                break  
 | 
              
 | 
    if winnerID not in roomPlayerIDList or loserID not in roomPlayerIDList:  
 | 
        GameWorld.ErrLog("¿ç·þPK·¿¼ä¼°Íæ¼Ò²»Æ¥Å䣬²»½áË㣡roomID=%s,winnerID=%s,loserID=%s,roomPlayerIDList=%s"   
 | 
                         % (roomID, winnerID, loserID, vsRoom.roomPlayerIDList))  
 | 
        return  
 | 
      
 | 
    if winnerID not in PyGameData.g_crossPKPlayerDict:  
 | 
        GameWorld.ErrLog("¿ç·þPK·¿¼ä»ñÈ¡²»µ½Íæ¼ÒPKÊý¾Ý, roomID=%s,winnerID=%s" % (roomID, winnerID))  
 | 
        return  
 | 
    if loserID not in PyGameData.g_crossPKPlayerDict:  
 | 
        GameWorld.ErrLog("¿ç·þPK·¿¼ä»ñÈ¡²»µ½Íæ¼ÒPKÊý¾Ý, roomID=%s,loserID=%s" % (roomID, loserID))  
 | 
        return  
 | 
      
 | 
    winner = PyGameData.g_crossPKPlayerDict.pop(winnerID)  
 | 
    loser = PyGameData.g_crossPKPlayerDict.pop(loserID)  
 | 
    #winner = PyGameData.g_crossPKPlayerDict[winnerID]  
 | 
    #loser = PyGameData.g_crossPKPlayerDict[loserID]  
 | 
    seasonID = winner.seasonID  
 | 
      
 | 
    cWinCount = winner.cWinCount  
 | 
    winnerScore, loserScore = winner.pkScore, loser.pkScore  
 | 
    winnerDanLV, loserDanLV = winner.danLV, loser.danLV  
 | 
    winnerDayScore, loserDayScore = max(0, winnerScore - winner.ondayScore), max(0, loserScore - loser.ondayScore) # ½ñÈÕÒÑ»ñµÃ»ý·Ö£¬Õý»ý·Ö  
 | 
      
 | 
    GameWorld.Log("winnerDayScore=%s,winnerScore=%s,winnerDanLV=%s,cWinCount=%s" % (winnerDayScore, winnerScore, winnerDanLV, cWinCount))  
 | 
    GameWorld.Log("loserDayScore=%s,loserScore=%s,loserDanLV=%s" % (loserDayScore, loserScore, loserDanLV))  
 | 
      
 | 
    winIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", winnerDanLV)  
 | 
    loseIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", loserDanLV)  
 | 
    if not winIpyData or not loseIpyData:  
 | 
        GameWorld.ErrLog("¿ç·þPK·¿¼ä¶ÎλÊý¾ÝÒì³£! roomID=%s,winnerDanLV=%s,loserDanLV=%s" % (roomID, winnerDanLV, loserDanLV))  
 | 
          
 | 
    baseScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKScore", 2) # Ê¤¸º±£µ×·Ö  
 | 
    wBaseScore = baseScoreList[0] if len(baseScoreList) > 0 else 0  
 | 
    lBaseScore = baseScoreList[1] if len(baseScoreList) > 1 else 0  
 | 
    wExScore = eval(IpyGameDataPY.GetFuncCompileCfg("CrossRealmPKScore", 3)) # Ê¤·½¸½¼Ó·Ö  
 | 
    lExScore = 0  
 | 
      
 | 
    winnerAddScore = wBaseScore + wExScore  
 | 
    loserAddScore = lBaseScore + lExScore  
 | 
      
 | 
    dayMaxScore = IpyGameDataPY.GetFuncCfg("CrossRealmPKScore", 1) # Ã¿ÈÕ»ñµÃ»ý·ÖÉÏÏÞ£¬0Ϊ²»ÏÞÖÆ  
 | 
    if dayMaxScore:  
 | 
        if winnerAddScore > 0:  
 | 
            winnerAddScore = min(dayMaxScore - winnerDayScore, winnerAddScore)  
 | 
        if loserAddScore > 0:  
 | 
            loserAddScore = min(dayMaxScore - loserDayScore, loserAddScore)  
 | 
      
 | 
    winner.pkScore += winnerAddScore  
 | 
    loser.pkScore += loserAddScore  
 | 
      
 | 
    winner.cWinCount += 1  
 | 
    loser.cWinCount = 0  
 | 
      
 | 
    if winIpyData and winIpyData.GetLVUpScore() and winner.pkScore >= winIpyData.GetLVUpScore():  
 | 
        winner.danLV += 1  
 | 
              
 | 
    if loseIpyData and loseIpyData.GetLVUpScore() and loser.pkScore >= loseIpyData.GetLVUpScore():  
 | 
        loser.danLV += 1  
 | 
          
 | 
    GameWorld.Log("wBaseScore=%s,wExScore=%s,winnerAddScore=%s,updScore=%s,updDanLV=%s,updCWinCount=%s" % (wBaseScore, wExScore, winnerAddScore, winner.pkScore, winner.danLV, winner.cWinCount))  
 | 
    GameWorld.Log("lBaseScore=%s,lExScore=%s,loserAddScore=%s,updScore=%s,updDanLV=%s,updCWinCount=%s" % (lBaseScore, lExScore, loserAddScore, loser.pkScore, loser.danLV, loser.cWinCount))  
 | 
      
 | 
    timeStr = GameWorld.GetCurrentDataTimeStr()  
 | 
    playerOverDict = {}  
 | 
    # Í¨Öª¿Í»§¶ËÕ½¶·½á¹û  
 | 
    for playerID in [winnerID, loserID]:  
 | 
        if playerID == winnerID:  
 | 
            serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \  
 | 
                winner.serverGroupID, winner.pkScore, winner.danLV, winner.cWinCount, winnerAddScore, loser.playerID, loser.playerName  
 | 
        else:  
 | 
            serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \  
 | 
                loser.serverGroupID, loser.pkScore, loser.danLV, loser.cWinCount, loserAddScore, winner.playerID, winner.playerName  
 | 
                  
 | 
        player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
        notifyState = True if player else False  
 | 
          
 | 
        playerOverDict[playerID] = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList] \  
 | 
                                    + [serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]  
 | 
        if not player:  
 | 
            continue  
 | 
          
 | 
        overPack = ChPyNetSendPack.tagGCCrossRealmPKOverInfo()  
 | 
        overPack.TimeStr = timeStr  
 | 
        overPack.OverType = overType  
 | 
        overPack.WinnerID = winnerID  
 | 
        overPack.RoundWinnerID = roundWinnerIDList  
 | 
        overPack.RoundCount = len(overPack.RoundWinnerID)  
 | 
        overPack.AddScore = addScore  
 | 
        overPack.Score = pkScore  
 | 
        overPack.DanLV = danLV  
 | 
        overPack.CWinCnt = cWinCount  
 | 
        overPack.TagName = tagPlayerName  
 | 
        overPack.TagNameLen = len(overPack.TagName)  
 | 
        NetPackCommon.SendFakePack(player, overPack)  
 | 
          
 | 
        GameWorld.Log("ͬ²½Íæ¼ÒPK½á¹û: serverGroupID=%s,roomID=%s,addScore=%s,pkScore=%s,danLV=%s,cWinCount=%s,tagPlayerID=%s"   
 | 
                      % (serverGroupID, roomID, addScore, pkScore, danLV, cWinCount, tagPlayerID), playerID)  
 | 
          
 | 
    serverGroupIDList = [winner.serverGroupID, loser.serverGroupID]  
 | 
    GameWorld.Log("ͬ²½×Ó·þÕ½¶·½á¹û: seasonID=%s,timeStr=%s,roomID=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s"   
 | 
                  % (seasonID, timeStr, roomID, overType, winnerID, roundWinnerIDList))  
 | 
    # Í¬²½×Ó·þ  
 | 
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKOverInfo, playerOverDict, serverGroupIDList)  
 | 
    return  
 | 
  
 | 
##================================== ÒÔÏÂÊÇ×Ó·þÂß¼ ==========================================  
 | 
  
 | 
def CrossServerMsg_PKMatchReqRet(retInfo):  
 | 
    ## ¿ç·þPKÆ¥ÅäÇëÇó½á¹û  
 | 
    playerID, result = retInfo  
 | 
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
    if not curPlayer:  
 | 
        return  
 | 
      
 | 
    if result == -2:  
 | 
        PlayerControl.NotifyCode(curPlayer, "InCrossPKing")  
 | 
        return  
 | 
      
 | 
    if result == 1:  
 | 
        NetPackCommon.SendFakePack(curPlayer, ChPyNetSendPack.tagGCCrossRealmPKStartMatch())  
 | 
          
 | 
    return  
 | 
  
 | 
def CrossServerMsg_PKMatchResult(vsRoomDict):  
 | 
    ## ¿ç·þPKÆ¥Åä½á¹û  
 | 
    curServerGroupID = GameWorld.GetServerGroupID()  
 | 
    actionType = ShareDefine.Def_MergeAction_MergePK  
 | 
    mapPosList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKMatch", 5)  
 | 
    GameWorld.Log("=== ÊÕµ½PKÆ¥Åä½á¹û´¦Àí  === curServerGroupID=%s" % curServerGroupID)  
 | 
    if not mapPosList:  
 | 
        GameWorld.ErrLog("ûÓÐÅäÖöÔÕ½µØÍ¼½øÈë×ø±ê£¡")  
 | 
        return  
 | 
      
 | 
    for roomID, roomInfo in vsRoomDict.items():  
 | 
        mapID, playerList = roomInfo  
 | 
        GameWorld.Log("    roomID=%s,playerList=%s" % (roomID, playerList))  
 | 
        for i, playerInfo in enumerate(playerList):  
 | 
            serverGroupID, playerID = playerInfo  
 | 
            if serverGroupID != curServerGroupID:  
 | 
                GameWorld.DebugLog("        ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  
 | 
                continue  
 | 
            player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
            if not player:  
 | 
                GameWorld.DebugLog("        Íæ¼Ò²»ÔÚÏß, playerID=%s" % (playerID))  
 | 
                continue  
 | 
            if PlayerControl.GetIsTJG(player):  
 | 
                GameWorld.DebugLog("        Íæ¼ÒÍÑ»úÖÐ, playerID=%s" % (playerID))  
 | 
                continue  
 | 
            PlayerControl.SetVsRoomId(player, roomID, True)  
 | 
            # Í¨ÖªµØÍ¼Íæ¼ÒÆ¥Åä³É¹¦, ÉÏ´«Êý¾Ý, ×¼±¸½øÈë¿ç·þ·þÎñÆ÷  
 | 
            posX, posY = mapPosList[i] if len(mapPosList) > i else mapPosList[0]  
 | 
            CrossRealmPlayer.SendCrossRealmReg(player, actionType, mapID, mapID, 0, posX, posY)  
 | 
              
 | 
    return  
 | 
  
 | 
def CrossServerMsg_PKReadyOKRoomList(readyOKRoomList):  
 | 
    ## ×Ó·þ½ÓÊÕÍæ¼ÒÒÑ×¼±¸ºÃµÄPK·¿¼äÐÅÏ¢, ´Ë·¿¼äÀïµÄÍæ¼Ò¿É´«ËͽøÈë¿ç·þ  
 | 
      
 | 
    curServerGroupID = GameWorld.GetServerGroupID()  
 | 
    GameWorld.Log("===ÊÕµ½¿ç·þ·þÎñÆ÷֪ͨÒÑ×¼±¸ºÃµÄ¶ÔÕ½PK·¿¼äÐÅÏ¢´¦Àí=== curServerGroupID=%s" % curServerGroupID)  
 | 
    # serverGroupID, playerName, playerJob  
 | 
      
 | 
    for roomID, readyMemberDict in readyOKRoomList:  
 | 
        for playerID, playerInfo in readyMemberDict.items():  
 | 
            serverGroupID = playerInfo["ServerGroupID"]  
 | 
            playerName = playerInfo["Name"]  
 | 
              
 | 
            if serverGroupID != curServerGroupID:  
 | 
                GameWorld.DebugLog("    ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  
 | 
                continue  
 | 
              
 | 
            player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
            if not player:  
 | 
                GameWorld.DebugLog("    Íæ¼Ò²»ÔÚÏß , playerID=%s" % (playerID))  
 | 
                continue  
 | 
            if PlayerControl.GetIsTJG(player):  
 | 
                GameWorld.DebugLog("    Íæ¼ÒÍÑ»úÖÐ, playerID=%s" % (playerID))  
 | 
                continue  
 | 
            player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 1)  
 | 
              
 | 
            matchPlayer = ChPyNetSendPack.tagGCCrossRealmPKMatchPlayer()  
 | 
            for readyPlayerID, readyPlayerInfo in readyMemberDict.items():  
 | 
                if readyPlayerID != playerID:  
 | 
                    matchPlayer.PlayerID = readyPlayerID  
 | 
                    matchPlayer.PlayerName = readyPlayerInfo["Name"]  
 | 
                    matchPlayer.NameLen = len(matchPlayer.PlayerName)  
 | 
                    matchPlayer.Job = readyPlayerInfo["Job"]  
 | 
                    matchPlayer.LV = readyPlayerInfo["LV"]  
 | 
                    matchPlayer.MaxHP = readyPlayerInfo["MaxHP"]  
 | 
                    break  
 | 
                  
 | 
            PlayerControl.SetCrossRealmState(player, 1)  
 | 
              
 | 
            # Í¨ÖªÆ¥Åä³É¹¦£¬¿É½øÈë¿ç·þ  
 | 
            matchOKPack = ChPyNetSendPack.tagGCCrossRealmPKMatchOK()  
 | 
            matchOKPack.RoomID = roomID  
 | 
            matchOKPack.PlayerName = playerName  
 | 
            matchOKPack.NameLen = len(matchOKPack.PlayerName)  
 | 
            matchOKPack.MatchPlayer = [matchPlayer]  
 | 
            matchOKPack.MatchPlayerCount = len(matchOKPack.MatchPlayer)  
 | 
            NetPackCommon.SendFakePack(player, matchOKPack)  
 | 
            GameWorld.Log("    Í¨ÖªÍæ¼Ò½øÈë¿ç·þPK¶ÔÕ½·¿¼ä! roomID=%s,playerID=%s,matchPlayerID=%s" % (roomID, playerID, matchPlayer.PlayerID))  
 | 
              
 | 
            # µ½ÕâÀïĬÈÏÈÏΪһ¶¨»áÓнá¹ûµÄ£¬ËùÒÔ±¾·þÖ±½ÓÔö¼Ó´ÎÊý  
 | 
            #player.MapServer_QueryPlayerResult(0, 0, 'MergePKAddCnt', "", 0)  
 | 
    return  
 | 
  
 | 
def CrossServerMsg_PKTimeoutRoomList(timeoutRoomDict):  
 | 
    ## ×Ó·þ½ÓÊÕÒѳ¬Ê±µÄPK·¿¼äÐÅÏ¢, ´Ë·¿¼äÀïµÄÍæ¼ÒÖØÖÿç·þ״̬  
 | 
      
 | 
    curServerGroupID = GameWorld.GetServerGroupID()  
 | 
    GameWorld.Log("===ÊÕµ½¿ç·þ·þÎñÆ÷֪ͨÒѳ¬Ê±µÄ¶ÔÕ½PK·¿¼äÐÅÏ¢´¦Àí=== curServerGroupID=%s" % curServerGroupID)  
 | 
      
 | 
    for roomID, roomPlayerInfo in timeoutRoomDict.items():  
 | 
        if not roomPlayerInfo:  
 | 
            continue  
 | 
        serverGroupID, playerID = roomPlayerInfo  
 | 
          
 | 
        if serverGroupID != curServerGroupID:  
 | 
            GameWorld.DebugLog("    ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  
 | 
            continue  
 | 
          
 | 
        player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
        if not player:  
 | 
            GameWorld.DebugLog("    Íæ¼Ò²»ÔÚÏß , playerID=%s" % (playerID))  
 | 
            continue  
 | 
        if PlayerControl.GetIsTJG(player):  
 | 
            GameWorld.DebugLog("    Íæ¼ÒÍÑ»úÖÐ, playerID=%s" % (playerID))  
 | 
            continue  
 | 
        playerVSRoomID = player.GetVsRoomId()  
 | 
        if playerVSRoomID and playerVSRoomID != roomID:  
 | 
            GameWorld.DebugLog("    ·¿¼äID²»Í¬, playerID=%s" % (playerID))  
 | 
            continue  
 | 
        player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)  
 | 
        PlayerControl.SetCrossRealmState(player, 0)  
 | 
          
 | 
    return  
 | 
  
 | 
def CrossServerMsg_PKOverInfo(playerOverDict):  
 | 
    ## ×Ó·þ½ÓÊÕ¿ç·þPK½á¹ûÐÅÏ¢  
 | 
      
 | 
    curServerGroupID = GameWorld.GetServerGroupID()  
 | 
    GameWorld.Log("===ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¿ç·þPK½á¹û=== curServerGroupID=%s" % curServerGroupID)  
 | 
      
 | 
    for playerID, overInfo in playerOverDict.items():  
 | 
        roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, \  
 | 
            serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo  
 | 
        if serverGroupID != curServerGroupID:  
 | 
            GameWorld.DebugLog("    ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  
 | 
            continue  
 | 
          
 | 
        sendMapOverInfo = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]  
 | 
        player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
        if not player or PlayerControl.GetIsTJG(player):  
 | 
            GameWorld.Log("    Íæ¼Ò²»ÔÚÏß »òÍÑ»úÖУ¬ÏÈ»º´æ£¬Íæ¼ÒÉÏÏߺóÔÙͬ²½£¬playerID=%s" % (playerID))  
 | 
            PyGameData.g_crossPKUnNotifyOverInfo[playerID] = sendMapOverInfo  
 | 
            continue  
 | 
          
 | 
        sysMsg = str(sendMapOverInfo)  
 | 
        player.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))  
 | 
        GameWorld.Log("֪ͨµØÍ¼¿ç·þPK½áËã: roomID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s, pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s,mapID=%s"   
 | 
                      % (roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState, player.GetMapID()), playerID)  
 | 
    return  
 | 
  
 | 
def __OnLoginNotifyPKOverInfo(curPlayer):  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    if playerID not in PyGameData.g_crossPKUnNotifyOverInfo:  
 | 
        return  
 | 
    overInfo = PyGameData.g_crossPKUnNotifyOverInfo.pop(playerID)  
 | 
    PlayerControl.SetCrossRealmState(curPlayer, 0)  
 | 
    sysMsg = str(overInfo)  
 | 
    curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))  
 | 
    GameWorld.Log("Íæ¼ÒÉÏÏß֪ͨµØÍ¼Î´½áËãµÄ¿ç·þPK½áËã: mapID=%s,overInfo=%s" % (curPlayer.GetMapID(), overInfo), playerID)  
 | 
    return  
 | 
  
 | 
  
 |