ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerBillboard.py
@@ -20,32 +20,110 @@
import GameWorld
import ChConfig
import ShareDefine
import ReadChConfig
import PlayerControl
import ChPyNetSendPack
import NetPackCommon
import PlayerDBGSEvent
import NetPackCommon
import DataRecordPack
import PlayerFamily
import PyDataManager
import PlayerViewCache
import IpyGameDataPY
import PyGameData
import time
import random
Def_Key_BillboardSortTick = "BillboardSortTick_%s" # 排行榜是否排序tick,参数(排行榜类型)
Def_Key_BillboardNeedSort = "BillboardNeedSort_%s" # 排行榜是否需要排序,参数(排行榜类型)
#需要每天记录到oss的排行榜类型
Def_NoteOssBillboardTypeList = [
    ShareDefine.Def_BT_LV ,                  #个人等级日榜
    ShareDefine.Def_BT_FightPower,           #个人战斗力
                                ]
#需要每天拷贝昨日榜单的排行榜类型字典
Def_NeedCopyYesterday_Dict = {
    #昨日榜(拷贝)                                    #今日榜(源数据)
                         }
class BillboardObj(object):
    ''' 榜单额外数据管理
    '''
    def __init__(self, billboardType):
        self.__billboardType = billboardType
        self.__idOrderDict = {} # {id:名次, ...}
        self.__orderRuleList = None
        return
    def OnBillboardChange(self):
        ## 榜单数据变更
        self.__idOrderDict = {}
        return
    def GetIDOrderDict(self):
        ## 获取ID对应名次字典,本服榜仅处理有特殊排名规则的
        # @return: {ID:名次, ...}  名次从1开始,如果返回空字典,则使用默认名次逻辑,即 index + 1
        if not self.__orderRuleList:
            return {}
        if not self.__idOrderDict:
            billBoard = GameWorld.GetBillboard().FindBillboard(self.__billboardType)
            if not billBoard:
                return {}
            billboardDataCount = billBoard.GetCount()
            rankPre = 0
            billboardIndex = 0
            for rank, needCmpValue in self.__orderRuleList:
                orderCountTotal = rank - rankPre # 奖励名次数量
                rankPre = rank
                for index in xrange(billboardIndex, billboardDataCount):
                    if orderCountTotal <= 0:
                        break
                    billboardData = billBoard.At(index)
                    if billboardData.GetCmpValue() < needCmpValue:
                        break
                    orderReal = rank - orderCountTotal + 1
                    self.__idOrderDict[billboardData.GetID()] = orderReal
                    orderCountTotal -= 1
                    billboardIndex += 1
        return self.__idOrderDict
    def SetOrderRuleList(self, orderRuleList):
        ## 排名所需值规则列表
        # @param orderRuleList: 排名所需值规则列表 [[order, needCmpValue], ...]
        self.__orderRuleList = orderRuleList
        self.__idOrderDict = {} # 设置后需重置,可能配置规则变化了导致实际排名可能变化
        GameWorld.Log("设置排名所需值规则列表: billboardType=%s, %s" % (self.__billboardType, orderRuleList))
        return
class BillboardMgr(object):
    ''' 榜单额外管理
    '''
    def __init__(self):
        self.__billboardDict = {} # {榜单类型:Billboard, ...}
        return
    def GetBillboardObj(self, billboardType):
        if billboardType in self.__billboardDict:
            billboard = self.__billboardDict[billboardType]
        else:
            billboard = BillboardObj(billboardType)
            self.__billboardDict[billboardType] = billboard
        return billboard
def GetBillboardMgr():
    if PyGameData.g_billboardMgrMgr:
        billMgr = PyGameData.g_billboardMgrMgr
    else:
        billMgr = BillboardMgr()
        PyGameData.g_billboardMgrMgr = billMgr
    return billMgr
def NoteOssBillboardInfoByDay():
    ## 每天记录排行榜信息到oss中
    if GameWorld.IsCrossServer():
        return
    Def_NoteOssBillboardTypeList = IpyGameDataPY.GetFuncEvalCfg("BillboardSet", 1)
    for billboardType in Def_NoteOssBillboardTypeList:
        DataRecordPack.DR_BillboardDataByDay(billboardType)
        DataRecordPack.DR_BillboardData(billboardType, "OnDay")
    return
def CopyBillboardOnDay():
@@ -84,7 +162,7 @@
        billBoard = billboardMgr.FindBillboard(index)
        #排序一次排行榜
        billBoard.Sort()
    return
def CopyBillboard(newBillboardIndex, oldBillboardIndex):
@@ -113,9 +191,16 @@
        type2 = oldBillBoardData.GetType2()
        value1 = oldBillBoardData.GetValue1()
        value2 = oldBillBoardData.GetValue2()
        value3 = oldBillBoardData.GetValue3()
        value4 = oldBillBoardData.GetValue4()
        value5 = oldBillBoardData.GetValue5()
        value6 = oldBillBoardData.GetValue6()
        value7 = oldBillBoardData.GetValue7()
        value8 = oldBillBoardData.GetValue8()
        cmpValue = oldBillBoardData.GetCmpValue()
        cmpValue2 = oldBillBoardData.GetCmpValue2()
        cmpValue3 = oldBillBoardData.GetCmpValue3()
        userData = oldBillBoardData.GetUserData()
        #---获取排行榜信息---
        billBoard, billBoardData = GetBillBoardData(newBillboardIndex, id, cmpValue)
@@ -132,9 +217,17 @@
        billBoardData.SetType2(type2)
        billBoardData.SetValue1(value1)
        billBoardData.SetValue2(value2)
        billBoardData.SetValue3(value3)
        billBoardData.SetValue4(value4)
        billBoardData.SetValue5(value5)
        billBoardData.SetValue6(value6)
        billBoardData.SetValue7(value7)
        billBoardData.SetValue8(value8)
        billBoardData.SetCmpValue(cmpValue)
        billBoardData.SetCmpValue2(cmpValue2)
        billBoardData.SetCmpValue3(cmpValue3)
        billBoardData.SetUserData(userData)
        billBoardData.SetDataLen(len(userData))
        
    GameWorld.Log("    CopyBillboard newBillboardIndex=%s, oldBillboardIndex=%s" % (newBillboardIndex, oldBillboardIndex))
@@ -151,6 +244,33 @@
    billBoard.Clear()
    
    GameWorld.Log('billboardIndex %s clear.'%billboardIndex)
    return
def UpdateBillboardMaxCount(billboardIndex, updMaxCount, isDelExtra=True):
    ''' 变更竞技场榜单最大数据数
    @param updMaxCount: 更新的最大数据排名
    @param isDelExtra: 是否删除原榜单排名数据超过更新后的最大排名,默认删除
    '''
    billBoard = GameWorld.GetBillboard().FindBillboard(billboardIndex)
    if not billBoard:
        return
    curCount = billBoard.GetCount()
    curMaxCount = billBoard.GetMaxCount()
    # 不超过程序内置配置的最大数量
    if billboardIndex in ChConfig.Def_BT_Cnt:
        updMaxCount = min(updMaxCount, ChConfig.Def_BT_Cnt[billboardIndex])
    if curMaxCount == updMaxCount:
        return
    billBoard.SetMaxCount(updMaxCount)
    GameWorld.Log("    变更榜单最大数据数! billboardIndex=%s,curCount=%s,curMaxCount=%s,updMaxCount=%s"
                  % (billboardIndex, curCount, curMaxCount, updMaxCount))
    # 清除多余榜单数据
    if isDelExtra and curCount > updMaxCount:
        for delIndex in xrange(curCount - 1, updMaxCount - 1, -1):
            if delIndex >= 0:
                GameWorld.Log("        DeleteByIndex: %s" % delIndex)
                billBoard.DeleteByIndex(delIndex)
    return
####################################################################################################
@@ -214,6 +334,9 @@
    if packType in ChConfig.Def_InterdictLook_BT_Type:
        #不可通过此封包查看
        return
    if ChConfig.Def_BT_Cnt.get(packType, 0) > 100:
        GameWorld.DebugLog("该榜单最大名次较大,需使用分页查询! A9 A2 查看排行榜#tagCPYWatchBillboard")
        return
    if not __CheckWatchCD(curPlayer, packType, tick):
        return
@@ -305,7 +428,7 @@
#    BYTE        Type;        //类型 TBillboardType
#    DWORD        StartIndex;    //查看的起始名次索引, 默认0
#    BYTE        WatchCnt;    //查看条数,默认20,最大不超过100
#    BYTE        IsWatchSelf;    //是否查看自己名次前后,默认10条数据
#    DWORD        WatchID;        //查看指定ID名次前后,如玩家ID、家族ID等
#};
def Client_PYWatchBillboard(index, clientData, tick):
    
@@ -316,14 +439,19 @@
    packType = clientData.Type
    startIndex = clientData.StartIndex
    watchCnt = clientData.WatchCnt
    isWatchSelf = clientData.IsWatchSelf
    if not __CheckWatchCD(curPlayer, packType, tick):
        return
    watchID = clientData.WatchID
    #if not __CheckWatchCD(curPlayer, packType, tick):
    #    return
    
    Sync_BillboardEx(curPlayer, packType, isWatchSelf, startIndex, watchCnt)
    if GameWorld.GetGameWorld().GetDictByKey(Def_Key_BillboardNeedSort % packType):
        GameWorld.GetGameWorld().SetDict(Def_Key_BillboardNeedSort % packType, 0)
        #GameWorld.DebugLog("玩家查看排行榜,强制排序!packType=%s" % (packType))
        SortBillboardByIndex(packType)
    Sync_BillboardEx(curPlayer, packType, watchID, startIndex, watchCnt)
    return
def Sync_BillboardEx(curPlayer, bbType, isWatchSelf=False, startIndex=0, watchCnt=20):
def Sync_BillboardEx(curPlayer, bbType, watchID=0, startIndex=0, watchCnt=20):
    if bbType < 0 or bbType >= ShareDefine.Def_BT_Max:
        return
    
@@ -332,12 +460,12 @@
        GameWorld.ErrLog("找不到排行榜数据!bbType=%s" % (bbType))
        return
    
    playerID = curPlayer.GetPlayerID()
    #playerID = curPlayer.GetPlayerID()
    count = billBoard.GetCount()
    endIndex = 0
    # 查看自己前后名次
    if isWatchSelf:
        playerIndex = billBoard.IndexOfByID(playerID)
    if watchID:
        playerIndex = billBoard.IndexOfByID(watchID)
        if playerIndex != -1:
            # 前5后4,首尾补足10条记录
            endIndex = min(playerIndex + 5, count)
@@ -353,9 +481,13 @@
        watchCnt = 20 if not watchCnt else min(watchCnt, 100) # 默认20,最多100
        endIndex = min(startIndex + watchCnt, count)
        
    billboardMgr = GetBillboardMgr()
    billboardObj = billboardMgr.GetBillboardObj(bbType)
    idOrderDict = billboardObj.GetIDOrderDict()
    billBoardData = ChPyNetSendPack.tagPYBillboardData()
    billBoardData.Clear()
    billBoardData.IsWatchSelf = isWatchSelf
    billBoardData.WatchID = watchID
    billBoardData.Type = bbType
    billBoardData.Billboard = []    
    for index in xrange(startIndex, endIndex):
@@ -367,7 +499,7 @@
        
        bbInfo = ChPyNetSendPack.tagPYBillboardInfo()
        bbInfo.Clear()
        bbInfo.OrderIndex = index
        bbInfo.OrderIndex = idOrderDict.get(bbData.GetID(), index + 1) - 1
        bbInfo.ID = bbData.GetID()
        bbInfo.ID2 = bbData.GetID2()
        bbInfo.Name1 = bbData.GetName1()
@@ -375,9 +507,17 @@
        bbInfo.Type2 = bbData.GetType2()
        bbInfo.Value1 = bbData.GetValue1()
        bbInfo.Value2 = bbData.GetValue2()
        bbInfo.Value3 = bbData.GetValue3()
        bbInfo.Value4 = bbData.GetValue4()
        bbInfo.Value5 = bbData.GetValue5()
        bbInfo.Value6 = bbData.GetValue6()
        bbInfo.Value7 = bbData.GetValue7()
        bbInfo.Value8 = bbData.GetValue8()
        bbInfo.CmpValue = bbData.GetCmpValue()
        bbInfo.CmpValue2 = bbData.GetCmpValue2()
        bbInfo.CmpValue3 = bbData.GetCmpValue3()
        bbInfo.UserData = bbData.GetUserData()
        bbInfo.DataLen = len(bbInfo.UserData)
        
        billBoardData.Billboard.append(bbInfo)
        
@@ -389,7 +529,7 @@
def MapServer_UpdateBillboard(billInfoDict, tick):
    '''地图更新排行榜, 通用
    {"Type":bType, "Type2":bType2, "ID":bID, "ID2":bID2, "Name1":bName, "Name2":bName2, "ExInfo":exInfo,
    "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3}
    "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3, "autoSort":autoSort}
    '''
    
    bType = billInfoDict["Type"]
@@ -400,13 +540,21 @@
    bName2 = billInfoDict["Name2"]
    value1 = billInfoDict["Value1"]
    value2 = billInfoDict["Value2"]
    value3 = billInfoDict.get("Value3", 0)
    value4 = billInfoDict.get("Value4", 0)
    value5 = billInfoDict.get("Value5", 0)
    value6 = billInfoDict.get("Value6", 0)
    value7 = billInfoDict.get("Value7", 0)
    value8 = billInfoDict.get("Value8", 0)
    cmpValue = billInfoDict["CmpValue"]
    cmpValue2 = billInfoDict["CmpValue2"]
    cmpValue3 = billInfoDict["CmpValue3"]
    userData = billInfoDict.get("UserData", "")
    if bType not in ShareDefine.BillboardTypeList:
        return
    #if not cmpValue and not cmpValue2 and not cmpValue3:
    #    return
    kwargs = {"value3":value3, "value4":value4, "value5":value5, "value6":value6, "value7":value7, "value8":value8, "userData":userData}
    
    #删除该数据
    if cmpValue == -1:
@@ -422,26 +570,24 @@
    
    gameWorld = GameWorld.GetGameWorld()
    lastSortTick = gameWorld.GetDictByKey(Def_Key_BillboardSortTick % bType)
    autoSort = (tick - lastSortTick) >= 60000 # 1分钟强制排序一次
    autoSort = (tick - lastSortTick) >= 60000 or billInfoDict.get("autoSort") == True # 1分钟强制排序一次
    if autoSort:
        gameWorld.SetDict(Def_Key_BillboardSortTick % bType, tick)
    #GameWorld.DebugLog("更新排行榜:bType=%s,autoSort=%s,tick=%s,lastSortTick=%s,d=%s" % (bType, autoSort, tick, lastSortTick, tick - lastSortTick))
    
    UpdatePlayerBillboard(bID, bName, bName2, bType, bType2, value1, value2, cmpValue, autoSort, cmpValue2, cmpValue3)
    gameWorld.SetDict(Def_Key_BillboardNeedSort % bType, 1)
    #__UpdateBillboardSortState(gameWorld, bType, autoSort, isUpd)
    UpdatePlayerBillboard(bID, bName, bName2, bType, bType2, value1, value2, cmpValue, autoSort, cmpValue2, cmpValue3, **kwargs)
    
    exInfo = billInfoDict["ExInfo"]
    # 以下为榜单附加特殊处理
    if bType == ShareDefine.Def_BT_FightPower:
        playerID = bID
        fightPowerTotal = cmpValue
        fightPowerTotal = cmpValue * ChConfig.Def_PerPointValue + cmpValue2
        familyID = exInfo[0]
        playerJob = bType2
        
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
        if curPlayer:
            curPlayer.SetFightPower(fightPowerTotal)
            PlayerControl.SetFightPower(curPlayer, fightPowerTotal)
            
        #更新战盟成员战力
        PlayerFamily.UpdFamilyMemberFightPower(familyID, playerID, fightPowerTotal)
@@ -450,21 +596,104 @@
        job = playerJob % 10
        if job in ShareDefine.JobFightPowerBillboardDict:
            jobBType = ShareDefine.JobFightPowerBillboardDict[job]
            UpdatePlayerBillboard(bID, bName, bName2, jobBType, bType2, value1, value2, cmpValue, autoSort)
            gameWorld.SetDict(Def_Key_BillboardNeedSort % jobBType, 1)
            #__UpdateBillboardSortState(gameWorld, jobBType, autoSort, isUpd)
            UpdatePlayerBillboard(bID, bName, bName2, jobBType, bType2, value1, value2, cmpValue, autoSort, cmpValue2, **kwargs)
            
    return
def __UpdateBillboardSortState(gameWorld, bType, autoSort, isUpd):
    key = Def_Key_BillboardNeedSort % bType
    needSort = gameWorld.GetDictByKey(key)
    if not autoSort and isUpd and not needSort:
        gameWorld.SetDict(key, 1)
    elif autoSort and needSort:
        gameWorld.SetDict(key, 0)
def DelJobFightPowerBillboard(curPlayer, delJob):
    ## 删除玩家对应职业战力榜  - 一般是玩家职业改变了,需要删除旧职业的职业战力榜单
    if delJob not in ShareDefine.JobFightPowerBillboardDict:
        return
    jobBType = ShareDefine.JobFightPowerBillboardDict[delJob]
    playerID = curPlayer.GetPlayerID()
    billboardMgr = GameWorld.GetBillboard()
    playerBillBoard = billboardMgr.FindBillboard(jobBType)
    if not playerBillBoard:
        return
    if playerBillBoard.FindByID(playerID):
        playerBillBoard.DeleteByID(playerID)
        GameWorld.DebugLog("删除玩家职业战力榜单: delJob=%s,jobBType=%s" % (delJob, jobBType), playerID)
    return
def GetBillboardOperateInfo(curPlayer):
    # 排行榜中所保存的运营商相关信息
    platform = curPlayer.GetAccID()
    if platform in ["tencent"]:
        return curPlayer.GetOperateInfo()
    return platform
def UpdateFamilyBillboard(bType, familyBillInfo, cmpValue, cmpValue2=0):
    ## 更新仙盟排行榜
    if "id" not in familyBillInfo:
        return
    familyID = familyBillInfo["id"]
    familyName = familyBillInfo["name"]
    id2 = familyBillInfo["id2"]
    name2 = familyBillInfo["name2"]
    value1 = familyBillInfo["value1"]
    value2 = familyBillInfo["value2"]
    value3 = familyBillInfo["value3"]
    value4 = familyBillInfo["value4"]
    value5 = familyBillInfo["value5"]
    type2 = 0
    autoSort = True
    UpdatePlayerBillboard(familyID, familyName, name2, bType, type2, value1, value2, cmpValue, autoSort, cmpValue2,
                          id2=id2, value3=value3, value4=value4, value5=value5)
    return
def UpdatePlayerBillboardEx(curPlayer, playerID, bType, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0, autoSort=False):
    ## 更新玩家排行榜
    # @param curPlayer: 可能为None
    playerOpInfo = ""
    playerJob = 0
    playerName = ""
    playerRealmLV = 0
    face = 0
    facePic = 0
    if curPlayer:
        playerID = curPlayer.GetID()
        playerJob = curPlayer.GetJob()
        playerName = curPlayer.GetName()
        playerRealmLV = curPlayer.GetOfficialRank()
        playerOpInfo = GetBillboardOperateInfo(curPlayer)
        face = curPlayer.GetFace()
        facePic = curPlayer.GetFacePic()
    else:
        socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(playerID)
        if socialPlayer:
            playerJob = socialPlayer.playerInfo.Job
            playerName = socialPlayer.playerInfo.PlayerName
            playerRealmLV = socialPlayer.playerInfo.RealmLV
            face = socialPlayer.playerInfo.Face
            facePic = socialPlayer.playerInfo.FacePic
        else:
            curCache = PlayerViewCache.FindViewCache(playerID)
            if curCache:
                cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)
                playerJob = cacheDict["Job"]
                playerName = cacheDict["Name"]
                playerRealmLV = cacheDict["RealmLV"]
                face = cacheDict.get("Face", 0)
                facePic = cacheDict.get("FacePic", 0)
    if not playerName and playerID < 10000:
        playerJob = random.choice([1, 2])
        playerName = "testName%s" % playerID
        playerRealmLV = random.randint(1, 10)
        
    #GameWorld.DebugLog("__UpdateBillboardSortState:bType=%s,autoSort=%s,isUpd=%s,needSort=%s" % (bType, autoSort, isUpd, gameWorld.GetDictByKey(key)))
    if bType in ShareDefine.BTValue1_OfficialRankList:
        value1 = playerRealmLV
    tick = GameWorld.GetGameWorld().GetTick()
    gameWorld = GameWorld.GetGameWorld()
    lastSortTick = gameWorld.GetDictByKey(Def_Key_BillboardSortTick % bType)
    autoSort = ((tick - lastSortTick) >= 60000 or autoSort) # 1分钟强制排序一次
    if autoSort:
        gameWorld.SetDict(Def_Key_BillboardSortTick % bType, tick)
    UpdatePlayerBillboard(playerID, playerName, playerOpInfo, bType, playerJob, value1, value2, cmpValue, autoSort, cmpValue2, cmpValue3, value3=face, value4=facePic)
    return
#---------------------------------------------------------------------
@@ -499,8 +728,8 @@
# @param autoSort 是否自动排序
# @return 返回值无意义
# @remarks 更新角色排行榜.
def UpdatePlayerBillboard(curPlayerID, curPlayerName, curPlayerOpInfo, billboardIndex, billboardType,
                          value1, value2, cmpValue, autoSort = True, cmpValue2 = 0, cmpValue3 = 0):
def UpdatePlayerBillboard(curPlayerID, name1, name2, billboardIndex, type2, value1, value2, cmpValue,
                          autoSort = True, cmpValue2 = 0, cmpValue3 = 0, **kwargs):
    
    playerBillBoard, playerBillBoardData = GetBillBoardData(billboardIndex, curPlayerID, cmpValue, cmpValue2, cmpValue3)
    
@@ -509,46 +738,53 @@
        return False
    
    isNewData = playerBillBoardData.GetID2() == 0 # 是否是新增的数据
    # 值相同不更新
    if not isNewData and playerBillBoardData.GetValue1() == value1 and playerBillBoardData.GetValue2() == value2 \
        and playerBillBoardData.GetCmpValue() == cmpValue and playerBillBoardData.GetCmpValue2() == cmpValue2:
        GameWorld.DebugLog("更新排行榜值相同不更新! index=%s,type2=%s,value1=%s,value2=%s,cmpValue=%s,cmpValue2==%s,cmpValue3==%s"
                           % (billboardIndex, billboardType, value1, value2, cmpValue, cmpValue2, cmpValue3), curPlayerID)
        opInfo = playerBillBoardData.GetName2()
        if opInfo != str(curPlayerOpInfo):
            playerBillBoardData.SetName2(str(curPlayerOpInfo))
            GameWorld.DebugLog("    更新operatInfo=%s" % curPlayerOpInfo, curPlayerID)
        return False
    # 没设置值默认为时间time,先上榜的排前面
    cmpValueChange = isNewData or playerBillBoardData.GetCmpValue() != cmpValue or playerBillBoardData.GetCmpValue2() != cmpValue2 \
        or (cmpValue3 and playerBillBoardData.GetCmpValue3() != cmpValue3)
    if cmpValue3 == 0:
        # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
        if isNewData or playerBillBoardData.GetCmpValue() != cmpValue or playerBillBoardData.GetCmpValue2() != cmpValue2:
        if cmpValueChange:
            # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
            calcTime = GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
            cmpValue3 = max(0, calcTime - int(time.time())) # 比较值3如果没指定值则默认存当前更新的time
        else:
            cmpValue3 = playerBillBoardData.GetCmpValue3()
    #设置排行榜数据
    playerBillBoardData.SetType(billboardIndex)
    #附属类型
    playerBillBoardData.SetType2(billboardType)
    playerBillBoardData.SetType2(type2)
    playerBillBoardData.SetID(curPlayerID)
    playerBillBoardData.SetID2(curPlayerID)
    playerBillBoardData.SetName1(curPlayerName)
    playerBillBoardData.SetName2(str(curPlayerOpInfo))
    playerBillBoardData.SetID2(kwargs.get("id2", curPlayerID))
    playerBillBoardData.SetName1(name1)
    playerBillBoardData.SetName2(str(name2))
    #SetValue1存储空间为Word
    playerBillBoardData.SetValue1(value1)
    #SetValue2存储空间为DWord
    playerBillBoardData.SetValue2(value2)
    playerBillBoardData.SetValue3(kwargs.get("value3", 0))
    playerBillBoardData.SetValue4(kwargs.get("value4", 0))
    playerBillBoardData.SetValue5(kwargs.get("value5", 0))
    playerBillBoardData.SetValue6(kwargs.get("value6", 0))
    playerBillBoardData.SetValue7(kwargs.get("value7", 0))
    playerBillBoardData.SetValue8(kwargs.get("value8", 0))
    playerBillBoardData.SetUserData(kwargs.get("userData", ""))
    playerBillBoardData.SetDataLen(len(playerBillBoardData.GetUserData()))
    playerBillBoardData.SetCmpValue(cmpValue)
    playerBillBoardData.SetCmpValue2(cmpValue2)
    if cmpValue3 > 0:
        playerBillBoardData.SetCmpValue3(cmpValue3)
    GameWorld.DebugLog("更新排行榜值 index=%s,type2=%s,value1=%s,value2=%s,cmpValue=%s,cmpValue2==%s,cmpValue3==%s,isNewData=%s,cmpValueChange=%s,%s"
                       % (billboardIndex, type2, value1, value2, cmpValue, cmpValue2, cmpValue3, isNewData, cmpValueChange, kwargs), curPlayerID)
    if not cmpValueChange:
        return True
    
    GameWorld.DebugLog("更新排行榜值 index=%s,type2=%s,value1=%s,value2=%s,cmpValue=%s,cmpValue2==%s,cmpValue3==%s,isNewData=%s"
                       % (billboardIndex, billboardType, value1, value2, cmpValue, cmpValue2, cmpValue3, isNewData), curPlayerID)
    billboardMgr = GetBillboardMgr()
    billboardObj = billboardMgr.GetBillboardObj(billboardIndex)
    billboardObj.OnBillboardChange()
    if not autoSort:
        #不自动排序
        GameWorld.GetGameWorld().SetDict(Def_Key_BillboardNeedSort % billboardIndex, 1) # 设置需要下次查看需要先排序
        return True
    
    #重新排序排行榜
@@ -655,13 +891,6 @@
def IsBillboardLVLimit(playerLV, billboardType):
    # 等级判断已由地图处理掉,这里不再做判断
    return True
#    BillBoardLimitInfo = ReadChConfig.GetEvalChConfig("BillBoardLimit")
#    defaultMinLV, limitLVDict = BillBoardLimitInfo
#    lvBillBoardMinLV = limitLVDict.get(billboardType, defaultMinLV)
#    if playerLV < lvBillBoardMinLV:
#        return True
#
#    return False
def RedressBillboard(curPlayer):
    ## 纠正排行榜中的玩家名字记录
@@ -720,3 +949,50 @@
        
    return
def UpdateBillboardFace(curPlayer):
    ## 更新排行榜中的玩家头像
    curPlayerID = curPlayer.GetID()
    curFace = curPlayer.GetFace()
    billboardMgr = GameWorld.GetBillboard()
    for billboardIndex in ShareDefine.BillboardTypeList:
        if billboardIndex in ShareDefine.FamilyBillboardList:
            continue
        billBoard = billboardMgr.FindBillboard(billboardIndex)
        if not billBoard:
            #找不到这类型排行榜
            continue
        playerBillBoardData = billBoard.FindByID(curPlayerID)
        if not playerBillBoardData:
            #该玩家没有在排行榜上
            continue
        playerBillBoardData.SetValue3(curFace)
    return
def UpdateBillboardFacePic(curPlayer):
    ## 更新排行榜中的玩家头像
    curPlayerID = curPlayer.GetID()
    curFacePic = curPlayer.GetFacePic()
    billboardMgr = GameWorld.GetBillboard()
    for billboardIndex in ShareDefine.BillboardTypeList:
        if billboardIndex in ShareDefine.FamilyBillboardList:
            continue
        billBoard = billboardMgr.FindBillboard(billboardIndex)
        if not billBoard:
            #找不到这类型排行榜
            continue
        playerBillBoardData = billBoard.FindByID(curPlayerID)
        if not playerBillBoardData:
            #该玩家没有在排行榜上
            continue
        playerBillBoardData.SetValue4(curFacePic)
    return