From 23bf40a8f81f642e0c186306092d7364c6ba1afb Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 03 六月 2021 11:25:52 +0800
Subject: [PATCH] 8970 【后端】【btzf】【bt】【bt2】【主干】装备格数新增到16阶(装备背包格子加到203格;穿装备无格子报错防范;GM广播时间格式错误报错防范)

---
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py |  571 ++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 440 insertions(+), 131 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
index dd7e024..79bce76 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
@@ -36,19 +36,32 @@
 import ChPyNetSendPack
 import PlayerDBGSEvent
 import PlayerUniversalGameRec
+import PlayerCompensation
 import IpyGameDataPY
-import MergePlayer
 import PyGameDataStruct
+import CrossRealmPlayer
 import PyDataManager
 import PlayerControl
+import CrossRealmMsg
 import CommFunc
 import PyGameData
 import PlayerGeTui
+import IPY_GameServer
+import PlayerTeam
+import CrossBoss
+import PlayerFB
+
 import time
 
-
-
+''' boss首杀
+ShareDefine.Def_UniversalGameRecType_BossFirstKill
+value1:bossID
+StrValue2:killedTimeStr
+StrValue3:playerName,playerName,...
 '''
+
+
+''' boss击杀信息
 ShareDefine.Def_UniversalGameRecType_BossInfo
 value1:bossID
 value2:killedTime
@@ -99,18 +112,19 @@
     if bossID <= 0:
         return
     
-    # 设置不存活,击杀玩家名
-    killPlayerName = msgList[1]
-    hurtValue = msgList[2]
-    isAddKillCnt = msgList[3]
-    isNotify = msgList[4] if len(msgList) > 4 else True
-    mapID = msgList[5] if len(msgList) > 5 else None
+    bossID, killPlayerName, hurtValue, isNotify, mapID, realMapID, copyMapID, killerIDList = msgList
+    mapID = PlayerFB.GetRecordMapID(mapID)
+    if GameWorld.IsCrossServer():
+        CrossBoss.DoCrossBossOnKilled(bossID, killPlayerName, mapID, realMapID, copyMapID, killerIDList)
+        return
+    
+    isAddKillCnt = False
     
     isMapNeedShunt = IsMapNeedBossShunt(mapID)
     isAlive = __GetIsAlive(bossID)
     
-    GameWorld.DebugLog("击杀世界boss DoGameWorldBossOnKilled...bossID=%s,hurtValue=%s,mapID=%s,tick=%s,isMapNeedShunt=%s,isAlive=%s" 
-                       % (bossID, hurtValue, mapID, tick, isMapNeedShunt, isAlive))
+    GameWorld.Log("击杀世界boss DoGameWorldBossOnKilled...bossID=%s,hurtValue=%s,mapID=%s,tick=%s,isMapNeedShunt=%s,isAlive=%s" 
+                  % (bossID, hurtValue, mapID, tick, isMapNeedShunt, isAlive))
     if isMapNeedShunt and not isAlive:
         GameWorld.DebugLog("需要分流的地图boss被击杀,但是当前boss全局状态为死亡状态,不再更新boss击杀信息!")
         return
@@ -131,7 +145,13 @@
         # 全服广播世界boss变更信息
         Sync_BossInfo(None, [bossID])
         SendMapServerBossKilledCnt(bossID)
-
+        
+    horsePetRobBossIDList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 1)
+    if bossID in horsePetRobBossIDList:
+        OnFamilyKillHorsePetRobBoss(killPlayerName)
+        
+    # boss首杀
+    OnBossFirstKill(bossID, killerIDList)
     return
 
 def __UpdateBossRefreshList(bossID, killedTime=0, refreshTime=0):
@@ -147,29 +167,31 @@
     GameWorld.DebugLog('    PyGameData.g_sortBOSSRefreshList=%s'%PyGameData.g_sortBOSSRefreshList)
     return
 
-## 世界boss重生
-#  @param msgList 信息列表
-#  @param tick 时间戳
-#  @return None
-def DoGameWorldBossOnReborn(msgList, tick):
+def OnGameWorldBossStateChange(msgList, tick):
+    ## 世界boss状态变更
     if len(msgList) <= 0:
         return
-
-    bossID = msgList[0]
-    isAlive = msgList[1]
-    mapID = msgList[2] if len(msgList) > 2 else None
-    lineID = msgList[3] if len(msgList) > 3 else None
-    GameWorld.DebugLog("世界boss DoGameWorldBossOnReborn...mapID=%s,lineID=%s,bossID=%s,state=%s,tick=%s" % (mapID, lineID, bossID, isAlive, tick))
+    
+    bossID, isAlive, mapID, realMapID, copyMapID = msgList
+    mapID = PlayerFB.GetRecordMapID(mapID)
+    if GameWorld.IsCrossServer():
+        CrossBoss.DoCrossBossStateChange(bossID, isAlive, mapID, realMapID, copyMapID)
+        return
+    
+    lineID = copyMapID
+    GameWorld.Log("世界boss状态变更: mapID=%s,lineID=%s,bossID=%s,state=%s,tick=%s" % (mapID, lineID, bossID, isAlive, tick))
     
     if bossID <= 0:
         return
     
+    bossShuntMapIDList = IpyGameDataPY.GetFuncEvalCfg("BossShunt")
+    isBossShuntMap = mapID in bossShuntMapIDList
     isMapNeedShunt = IsMapNeedBossShunt(mapID)
     if not isAlive:
         DoRemoveBossShuntPlayerByNPCID(mapID, lineID, bossID)
         
-    if isMapNeedShunt:
-        __UpdBossLineState(bossID, lineID, isAlive)
+    if isBossShuntMap:
+        __UpdBossLineState(bossID, lineID, isAlive, isMapNeedShunt)
     
     #__GetBossRecDataByID(bossID) # 检查是否有该boss记录,没有的话创建新纪录
     if isAlive != __GetIsAlive(bossID):
@@ -178,30 +200,26 @@
         Sync_BossInfo(None, [bossID])
         
     # 仙盟归属boss的重置
-    if bossID in PyGameData.g_familyOwnerBossInfo:
+    if isAlive and bossID in PyGameData.g_familyOwnerBossInfo:
         PyGameData.g_familyOwnerBossInfo.pop(bossID)
     return
 
-
-def __UpdBossLineState(bossID, lineID, isAlive):
+def __UpdBossLineState(bossID, lineID, isAlive, isMapNeedShunt):
     if lineID == None:
         return
-    bossDeadLineList = PyGameData.g_bossShuntDeadLine.get(bossID, [])
-    if isAlive and lineID in bossDeadLineList:
-        bossDeadLineList.remove(lineID)
-    elif not isAlive and lineID not in bossDeadLineList:
-        bossDeadLineList.append(lineID)
-    else:
+    bossLineStateDict = PyGameData.g_bossShuntLineState.get(bossID, {})
+    if bossLineStateDict.get(lineID) == isAlive:
+        return
+    bossLineStateDict[lineID] = isAlive
+    PyGameData.g_bossShuntLineState[bossID] = bossLineStateDict
+    # 为方便内网清除开服天测试,状态都更新
+    
+    if not isMapNeedShunt:
         return
     
-    PyGameData.g_bossShuntDeadLine[bossID] = bossDeadLineList
-    if not bossDeadLineList:
-        PyGameData.g_bossShuntDeadLine.pop(bossID)
-        
-    if bossID not in PyGameData.g_bossShuntDeadLineChangeBoss:
-        PyGameData.g_bossShuntDeadLineChangeBoss.append(bossID)
-    #GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntDeadLine, PyGameData.g_bossShuntDeadLine)
-    GameWorld.DebugLog("    boss已死亡线路变更: %s" % PyGameData.g_bossShuntDeadLine)
+    if bossID not in PyGameData.g_bossShuntStateChangeBoss:
+        PyGameData.g_bossShuntStateChangeBoss.append(bossID)
+    GameWorld.Log("    分流Boss线路状态变更: %s" % PyGameData.g_bossShuntLineState)
     return
 
 
@@ -212,7 +230,7 @@
     recTypeListData = __GetBossPrizeRecData()
     # 查找是否已有记录
     bossRec = None
-    for index in range(recTypeListData.Count()):
+    for index in xrange(recTypeListData.Count()):
         universalRecData = recTypeListData.At(index)
         if universalRecData.GetValue1() == bossID:
             bossRec = universalRecData
@@ -305,6 +323,32 @@
 #        
 #    return
 
+#// A9 04 查询boss信息 #tagCGQueryBossInfo
+#
+#
+#struct    tagCGQueryBossInfo
+#{
+#    tagHead        Head;
+#    BYTE        Count;    //数量
+#    DWORD        BossIDList[Count];    //boosid
+#};
+def OnQueryBossInfo(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    bossIDList = clientData.BossIDList
+    if not bossIDList:
+        Sync_BossInfo(curPlayer)
+        CrossBoss.Sync_CrossBossInfo(curPlayer)
+        return
+    bossID = bossIDList[0]
+    ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossID)
+    if not ipyData:
+        return
+    mapID = ipyData.GetMapID()
+    if mapID in ChConfig.Def_CrossMapIDList:
+        CrossBoss.Sync_CrossBossInfo(curPlayer, bossIDList)
+    else:
+        Sync_BossInfo(curPlayer, bossIDList)
+    return
 
 
 ## 同步boss相关信息
@@ -318,12 +362,18 @@
     recTypeListData = __GetBossPrizeRecData()
     bossInfo.BossInfoList = []
     #GameWorld.DebugLog("Sync_BossInfo...count=%s,curTime=%s" % (recTypeListData.Count(), curTime))
-    for index in range(recTypeListData.Count()):
+    for index in xrange(recTypeListData.Count()):
         universalRecData = recTypeListData.At(index)
         bossID = universalRecData.GetValue1()
         if not bossID:
             continue
         if syncBOSSIDList and bossID not in syncBOSSIDList:
+            continue
+        ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossID)
+        if not ipyData:
+            continue
+        mapID = ipyData.GetMapID()
+        if mapID in ChConfig.Def_CrossMapIDList:
             continue
         bossInfoObj = ChPyNetSendPack.tagBossInfoObj()
         bossInfoObj.BossID = bossID
@@ -333,6 +383,7 @@
         killedTime = universalRecData.GetValue2() 
         refreshTime = __GetBossRefreshTime(bossInfoObj.BossID)
         bossInfoObj.RefreshSecond = max(0, refreshTime - (curTime - killedTime))
+        bossInfoObj.RefreshCD = refreshTime
         #bossInfoObj.KilledCnt = __GetKilledCnt(universalRecData)
             
         bossInfo.BossInfoList.append(bossInfoObj)
@@ -340,11 +391,14 @@
 #                           % (bossInfoObj.BossID, bossInfoObj.IsAlive, bossInfoObj.KillRecord, 
 #                              killedTime, bossInfoObj.RefreshSecond))
         
+    if not bossInfo.BossInfoList:
+        return
+    
     bossInfo.BossCnt = len(bossInfo.BossInfoList)
     if not curPlayer:
         # 全服广播在线玩家
         playerManager = GameWorld.GetPlayerManager()
-        for i in range(0, playerManager.GetActivePlayerCount()):
+        for i in xrange(playerManager.GetActivePlayerCount()):
             curPlayer = playerManager.GetActivePlayerAt(i)
             if curPlayer == None or not curPlayer.GetInitOK():
                 continue
@@ -364,6 +418,9 @@
     if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossProcessTick, tick):
         #间隔未到 
         return
+    if GameWorld.IsCrossServer():
+        CrossBoss.DoCheckCrossBossReborn(tick)
+        return
     curTime = int(time.time())
     DoCheckWorldBossShuntInfo(curTime, tick)
     BossRebornWorldNotify(curTime)
@@ -371,7 +428,13 @@
         for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):
             ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)
             bossID = ipyData.GetNPCID()
+            mapID = ipyData.GetMapID()
+            if mapID in ChConfig.Def_CrossMapIDList:
+                continue
             bossPrizeRec = __GetBossRecDataByID(bossID)
+            refreshTimeStr = ipyData.GetRefreshTime()
+            if not refreshTimeStr or refreshTimeStr == "0":
+                continue
             killedTime = bossPrizeRec.GetValue2()
             refreshTime = __GetBossRefreshTime(bossID)
             PyGameData.g_sortBOSSRefreshList.append([bossID, killedTime, refreshTime])
@@ -393,7 +456,7 @@
             break
         
         #此处只处理复活的
-        PlayerGeTui.GeTuiBossReborn(bossID)
+        #PlayerGeTui.GeTuiBossReborn(bossID)
         __SetIsAlive(bossID, 1)
         syncBOSSIDList.append(bossID)
         
@@ -408,23 +471,25 @@
 
 #BOSS个推提前倒计时通知处理,   复活由DoCheckWorldBossReborn处理
 def ProcessBossGeTui(tick):
-    if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossGeTuiTick, tick):
-        #间隔未到 
-        return
-    
-    curTime = int(time.time())
-    for bossInfo in PyGameData.g_sortBOSSRefreshList:
-        bossID, killedTime, refreshTime = bossInfo
-        isAlive = __GetIsAlive(bossID)
-        if isAlive:
-            #GameWorld.DebugLog("    bossID=%s,未被击杀!" % bossID)
-            continue
-        rebornSecond = max(0, refreshTime - (curTime - killedTime))
-        if not rebornSecond:
-            #不处理复活BOSS
-            continue
-        
-        PlayerGeTui.GeTuiBoss(bossID, rebornSecond)
+    return
+#    if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossGeTuiTick, tick):
+#        #间隔未到 
+#        return
+#    if GameWorld.IsCrossServer():
+#        return
+#    curTime = int(time.time())
+#    for bossInfo in PyGameData.g_sortBOSSRefreshList:
+#        bossID, killedTime, refreshTime = bossInfo
+#        isAlive = __GetIsAlive(bossID)
+#        if isAlive:
+#            #GameWorld.DebugLog("    bossID=%s,未被击杀!" % bossID)
+#            continue
+#        rebornSecond = max(0, refreshTime - (curTime - killedTime))
+#        if not rebornSecond:
+#            #不处理复活BOSS
+#            continue
+#        
+#        PlayerGeTui.GeTuiBoss(bossID, rebornSecond)
 
 
 def GetBossIsAliveOrCanReborn(bossID):
@@ -444,18 +509,21 @@
     for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):
         ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)
         bossID = ipyData.GetNPCID()
+        mapID = ipyData.GetMapID()
+        if mapID in ChConfig.Def_CrossMapIDList:
+            continue
         isAlive = __GetIsAlive(bossID)
         if not isAlive:
             continue
-        mapID = ipyData.GetMapID()
-        if mapID != ChConfig.Def_FBMapID_SealDemon:
-            GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)
+        #if mapID not in ChConfig.WorldBossFBMapIDList:
+        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)
     return
 
 ## 玩家登录通知
 #  @param curPlayer
 #  @return None
 def OnPlayerLogin(curPlayer):
+    CrossBoss.OnPlayerLogin(curPlayer)
     Sync_BossInfo(curPlayer)
     PyDataManager.GetBossAttentionManager().NotifyBossAttentionInfo(curPlayer)
     if IsMapNeedBossShunt(0):
@@ -471,30 +539,54 @@
 #  @param None
 #  @return None
 def OnMapServerInitOK():
+    if GameWorld.IsCrossServer():
+        CrossBoss.OnCrossMapServerInitOK()
+        return
     SendMapServerBossKilledCnt()
     __SendMapServerAliveBoss()
     if IsMapNeedBossShunt(0):
         GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)
-        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntDeadLine, PyGameData.g_bossShuntDeadLine)
-    #通知一个参数
-    bossID = IpyGameDataPY.GetFuncCfg('DogzFBRefreshCfg', 2)
-    onlineCnt = __GetBossOnlineHeroCnt(bossID)[0]
-    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossOnlineHeroCnt % bossID, onlineCnt)
+        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntLineState, PyGameData.g_bossShuntLineState)
+    
+    #仙盟击杀骑宠boss数
+    if PyGameData.g_familyKillHorsePetRobBossCntDict:
+        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyKillHorsePetRobBossCnt, PyGameData.g_familyKillHorsePetRobBossCntDict)
     return
 
 
 ##--------------------------------------------------------------------------------------------------
 
+def CrossServerMsg_DropGoodItem(msgList, tick):
+    ## 收到跨服服务器同步的掉落好物品信息
+    playerID = msgList[0]
+    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+    if curPlayer:
+        msgList[1] = curPlayer.GetName() # 本服玩家在线,修改为本服玩家的名字展示
+    OnKillBossDropGoodItem(msgList, tick)
+    return
+
 def OnKillBossDropGoodItem(msgList, tick):
     # playerName, mapID, npcID, itemID, userData
-    if len(msgList) != 7:
+    if len(msgList) != 10:
         return
-    playerID, killerName, mapID, npcID, itemID, userData, weightValue = msgList
-    GameWorld.DebugLog("击杀Boss掉落好物品: mapID=%s,npcID=%s,killerName=%s,itemID=%s, userData=%s, weightValue=%s" 
-                       % (mapID, npcID, killerName, itemID, userData, weightValue))
+    playerID, killerName, mapID, lineID, npcID, itemID, userData, weightValue, serverGroupID, playerLV = msgList
+    GameWorld.DebugLog("击杀Boss掉落好物品: mapID=%s,npcID=%s,killerName=%s,itemID=%s, userData=%s, weightValue=%s, serverGroupID=%s" 
+                       % (mapID, npcID, killerName, itemID, userData, weightValue, serverGroupID))
     maxRecordCnt = IpyGameDataPY.GetFuncCfg('DropRecordNum')
     if not maxRecordCnt:
         return
+    
+    if GameWorld.IsCrossServer():
+        # 同步到玩家对应子服
+        if not serverGroupID:
+            return
+        zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID)
+        if not zoneIpyData:
+            return
+        serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_DropGoodItem, msgList, serverGroupIDList)
+        return
+    
     recType = ShareDefine.Def_UniversalGameRecType_BossDropGoodItemInfo
     universalRecMgr = GameWorld.GetUniversalRecMgr()
     recordList = universalRecMgr.GetTypeList(recType)
@@ -522,8 +614,11 @@
             if commonList and commonList[0][0] != -1:
                 recordList.Delete(commonList[0][0])
         
-    PlayerUniversalGameRec.MapServer_UniversalGameRec(None, recType, [mapID, npcID, itemID, playerID, weightValue],
-                                                      [killerName, "", userData])
+    PlayerUniversalGameRec.MapServer_UniversalGameRec(None, recType, [mapID*100+lineID, npcID, itemID, playerID, weightValue],
+                                                      [killerName, '%s|%s'%(serverGroupID, playerLV), userData])
+    
+    msgList = [killerName, playerID, mapID, npcID, itemID, userData, serverGroupID, playerLV, lineID]
+    PlayerControl.WorldNotify(0, 'DropRecord' , msgList)
     return
 
 
@@ -535,11 +630,16 @@
     if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossOnlineCntTick, tick):
         #间隔未到 
         return
+    if GameWorld.IsCrossServer():
+        return
     GameWorld.DebugLog('世界boss在线人数统计')
     bossRebornDict = {}
     for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):
         ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)
         bossID = ipyData.GetNPCID()
+        mapID = ipyData.GetMapID()
+        if mapID in ChConfig.Def_CrossMapIDList:
+            continue
         refreshTimeStr = ipyData.GetRefreshTime()
         if 'onlineCnt' in refreshTimeStr:
             bossRebornDict[bossID] = ipyData.GetLVLimit()
@@ -559,15 +659,6 @@
             if lvLimit[0] <= findLV <= lvLimit[1]:
                 playerCntDict[bossid] = playerCntDict.get(bossid, 0) + 1
     GameWorld.DebugLog('    boss等级信息对应本服在线人数 %s' % playerCntDict)
-    
-    # 此处需要统计累加当前在跨服服务器的玩家
-    mergeServerOnlinePlayerDict = MergePlayer.GetMergeServerOnlinePlayerInfo()
-    for playerInfo in mergeServerOnlinePlayerDict.values():
-        findLV = playerInfo[MergePlayer.Def_MSOLPlayer_LV]
-        for bossid, lvLimit in bossRebornDict.items():
-            if lvLimit[0] <= findLV <= lvLimit[1]:
-                playerCntDict[bossid] = playerCntDict.get(bossid, 0) + 1
-    GameWorld.DebugLog('    boss等级信息对应本服及跨服在线人数 %s' % playerCntDict)
     
     for bossid, curOnlineCnt in playerCntDict.items():
         SetBossOnlineHeroCnt(bossid, curOnlineCnt)
@@ -594,8 +685,6 @@
     
     newNum = newOnlieCnt * 100 + unUpdataCnt
     PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_GameWorldBossOnlineCnt % bossid, newNum)
-    if bossid == IpyGameDataPY.GetFuncCfg('DogzFBRefreshCfg', 2):
-        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossOnlineHeroCnt % bossid, newOnlieCnt)
     GameWorld.DebugLog("设置计算boss刷新时间用的在线人数 Change:bossid=%s, beforeOnlineCnt = %s, newOnlieCnt = %s, unUpdataCnt=%s" % (bossid, beforeOnlineCnt, newOnlieCnt, unUpdataCnt))
     return
 
@@ -607,14 +696,20 @@
 
 def SetBossRefreshTime(bossid, killedTime):
     '''设置boss刷新时间'''
-    ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossid)
+    ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', bossid)
     if not ipyData:
         return
     onlineCnt = __GetBossOnlineHeroCnt(bossid)[0]
+    LVLimit = ipyData.GetLVLimit()
+    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)
+    if openServerDay != 0 and LVLimit and len(LVLimit) == 2:
+        yesterdayCnt = len([1 for lv in PyGameData.g_yesterdayPlayerLVDict.values() if LVLimit[0]<=lv <= LVLimit[1]]) #参数昨日活跃人数
+    else:
+        yesterdayCnt = IpyGameDataPY.GetFuncCfg('FirstDayActivePlayerCnt')
     refreshTime = eval(ipyData.GetRefreshTime())
     PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRefreshTime % bossid, refreshTime)
     __UpdateBossRefreshList(bossid, killedTime, refreshTime)
-    GameWorld.DebugLog('    设置boss刷新时间 BossID=%s,onlineCnt=%s,refreshTime=%s' % (bossid, onlineCnt, refreshTime))
+    GameWorld.DebugLog('    设置boss刷新时间 BossID=%s,onlineCnt=%s,yesterdayCnt=%s,refreshTime=%s' % (bossid, onlineCnt, yesterdayCnt, refreshTime))
     return
 
 
@@ -652,6 +747,7 @@
     def GetBossAttentionDict(self):
         return self.bossAttentionDict
 
+    # RecordData改json记录 bossid存为字符串
     def UpdateBossAttention(self, playerid, bossid, isAdd):
         if playerid in self.bossAttentionDict:
             bossAttentionData = self.bossAttentionDict[playerid]
@@ -693,7 +789,7 @@
         packData.BossList = []
         for bossid, addState in bttentionDict.items():
             bossInfo = ChPyNetSendPack.tagGCBossAttention()
-            bossInfo.BossID=bossid
+            bossInfo.BossID=int(bossid)
             bossInfo.AddState=addState
             packData.BossList.append(bossInfo)
         
@@ -710,7 +806,7 @@
             cnt += 1
             savaData += attentionData.getBuffer()
                 
-        GameWorld.Log("SaveBossAttention cnt :%s" % cnt)
+        GameWorld.Log("SaveBossAttention cnt :%s len=%s" % (cnt, len(savaData)))
         return CommFunc.WriteDWORD(cntData, cnt) + savaData
     
     # 从数据库载入数据
@@ -725,10 +821,7 @@
             data.clear()
             pos += data.readData(datas, pos, dataslen)
             playerID = data.PlayerID
-            if type(eval(data.RecordData)) != list:
-                self.bossAttentionDict[playerID] = data
-            else:
-                data.clear()
+            self.bossAttentionDict[playerID] = data
             
         return pos
 
@@ -799,10 +892,10 @@
 
 def DoCheckWorldBossShuntInfo(curTime, tick):
     ## 定时检查boss分流信息数据
-    if PyGameData.g_bossShuntDeadLineChangeBoss and curTime % 2 == 0:
-        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntDeadLine, PyGameData.g_bossShuntDeadLine)
-        Sync_BossShuntLineInfo(None, PyGameData.g_bossShuntDeadLineChangeBoss)
-        PyGameData.g_bossShuntDeadLineChangeBoss = []
+    if PyGameData.g_bossShuntStateChangeBoss and curTime % 5 == 0:
+        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntLineState, PyGameData.g_bossShuntLineState)
+        Sync_BossShuntLineInfo(None, PyGameData.g_bossShuntStateChangeBoss)
+        PyGameData.g_bossShuntStateChangeBoss = []
         
     if curTime % 10 != 0:
         return
@@ -857,16 +950,23 @@
 def Sync_BossShuntLineInfo(curPlayer=None, syncBOSSIDList=[]):
     
     if not syncBOSSIDList:
-        syncBOSSIDList = PyGameData.g_bossShuntDeadLine.keys()
+        syncBOSSIDList = PyGameData.g_bossShuntLineState.keys()
     
     bossShuntLineInfo = ChPyNetSendPack.tagGCBossShuntLineStateInfo()
     bossShuntLineInfo.Clear()
     bossShuntLineInfo.BossLineStateInfo = []
     for bossID in syncBOSSIDList:
+        bossLineStateDict = PyGameData.g_bossShuntLineState.get(bossID, {})
+        lineIDList = []
+        stateList = []
+        for lineID, state in bossLineStateDict.items():
+            lineIDList.append(lineID)
+            stateList.append(state)
         bossLineState = ChPyNetSendPack.tagGCBossShuntLineState()
         bossLineState.BossID = bossID
-        bossLineState.DeadLineList = PyGameData.g_bossShuntDeadLine.get(bossID, [])
-        bossLineState.DeadLineCount = len(bossLineState.DeadLineList)
+        bossLineState.LineIDList = lineIDList
+        bossLineState.StateList = stateList
+        bossLineState.LineCount = len(bossLineState.LineIDList)
         bossShuntLineInfo.BossLineStateInfo.append(bossLineState)
         
     bossShuntLineInfo.Count = len(bossShuntLineInfo.BossLineStateInfo)
@@ -887,6 +987,11 @@
         NetPackCommon.SendFakePack(curPlayer, bossShuntLineInfo)
     return
 
+def BossRebornOnDayEx():
+    ## boss复活过天
+    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt, 0)
+    Sync_BossRebornPoint()
+    return
 
 def AddBossRebornPoint(addPoint):
     ## 增加boss复活点
@@ -902,16 +1007,24 @@
     if not totalPoint:
         GameWorld.Log(' 增加boss复活点 没有总点数!!!!')
         return
+    rebornCnt = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt)
+    maxRebornCnt = IpyGameDataPY.GetFuncCfg('BossRebornTotalPoint', 3)
+    if maxRebornCnt and rebornCnt >= maxRebornCnt:
+        GameWorld.DebugLog(' boss复活已达到最大次数! maxRebornCnt=%s' % maxRebornCnt)
+        return
+    
     curPoint = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint)
     
     updPoint = (curPoint+addPoint)%totalPoint
     PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint, updPoint)
     if curPoint+addPoint >= totalPoint:
         #重生boss
+        PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt, rebornCnt+1)
+        
         killBossCntLimitDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 1, {})
         canRebornBossIDList = []
         for bidlist, bkey in killBossCntLimitDict.items():
-            if bkey not in [0, 1]:
+            if bkey not in [ShareDefine.Def_Boss_Func_World, ShareDefine.Def_Boss_Func_Home]:
                 continue
             canRebornBossIDList += list(bidlist)
         
@@ -927,8 +1040,12 @@
             refreshTime = 0
             PyGameData.g_sortBOSSRefreshList[i] = [bossID, killedTime, refreshTime]
             bossIDList.append(bossID)
+        curTime = int(time.time())
+        PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1])))
         GameWorld.Log(' boss复活活动 重生boss bossIDList=%s'%bossIDList)
-        g_lastBossRebornTime = int(time.time())
+        g_lastBossRebornTime = curTime
+        
+        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ActionBossRebornSign % ShareDefine.OperationActionName_BossReborn, int(time.time()))
     else:
         #广播
         needNotifyPointPerList = IpyGameDataPY.GetFuncEvalCfg('BossRebornNotify')
@@ -945,6 +1062,8 @@
 def ResetBossRebornPoint():
     ## 重置boss复活点
     PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint, 0)
+    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt, 0)
+    
     # 活动开启时设置参数 服务器人数
     lvLimit = IpyGameDataPY.GetFuncCfg('ServerActivePlayerCnt')
     yesterdayPlayerCnt = len([1 for lv in PyGameData.g_yesterdayPlayerLVDict.values() if lv >= lvLimit]) #参数昨日活跃人数
@@ -996,6 +1115,8 @@
     if not totalPoint:
         totalPoint = SetBossRebornNeedPoint()
     packData.TotalPoint = totalPoint
+    packData.RebornCnt = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt)
+    packData.TotalRebornCnt = IpyGameDataPY.GetFuncCfg('BossRebornTotalPoint', 3)
     playerManager = GameWorld.GetPlayerManager()
     if not curPlayer:
         for i in xrange(playerManager.GetActivePlayerCount()):
@@ -1011,35 +1132,91 @@
         NetPackCommon.SendFakePack(curPlayer, packData)
     return
 
-def Sync_DogzNPCRefreshTime(msgList):
-    #同步神兽副本NPC刷新时间
-    playerID, refreshTimeDict = msgList
-    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if playerID else None
-    if playerID and not curPlayer:
+## -----------------------------------------------------------------------------------------------
+
+def OnFamilyKillHorsePetRobBoss(killFamilyName):
+    ## 仙盟击杀骑宠boss
+    
+    family = GameWorld.GetFamilyManager().FindFamilyByName(killFamilyName)
+    if not family:
+        GameWorld.ErrLog("找不到该仙盟名: killFamilyName=%s" % killFamilyName)
         return
-    if not refreshTimeDict:
+    
+    familyID = family.GetID()
+    PyGameData.g_familyKillHorsePetRobBossCntDict[familyID] = PyGameData.g_familyKillHorsePetRobBossCntDict.get(familyID, 0) + 1
+    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyKillHorsePetRobBossCnt, PyGameData.g_familyKillHorsePetRobBossCntDict)
+    GameWorld.Log("骑宠争夺仙盟击杀Boss数统计: %s" % PyGameData.g_familyKillHorsePetRobBossCntDict)
+    return
+
+def SyncMapServer_HorsePetRobBossPlayerCount():
+    ## 活动开始前,同步有效活动人数到地图,作为Boss属性成长系数用
+    
+    diffWorldLV = int(IpyGameDataPY.GetFuncCfg("FairyGrabBossID", 3))
+    funcLimitLV = PlayerControl.GetFuncLimitLV(ShareDefine.GameFuncID_HorsePetRobBoss)
+    curWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
+    minLV = max(funcLimitLV, curWorldLV + diffWorldLV)
+    
+    playerCount = 0
+    playerManager = GameWorld.GetPlayerManager()
+    for i in xrange(playerManager.GetActivePlayerCount()):
+        findPlayer = playerManager.GetActivePlayerAt(i)
+        if findPlayer == None or not findPlayer.GetInitOK():
+            continue
+        
+        if PlayerControl.GetIsTJG(findPlayer):
+            continue
+        
+        if not findPlayer.GetFamilyID():
+            continue
+        
+        if findPlayer.GetLV() < minLV:
+            continue
+        
+        playerCount += 1
+        
+    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_HorsePetRobBossPlayerCount, playerCount)
+    GameWorld.Log("同步骑宠争夺有效参与人数: playerCount=%s,minLV=%s,funcLimitLV=%s,curWorldLV=%s,diffWorldLV=%s" 
+                  % (playerCount, minLV, funcLimitLV, curWorldLV, diffWorldLV))
+    return
+
+def OnHorsePetRobBossActionChange(isOpen):
+    ## 骑宠争夺活动状态变更
+    
+    # 无论开关都重置, 服务器活动中维护暂时不处理
+    PyGameData.g_familyKillHorsePetRobBossCntDict = {}
+    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyKillHorsePetRobBossCnt, PyGameData.g_familyKillHorsePetRobBossCntDict)
+    
+    
+    return
+
+def MapServer_HorsePetRobBossHurtPlayer(msgInfo):
+    ## 骑宠争夺boss伤血玩家同步
+    GameWorld.Log("骑宠争夺boss伤血玩家同步: %s" % str(msgInfo))
+    if not isinstance(msgInfo, list) and len(msgInfo) != 2:
         return
-    packData = ChPyNetSendPack.tagGCDogzNPCRefreshTime()
-    packData.InfoList=[]
-    for npcid, rTime in refreshTimeDict.items():
-        timeInfo = ChPyNetSendPack.tagDogzTimeInfoObj()
-        timeInfo.NPCID = npcid
-        timeInfo.RefreshSecond = rTime
-        packData.InfoList.append(timeInfo)
-    packData.Cnt = len(packData.InfoList)
-    if not playerID:
-        playerManager = GameWorld.GetPlayerManager()
-        for i in xrange(playerManager.GetActivePlayerCount()):
-            curPlayer = playerManager.GetActivePlayerAt(i)
-            if curPlayer == None or not curPlayer.GetInitOK():
-                continue
-            if PlayerControl.GetIsTJG(curPlayer):
-                continue
-            NetPackCommon.SendFakePack(curPlayer, packData)
-    else:
-        if PlayerControl.GetIsTJG(curPlayer):
+    
+    bossID, familyHurtPlayerIDListDict = msgInfo
+    PyGameData.g_horsePetRobBossHurtPlayerIDInfo[bossID] = familyHurtPlayerIDListDict
+    GameWorld.Log("伤血玩家汇总: %s" % PyGameData.g_horsePetRobBossHurtPlayerIDInfo)
+    
+    # 判断是否都同步上来了
+    horsePetRobBossIDList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 1)
+    for needBossID in horsePetRobBossIDList:
+        if needBossID not in PyGameData.g_horsePetRobBossHurtPlayerIDInfo:
             return
-        NetPackCommon.SendFakePack(curPlayer, packData)
+        
+    # 结算活动参与奖励
+    joinAwardItemList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 2)
+    joinPlayerIDList = []
+    for familyHurtPlayerIDDict in PyGameData.g_horsePetRobBossHurtPlayerIDInfo.values():
+        for playerIDList in familyHurtPlayerIDDict.values():
+            for playerID in playerIDList:
+                if playerID not in joinPlayerIDList:
+                    joinPlayerIDList.append(playerID)
+                    
+    GameWorld.Log("结算骑宠争夺参与奖玩家: joinPlayerIDList=%s" % joinPlayerIDList)
+    PlayerCompensation.SendMailByKey("FairyGrabBossJoin", joinPlayerIDList, joinAwardItemList)
+    PyGameData.g_horsePetRobBossHurtPlayerIDInfo = {}
     return
 
 def MapServer_FamilyOwnerBossInfo(msgInfo):
@@ -1050,6 +1227,7 @@
         return
     
     PyGameData.g_familyOwnerBossInfo.update(msgInfo)
+    #GameWorld.DebugLog("    PyGameData.g_familyOwnerBossInfo=%s" % PyGameData.g_familyOwnerBossInfo)
     return
 
 #// AC 04 查询仙盟抢Boss所有Boss当前进度 #tagCGQueryAllFamilyBossHurt
@@ -1079,3 +1257,134 @@
     NetPackCommon.SendFakePack(curPlayer, hurtPack)
     return
 
+#// AC 05 召集仙盟成员打boss #tagCGCallupFamilyMemberToBoss
+#
+#struct    tagCGCallupFamilyMemberToBoss
+#{
+#    tagHead        Head;
+#    DWORD        NPCID;
+#};
+def OnCallupFamilyMemberToBoss(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    npcID = clientData.NPCID
+    
+    curFamily = curPlayer.GetFamily()
+    if curFamily == None:
+        return
+    curMember = curFamily.FindMember(playerID)
+    if curMember == None:
+        return
+    if curMember.GetFamilyLV() == IPY_GameServer.fmlMember:
+        GameWorld.DebugLog("普通成员无法召集!", playerID)
+        return
+    PlayerControl.FamilyNotify(curFamily.GetID(), "FairyGrabBossHelp", [curPlayer.GetName(), npcID])
+    return
+
+## -------------------------------------- boss 首杀 ------------------------------------------------
+def __GetBossFirstKillRecDataList():
+    ## 获取boss首杀记录信息列表
+    return GameWorld.GetUniversalRecMgr() .GetTypeList(ShareDefine.Def_UniversalGameRecType_BossFirstKill)
+
+def __GetBossFirstKillRecDataByID(bossID):
+    ## 获取boss首杀记录信息数据
+    
+    recTypeListData = __GetBossFirstKillRecDataList()
+    # 查找是否已有记录
+    bossFirstKillRec = None
+    for index in xrange(recTypeListData.Count()):
+        universalRecData = recTypeListData.At(index)
+        if universalRecData.GetValue1() == bossID:
+            bossFirstKillRec = universalRecData
+            break
+        
+    if bossFirstKillRec == None:
+        #还未记录,则添加一个记录对象
+        bossFirstKillRec = recTypeListData.AddRec()        
+        bossFirstKillRec.SetValue1(bossID)
+        
+    return bossFirstKillRec
+
+def OnBossFirstKill(bossID, killerIDList):
+    ## 处理boss首杀逻辑
+    
+    maxOSDay = IpyGameDataPY.GetFuncCfg("OSCBossFirstKill", 1)
+    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
+    if openServerDay > maxOSDay:
+        GameWorld.DebugLog("超过开服天(%s), 不开放首杀活动!" % maxOSDay)
+        return
+    
+    if not bossID or not killerIDList:
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", bossID)
+    if not ipyData:
+        return
+    
+    fkRecData = __GetBossFirstKillRecDataByID(bossID)
+    if not fkRecData:
+        return
+    
+    firstKillTimeStr = fkRecData.GetStrValue2()
+    if firstKillTimeStr:
+        GameWorld.DebugLog("已经首杀过了! bossID=%s, %s" % (bossID, firstKillTimeStr))
+        return
+    
+    killPlayerList = []
+    playerMgr = GameWorld.GetPlayerManager()
+    for playerID in killerIDList:
+        player = playerMgr.FindPlayerByID(playerID)
+        if not player:
+            continue
+        teamMemLV = PlayerTeam.__GetPlayerTeamLV(player)
+        killPlayerList.append([teamMemLV, player.GetName()])
+    if not killPlayerList:
+        return
+    
+    killPlayerList.sort(reverse=True)
+    fkPlayerNameList = [nameInfo[1] for nameInfo in killPlayerList]
+    
+    fkRecData.SetStrValue2(GameWorld.GetCurrentDataTimeStr())
+    fkRecData.SetStrValue3(",".join(fkPlayerNameList))
+    
+    # 首杀奖励邮件
+    PlayerCompensation.SendMailByKey("BossFirstKillMail", killerIDList, ipyData.GetServerFirstKillPlayerAward(), [bossID])
+    
+    ## 主动广播全服玩家
+    PlayerUniversalGameRec.SendUniversalGameRecSingle(None, fkRecData)
+    return
+
+
+#// A9 01 获取Boss首杀奖励 #tagCGGetBossFirstKillAward
+#
+#struct    tagCGGetBossFirstKillAward
+#{
+#    tagHead    Head;
+#    DWORD    NPCID;
+#    BYTE    AwardType;    // 0-首杀红包奖励;1-个人首杀奖励
+#};
+def OnGetBossFirstKillAward(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    bossID = clientData.NPCID
+    awardType = clientData.AwardType
+    
+    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", bossID)
+    if not ipyData:
+        return
+    
+    if awardType == 0:
+        fkRecData = __GetBossFirstKillRecDataByID(bossID)
+        if not fkRecData:
+            return
+        
+        firstKillTimeStr = fkRecData.GetStrValue2()
+        if not firstKillTimeStr:
+            GameWorld.DebugLog("Boss还未首杀,不能领取boss首杀公共红包奖励! bossID=%s" % (bossID), curPlayer.GetPlayerID())
+            return
+        
+    msgInfo = str([bossID, awardType])
+    curPlayer.MapServer_QueryPlayerResult(0, 0, "BossFirstKill", msgInfo, len(msgInfo))
+    return
+
+## ------------------------------------------------------------------------------------------------
+

--
Gitblit v1.8.0