From 11c9a3b5846401523e4dafc17f2a074a712730da Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 11 三月 2026 18:27:10 +0800
Subject: [PATCH] 526 【挑战】PVP群英榜-后端(本服群英榜;优化机器人表支持按功能加载不同的机器人;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py | 285 +++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 238 insertions(+), 47 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
index b474f25..ccacc87 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
@@ -19,19 +19,29 @@
import ShareDefine
import PlayerControl
import ChPyNetSendPack
+import PlayerViewCache
import NetPackCommon
import IpyGameDataPY
+import DBBillboard
+import PlayerMail
import DBDataMgr
import time
-def OnDay():
+def OnDay(centerEventValue=0):
+ # @param centerEventValue: 跨服中心事件值,不为0时代表是跨服中心同步的事件,只处理跨服功能需要处理的逻辑
drBillboardTypeList = []
- if GameWorld.IsCrossServer():
+ if centerEventValue:
+ if not GameWorld.IsCrossServer():
+ # 跨服事件只跨服服务器处理
+ return
drBillboardTypeList = ShareDefine.CrossBillboardTypeList
+ eventName = "OnDay%s" % centerEventValue
+
else:
drBillboardTypeList = IpyGameDataPY.GetFuncEvalCfg("BillboardSet", 1)
+ eventName = "OnDay"
billboardMgr = DBDataMgr.GetBillboardMgr()
for billboardType in drBillboardTypeList:
@@ -40,13 +50,13 @@
groupList = billboardMgr.GetBillboardGroupList(billboardType)
for billboardType, groupValue1, groupValue2 in groupList:
billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
- billboardObj.SaveDRData("OnDay")
+ billboardObj.SaveDRData(eventName)
return
def BillboardOnLogin(curPlayer):
# 上线默认同步排行榜
- UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故上线不再同步
+ #UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故上线不再同步
return
def GetBillboardOperateInfo(curPlayer):
@@ -55,14 +65,6 @@
return platform
def GetBillboardJob(curPlayer): return curPlayer.GetJob()
-
-def UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=False):
- ##下线更新玩家排行榜
- if GameWorld.IsCrossServer():
- # 跨服服务器不用更新本服榜
- return
-
- return
def UpdatePlayerBillboardName(curPlayer):
## 更新排行榜中的玩家名字记录
@@ -84,29 +86,7 @@
# 跨服榜更新, 待处理
return
-def UpdatePlayerFPTotalBillboard(curPlayer, isForceUpdate=False, isCheckRule=True):
- ##更新玩家总战斗力
- return
-
-def UpdatePyPetBillboard(curPlayer, isForceUpdate=False, isUpdateTotal=True):
- ## 更新宠物排行榜
- return
-
-def UpdateRealmBillboard(curPlayer):
- ##境界榜
- return
-
-#def __CanPlayerBillboardComm(curPlayer):
-# ## 玩家可否上榜通用检查
-# if not GameWorld.IsNormalPlayer(curPlayer):
-# return False
-# #if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Billboard):
-# # GameWorld.DebugLog("排行榜未开启,无法上榜!curLV=%s" % (curPlayer.GetLV()), curPlayer.GetPlayerID())
-# # return False
-#
-# return True
-
-def UpdatePlayerBillboard(curPlayer, bType, cmpValue, cmpValue2=0, cmpValue3=0, autoSort=False, **kwargs):
+def UpdatePlayerBillboard(curPlayer, bType, cmpValue, cmpValue2=0, cmpValue3=0, autoSort=False, groupValue1=0, **kwargs):
## 更新玩家排行榜
#if not cmpValue and not cmpValue2 and not cmpValue3:
@@ -123,10 +103,105 @@
kwargs["value5"] = curPlayer.GetModelMark()
kwargs["value6"] = curPlayer.GetEquipShowSwitch()
- groupValue1 = 0
UpdateBillboard(bType, groupValue1, playerID, playerName, playerOpInfo, playerJob, value1, value2,
cmpValue, cmpValue2, cmpValue3, autoSort=autoSort, **kwargs)
return
+
+def __updPlayerBillViewInfo(billData):
+ playerID = billData.GetID()
+ curCache = PlayerViewCache.FindViewCache(playerID)
+ if not curCache:
+ return
+ billData.SetName1(curCache.GetPlayerName())
+ billData.SetName2(curCache.GetAccID())
+ billData.SetType2(curCache.GetJob())
+ billData.SetValue1(curCache.GetRealmLV())
+ billData.SetValue2(curCache.GetTitleID())
+ billData.SetValue3(curCache.GetFace())
+ billData.SetValue4(curCache.GetFacePic())
+ billData.SetValue5(curCache.GetModelMark())
+ billData.SetValue6(curCache.GetEquipShowSwitch())
+ return
+
+def UpdateBillboardLayer(dataID, billboardType, cmpValue, groupValue1=0, autoSort=True):
+ ## 更新榜单所在的层级,一般用于层级模式的榜单,层级模式默认与目标交换名次
+ if GameWorld.IsCrossServer():
+ if billboardType not in ShareDefine.CrossBillboardTypeList:
+ return
+ else:
+ if billboardType not in ShareDefine.BillboardTypeList:
+ return
+
+ if not dataID:
+ return
+
+ groupValue2 = 0
+ billboardMgr = DBDataMgr.GetBillboardMgr()
+ billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+ layerIDList = billboardObj.GetLayerIDList()
+ layerIDCnt = len(layerIDList)
+ if cmpValue <= 0 or cmpValue > layerIDCnt:
+ GameWorld.ErrLog("更新层级榜单名次异常! dataID=%s,billboardType=%s,cmpValue=%s,layerIDCnt=%s" % (dataID, billboardType, cmpValue, layerIDCnt), dataID)
+ return
+ tagIndex = cmpValue - 1
+ tagID = layerIDList[tagIndex]
+ if dataID == tagID:
+ return True
+ tagBillData = billboardObj.FindByID(tagID) # 当是填充的机器人时不存在数据
+ curBillData = billboardObj.FindByID(dataID)
+
+ curTime = int(time.time())
+
+ # 未上榜的替换上榜的
+ if not curBillData:
+ if tagBillData:
+ curBillData = tagBillData
+ curBillData.Clear()
+ tagBillData = None
+ else:
+ curBillData = billboardObj.AddNewBillboardData(dataID)
+
+ # 上榜的直接交换
+ else:
+ curCmpValue = curBillData.GetCmpValue()
+ if curCmpValue <= cmpValue:
+ GameWorld.DebugLog("层级榜单名次值没有提高不更新榜单! curCmpValue=%s <= %s" % (curCmpValue, cmpValue), dataID)
+ return
+ layerIDList[curCmpValue - 1] = tagID
+
+ if tagBillData:
+ tagBillData.SetCmpValue(curCmpValue)
+ tagBillData.SetTime(curTime)
+
+ layerIDList[cmpValue - 1] = dataID
+ billboardObj.SetLayerIDList(layerIDList)
+ curBillData.SetID(dataID)
+ curBillData.SetCmpValue(cmpValue)
+ curBillData.SetTime(curTime)
+
+ __updPlayerBillViewInfo(curBillData)
+
+ GameWorld.DebugLog("更新排行层值: billboardType=%s,groupValue1=%s,dataID=%s,cmpValue=%s,tagID=%s"
+ % (billboardType, groupValue1, dataID, cmpValue, tagID), dataID)
+ if autoSort:
+ billboardObj.SortData()
+ return True
+
+def SetTempDataByViewCache(playerID, billType, groupValue1=0, groupValue2=0, cmpValue=0):
+ ## 根据玩家缓存更新临时榜单数据,一般用于填充机器人
+ TempBillData = DBBillboard.TempBillData
+ TempBillData.Clear()
+ TempBillData.SetType(billType)
+ TempBillData.SetGroupValue1(groupValue1)
+ TempBillData.SetGroupValue2(groupValue2)
+ if not playerID:
+ return TempBillData
+
+ TempBillData.SetID(playerID)
+ TempBillData.SetCmpValue(cmpValue)
+ __updPlayerBillViewInfo(TempBillData)
+
+ return TempBillData
def UpdateBillboardByID(dataID, billboardType, cmpValue, cmpValue2=0, cmpValue3=0, autoSort=False):
## 直接根据榜单ID修改榜单排行相关值,其他值不修改
@@ -198,6 +273,9 @@
billboardMgr = DBDataMgr.GetBillboardMgr()
billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+ if billboardObj.IsOrderRuleByLayer():
+ # 该模式不处理,请使用 UpdateBillboardLayer
+ return
billboardData = billboardObj.FindByID(dataID)
isNewData = False
if not billboardData:
@@ -270,11 +348,6 @@
return
return lastBillBoardData
-def UpdatePlayerCrossBillboard(curPlayer, bType, groupValue1, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0,
- groupValue2=0, **kwargs):
- ## 在本服直接更新玩家跨服排行榜,发送到跨服,之后扩展
- return
-
#// A1 30 查看榜单 #tagCMViewBillboard
#
#struct tagCMViewBillboard
@@ -310,7 +383,12 @@
billboardObj.SortDelayDo()
idOrderDict = billboardObj.GetIDOrderDict()
count = billboardObj.GetCount()
-
+ isLayerMode = billboardObj.IsOrderRuleByLayer() # 层级模式有机器人填充,默认为最大,实际榜单数据中没有机器人数据
+ layerIDList = []
+ if isLayerMode:
+ layerIDList = billboardObj.GetLayerIDList()
+ count = len(layerIDList)
+
maxIndex = count - 1
startIndex = max(min(startIndex, maxIndex), 0)
viewCnt = 20 if not viewCnt else min(viewCnt, 100) # 默认20,最多100
@@ -321,7 +399,13 @@
# 查看viewID前后名次
if viewID:
viewBFCnt = 3 # 查看ViewID返回前后数据条数,一般设置为奇数
- viewIDIndex = billboardObj.IndexOfByID(viewID)
+ viewIDIndex = -1
+ if isLayerMode:
+ billboardData = billboardObj.FindByID(viewID)
+ if billboardData:
+ viewIDIndex = billboardData.GetCmpValue() - 1
+ else:
+ viewIDIndex = billboardObj.IndexOfByID(viewID)
if viewIDIndex != -1:
# 前x后x
viewIDStartIndex = max(0, viewIDIndex - viewBFCnt / 2)
@@ -335,10 +419,24 @@
clientPack.DataTotal = count
clientPack.PageDataList = []
for index in viewRange:
- billboardData = billboardObj.At(index)
+ if index >= count:
+ break
+ billboardData = None
+ if isLayerMode:
+ rank = index + 1
+ dataID = layerIDList[index]
+ billboardData = billboardObj.FindByID(dataID)
+ if not billboardData:
+ cmpValue = rank
+ billboardData = SetTempDataByViewCache(dataID, bbType, groupValue1, groupValue2, cmpValue)
+ else:
+ billboardData = billboardObj.At(index)
+ rank = idOrderDict.get(billboardData.GetID(), 0)
+ if not billboardData:
+ continue
viewData = ChPyNetSendPack.tagMCViewBillboardData()
viewData.Index = index
- viewData.Rank = idOrderDict.get(billboardData.GetID(), 0)
+ viewData.Rank = rank
viewData.ID = billboardData.GetID()
viewData.ID2 = billboardData.GetID2()
viewData.Name1 = billboardData.GetName1()
@@ -363,10 +461,22 @@
clientPack.ViewID = viewID
clientPack.ViewIDDataList = []
for index in viewIDRange:
- billboardData = billboardObj.At(index)
+ billboardData = None
+ if isLayerMode:
+ rank = index + 1
+ dataID = layerIDList[index]
+ billboardData = billboardObj.FindByID(dataID)
+ if not billboardData:
+ cmpValue = rank
+ billboardData = SetTempDataByViewCache(dataID, bbType, groupValue1, groupValue2, cmpValue)
+ else:
+ billboardData = billboardObj.At(index)
+ rank = idOrderDict.get(billboardData.GetID(), 0)
+ if not billboardData:
+ continue
viewData = ChPyNetSendPack.tagMCViewBillboardData()
viewData.Index = index
- viewData.Rank = idOrderDict.get(billboardData.GetID(), 0)
+ viewData.Rank = rank
viewData.ID = billboardData.GetID()
viewData.ID2 = billboardData.GetID2()
viewData.Name1 = billboardData.GetName1()
@@ -388,3 +498,84 @@
clientPack.ViewIDDataList.append(viewData)
clientPack.ViewIDDataCnt = len(clientPack.ViewIDDataList)
return clientPack
+
+def SetOrderRuleListByActTempID(billboardType, templateID, groupValue1=0, groupValue2=0):
+ ## 根据活动榜单模版更新排名规则
+ orderRuleList = []
+ orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBillboardAward", templateID)
+ if orderIpyDataList:
+ for ipyData in orderIpyDataList:
+ orderRuleList.append([ipyData.GetRankB(), ipyData.GetNeedValue()])
+
+ billboardMgr = DBDataMgr.GetBillboardMgr()
+ billBoard = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+ billBoard.SetOrderRuleList(orderRuleList)
+ return
+
+def DoGiveBillboardAwardByActTempID(billboardType, funcName, templateID, mailKey, groupValue1=0, groupValue2=0, isClearData=False):
+ ## 根据活动榜单模版结算排名奖励,邮件发放
+ # @param funcName: 自定义的功能名称
+ billboardAwardDict = {}
+ orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBillboardAward", templateID)
+ if orderIpyDataList:
+ for ipyData in orderIpyDataList:
+ billboardAwardDict[str(ipyData.GetRankB())] = ipyData.GetAwardItemList()
+ DoGiveBillboardAwardByMail(billboardType, funcName, billboardAwardDict, mailKey, groupValue1, groupValue2, isClearData)
+ return
+
+def DoGiveBillboardAwardByMail(billboardType, funcName, billboardAwardDict, mailKey, groupValue1=0, groupValue2=0, isClearData=False):
+ ## 结算排行奖励邮件发放
+ # @param funcName: 自定义的功能名称
+ # @param billboardAwardDict: {"名次":[[itemID,itemCnt], ...], ...}
+ # @param mailKey: 邮件模版key
+
+ GameWorld.Log("----- %s 结算排行奖励! -----" % (funcName))
+ if not billboardAwardDict:
+ return
+ orderList = [int(orderStr) for orderStr in billboardAwardDict.keys()]
+ orderList.sort()
+ GameWorld.Log(" 奖励名次列表: %s" % orderList)
+
+ billboardMgr = DBDataMgr.GetBillboardMgr()
+ billBoard = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+ if not billBoard:
+ return
+ billBoard.SortDelayDo()
+ idOrderDict = billBoard.GetIDOrderDict()
+
+ awardOrder = orderList[0]
+ orderPlayerIDDict = {}
+ billboardCount, billboardMaxCount = billBoard.GetCount(), billBoard.GetMaxCount()
+ GameWorld.Log(" 榜单数据数: %s/%s" % (billboardCount, billboardMaxCount))
+ for index in xrange(billboardCount):
+ billBoardData = billBoard.At(index)
+ if not billBoardData:
+ continue
+ playerID = billBoardData.GetID()
+ order = idOrderDict.get(playerID, index + 1)
+
+ endAward = False # 发奖是否结束
+ while order > awardOrder:
+ nextOrderIndex = orderList.index(awardOrder) + 1
+ if nextOrderIndex >= len(orderList):
+ endAward = True
+ break
+ awardOrder = orderList[nextOrderIndex]
+ if endAward:
+ break
+
+ if playerID < ShareDefine.RealPlayerIDStart:
+ # 非真人不处理
+ continue
+
+ orderPlayerIDDict[playerID] = [order, awardOrder]
+
+ paramList = [order]
+ awardList = billboardAwardDict[str(awardOrder)]
+ PlayerMail.SendMailByKey(mailKey, playerID, awardList, paramList)
+
+ GameWorld.Log(" 奖励玩家名次信息: %s" % orderPlayerIDDict)
+ if isClearData:
+ billBoard.ClearData("Award")
+ GameWorld.Log("---------------------------------------------------")
+ return
--
Gitblit v1.8.0