ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
@@ -17,33 +17,156 @@
import ShareDefine
import PlayerControl
import CrossRealmPlayer
import ChPyNetSendPack
import NetPackCommon
import IpyGameDataPY
import ChPyNetSendPack
import CrossRealmPlayer
import DataRecordPack
import IPY_GameWorld
import ItemControler
import ItemCommon
import GameWorld
import ChConfig
def DoPlayerOnDay(curPlayer):
    if GameWorld.IsCrossServer():
        return
    totalScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore)
    if not totalScore:
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_OnDayScore, totalScore)
    zoneID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_ZoneID)
    seasonID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonID)
    # 邮件发放未领取的每日PK次数奖励
    dayPKCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 1, {})
    dayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
    dayPKCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayPKCountAwardState)
    SendDayPKAwardByMail(curPlayer, zoneID, seasonID, "PKCount", dayPKCount, dayPKCountAwardState, dayPKCountAwardDict, "CrossServer1")
    # 邮件发放未领取的每日胜利次数奖励
    dayWinCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 2, {})
    dayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount)
    dayWinCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayWinCountAwardState)
    SendDayPKAwardByMail(curPlayer, zoneID, seasonID, "WinCount", dayWinCount, dayWinCountAwardState, dayWinCountAwardDict, "CrossServer2")
    # 重置每日奖励状态
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayWinCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayPKCountAwardState, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayWinCountAwardState, 0)
    SyncCrossRealmPKPlayerInfo(curPlayer)
    SyncCrossRealmPKAwardState(curPlayer)
    return
def IsCrossRealmPKOpen():
def DoPlayerLogin(curPlayer):
    if GameWorld.IsCrossServer():
        return
    mapZoneID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
    if not mapZoneID or not mapSeasonID:
        return
    if not __CheckResetPlayerCrossPKData(curPlayer, mapZoneID, mapSeasonID):
        SyncCrossRealmPKPlayerInfo(curPlayer)
        SyncCrossRealmPKAwardState(curPlayer)
        SyncCrossRealmPKHisSeasonInfo(curPlayer)
    return
def IsCrossRealmPKMatchState():
    ## 跨服PK匹配赛是否开启
    return 1
    return GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState) == ChConfig.Def_Action_Open
    return GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState \
                                                          % ShareDefine.DailyActionID_CrossReamPK) == ChConfig.Def_Action_Open
def GetCrossPKZoneID():
    ## 获取本服跨服PK所属赛区
    return 1
def OnCrossRealmPKSeasonChange(value):
    ## 赛区赛季状态变更,规定所有赛区的赛季ID都一样,且赛季ID一定是自增的,所以这里只判断赛季ID变更即可
    if GameWorld.IsCrossServer():
        return
    mapZoneID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
    if mapSeasonID == value:
        GameWorld.DebugLog("跨服PK赛季信息与地图当前值相同,不处理!")
        return
    GameWorld.Log("跨服PK赛季信息变更: mapSeasonID=%s,value=%s" % (mapSeasonID, value))
    mapSeasonID = value
    playerManager = GameWorld.GetPlayerManager()
    for i in xrange(playerManager.OnlineCount()):
        curPlayer = playerManager.OnlineAt(i)
        if not curPlayer or curPlayer.IsEmpty():
            continue
        #检查重置玩家信息
        __CheckResetPlayerCrossPKData(curPlayer, mapZoneID, mapSeasonID)
    return
def GetSeasonID():
    ## 获取当前赛季ID
    return 1
def __CheckResetPlayerCrossPKData(curPlayer, mapZoneID, mapSeasonID):
    ## 检查玩家赛区赛季状态数据
    playerID = curPlayer.GetPlayerID()
    zoneID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_ZoneID)
    seasonID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonID)
    if mapSeasonID == seasonID:
        GameWorld.DebugLog("玩家跨服PK赛季信息相同,不处理! mapSeasonID=%s,seasonID=%s" % (mapSeasonID, seasonID), playerID)
        return
    GameWorld.Log("玩家跨服PK赛区赛季信息不同! 处理相关数据! mapSeasonID=%s,seasonID=%s" % (mapSeasonID, seasonID), playerID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, mapSeasonID)
    playerDanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
    danLVAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLVAwardState)
def IsCrossRealmPKSeasonOpen():
    GameWorld.Log("开始新赛季,发放上赛季未领取的奖励,重置赛季数据! zoneID=%s,seasonID=%s,newSeasonID=%s,playerDanLV=%s,danLVAwardState=%s"
                  % (zoneID, seasonID, mapSeasonID, playerDanLV, danLVAwardState), playerID)
    # 邮件发放上赛季未领取的段位奖励、赛季奖励(排名或段位)
    for awardDanLV in xrange(playerDanLV + 1):
        danLVIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", awardDanLV)
        if not danLVIpyData:
            continue
        awardItemList = danLVIpyData.GetDanLVAwardList()
        if not awardItemList:
            continue
        if pow(2, awardDanLV) & danLVAwardState:
            GameWorld.DebugLog("    已经领取过该段位达标奖励!awardDanLV=%s,danLVAwardState=%s" % (awardDanLV, danLVAwardState), playerID)
            continue
        eventName = "DanLV"
        GameWorld.Log("    邮件补发未领取的段位达标奖励!awardDanLV=%s,danLVAwardState=%s,awardItemList=%s"
                      % (awardDanLV, danLVAwardState, awardItemList), playerID)
        mailDetail = {"EventName":eventName, "zoneID":zoneID, "seasonID":seasonID, "awardDanLV":awardDanLV,
                      "danLVAwardState":danLVAwardState, "mapSeasonID":mapSeasonID}
        PlayerControl.SendMailByKey("CrossServer3", [playerID], awardItemList, [seasonID, awardDanLV], detail=mailDetail)
        DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, True, mailDetail)
    # 查询 GameServer 玩家赛季排名
    if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState):
        OnQueryCrossPKSeasonOrderAward(curPlayer, zoneID, seasonID, True)
    # 重置状态
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TotalScore, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_OnDayScore, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLV, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_PKCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_WinCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_CWinCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayWinCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayPKCountAwardState, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayWinCountAwardState, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLVAwardState, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardState, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_ZoneID, mapZoneID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, mapSeasonID)
    SyncCrossRealmPKPlayerInfo(curPlayer)
    SyncCrossRealmPKAwardState(curPlayer)
    return True
#// C1 01 跨服PK匹配 #tagCMCrossRealmPKMatch
@@ -62,45 +185,33 @@
    if GameWorld.IsCrossServer():
        GameWorld.DebugLog("跨服服务器无法发起匹配!")
        return
    if not IsCrossRealmPKOpen():
        GameWorld.Log("OnRequestMergePK 跨服活动未开启,不可进行匹配!", playerID)
        PlayerControl.NotifyCode(curPlayer, "GeRen_hgg_21675")
    if GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState) != 1:
        GameWorld.DebugLog("OnRequestMergePK 跨服赛季未开启,不可进行匹配!", playerID)
        PlayerControl.NotifyCode(curPlayer, "SeasonIsNotOpen")
        return
    if not IsCrossRealmPKMatchState():
        GameWorld.DebugLog("OnRequestMergePK 跨服匹配未开启,不可进行匹配!", playerID)
        PlayerControl.NotifyCode(curPlayer, "MatchIsNotOpen")
        return
    
    GameWorld.Log("收到跨服PK匹配: type=%s,accID=%s" % (requestType, accID), playerID)
    
    # 进行匹配
    if requestType == 1:
#        pkCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_Cnt)
#        buyCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_BuyCnt)
#        unUsedBuyCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_UnUsedBuyCnt)
#        freeCnt, maxBuyCnt, moneyType, buyCostFormat = ReadChConfig.GetEvalChConfig("MergePK_BuyCost")
#
#        # 超出免费次数 且 无可用的已购买次数  则需购买次数
#        if pkCnt >= freeCnt and unUsedBuyCnt <= 0:
#
#            if buyCnt >= maxBuyCnt:
#                GameWorld.Log("    已达到最大可购买PK次数,不可再买!:buyCnt=%s,maxBuyCnt=%s,pkCnt=%s,unUsedBuyCnt=%s"
#                              % (buyCnt, maxBuyCnt, pkCnt, unUsedBuyCnt), playerID)
#                return
#
#            buyCost = eval(buyCostFormat)
#            infoDict = {"pkCnt":pkCnt, "freeCnt":freeCnt, "buyCnt":buyCnt, "buyCost":buyCost}
#            if not PlayerControl.PayMoney(curPlayer, moneyType, buyCost, ChConfig.Def_Cost_BuyMergePKCnt, infoDict):
#                return
#
#            # 增加购买次数 及 未使用的购买次数
#            __SetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_BuyCnt, buyCnt + 1)
#            __SetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_UnUsedBuyCnt, unUsedBuyCnt + 1)
#            Sync_MergePKCnt(curPlayer)
#
#            GameWorld.Log("    购买PK次数消耗: pkCnt=%s,freeCnt=%s,buyCnt=%s,moneyType=%s,buyCost=%s"
#                              % (pkCnt, freeCnt, buyCnt, moneyType, buyCost), playerID)
        dayFreeMatchCountMax = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatchCount", 1)
        if dayFreeMatchCountMax:
            todayPKCount  = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
            todayBuyCount  = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayBuyCount)
            if todayPKCount >= (dayFreeMatchCountMax + todayBuyCount):
                GameWorld.DebugLog("PK次数不足,无法发起匹配! todayPKCount=%s >= (dayFreeMatchCountMax=%s + todayBuyCount=%s)"
                                   % (todayPKCount, dayFreeMatchCountMax, todayBuyCount), playerID)
                return
        dataMsg = {
                   "seasonID":GetSeasonID(), # 赛季ID
                   "pkZoneID":GetCrossPKZoneID(), # PK赛区
                   "seasonID":GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID), # 赛季ID
                   "pkZoneID":GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID), # PK赛区
                   "accID":accID,
                   "playerID":playerID,
                   "playerName":CrossRealmPlayer.GetCrossPlayerName(curPlayer),
@@ -108,8 +219,9 @@
                   "playerLV":curPlayer.GetLV(),
                   "maxHP":curPlayer.GetMaxHP(),
                   "fightPower":curPlayer.GetFightPower(),
                   "realmLV":curPlayer.GetOfficialRank(),
                   "pkScore":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore), # 当前积分
                   "danLV":1, #curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV), # 当前段位
                   "danLV":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV), # 当前段位
                   "cWinCount":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_CWinCount), # 连胜次数
                   "ondayScore":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_OnDayScore), # 过天时的积分
                   }
@@ -127,19 +239,23 @@
def CrossServerMsg_PKOverInfo(curPlayer, overInfo):
    ## 收到跨服服务器的PK结算信息
    playerID = curPlayer.GetPlayerID()
    roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo
    roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo
    isWinner = winnerID == playerID
    GameWorld.Log("地图收到跨服PK结算: isWinner=%s,roomID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s,pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s"
                  % (isWinner, roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState), playerID)
    curSeasonID = GetSeasonID()
    GameWorld.Log("地图收到跨服PK结算: isWinner=%s,roomID=%s,zoneID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s,pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s"
                  % (isWinner, roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState), playerID)
    curSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
    if curSeasonID != seasonID:
        GameWorld.Log("    非本赛季的结算信息,不处理!curSeasonID=%s,seasonID=%s" % (curSeasonID, seasonID), playerID)
        return
    
    # 赛季是否已结算
    if not IsCrossRealmPKSeasonOpen():
        GameWorld.Log("    赛季已经结算过了,不处理!seasonID=%s" % (seasonID), playerID)
    # 赛季已关闭
    if GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState) != 1:
        GameWorld.Log("    赛季已关闭,不处理!seasonID=%s" % (seasonID), playerID)
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_ZoneID, zoneID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, seasonID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonDanLV % seasonID, danLV)
    
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TotalScore, pkScore)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLV, danLV)
@@ -157,7 +273,12 @@
    if GameWorld.CheckTimeIsSameServerDayEx(GameWorld.ChangeTimeStrToNum(timeStr)):
        todayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount) + 1
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, todayPKCount)
        if isWinner:
            todayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount) + 1
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayWinCount, todayWinCount)
    SyncCrossRealmPKPlayerInfo(curPlayer)
    ## 跨服已经通知过了,证明还在跨服服务器,不做以下的处理
    if notifyState:
        return
@@ -186,7 +307,30 @@
#};
def OnCrossRealmPKBuy(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    dayFreeMatchCountMax = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatchCount", 1)
    if not dayFreeMatchCountMax:
        GameWorld.DebugLog("每日匹配次数没有限制,不需要购买次数!", playerID)
        return
    dayBuyCountMax = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatchCount", 2)
    todayBuyCount  = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayBuyCount)
    if dayBuyCountMax and todayBuyCount >= dayBuyCountMax:
        GameWorld.DebugLog("今日购买次数已满,无法购买!todayBuyCount=%s" % (todayBuyCount), playerID)
        return
    
    costGold = eval(IpyGameDataPY.GetFuncCompileCfg("CrossRealmPKMatchCount", 3))
    costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, ShareDefine.TYPE_Price_Gold_Paper_Money, costGold)
    if not costMoneyList:
        GameWorld.DebugLog("仙玉绑玉不足: todayBuyCount=%s,costGold=%s" % (todayBuyCount, costGold), playerID)
        return
    infoDict = {"Event":"BuyPKCount", "todayBuyCount":todayBuyCount}
    for moneyType, moneyNum in costMoneyList:
        PlayerControl.PayMoney(curPlayer, moneyType, moneyNum, ChConfig.Def_Cost_CrossRealmPK, infoDict)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, todayBuyCount + 1)
    GameWorld.DebugLog("购买跨服PK次数: todayBuyCount=%s" % (todayBuyCount), playerID)
    SyncCrossRealmPKPlayerInfo(curPlayer)
    return
@@ -200,31 +344,269 @@
#};
def OnCrossRealmPKGetAward(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if not curPlayer:
        return
    playerID = curPlayer.GetPlayerID()
    awardType = clientData.AwardType
    awardData = clientData.AwardData
    zoneID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
    seasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
    if not zoneID or not seasonID:
        GameWorld.DebugLog("当前没有跨服PK赛季, 无法领取奖励! zoneID=%s,seasonID=%s" % (zoneID, seasonID))
        return
    
    if awardType == 1:
        awardPKCount = awardData
        playerTodayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
        GameWorld.DebugLog("玩家领取每日匹配次数奖励! awardPKCount=%s,playerTodayPKCount=%s" % (awardPKCount, playerTodayPKCount), playerID)
        if playerTodayPKCount < awardPKCount:
            GameWorld.DebugLog("    PK次数不足,无法领取!", playerID)
            return
        dayPKCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 1, {}) # {"次数":[[物品ID,个数,是否绑定], ...], ...}
        awardPKCountList = dayPKCountAwardDict.keys()
        awardPKCountList.sort()
        awardPKCountStr = str(awardPKCount)
        if awardPKCountStr not in awardPKCountList:
            GameWorld.DebugLog("    没有该PK次数奖励!")
            return
        awardIndex = awardPKCountList.index(awardPKCountStr)
        awardStateDictName = ChConfig.Def_PDict_CrossPK_DayPKCountAwardState
        awardItemList = dayPKCountAwardDict[awardPKCountStr]
        eventName = "PKCount"
        drDataDict = {"awardPKCount":awardPKCount}
    elif awardType == 2:
        awardWinCount = awardData
        playerTodayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount)
        GameWorld.DebugLog("玩家领取每日胜利次数奖励! awardWinCount=%s,playerTodayWinCount=%s" % (awardWinCount, playerTodayWinCount), playerID)
        if playerTodayWinCount < awardWinCount:
            GameWorld.DebugLog("    胜利次数不足,无法领取!", playerID)
            return
        dayWinCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 2, {}) # {"次数":[[物品ID,个数,是否绑定], ...], ...}
        awardWinCountList = dayWinCountAwardDict.keys()
        awardWinCountList.sort()
        awardWinCountStr = str(awardWinCount)
        if awardWinCountStr not in awardWinCountList:
            GameWorld.DebugLog("    没有该胜利次数奖励!", playerID)
            return
        awardIndex = awardWinCountList.index(awardWinCountStr)
        awardStateDictName = ChConfig.Def_PDict_CrossPK_DayWinCountAwardState
        awardItemList = dayWinCountAwardDict[awardWinCountStr]
        eventName = "WinCount"
        drDataDict = {"awardWinCount":awardWinCount}
    elif awardType == 3:
        awardDanLV = awardData
        playerDanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
        GameWorld.DebugLog("玩家领取段位达标奖励! awardDanLV=%s,playerDanLV=%s" % (awardDanLV, playerDanLV), playerID)
        if playerDanLV < awardDanLV:
            GameWorld.DebugLog("    段位未达标,无法领取!", playerID)
            return
        danLVIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", awardDanLV)
        if not danLVIpyData:
            return
        awardIndex = awardDanLV
        awardStateDictName = ChConfig.Def_PDict_CrossPK_DanLVAwardState
        awardItemList = danLVIpyData.GetDanLVAwardList()
        eventName = "DanLV"
        drDataDict = {"awardDanLV":awardDanLV}
    elif awardType == 4:
        GameWorld.DebugLog("玩家领取赛季结算奖励!", playerID)
        if GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState) != 2:
            GameWorld.DebugLog("非赛季结算阶段,不可领取!", playerID)
            return
        if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState):
            GameWorld.DebugLog("已经领取过该奖励,不可领取!", playerID)
            return
        # 查询 GameServer 玩家赛季排名
        OnQueryCrossPKSeasonOrderAward(curPlayer, zoneID, seasonID, False)
        return
    else:
        return
    if not awardItemList:
        GameWorld.DebugLog("该奖励没有配置奖励物品!", playerID)
        return
    awardState = curPlayer.NomalDictGetProperty(awardStateDictName)
    if pow(2, awardIndex) & awardState:
        GameWorld.DebugLog("    已经领取过该奖励!awardIndex=%s,awardState=%s" % (awardIndex, awardState), playerID)
        return
    needSpace = len(awardItemList)
    # 背包空间
    packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
    if packSpace < needSpace:
        PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_202580")
        return
    awardState |= pow(2, awardIndex)
    PlayerControl.NomalDictSetProperty(curPlayer, awardStateDictName, awardState)
    SyncCrossRealmPKAwardState(curPlayer)
    GameWorld.DebugLog("玩家领取跨服PK奖励! awardType=%s,awardData=%s,awardIndex=%s,awardState=%s,awardItemList=%s"
                       % (awardType, awardData, awardIndex, awardState, awardItemList), playerID)
    drDataDict.update({"awardIndex":awardIndex, "awardState":awardState, "awardItemList":awardItemList})
    for itemID, itemCnt, isBind in awardItemList:
        ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem])
    DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, False, drDataDict)
    return
def SendDayPKAwardByMail(curPlayer, zoneID, seasonID, eventName, dataCount, awardState, awardItemDict, mailTypeKey):
    ## 邮件发放未领取的每日奖励
    playerID = curPlayer.GetPlayerID()
    awardCountList = awardItemDict.keys()
    awardCountList.sort()
    for i, awardCountStr in enumerate(awardCountList):
        awardCount = int(awardCountStr)
        if dataCount < awardCount:
            GameWorld.DebugLog("跨服PK每日奖励次数不足: eventName=%s,i=%s,awardCount=%s > dataCount=%s" % (eventName, i, awardCount, dataCount), playerID)
            break
        if pow(2, i) & awardState:
            GameWorld.DebugLog("已领取该跨服PK每日奖励: eventName=%s,i=%s,awardCount=%s" % (eventName, i, awardCount), playerID)
            continue
        awardItemList = awardItemDict[awardCountStr]
        GameWorld.Log("邮件发放跨服PK未领取的每日奖励: zoneID=%s,seasonID=%s,eventName=%s,i=%s,awardCount=%s,dataCount=%s,awardState=%s,awardItemList=%s"
                      % (zoneID, seasonID, eventName, i, awardCount, dataCount, awardState, awardItemList), playerID)
        mailDetail = {"EventName":eventName, "zoneID":zoneID, "seasonID":seasonID, "awardCount":awardCount, "awardState":awardState}
        PlayerControl.SendMailByKey(mailTypeKey, [playerID], awardItemList, [awardCount], detail=mailDetail)
        DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, True, mailDetail)
    return
def OnQueryCrossPKSeasonOrderAward(curPlayer, zoneID, seasonID, isMail):
    # 查询 GameServer 玩家赛季排名
    playerID = curPlayer.GetPlayerID()
    danLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
    eventName, eventData = "SeasonAward", [danLV, isMail]
    sendMsg = str([zoneID, seasonID, eventName, eventData])
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "CrossPKSeasonOrder", sendMsg, len(sendMsg))
    GameWorld.Log("查询GameServer玩家赛区赛季排名: zoneID=%s, seasonID=%s, sendMsg=%s" % (zoneID, seasonID, sendMsg), playerID)
    return
def GameServer_CrossPKSeasonOrder(curPlayer, msgList):
    zoneID, seasonID, eventName, eventData, order = msgList
    # 领取赛季奖励
    if eventName == "SeasonAward":
        danLV, isMail = eventData
        DoGetPKSeasonAward(curPlayer, eventName, zoneID, seasonID, order, danLV, isMail)
    return
def DoGetPKSeasonAward(curPlayer, eventName, zoneID, seasonID, order, danLV, isMail):
    ## 执行发放赛季结算奖励,名次奖励与最高段位奖励互斥,优先名次奖励
    awardItemList = []
    seasonAwardLV = danLV
    playerID = curPlayer.GetPlayerID()
    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
    GameWorld.Log("发放玩家跨服PK赛季结算奖励! zoneID=%s,seasonID=%s,order=%s,danLV=%s,isMail=%s,seasonAwardLV=%s,mapSeasonID=%s"
                  % (zoneID, seasonID, order, danLV, isMail, seasonAwardLV, mapSeasonID), playerID)
    mailTypeKey, mailParamList, mailDetail = "", [], {"EventName":eventName, "zoneID":zoneID, "seasonID":seasonID,
                                                      "order":order, "danLV":danLV, "mapSeasonID":mapSeasonID}
    if order > 0:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonOrder % seasonID, order)
        seasonOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 3, {}) # {"名次":[[物品ID,个数,是否绑定], ...], ...}
        fromOrder, toOrder = 1, 1
        awardOrderList = sorted(seasonOrderAwardDict.keys())
        for i, awardOrderStr in enumerate(awardOrderList):
            awardOrder = int(awardOrderStr)
            if order <= awardOrder:
                toOrder = awardOrder
                awardItemList = seasonOrderAwardDict[awardOrderStr]
                maxDanLV = IpyGameDataPY.IPY_Data().GetCrossRealmPKDanCount() - 1 # 因为段位等级从0开始,所以最大段位等级要减1
                seasonAwardLV = maxDanLV + (len(awardOrderList) - i)
                GameWorld.Log("获得排名奖励, 更新奖励等级: awardOrderList=%s,i=%s,maxDanLV=%s,seasonAwardLV=%s" % (awardOrderList, i, maxDanLV, seasonAwardLV), playerID)
                mailTypeKey = "CrossServer4"
                mailParamList = [seasonID, fromOrder, toOrder]
                break
            fromOrder = awardOrder + 1
    # 没有奖励的话取段位奖励
    if not awardItemList:
        danLVIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", danLV)
        if not danLVIpyData:
            return
        awardItemList = danLVIpyData.GetSeasonDanLVAwardList()
        mailTypeKey = "CrossServer5"
        mailParamList = [seasonID, danLV]
    if not awardItemList:
        GameWorld.Log("没有玩家对应的赛季结算奖励!", playerID)
        return
    ## 发奖励之前需再判断一次,防止重复发包重复领取
    if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState):
        GameWorld.Log("已经发放过赛季结算奖励!", playerID)
        return
    if seasonID == mapSeasonID:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardState, 1)
        SyncCrossRealmPKAwardState(curPlayer)
        GameWorld.Log("还是同一个赛季,设置赛季奖励已领取!")
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardLV % seasonID, seasonAwardLV)
    if not isMail:
        needSpace = len(awardItemList)
        packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
        if packSpace < needSpace:
            isMail = True
    if isMail:
        PlayerControl.SendMailByKey(mailTypeKey, [playerID], awardItemList, mailParamList, detail=mailDetail)
    else:
        for itemID, itemCnt, isBind in awardItemList:
            ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem])
    GameWorld.Log("领取成功! awardItemList=%s" % (awardItemList), playerID)
    drDataDict = {"awardItemList":awardItemList, "order":order, "danLV":danLV, "seasonAwardLV":seasonAwardLV, "isMail":isMail}
    DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, isMail, drDataDict)
    return
def SyncCrossRealmPKPlayerInfo(curPlayer):
#    DWORD        Score;    // 当前积分
#    BYTE        DanLV;    // 当前段位
#    WORD        PKCount;    // PK次数
#    WORD        WinCount;    // 胜利次数
#    WORD        CWinCount;    // 连胜次数
#    BYTE        DayPKCount;    // 当日已PK次数
#    BYTE        DayWinCount;    // 当日已胜利次数
#    BYTE        DayBuyCount; // 当日已购买次数
    ## 同步玩家跨服PK玩家相关信息,积分、段位、相关次数等信息
    pkPlayerInfo = ChPyNetSendPack.tagMCCrossRealmPKPlayerInfo()
    pkPlayerInfo.Score = 0
    pkPlayerInfo.DanLV = 0
    pkPlayerInfo.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore)
    pkPlayerInfo.DanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
    pkPlayerInfo.PKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_PKCount)
    pkPlayerInfo.WinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_WinCount)
    pkPlayerInfo.CWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_CWinCount)
    pkPlayerInfo.DayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
    pkPlayerInfo.DayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount)
    pkPlayerInfo.DayBuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayBuyCount)
    NetPackCommon.SendFakePack(curPlayer, pkPlayerInfo)
    return
    
def SyncCrossRealmPKAwardState(curPlayer):
#    DWORD        DayPKCountAwardState;    // 每日匹配次数奖励记录,二进制位存储是否已领取,按匹配次数升序排序索引代表奖励位
#    DWORD        DayWinCountAwardState;    // 每日胜利次数奖励记录,二进制位存储是否已领取,按胜利次数升序排序索引代表奖励位
#    DWORD        DanLVAwardState;        // 段位达标奖励记录,二进制位存储是否已领取,按段位代表奖励位
#    BYTE        SeasonAwardState;    // 赛季结算奖励是否已领取
    ## 同步玩家跨服PK相关奖励状态
    pkAwardPack = ChPyNetSendPack.tagMCCrossRealmPKAwardState()
    pkAwardPack.DayPKCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayPKCountAwardState)
    pkAwardPack.DayWinCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayWinCountAwardState)
    pkAwardPack.DanLVAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLVAwardState)
    pkAwardPack.SeasonAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState)
    NetPackCommon.SendFakePack(curPlayer, pkAwardPack)
    return
def SyncCrossRealmPKHisSeasonInfo(curPlayer):
    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
    hisSeasonInfo = ChPyNetSendPack.tagMCCrossRealmPKPlayerHisSeasonInfo()
    hisSeasonInfo.SeasonList = []
    for seasonID in xrange(1, mapSeasonID + 1):
        seasonInfo = ChPyNetSendPack.tagMCCrossRealmPKPlayerHisSeason()
        seasonInfo.SeasonID = seasonID
        seasonInfo.DanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonDanLV % seasonID)
        seasonInfo.Order = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonOrder % seasonID)
        seasonInfo.AwardLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardLV % seasonID)
        hisSeasonInfo.SeasonList.append(seasonInfo)
    hisSeasonInfo.Count = len(hisSeasonInfo.SeasonList)
    NetPackCommon.SendFakePack(curPlayer, hisSeasonInfo)
    return
def DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, isMail, drDataDict):
    ## 记录领奖流向
    drDataDict.update({"zoneID":zoneID, "seasonID":seasonID, "isMail":isMail})
    DataRecordPack.SendEventPack("GetCrossPKAward_%s" % eventName, drDataDict, curPlayer)
    return