ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
@@ -19,20 +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:
@@ -41,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):
@@ -56,14 +65,6 @@
    return platform
def GetBillboardJob(curPlayer): return curPlayer.GetJob()
def UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=False):
    ##下线更新玩家排行榜
    if GameWorld.IsCrossServer():
        # 跨服服务器不用更新本服榜
        return
    return
def UpdatePlayerBillboardName(curPlayer):
    ## 更新排行榜中的玩家名字记录
@@ -85,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:
@@ -124,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修改榜单排行相关值,其他值不修改
@@ -199,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:
@@ -271,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
@@ -311,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
@@ -322,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)
@@ -336,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()
@@ -364,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()
@@ -390,9 +499,37 @@
    clientPack.ViewIDDataCnt = len(clientPack.ViewIDDataList)
    return clientPack
def DoGiveBillboardAwardByMail(billboardType, funcName, billboardAwardDict, mailKey):
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):
    ## 结算排行奖励邮件发放
    GameWorld.Log("=== %s结算排行奖励! === " % (funcName))
    # @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()]
@@ -400,10 +537,11 @@
    GameWorld.Log("    奖励名次列表: %s" % orderList)
    
    billboardMgr = DBDataMgr.GetBillboardMgr()
    billBoard = billboardMgr.GetBillboard(billboardType)
    billBoard = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
    if not billBoard:
        return
    billBoard.SortDelayDo()
    idOrderDict = billBoard.GetIDOrderDict()
    
    awardOrder = orderList[0]
    orderPlayerIDDict = {}
@@ -413,15 +551,19 @@
        billBoardData = billBoard.At(index)
        if not billBoardData:
            continue
        order = index + 1
        playerID = billBoardData.GetID()
        order = idOrderDict.get(playerID, index + 1)
        
        if order > awardOrder:
        endAward = False # 发奖是否结束
        while order > awardOrder:
            nextOrderIndex = orderList.index(awardOrder) + 1
            if nextOrderIndex >= len(orderList):
                endAward = True
                break
            awardOrder = orderList[nextOrderIndex]
        playerID = billBoardData.GetID()
        if endAward:
            break
        if playerID < ShareDefine.RealPlayerIDStart:
            # 非真人不处理
            continue
@@ -433,5 +575,7 @@
        PlayerMail.SendMailByKey(mailKey, playerID, awardList, paramList)
        
    GameWorld.Log("    奖励玩家名次信息: %s" % orderPlayerIDDict)
    GameWorld.Log("===================================================")
    if isClearData:
        billBoard.ClearData("Award")
    GameWorld.Log("---------------------------------------------------")
    return