From 69871482099a1c7022cad6c8d8cd90d3b163f0f2 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 25 十二月 2018 21:11:32 +0800
Subject: [PATCH] 5424 【后端】【1.4】跨服竞技场开发(增加赛季时间管理、赛区赛季榜单、玩家各种PK数据、各种奖励领取及邮件补发、王者法宝等级)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py |  518 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 450 insertions(+), 68 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
index 813dc47..3e926b1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
+++ b/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
 

--
Gitblit v1.8.0