From ea6dff19b5877d55473d445788e1a2ff5789f6b9 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 17 三月 2026 10:01:57 +0800
Subject: [PATCH] 526 【挑战】PVP群英榜-后端(战斗日志Value1增加存储ServerID;群英榜单10的UserData增加Json格式存储FightPower;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBBillboard.py | 107 +++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 86 insertions(+), 21 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBBillboard.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBBillboard.py
index 552dd85..e17269f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBBillboard.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBBillboard.py
@@ -22,14 +22,17 @@
import IpyGameDataPY
import DBDataMgr
import CommFunc
+import DBComm
import json
+import time
class BillboardData():
## 榜单数据
def __init__(self, dbData=None):
self.__dbData = DBStruct.tagDBBillboard() if not dbData else dbData
+ self.__dataDict = DBComm.UserDataDict(self.__dbData, "UserData", "DataLen", True)
return
def GetType(self): return self.__dbData.BillboardType
@@ -70,17 +73,11 @@
def SetCmpValue2(self, cmpValue2): self.__dbData.CmpValue2 = cmpValue2
def GetCmpValue3(self): return self.__dbData.CmpValue3
def SetCmpValue3(self, cmpValue3): self.__dbData.CmpValue3 = cmpValue3
- def GetUserData(self): return self.__dbData.UserData
- def SetUserData(self, userData):
- if not isinstance(userData, str):
- if isinstance(userData, dict) or isinstance(userData, list):
- userData = json.dumps(userData, ensure_ascii=False)
- else:
- userData = ""
- userData = userData.replace(" ", "")
- self.__dbData.UserData = userData
- self.__dbData.DataLen = len(self.__dbData.UserData)
- return
+ def GetTime(self): return self.__dbData.Time
+ def SetTime(self, updTime): self.__dbData.Time = updTime
+ def GetUserDict(self): return self.__dataDict.GetData()
+ def GetUserData(self): return self.__dataDict.ToString()
+ def SetUserData(self, value): self.__dataDict.SetData(value)
def GetBuffer(self): return self.__dbData.getBuffer()
def Clear(self): return self.__dbData.clear()
def Copy(self, setType=None):
@@ -105,8 +102,11 @@
copyData.SetCmpValue(self.GetCmpValue())
copyData.SetCmpValue2(self.GetCmpValue2())
copyData.SetCmpValue3(self.GetCmpValue3())
+ copyData.SetTime(self.GetTime())
return copyData
+TempBillData = BillboardData()
+
class Billboard():
## 某个排行榜类
@@ -117,21 +117,26 @@
self.__billboardList = [] # [BillboardData, ...]
self.__idIndexDict = {} # {id:index, ...}
self.__idOrderDict = {} # {id:名次, ...}
- self.__orderRuleList = None # 指定排名所需值规则列表 [[order, needCmpValue], ...]
self.__sortDelay = False # 是否需要延迟排序
+ self.__orderRuleList = None # 指定排名所需值规则列表 [[order, needCmpValue], ...]
+
+ # 【层级模式】机器人填充数据模式,一般如果机器人数据量比较大的情况下实用该模式,如群英榜
+ # 层级模式下,因为机器人数量一般比较大,比如1万,为了节约内存占用及遍历排序等效率,填充的机器人数据不插入实际的 __billboardList 里
+ self.__orderRuleByLayer = False # 按固定层级模式,第1层即第1名,CmpValue直接使用名次值,方便排序用,由功能自行管理好CmpValue值
+ self.__layerIDList = [] # 层级ID列表,顺序即排名,索引0为第1名,ID包含填充的机器人ID,初始的数据由功能按规则设置填充的机器人ID
return
def GetType(self): return self.__billboardType
def GetGroupValue1(self): return self.__groupValue1
def GetGroupValue2(self): return self.__groupValue2
- def ClearData(self):
+ def ClearData(self, drName=""):
if not self.__billboardList:
return
- GameWorld.Log("Billboard ClearData billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s"
- % (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList)))
- if GameWorld.IsCrossServer():
- self.SaveDRData("Clear")
+ GameWorld.Log("Billboard ClearData billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s,drName=%s"
+ % (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList), drName))
+ if drName or GameWorld.IsCrossServer():
+ self.SaveDRData(drName if drName else "Clear")
self.__billboardList = [] # [BillboardData, ...]
self.__idOrderDict = {} # {id:名次, ...}
self.__idIndexDict = {}
@@ -140,10 +145,15 @@
def SortData(self):
GameWorld.DebugLog("榜单排序: billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s"
% (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList)))
- self.__billboardList.sort(key=lambda b: (b.GetCmpValue(), b.GetCmpValue2(), b.GetCmpValue3()), reverse=True)
+ if self.__orderRuleByLayer:
+ self.__billboardList.sort(key=lambda b: (-b.GetCmpValue(), -b.GetTime()), reverse=True)
+ else:
+ self.__billboardList.sort(key=lambda b: (b.GetCmpValue(), b.GetCmpValue2(), b.GetCmpValue3(), -b.GetTime()), reverse=True)
self.__idOrderDict = {} # 排序后重置,下次查询时更新并缓存
self.__idIndexDict = {}
self.__sortDelay = False
+ if self.__orderRuleByLayer:
+ self.__fixAndFillLayer()
return
def SetSortDelay(self):
@@ -158,9 +168,9 @@
if not self.__sortDelay:
return
self.SortData()
- return
+ return True
- def AddNewBillboardData(self):
+ def AddNewBillboardData(self, dataID):
newData = None
if self.IsFull():
return newData
@@ -168,6 +178,7 @@
newData.SetType(self.__billboardType)
newData.SetGroupValue1(self.__groupValue1)
newData.SetGroupValue2(self.__groupValue2)
+ newData.SetID(dataID)
self.AddBillboardData(newData)
return newData
@@ -238,7 +249,7 @@
"Value5":bData.GetValue5(), "Value6":bData.GetValue6(),
"Value7":bData.GetValue7(), "Value8":bData.GetValue8(),
"CmpValue":bData.GetCmpValue(), "CmpValue2":bData.GetCmpValue2(),
- "CmpValue3":bData.GetCmpValue3(), "UserData":bData.GetUserData()}
+ "CmpValue3":bData.GetCmpValue3(), "Time":bData.GetTime(), "UserData":bData.GetUserData()}
DataRecordPack.SendEventPack(eventTypeStr, dataDict)
return
@@ -269,12 +280,66 @@
billboardIndex += 1
for order, billboardData in enumerate(self.__billboardList, 1):
self.__idIndexDict[billboardData.GetID()] = order - 1
+ # 按层级固定排位的
+ elif self.__orderRuleByLayer:
+ if not self.SortDelayDo():
+ self.__fixAndFillLayer()
else:
for order, billboardData in enumerate(self.__billboardList, 1):
self.__idOrderDict[billboardData.GetID()] = order
self.__idIndexDict[billboardData.GetID()] = order - 1
return self.__idOrderDict
+ def IsOrderRuleByLayer(self): return self.__orderRuleByLayer
+ def SetOrderRuleByLayer(self, layerRobotIDList):
+ '''设置排名规则为层级模式,即一个名次一个坑位层级,该模式支持机器人填充数据
+ 该模式下 CmpValue 固定为 MaxCount - 名次 + 1
+ @param layerRobotIDList: 填充的机器人ID排名列表
+ '''
+ self.__orderRuleByLayer = True
+ self.__layerIDList = layerRobotIDList
+ self.SortData() # 强制排序处理
+ return
+ def SetLayerIDList(self, layerIDList): self.__layerIDList = layerIDList
+ def GetLayerIDList(self): return self.__layerIDList
+ def __fixAndFillLayer(self):
+ ## 检查修正并填充满最终层级ID顺序
+ maxCount = self.GetMaxCount()
+ layerIDCnt = len(self.__layerIDList)
+ if layerIDCnt < maxCount:
+ self.__layerIDList.extend([0]*(maxCount-layerIDCnt)) # 先用0填充,确保长度一致
+
+ # 先检查修正真实榜单数据的排名值,确保唯一
+ orderIDDict = {}
+ for index, billboardData in enumerate(self.__billboardList):
+ dataID = billboardData.GetID()
+ order = billboardData.GetCmpValue()
+ if order > maxCount:
+ # 超过的默认不上榜,后面的数据不再处理,外层的数据使用替换的模式,故理论上不会有多余的数据,这里暂做个防范
+ break
+ if order <= 0:
+ # 没有名次数据的也不上榜,但先跳过继续处理后面的数据
+ continue
+
+ while 1 <= order <= maxCount:
+ if order not in orderIDDict:
+ orderIDDict[order] = dataID
+ self.__idOrderDict[dataID] = order
+ self.__idIndexDict[dataID] = index
+ break
+ # 重复的数据修正层级比较值,确保唯一
+ order += 1
+ billboardData.SetCmpValue(order)
+
+ for index, layerID in enumerate(self.__layerIDList):
+ order = index + 1
+ dataID = layerID
+ if order in orderIDDict:
+ dataID = orderIDDict[order]
+ self.__layerIDList[index] = dataID
+
+ return
+
def SetOrderRuleList(self, orderRuleList):
## 排名所需值规则列表
# @param orderRuleList: 排名所需值规则列表 [[order, needCmpValue], ...]
--
Gitblit v1.8.0