From a5704bbcc5d2b17998615e9af7f497498a79f90f Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 25 六月 2024 16:15:46 +0800
Subject: [PATCH] 10185 【越南】【港台】【主干】BOSS凭证修改(排行榜优化;跨服榜查看改为直接查跨服数据,支持分页查询;跨服凭证个人榜单最大调整为1000条,其他100;)

---
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py |  137 ++++++++++++++++++++++++++++++---------------
 1 files changed, 92 insertions(+), 45 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
index aee6b1f..42fd0af 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
@@ -28,8 +28,6 @@
 import operator
 import time
 
-Def_CrossBillboard_MaxDataCount = 200 # 跨服榜单数据最大条数暂固定最大为100条,如有需要调整需针对实际情况进行评估(如数据同步、同步封包等)
-
 class CrossBillboardManager(object):
     ## 跨服排行榜管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
     
@@ -112,6 +110,7 @@
         self.__billboardType = billboardType
         self.__groupValue1 = groupValue1
         self.__groupValue2 = groupValue2
+        self.__maxCount = ShareDefine.CrossBillboard_MaxDataCount.get(billboardType, 100)
         self.__crossServerDataVer = 0 # 主服榜单数据版本
         self.__clientServerDataVer = 0 # 子服榜单数据版本
         self.__billboardList = [] # [tagDBCrossBillboard, ...] 
@@ -159,6 +158,17 @@
         order = idOrderDict[findID]
         return self.__billboardList[order - 1]
     
+    def IndexOfByID(self, findID):
+        ''' 根据ID查询所在榜单索引
+        @param findID: 查找的ID
+        @return: -1 or >=0
+        '''
+        idOrderDict = self.GetIDOrderDict()
+        if findID not in idOrderDict:
+            return -1
+        order = idOrderDict[findID]
+        return order - 1
+    
     def SaveDRData(self):
         ## 记录流向数据
         eventTypeName = "CrossBillboard_%s" % (self.__billboardType)
@@ -189,10 +199,10 @@
         return self.__idOrderDict
     
     def GetCount(self): return len(self.__billboardList)
-    def GetMaxCount(self): return Def_CrossBillboard_MaxDataCount
+    def GetMaxCount(self): return self.__maxCount
     
     def At(self, i): return self.__billboardList[i]
-    def IsFull(self): return len(self.__billboardList) >= Def_CrossBillboard_MaxDataCount
+    def IsFull(self): return len(self.__billboardList) >= self.__maxCount
     
     def UpdCrossServerDataVer(self, version=None):
         ## 更新跨服榜单数据版本号,用于跨服主服、子服验证数据版本,同步榜单数据用
@@ -201,7 +211,7 @@
         if version == None:
             version = int(time.time())
         self.__crossServerDataVer = version
-        SyncCrossBillboardToClientServer(self.__billboardType, self.__groupValue1, self.__groupValue2)
+        #SyncCrossBillboardToClientServer(self.__billboardType, self.__groupValue1, self.__groupValue2)
         return
     def GetCrossServerDataVer(self): return self.__crossServerDataVer
     
@@ -316,6 +326,9 @@
 #    BYTE        Type;        //榜单类型
 #    BYTE        GroupValue1;    // 分组值1
 #    BYTE        GroupValue2;    // 分组值2,与分组值1组合归为同组榜单数据
+#    DWORD        StartIndex;    //查看的起始名次索引, 默认0
+#    BYTE        WatchCnt;    //查看条数,默认20,最大不超过100
+#    BYTE        IsWatchSelf;    //是否查看自己名次前后,默认10条数据
 #};
 def OnViewCrossBillboard(index, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
@@ -323,21 +336,20 @@
         return
     playerID = curPlayer.GetPlayerID()
     billboardType, groupValue1, groupValue2 = clientData.Type, clientData.GroupValue1, clientData.GroupValue2
+    startIndex = clientData.StartIndex
+    watchCnt = clientData.WatchCnt
+    isWatchSelf = clientData.IsWatchSelf
     
     if billboardType not in ShareDefine.CrossBillboardTypeList:
         return
     
-    billboardMgr = PyDataManager.GetCrossBillboardManager()
-    billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
+    # 支持分页查询,改为直接查跨服服务器
     
     GameWorld.DebugLog("玩家请求查看跨服排行榜: billboardType=%s,groupValue1=%s,groupValue2=%s" % (billboardType, groupValue1, groupValue2))
-    if not billboardObj.CheckClientServerDataVer():
-        SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardObj.GetBillboardDataList())
-        return
     
     # 请求查询跨服服务器
     dataMsg = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2,
-               "QueryData":{"EventName":"View", "PlayerID":playerID}}
+               "QueryData":{"EventName":"View", "PlayerID":playerID, "StartIndex":startIndex, "WatchCnt":watchCnt, "IsWatchSelf":isWatchSelf}}
     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryBillboard, dataMsg)
     return
 
@@ -366,9 +378,39 @@
     
     # 有查询数据时才同步榜单数据列表,否则只同步数据版本号
     if queryData:
+        playerID = queryData.get("PlayerID", 0)
+        startIndex = queryData.get("StartIndex", 0)
+        watchCnt = queryData.get("WatchCnt", 0)
+        isWatchSelf = queryData.get("IsWatchSelf", 0)
+        
+        count = billboardObj.GetCount()
+        endIndex = 0
+        # 查看自己前后名次
+        if isWatchSelf:
+            playerIndex = billboardObj.IndexOfByID(playerID)
+            if playerIndex != -1:
+                # 前5后4,首尾补足10条记录
+                endIndex = min(playerIndex + 5, count)
+                startIndex = max(0, endIndex - 10)
+                endIndex = min(endIndex + (10 - (endIndex - startIndex)), count)
+            else:
+                startIndex = 0
+                
+        # 指定索引分页查看
+        else:
+            startIndex = max(startIndex, 0)
+            startIndex = min(startIndex, count)
+            watchCnt = 20 if not watchCnt else min(watchCnt, 100) # 默认20,最多100
+            endIndex = min(startIndex + watchCnt, count)
+            
         syncBillboardList = []
-        billboardList = billboardObj.GetBillboardDataList()
-        for billboardData in billboardList:
+        for index in xrange(startIndex, endIndex):
+            
+            if startIndex < 0 or index >= count:
+                break
+            
+            billboardData = billboardObj.At(index)
+            
             ID = billboardData.ID
             ID2 = billboardData.ID2
             Name1 = billboardData.Name1
@@ -386,7 +428,7 @@
             CmpValue = billboardData.CmpValue
             CmpValue2 = billboardData.CmpValue2
             CmpValue3 = billboardData.CmpValue3
-            syncBillboardList.append([ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData])
+            syncBillboardList.append([index, ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData])
         msgData["BillboardDataList"] = syncBillboardList
         
     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_SyncBillboard, msgData, serverGroupIDList)
@@ -402,16 +444,16 @@
     GameWorld.DebugLog("收到跨服服务器同步的排行榜信息: billboardType=%s,groupValue1=%s,groupValue2=%s,crossServerDataVer=%s" 
                        % (billboardType, groupValue1, groupValue2, crossServerDataVer))
     
-    billboardMgr = PyDataManager.GetCrossBillboardManager()
-    billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
-    billboardObj.UpdClientServerBillboard(crossServerDataVer, syncBillboardList)
+    #billboardMgr = PyDataManager.GetCrossBillboardManager()
+    #billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
+    #billboardObj.UpdClientServerBillboard(crossServerDataVer, syncBillboardList)
     
     queryData = msgData.get("QueryData")
     if not queryData:
         return
     
     eventName = queryData.get("EventName")
-    eventData = queryData.get("EventData")
+    #eventData = queryData.get("EventData")
     queryPlayerID = queryData.get("PlayerID", 0)
     if not eventName or not queryPlayerID:
         return
@@ -421,40 +463,45 @@
         return
     
     if eventName == "View":        
-        SyncCrossBillboardToPlayer(queryPlayer, billboardType, groupValue1, groupValue2, billboardObj.GetBillboardDataList())
-    else:
-        idOrderDict = billboardObj.GetIDOrderDict()
-        order = idOrderDict.get(queryPlayerID, 0)
-        sysMsg = str([billboardType, groupValue1, groupValue2, eventName, eventData, order])
-        queryPlayer.MapServer_QueryPlayerResult(0, 0, "CrossBillboardOrder", sysMsg, len(sysMsg))
+        isWatchSelf = queryData.get("IsWatchSelf", 0)
+        SyncCrossBillboardToPlayer(queryPlayer, billboardType, groupValue1, groupValue2, syncBillboardList, isWatchSelf)
+    #else:
+    #    idOrderDict = billboardObj.GetIDOrderDict()
+    #    order = idOrderDict.get(queryPlayerID, 0)
+    #    sysMsg = str([billboardType, groupValue1, groupValue2, eventName, eventData, order])
+    #    queryPlayer.MapServer_QueryPlayerResult(0, 0, "CrossBillboardOrder", sysMsg, len(sysMsg))
         
     return
 
-def SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardList):
+def SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardList, isWatchSelf):
     ## 同步给玩家跨服榜单
     billboardInfo = ChPyNetSendPack.tagGCCrossBillboardInfo()
     billboardInfo.Type = billboardType
     billboardInfo.GroupValue1 = groupValue1
     billboardInfo.GroupValue2 = groupValue2
+    billboardInfo.IsWatchSelf = isWatchSelf
     billboardInfo.CrossBillboardDataList = []
-    for billboardData in billboardList:
+    for dataInfo in billboardList:
+        index, ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData = dataInfo
         billboardInfoData = ChPyNetSendPack.tagGCCrossBillboardData()
-        billboardInfoData.ID = billboardData.ID
-        billboardInfoData.Name1 = billboardData.Name1
-        billboardInfoData.Name2 = billboardData.Name2
-        billboardInfoData.Type2 = billboardData.Type2
-        billboardInfoData.Value1 = billboardData.Value1
-        billboardInfoData.Value2 = billboardData.Value2
-        billboardInfoData.Value3 = billboardData.Value3
-        billboardInfoData.Value4 = billboardData.Value4
-        billboardInfoData.Value5 = billboardData.Value5
-        billboardInfoData.Value6 = billboardData.Value6
-        billboardInfoData.Value7 = billboardData.Value7
-        billboardInfoData.Value8 = billboardData.Value8
-        billboardInfoData.CmpValue = billboardData.CmpValue
-        billboardInfoData.CmpValue2 = billboardData.CmpValue2
-        billboardInfoData.CmpValue3 = billboardData.CmpValue3
-        billboardInfoData.UserData = billboardData.UserData
+        billboardInfoData.OrderIndex = index
+        billboardInfoData.ID = ID
+        billboardInfoData.ID2 = ID2
+        billboardInfoData.Name1 = Name1
+        billboardInfoData.Name2 = Name2
+        billboardInfoData.Type2 = Type2
+        billboardInfoData.Value1 = Value1
+        billboardInfoData.Value2 = Value2
+        billboardInfoData.Value3 = Value3
+        billboardInfoData.Value4 = Value4
+        billboardInfoData.Value5 = Value5
+        billboardInfoData.Value6 = Value6
+        billboardInfoData.Value7 = Value7
+        billboardInfoData.Value8 = Value8
+        billboardInfoData.CmpValue = CmpValue
+        billboardInfoData.CmpValue2 = CmpValue2
+        billboardInfoData.CmpValue3 = CmpValue3
+        billboardInfoData.UserData = UserData
         billboardInfoData.DataLen = len(billboardInfoData.UserData)
         billboardInfo.CrossBillboardDataList.append(billboardInfoData)
     billboardInfo.BillboardCount = len(billboardInfo.CrossBillboardDataList)
@@ -507,8 +554,8 @@
             and (not cmpValue3 or cmpValue3 == billboardData.CmpValue3) \
             and value1 == billboardData.Value1 and value2 == billboardData.Value2 \
             and value3 == billboardData.Value3 and value4 == billboardData.Value4 \
-            and value5 == billboardData.Value1 and value6 == billboardData.Value6 \
-            and value7 == billboardData.Value1 and value8 == billboardData.Value8 \
+            and value5 == billboardData.Value5 and value6 == billboardData.Value6 \
+            and value7 == billboardData.Value7 and value8 == billboardData.Value8 \
             and name1 == billboardData.Name1 and name2 == billboardData.Name2 \
             and type2 == billboardData.Type2 and id2 == billboardData.ID2 and userData == billboardData.UserData:
             GameWorld.DebugLog("    榜单值相同,不同步跨服服务器! ")
@@ -625,7 +672,7 @@
             if not billboardObj.AddBillboardData(billboardData):
                 return
             
-    cmpValueChange = isNewData or billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2 or billboardData.CmpValue3 != cmpValue3
+    cmpValueChange = isNewData or billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2 or (cmpValue3 and billboardData.CmpValue3 != cmpValue3)
     # 没设置值默认为时间time,先上榜的排前面
     if cmpValue3 == 0:
         # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题

--
Gitblit v1.8.0