From a7e72a169ff9fbd6d9d061f7352a130b8d53f9a6 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 16 五月 2025 15:46:43 +0800
Subject: [PATCH] 16 卡牌服务端(排行榜)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py               |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py               |   72 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py           |  294 ++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py    |  478 ++++++++++-----
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py    |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBDataMgr.py              |   14 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBBillboard.py |  453 +++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py          |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Billboard.py     |  187 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                       |   12 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTruck.py        |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py           |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py                 |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py |    5 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py               |  199 ++++++
 15 files changed, 1,552 insertions(+), 183 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 572a9ab..1ed0e32 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -46,6 +46,18 @@
 PacketSubCMD_1=0x37
 PacketCallFunc_1=OnRequestMail
 
+;排行榜
+[PlayerBillboard]
+ScriptName = Player\PlayerBillboard.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 1
+
+PacketCMD_1=0xA1
+PacketSubCMD_1=0x30
+PacketCallFunc_1=OnViewBillboard
+
 ;法器
 [PlayerFaQi]
 ScriptName = Player\PlayerFaQi.py
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index fa57fb5..4d586a9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -6229,6 +6229,78 @@
 
 
 #------------------------------------------------------
+# A1 30 查看榜单 #tagCMViewBillboard
+
+class  tagCMViewBillboard(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("Type", c_ubyte),    #榜单类型
+                  ("GroupValue1", c_int),    #分组值1
+                  ("GroupValue2", c_int),    #分组值2,与分组值1组合归为同组榜单数据
+                  ("StartIndex", c_ushort),    #查看的起始名次索引, 默认0
+                  ("ViewCnt", c_ubyte),    #查看条数,默认20,单次最大不超过100
+                  ("ViewID", c_int),    #附带查看指定ID所在名次前后数据,如玩家ID、家族ID等,仅首页查询时有效,即StartIndex为0时
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA1
+        self.SubCmd = 0x30
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xA1
+        self.SubCmd = 0x30
+        self.Type = 0
+        self.GroupValue1 = 0
+        self.GroupValue2 = 0
+        self.StartIndex = 0
+        self.ViewCnt = 0
+        self.ViewID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMViewBillboard)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A1 30 查看榜单 //tagCMViewBillboard:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                Type:%d,
+                                GroupValue1:%d,
+                                GroupValue2:%d,
+                                StartIndex:%d,
+                                ViewCnt:%d,
+                                ViewID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.Type,
+                                self.GroupValue1,
+                                self.GroupValue2,
+                                self.StartIndex,
+                                self.ViewCnt,
+                                self.ViewID
+                                )
+        return DumpString
+
+
+m_NAtagCMViewBillboard=tagCMViewBillboard()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMViewBillboard.Cmd,m_NAtagCMViewBillboard.SubCmd))] = m_NAtagCMViewBillboard
+
+
+#------------------------------------------------------
 # A2 19 游戏建议收集 #tagCMAdviceSubmit
 
 class  tagCMAdviceSubmit(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 174b641..3cfdf96 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -22784,6 +22784,300 @@
 
 
 #------------------------------------------------------
+# A1 30 查看榜单返回信息 #tagMCViewBillboardRet
+
+class  tagMCViewBillboardData(Structure):
+    Index = 0    #(WORD Index)//数据在榜单列表中的索引,从0开始
+    Rank = 0    #(WORD Rank)//名次,从1开始,代表第1名
+    ID = 0    #(DWORD ID)
+    ID2 = 0    #(DWORD ID2)
+    Name1 = ""    #(char Name1[33])//名字1,用来显示排序对象名字 
+    Name2 = ""    #(char Name2[65])//名字2
+    Type2 = 0    #(BYTE Type2)//附加类型,用来表示排序对象的类型,比如,玩家所属职业门派,宠物类型等
+    Value1 = 0    #(DWORD Value1)//自定义值1
+    Value2 = 0    #(DWORD Value2)//自定义值2
+    Value3 = 0    #(DWORD Value3)
+    Value4 = 0    #(DWORD Value4)
+    Value5 = 0    #(DWORD Value5)
+    Value6 = 0    #(DWORD Value6)
+    Value7 = 0    #(DWORD Value7)
+    Value8 = 0    #(DWORD Value8)
+    CmpValue = 0    #(DWORD CmpValue)// 比较权值
+    CmpValue2 = 0    #(DWORD CmpValue2)// 比较权值
+    CmpValue3 = 0    #(DWORD CmpValue3)// 比较权值
+    DataLen = 0    #(WORD DataLen)
+    UserData = ""    #(String UserData)//附加信息
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.Index,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Rank,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.ID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ID2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Name1,_pos = CommFunc.ReadString(_lpData, _pos,33)
+        self.Name2,_pos = CommFunc.ReadString(_lpData, _pos,65)
+        self.Type2,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value4,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value5,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value6,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value7,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value8,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CmpValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CmpValue2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CmpValue3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.DataLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.UserData,_pos = CommFunc.ReadString(_lpData, _pos,self.DataLen)
+        return _pos
+
+    def Clear(self):
+        self.Index = 0
+        self.Rank = 0
+        self.ID = 0
+        self.ID2 = 0
+        self.Name1 = ""
+        self.Name2 = ""
+        self.Type2 = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.Value3 = 0
+        self.Value4 = 0
+        self.Value5 = 0
+        self.Value6 = 0
+        self.Value7 = 0
+        self.Value8 = 0
+        self.CmpValue = 0
+        self.CmpValue2 = 0
+        self.CmpValue3 = 0
+        self.DataLen = 0
+        self.UserData = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 2
+        length += 2
+        length += 4
+        length += 4
+        length += 33
+        length += 65
+        length += 1
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 2
+        length += len(self.UserData)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteWORD(data, self.Index)
+        data = CommFunc.WriteWORD(data, self.Rank)
+        data = CommFunc.WriteDWORD(data, self.ID)
+        data = CommFunc.WriteDWORD(data, self.ID2)
+        data = CommFunc.WriteString(data, 33, self.Name1)
+        data = CommFunc.WriteString(data, 65, self.Name2)
+        data = CommFunc.WriteBYTE(data, self.Type2)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        data = CommFunc.WriteDWORD(data, self.Value3)
+        data = CommFunc.WriteDWORD(data, self.Value4)
+        data = CommFunc.WriteDWORD(data, self.Value5)
+        data = CommFunc.WriteDWORD(data, self.Value6)
+        data = CommFunc.WriteDWORD(data, self.Value7)
+        data = CommFunc.WriteDWORD(data, self.Value8)
+        data = CommFunc.WriteDWORD(data, self.CmpValue)
+        data = CommFunc.WriteDWORD(data, self.CmpValue2)
+        data = CommFunc.WriteDWORD(data, self.CmpValue3)
+        data = CommFunc.WriteWORD(data, self.DataLen)
+        data = CommFunc.WriteString(data, self.DataLen, self.UserData)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Index:%d,
+                                Rank:%d,
+                                ID:%d,
+                                ID2:%d,
+                                Name1:%s,
+                                Name2:%s,
+                                Type2:%d,
+                                Value1:%d,
+                                Value2:%d,
+                                Value3:%d,
+                                Value4:%d,
+                                Value5:%d,
+                                Value6:%d,
+                                Value7:%d,
+                                Value8:%d,
+                                CmpValue:%d,
+                                CmpValue2:%d,
+                                CmpValue3:%d,
+                                DataLen:%d,
+                                UserData:%s
+                                '''\
+                                %(
+                                self.Index,
+                                self.Rank,
+                                self.ID,
+                                self.ID2,
+                                self.Name1,
+                                self.Name2,
+                                self.Type2,
+                                self.Value1,
+                                self.Value2,
+                                self.Value3,
+                                self.Value4,
+                                self.Value5,
+                                self.Value6,
+                                self.Value7,
+                                self.Value8,
+                                self.CmpValue,
+                                self.CmpValue2,
+                                self.CmpValue3,
+                                self.DataLen,
+                                self.UserData
+                                )
+        return DumpString
+
+
+class  tagMCViewBillboardRet(Structure):
+    Head = tagHead()
+    Type = 0    #(BYTE Type)//榜单类型
+    GroupValue1 = 0    #(DWORD GroupValue1)//分组值1
+    GroupValue2 = 0    #(DWORD GroupValue2)//分组值2,与分组值1组合归为同组榜单数据
+    DataTotal = 0    #(WORD DataTotal)//该榜单实际总数据数,分页查询时可通过此值及返回的分页最后一条榜单数据所在索引判断是否还有未查询数据
+    PageDataCnt = 0    #(BYTE PageDataCnt)
+    PageDataList = list()    #(vector<tagMCViewBillboardData> PageDataList)//返回分页数据列表
+    ViewID = 0    #(DWORD ViewID)//附带查看指定ID所在名次前后数据,如玩家ID、家族ID等
+    ViewIDDataCnt = 0    #(BYTE ViewIDDataCnt)
+    ViewIDDataList = list()    #(vector<tagMCViewBillboardData> ViewIDDataList)//ViewID所在名次前后数据列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xA1
+        self.Head.SubCmd = 0x30
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.Type,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.GroupValue1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.GroupValue2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.DataTotal,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.PageDataCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.PageDataCnt):
+            temPageDataList = tagMCViewBillboardData()
+            _pos = temPageDataList.ReadData(_lpData, _pos)
+            self.PageDataList.append(temPageDataList)
+        self.ViewID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ViewIDDataCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.ViewIDDataCnt):
+            temViewIDDataList = tagMCViewBillboardData()
+            _pos = temViewIDDataList.ReadData(_lpData, _pos)
+            self.ViewIDDataList.append(temViewIDDataList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xA1
+        self.Head.SubCmd = 0x30
+        self.Type = 0
+        self.GroupValue1 = 0
+        self.GroupValue2 = 0
+        self.DataTotal = 0
+        self.PageDataCnt = 0
+        self.PageDataList = list()
+        self.ViewID = 0
+        self.ViewIDDataCnt = 0
+        self.ViewIDDataList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 4
+        length += 4
+        length += 2
+        length += 1
+        for i in range(self.PageDataCnt):
+            length += self.PageDataList[i].GetLength()
+        length += 4
+        length += 1
+        for i in range(self.ViewIDDataCnt):
+            length += self.ViewIDDataList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.Type)
+        data = CommFunc.WriteDWORD(data, self.GroupValue1)
+        data = CommFunc.WriteDWORD(data, self.GroupValue2)
+        data = CommFunc.WriteWORD(data, self.DataTotal)
+        data = CommFunc.WriteBYTE(data, self.PageDataCnt)
+        for i in range(self.PageDataCnt):
+            data = CommFunc.WriteString(data, self.PageDataList[i].GetLength(), self.PageDataList[i].GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.ViewID)
+        data = CommFunc.WriteBYTE(data, self.ViewIDDataCnt)
+        for i in range(self.ViewIDDataCnt):
+            data = CommFunc.WriteString(data, self.ViewIDDataList[i].GetLength(), self.ViewIDDataList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                Type:%d,
+                                GroupValue1:%d,
+                                GroupValue2:%d,
+                                DataTotal:%d,
+                                PageDataCnt:%d,
+                                PageDataList:%s,
+                                ViewID:%d,
+                                ViewIDDataCnt:%d,
+                                ViewIDDataList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.Type,
+                                self.GroupValue1,
+                                self.GroupValue2,
+                                self.DataTotal,
+                                self.PageDataCnt,
+                                "...",
+                                self.ViewID,
+                                self.ViewIDDataCnt,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCViewBillboardRet=tagMCViewBillboardRet()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCViewBillboardRet.Head.Cmd,m_NAtagMCViewBillboardRet.Head.SubCmd))] = m_NAtagMCViewBillboardRet
+
+
+#------------------------------------------------------
 # A2 02 玩家攻击模式通知 #tagMCAttackMode
 
 class  tagMCAttackMode(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBDataMgr.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBDataMgr.py
index 2168596..99738ed 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBDataMgr.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBDataMgr.py
@@ -19,6 +19,7 @@
 import PyGameData
 import DBEventTrig
 import DBPlayerViewCache
+import DBBillboard
 import DBFamily
 import DBMail
 
@@ -46,9 +47,10 @@
     return
 
 def OnMinute(curTime):
-    curMinute = curTime.minute
+    #curMinute = curTime.minute
     ServerDataBackup()
-    DBFamily.OnMinute(curMinute)
+    DBFamily.OnMinute()
+    DBBillboard.OnMinute()
     return
 
 #------------------------------------------- 备档 ---------------------------------------------------
@@ -165,6 +167,7 @@
         self.PlayerViewCacheMgr = DBPlayerViewCache.PlayerViewCacheMgr()
         self.FamilyMgr = DBFamily.FamilyMgr()
         self.MailMgr = DBMail.MailMgr()
+        self.BillboardMgr = DBBillboard.BillboardMgr()
         return
     
     def GetSaveData(self):
@@ -173,6 +176,7 @@
         buff += self.PlayerViewCacheMgr.GetSaveData()
         buff += self.FamilyMgr.GetSaveData()
         buff += self.MailMgr.GetSaveData()
+        buff += self.BillboardMgr.GetSaveData()
         return buff
     
     def LoadGameData(self, gameBuffer, pos):
@@ -181,6 +185,7 @@
         pos = self.PlayerViewCacheMgr.LoadPyGameData(gameBuffer, pos, dataslen)
         pos = self.FamilyMgr.LoadPyGameData(gameBuffer, pos, dataslen)
         pos = self.MailMgr.LoadPyGameData(gameBuffer, pos, dataslen)
+        pos = self.BillboardMgr.LoadPyGameData(gameBuffer, pos, dataslen)
         return pos
     
 def GetDBDataMgr():
@@ -215,3 +220,8 @@
     dbDataMgr = GetDBDataMgr()
     return dbDataMgr.MailMgr
 
+def GetBillboardMgr():
+    ## 排行榜数据管理器
+    dbDataMgr = GetDBDataMgr()
+    return dbDataMgr.BillboardMgr
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py
index 2ca0b00..5f67798 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py
@@ -1698,3 +1698,202 @@
         else:
             self.GUID = Str[:36]
             
+
+# 排行榜表 #tagDBBillboard
+class tagDBBillboard(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('GroupValue1', ctypes.c_ulong),
+        ('GroupValue2', ctypes.c_ulong),
+        ('BillboardType', ctypes.c_ubyte),
+        ('ID', ctypes.c_ulong),
+        ('ID2', ctypes.c_ulong),
+        ('Name1', ctypes.c_char * 33),
+        ('Name2', ctypes.c_char * 65),
+        ('Type2', ctypes.c_ubyte),
+        ('Value1', ctypes.c_ulong),
+        ('Value2', ctypes.c_ulong),
+        ('Value3', ctypes.c_ulong),
+        ('Value4', ctypes.c_ulong),
+        ('Value5', ctypes.c_ulong),
+        ('Value6', ctypes.c_ulong),
+        ('Value7', ctypes.c_ulong),
+        ('Value8', ctypes.c_ulong),
+        ('CmpValue', ctypes.c_ulong),
+        ('CmpValue2', ctypes.c_ulong),
+        ('CmpValue3', ctypes.c_ulong),
+        ('DataLen', ctypes.c_ushort),
+        ('UserData', ctypes.c_char_p),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+    def clear(self):
+        self.GroupValue1 = 0
+        self.GroupValue2 = 0
+        self.BillboardType = 0
+        self.ID = 0
+        self.ID2 = 0
+        self.Name1 = ''
+        self.Name2 = ''
+        self.Type2 = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.Value3 = 0
+        self.Value4 = 0
+        self.Value5 = 0
+        self.Value6 = 0
+        self.Value7 = 0
+        self.Value8 = 0
+        self.CmpValue = 0
+        self.CmpValue2 = 0
+        self.CmpValue3 = 0
+        self.DataLen = 0
+        self.UserData = ''
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        self.GroupValue1, pos = CommFunc.ReadDWORD(buf, pos)
+        self.GroupValue2, pos = CommFunc.ReadDWORD(buf, pos)
+        self.BillboardType, pos = CommFunc.ReadBYTE(buf, pos)
+        self.ID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.ID2, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Name1, pos = CommFunc.ReadString(buf, pos, 33)
+        self.Name2, pos = CommFunc.ReadString(buf, pos, 65)
+        self.Type2, pos = CommFunc.ReadBYTE(buf, pos)
+        self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value3, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value4, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value5, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value6, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value7, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value8, pos = CommFunc.ReadDWORD(buf, pos)
+        self.CmpValue, pos = CommFunc.ReadDWORD(buf, pos)
+        self.CmpValue2, pos = CommFunc.ReadDWORD(buf, pos)
+        self.CmpValue3, pos = CommFunc.ReadDWORD(buf, pos)
+        self.DataLen, pos = CommFunc.ReadWORD(buf, pos)
+        tmp, pos = CommFunc.ReadString(buf, pos, self.DataLen)
+        self.UserData = ctypes.c_char_p(tmp)
+        return self.getLength()
+
+    def getBuffer(self):
+        buf = ''
+        buf = CommFunc.WriteDWORD(buf, self.GroupValue1)
+        buf = CommFunc.WriteDWORD(buf, self.GroupValue2)
+        buf = CommFunc.WriteBYTE(buf, self.BillboardType)
+        buf = CommFunc.WriteDWORD(buf, self.ID)
+        buf = CommFunc.WriteDWORD(buf, self.ID2)
+        buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 33, self.Name1)
+        buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 65, self.Name2)
+        buf = CommFunc.WriteBYTE(buf, self.Type2)
+        buf = CommFunc.WriteDWORD(buf, self.Value1)
+        buf = CommFunc.WriteDWORD(buf, self.Value2)
+        buf = CommFunc.WriteDWORD(buf, self.Value3)
+        buf = CommFunc.WriteDWORD(buf, self.Value4)
+        buf = CommFunc.WriteDWORD(buf, self.Value5)
+        buf = CommFunc.WriteDWORD(buf, self.Value6)
+        buf = CommFunc.WriteDWORD(buf, self.Value7)
+        buf = CommFunc.WriteDWORD(buf, self.Value8)
+        buf = CommFunc.WriteDWORD(buf, self.CmpValue)
+        buf = CommFunc.WriteDWORD(buf, self.CmpValue2)
+        buf = CommFunc.WriteDWORD(buf, self.CmpValue3)
+        buf = CommFunc.WriteWORD(buf, self.DataLen)
+        buf = CommFunc.WriteString(buf, self.DataLen, self.UserData)
+        return buf
+
+    def getLength(self):
+        length = 0
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_char) * 33
+        length += sizeof(ctypes.c_char) * 65
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ushort)
+        length += self.DataLen
+        return length
+
+    def outputString(self):
+        output = '''// 排行榜表 #tagDBBillboard:
+            GroupValue1 = %s,
+            GroupValue2 = %s,
+            BillboardType = %s,
+            ID = %s,
+            ID2 = %s,
+            Name1 = %s,
+            Name2 = %s,
+            Type2 = %s,
+            Value1 = %s,
+            Value2 = %s,
+            Value3 = %s,
+            Value4 = %s,
+            Value5 = %s,
+            Value6 = %s,
+            Value7 = %s,
+            Value8 = %s,
+            CmpValue = %s,
+            CmpValue2 = %s,
+            CmpValue3 = %s,
+            DataLen = %s,
+            UserData = %s,
+            ADOResult = %s,
+            '''%(
+                self.GroupValue1,
+                self.GroupValue2,
+                self.BillboardType,
+                self.ID,
+                self.ID2,
+                self.Name1,
+                self.Name2,
+                self.Type2,
+                self.Value1,
+                self.Value2,
+                self.Value3,
+                self.Value4,
+                self.Value5,
+                self.Value6,
+                self.Value7,
+                self.Value8,
+                self.CmpValue,
+                self.CmpValue2,
+                self.CmpValue3,
+                self.DataLen,
+                self.UserData,
+                self.ADOResult,
+            )
+        return output
+
+    #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
+    def SetName1(self,Str):
+        if len(Str)<=33:
+            self.Name1 = Str
+        else:
+            self.Name1 = Str[:33]
+            
+    def SetName2(self,Str):
+        if len(Str)<=65:
+            self.Name2 = Str
+        else:
+            self.Name2 = Str[:65]
+            
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
new file mode 100644
index 0000000..552dd85
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBBillboard.py
@@ -0,0 +1,453 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package DB.StructData.DBBillboard
+#
+# @todo:DB排行榜
+# @author hxp
+# @date 2025-05-16
+# @version 1.0
+#
+# 详细描述: DB排行榜
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-05-16 12:00"""
+#-------------------------------------------------------------------------------
+
+import DBStruct
+import GameWorld
+import ShareDefine
+import DataRecordPack
+import IpyGameDataPY
+import DBDataMgr
+import CommFunc
+
+import json
+
+class BillboardData():
+    ## 榜单数据
+    
+    def __init__(self, dbData=None):
+        self.__dbData = DBStruct.tagDBBillboard() if not dbData else dbData
+        return
+    
+    def GetType(self): return self.__dbData.BillboardType
+    def SetType(self, bType): self.__dbData.BillboardType = bType
+    def GetGroupValue1(self): return self.__dbData.GroupValue1
+    def SetGroupValue1(self, groupValue1): self.__dbData.GroupValue1 = groupValue1
+    def GetGroupValue2(self): return self.__dbData.GroupValue2
+    def SetGroupValue2(self, groupValue2): self.__dbData.GroupValue2 = groupValue2
+    def GetID(self): return self.__dbData.ID
+    def SetID(self, dataID): self.__dbData.ID = dataID
+    def GetID2(self): return self.__dbData.ID2
+    def SetID2(self, id2): self.__dbData.ID2 = id2
+    def GetName1(self): return self.__dbData.Name1
+    def SetName1(self, name): self.__dbData.Name1 = name
+    def GetName2(self): return self.__dbData.Name2
+    def SetName2(self, name2): self.__dbData.Name2 = name2
+    def GetType2(self): return self.__dbData.Type2
+    def SetType2(self, type2): self.__dbData.Type2 = type2
+    def GetValue1(self): return self.__dbData.Value1
+    def SetValue1(self, value1): self.__dbData.Value1 = value1
+    def GetValue2(self): return self.__dbData.Value2
+    def SetValue2(self, value2): self.__dbData.Value2 = value2
+    def GetValue3(self): return self.__dbData.Value3
+    def SetValue3(self, value3): self.__dbData.Value3 = value3
+    def GetValue4(self): return self.__dbData.Value4
+    def SetValue4(self, value4): self.__dbData.Value4 = value4
+    def GetValue5(self): return self.__dbData.Value5
+    def SetValue5(self, value5): self.__dbData.Value5 = value5
+    def GetValue6(self): return self.__dbData.Value6
+    def SetValue6(self, value6): self.__dbData.Value6 = value6
+    def GetValue7(self): return self.__dbData.Value7
+    def SetValue7(self, value7): self.__dbData.Value7 = value7
+    def GetValue8(self): return self.__dbData.Value8
+    def SetValue8(self, value8): self.__dbData.Value8 = value8
+    def GetCmpValue(self): return self.__dbData.CmpValue
+    def SetCmpValue(self, cmpValue): self.__dbData.CmpValue = cmpValue
+    def GetCmpValue2(self): return self.__dbData.CmpValue2
+    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 GetBuffer(self): return self.__dbData.getBuffer()
+    def Clear(self): return self.__dbData.clear()
+    def Copy(self, setType=None):
+        copyData = BillboardData()
+        copyData.SetType(setType if setType != None else self.GetType())
+        copyData.SetGroupValue1(self.GetGroupValue1())
+        copyData.SetGroupValue2(self.GetGroupValue2())
+        copyData.SetID(self.GetID())
+        copyData.SetID2(self.GetID2())
+        copyData.SetName1(self.GetName1())
+        copyData.SetName2(self.GetName2())
+        copyData.SetType2(self.GetType2())
+        copyData.SetValue1(self.GetValue1())
+        copyData.SetValue2(self.GetValue2())
+        copyData.SetValue3(self.GetValue3())
+        copyData.SetValue4(self.GetValue4())
+        copyData.SetValue5(self.GetValue5())
+        copyData.SetValue6(self.GetValue6())
+        copyData.SetValue7(self.GetValue7())
+        copyData.SetValue8(self.GetValue8())
+        copyData.SetUserData(self.GetUserData())
+        copyData.SetCmpValue(self.GetCmpValue())
+        copyData.SetCmpValue2(self.GetCmpValue2())
+        copyData.SetCmpValue3(self.GetCmpValue3())
+        return copyData
+    
+class Billboard():
+    ## 某个排行榜类
+    
+    def __init__(self, billboardType=0, groupValue1=0, groupValue2=0):
+        self.__billboardType = billboardType
+        self.__groupValue1 = groupValue1
+        self.__groupValue2 = groupValue2
+        self.__billboardList = [] # [BillboardData, ...] 
+        self.__idIndexDict = {} # {id:index, ...}
+        self.__idOrderDict = {} # {id:名次, ...}
+        self.__orderRuleList = None # 指定排名所需值规则列表 [[order, needCmpValue], ...]
+        self.__sortDelay = False # 是否需要延迟排序
+        return
+    
+    def GetType(self): return self.__billboardType
+    def GetGroupValue1(self): return self.__groupValue1
+    def GetGroupValue2(self): return self.__groupValue2
+    
+    def ClearData(self):
+        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")
+        self.__billboardList = [] # [BillboardData, ...] 
+        self.__idOrderDict = {} # {id:名次, ...}
+        self.__idIndexDict = {}
+        return
+    
+    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)
+        self.__idOrderDict = {} # 排序后重置,下次查询时更新并缓存
+        self.__idIndexDict = {}
+        self.__sortDelay = False
+        return
+    
+    def SetSortDelay(self):
+        ## 设置延迟排序
+        GameWorld.DebugLog("榜单设置延迟排序: billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s" 
+                      % (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList)))
+        self.__sortDelay = True
+        return
+    
+    def SortDelayDo(self):
+        ## 延迟排序执行排序
+        if not self.__sortDelay:
+            return
+        self.SortData()
+        return
+    
+    def AddNewBillboardData(self):
+        newData = None
+        if self.IsFull():
+            return newData
+        newData = BillboardData()
+        newData.SetType(self.__billboardType)
+        newData.SetGroupValue1(self.__groupValue1)
+        newData.SetGroupValue2(self.__groupValue2)
+        self.AddBillboardData(newData)
+        return newData
+    
+    def AddBillboardData(self, billboardData):
+        ## 添加榜单数据到该榜
+        # @param billboardData: BillboardData
+        # @return: 是否成功
+        if self.IsFull():
+            return False
+        self.__billboardList.append(billboardData)
+        self.__idIndexDict[billboardData.GetID()] = len(self.__billboardList) - 1
+        self.__sortDelay = True
+        # __idOrderDict 不处理,等下次排序后自动处理,所以新添加的数据可能找不到对应名次,但是能找到对应索引及数据
+        return True
+    
+    def FindByID(self, findID):
+        ''' 根据ID查询榜单数据
+        @param findID: 查找的ID
+        @return: None or BillboardData
+        '''
+        billData = None
+        self.GetIDOrderDict()
+        if findID not in self.__idIndexDict:
+            return billData
+        idIndex = self.__idIndexDict[findID]
+        if idIndex >= len(self.__billboardList):
+            return billData
+        billData = self.__billboardList[idIndex]
+        if not billData and False:
+            billData = BillboardData() # 不会执行到,只为了.出代码提示
+        return billData
+    
+    def IndexOfByID(self, findID):
+        ''' 根据ID查询所在榜单索引
+        @param findID: 查找的ID
+        @return: -1 or >=0
+        '''
+        self.GetIDOrderDict()
+        if findID not in self.__idIndexDict:
+            return -1
+        idIndex = self.__idIndexDict[findID]
+        return idIndex
+    
+    def SaveDRData(self, eventName="", addDataDict={}):
+        ## 记录流向数据
+        
+        self.SortDelayDo()
+        dataCount = len(self.__billboardList)
+        if not dataCount:
+            return
+        
+        idOrderDict = self.GetIDOrderDict()
+        serverTime = GameWorld.GetServerTime()
+        timeStr = "%02d%02d%02d%s" % (serverTime.hour, serverTime.minute, serverTime.second, str(serverTime.microsecond)[:3])
+        eventTypeStr = "Billboard_%s_%s_%s_%s_%s" % (self.__billboardType, self.__groupValue1, self.__groupValue2, eventName, timeStr)
+        
+        dataDict = {"BillboardType":self.__billboardType, "DataCount":dataCount, "addDataDict":addDataDict,
+                    "GroupValue1":self.__groupValue1, "GroupValue2":self.__groupValue2}
+        DataRecordPack.SendEventPack(eventTypeStr, dataDict)
+        
+        for index, bData in enumerate(self.__billboardList):
+            rank = idOrderDict.get(bData.GetID(), index + 1)
+            dataDict = {"Type2":bData.GetType2(), "Rank":rank, "Index":index,
+                        "ID":bData.GetID(), "ID2":bData.GetID2(),  
+                        "Name1":bData.GetName1(), "Name2":bData.GetName2(),
+                        "Value1":bData.GetValue1(), "Value2":bData.GetValue2(),
+                        "Value3":bData.GetValue3(), "Value4":bData.GetValue4(),
+                        "Value5":bData.GetValue5(), "Value6":bData.GetValue6(),
+                        "Value7":bData.GetValue7(), "Value8":bData.GetValue8(),
+                        "CmpValue":bData.GetCmpValue(), "CmpValue2":bData.GetCmpValue2(), 
+                        "CmpValue3":bData.GetCmpValue3(), "UserData":bData.GetUserData()}
+            DataRecordPack.SendEventPack(eventTypeStr, dataDict)
+            
+        return
+    
+    def GetBillboardDataList(self): return self.__billboardList
+    def GetIDOrderDict(self):
+        ## 获取ID对应名次字典
+        # @return: {ID:名次, ...}  名次从1开始
+        if not self.__idOrderDict or not self.__idIndexDict:
+            self.__idOrderDict = {}
+            self.__idIndexDict = {}
+            if self.__orderRuleList:
+                billboardDataCount = self.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 = self.At(index)
+                        if billboardData.GetCmpValue() < needCmpValue:
+                            break
+                        orderReal = rank - orderCountTotal + 1
+                        self.__idOrderDict[billboardData.GetID()] = orderReal
+                        orderCountTotal -= 1
+                        billboardIndex += 1
+                for order, billboardData in enumerate(self.__billboardList, 1):
+                    self.__idIndexDict[billboardData.GetID()] = order - 1
+            else:
+                for order, billboardData in enumerate(self.__billboardList, 1):
+                    self.__idOrderDict[billboardData.GetID()] = order
+                    self.__idIndexDict[billboardData.GetID()] = order - 1
+        return self.__idOrderDict
+    
+    def SetOrderRuleList(self, orderRuleList):
+        ## 排名所需值规则列表
+        # @param orderRuleList: 排名所需值规则列表 [[order, needCmpValue], ...]
+        self.__orderRuleList = orderRuleList
+        self.__idOrderDict = {} # 设置后需重置,可能配置规则变化了导致实际排名可能变化
+        self.__idIndexDict = {}
+        GameWorld.Log("设置排名所需值规则列表: billboardType=%s,groupValue1=%s,groupValue2=%s, %s" 
+                      % (self.__billboardType, self.__groupValue1, self.__groupValue2, orderRuleList))
+        return
+    
+    def GetCount(self): return len(self.__billboardList)
+    def GetMaxCount(self):
+        maxCountDict = IpyGameDataPY.GetFuncEvalCfg("BillboardSet", 2, {})
+        return maxCountDict.get(self.__billboardType, 100)
+    
+    def At(self, index):
+        billData = self.__billboardList[index]
+        if not billData and False:
+            billData = BillboardData() # 不会执行到,只为了.出代码提示
+        return billData
+    
+    def IsFull(self): return len(self.__billboardList) >= self.GetMaxCount()
+    
+    def DeleteByIndex(self, index):
+        if index >= len(self.__billboardList):
+            return
+        self.__billboardList.pop(index)
+        self.__idOrderDict = {}
+        self.__idIndexDict = {}
+        return
+    
+    def DeleteByID(self, dataID):
+        index = self.IndexOfByID(dataID)
+        if index >= 0:
+            self.DeleteByIndex(index)
+        return
+    
+class BillboardMgr():
+    ## 排行榜管理
+    
+    def __init__(self):
+        self.__billboardDict = {} # 排行榜字典 {(billboardType, groupValue1, groupValue2):Billboard, ...}
+        return
+    
+    def GetBillboardGroupList(self, bType):
+        ## 根据榜单类型获取该类型所有分组榜单信息
+        ## @return: [(billboardType, groupValue1, groupValue2), ...]
+        groupList = []
+        for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
+            if bType == billboardType:
+                groupList.append((billboardType, groupValue1, groupValue2))
+        return groupList
+    
+    def GetBillboard(self, billboardType, groupValue1=0, groupValue2=0):
+        ''' 获取排行榜
+        @param billboardType: 排行榜类型
+        @param groupValue1: 分组值1
+        @param groupValue2: 分组值2,与分组值1组合归为同组榜单数据
+        @return: Billboard
+        '''
+        key = (billboardType, groupValue1, groupValue2)
+        if key in self.__billboardDict:
+            billboardObj = self.__billboardDict[key]
+        else:
+            billboardObj = Billboard(billboardType, groupValue1, groupValue2)
+            self.__billboardDict[key] = billboardObj
+        return billboardObj
+    
+    def RemoveBillboard(self, billboardType):
+        ## 移除某个类型的榜单所有数据
+        for key in self.__billboardDict.keys():
+            if key[0] == billboardType:
+                self.__billboardDict.pop(key)
+        return
+    
+    def ClearBillboard(self, billboardType, groupValue1=None, groupValue2=None):
+        '''清除某个类型的榜单所有数据,可指定过滤groupValue,有流向记录
+        @param groupValue1: 不为None时验证 groupValue1 是否相同
+        @param groupValue2: 不为None时验证 groupValue2 是否相同
+        如果groupValue1 groupValue2 都传入None,相当于清空 billboardType 类型的所有榜单数据
+        '''
+        clearList = []
+        for bType, gValue1, gValue2 in self.__billboardDict.keys():
+            if bType != billboardType:
+                continue
+            if groupValue1 != None and groupValue1 != gValue1:
+                continue
+            if groupValue2 != None and groupValue2 != gValue2:
+                continue
+            key = (bType, gValue1, gValue2)
+            clearList.append(key)
+            
+        for bType, gValue1, gValue2 in clearList:
+            self.GetBillboard(bType, gValue1, gValue2).ClearData()
+        return
+    
+    def CopyBillboard(self, fromBillboardType, toBillboardType, groupValue1=None, groupValue2=None):
+        '''将某个类型的榜单完全拷贝到其他榜单 - 一般用于备份、转移数据
+        @param fromBillboardType: 源榜单类型
+        @param toBillboardType: 目标榜单类型
+        @param groupValue1: 默认为None-拷贝该类型所有榜单,大于等于0时-仅拷贝该类型下的指定榜单
+        @param groupValue2: 默认为None-拷贝该类型所有榜单,大于等于0时-仅拷贝该类型下的指定榜单
+        '''
+        
+        if groupValue1 == None:
+            self.RemoveBillboard(toBillboardType) # 默认清空目标榜单
+            groupList = self.GetBillboardGroupList(fromBillboardType)
+        else:
+            groupValue2 = groupValue2 if groupValue2 != None else 0
+            groupList = [fromBillboardType, groupValue1, groupValue2]
+            
+        for billboardType, groupValue1, groupValue2 in groupList:
+            frbillboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
+            toBillboardObj = self.GetBillboard(toBillboardType, groupValue1, groupValue2)
+            GameWorld.Log("CopyBillboard: billboardType=%s,toBillboardType=%s,groupValue1=%s,groupValue2=%s" 
+                          % (billboardType, toBillboardType, groupValue1, groupValue2))
+            toBillboardObj.ClearData()
+            for index in range(frbillboardObj.GetCount()):
+                frbillboardData = frbillboardObj.At(index)
+                toBillboardObj.AddBillboardData(frbillboardData.Copy(toBillboardType))
+                
+        return
+
+    # 保存数据 存数据库和realtimebackup
+    def GetSaveData(self):
+        savaData = ""
+        cntData = ""
+        cnt = 0
+        for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
+            billboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
+            for i in xrange(billboardObj.GetCount()):
+                billboardData = billboardObj.At(i)
+                cnt += 1
+                savaData += billboardData.GetBuffer()
+                
+        GameWorld.Log("Save DBBillboard count :%s len=%s" % (cnt, len(savaData)))
+        return CommFunc.WriteDWORD(cntData, cnt) + savaData
+    
+    # 从数据库载入数据
+    def LoadPyGameData(self, datas, pos, dataslen):
+        if pos >= dataslen:
+            return
+        
+        cnt, pos = CommFunc.ReadDWORD(datas, pos)
+        GameWorld.Log("Load DBBillboard count :%s" % cnt)
+        
+        for _ in xrange(cnt):
+            dbData = DBStruct.tagDBBillboard()
+            dbData.clear()
+            pos += dbData.readData(datas, pos, dataslen)
+            
+            billboardType, groupValue1, groupValue2 = dbData.BillboardType, dbData.GroupValue1, dbData.GroupValue2
+            
+            billboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
+            billboardObj.AddBillboardData(BillboardData(dbData))
+            
+        # 排序
+        for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
+            billboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
+            billboardObj.SortData()
+            
+        return pos
+    
+def OnMinute():
+    
+    ## 每分钟延迟排序
+    billboardMgr = DBDataMgr.GetBillboardMgr()
+    for billboardType in ShareDefine.BillboardTypeAllList:
+        groupList = billboardMgr.GetBillboardGroupList(billboardType)
+        for billboardType, groupValue1, groupValue2 in groupList:
+            billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+            billboardObj.SortDelayDo()
+            
+    return
+
+    
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
index 293d8de..c8bf380 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
@@ -630,7 +630,7 @@
             
         return pos
     
-def OnMinute(curMinute):
+def OnMinute():
     
     familyMgr = DBDataMgr.GetFamilyMgr()
     # 每分钟刷新下仙盟战力排序
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Billboard.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Billboard.py
new file mode 100644
index 0000000..eda747d
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Billboard.py
@@ -0,0 +1,187 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.Billboard
+#
+# @todo:榜单数据
+# @author hxp
+# @date 2025-05-16
+# @version 1.0
+#
+# 详细描述: 榜单数据
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-05-16 12:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PlayerBillboard
+import ShareDefine
+import DBDataMgr
+
+def __Help(curPlayer, errInfo=""):
+    GameWorld.DebugAnswer(curPlayer, "---------- %s" % GameWorld.GetCurrentDataTimeStr())
+    if errInfo:
+        GameWorld.DebugAnswer(curPlayer, errInfo)
+    GameWorld.DebugAnswer(curPlayer, "新增榜单假数据: Billboard 类型 分组值1 分组值2 条数 比较值1可选参数(比较值2 常规值1~5)")
+    GameWorld.DebugAnswer(curPlayer, "删除榜单假数据: Billboard 类型 分组值1 分组值2")
+    GameWorld.DebugAnswer(curPlayer, "榜单类型:0-战力,1-龙魂,2-灵瑶,4-等级,5-坐骑,6-灵宠,7-符印,8-脱机,9-境界,19-助战")
+    GameWorld.DebugAnswer(curPlayer, "开服活动榜类型:11-强化,12-坐骑,13-宝石,14-冲级,15-境界,16-战力,18-符印,20-神兵,21-充值,22-灵宠,24-灵根,25-升星,26-洗练")
+    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:17-仙界盛典,23-仙界盛典2,33-boss凭证,36-boss凭证仙盟,38-仙匣,39-古宝,40-骑宠")
+    GameWorld.DebugAnswer(curPlayer, "魅力榜单类型:30-总榜,31-周榜,32-日榜")
+    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:150-充值(分组值1配置ID)")
+    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:158-boss凭证,160-凭证仙盟,162-仙匣,163-古宝,164-骑宠")
+    GameWorld.DebugAnswer(curPlayer, "古神战场榜类型:151-参与榜,152-召集榜,153-积分榜")
+    GameWorld.DebugAnswer(curPlayer, "逐鹿万界榜类型:156-单场榜,157-周榜")
+    GameWorld.DebugAnswer(curPlayer, "跨服竞技场榜单:165,分组值1-分区,分组值2-赛季,value2-段位")
+    GameWorld.DebugAnswer(curPlayer, "注:如果没有特殊说明,本服榜单分组值均为0,跨服榜单分组值1为分区ID,分组2为0")
+    return
+
+## 执行逻辑
+#  @param curPlayer 当前玩家
+#  @param gmList []
+#  @return None
+def OnExec(curPlayer, gmList):
+    
+    paramLen = len(gmList)
+    if not paramLen:
+        __Help(curPlayer)
+        return
+    
+    value = gmList[0]
+    if value == "p":
+        __logFackData(curPlayer, gmList)
+        return
+    
+    billboardIndex = value
+    if billboardIndex >= ShareDefine.BillboardTypeAllList:
+        __Help(curPlayer, "榜单类型不存在!")
+        return
+    
+    if billboardIndex in ShareDefine.CrossBillboardTypeList:
+        GameWorld.DebugAnswer(curPlayer, "跨服榜单暂不处理")
+        return
+    
+    if len(gmList) <= 3:
+        __delFackData(curPlayer, gmList)
+    else:
+        __addFackData(curPlayer, gmList)
+    return
+
+def __addFackData(curPlayer, gmList):
+    ## 新增榜单假数据: Billboard 类型 分组值1 分组值2 条数 比较值1可选参数(比较值2 常规值1~5)
+    billboardType = gmList[0]
+    groupValue1 = gmList[1] if len(gmList) > 1 else 0
+    groupValue2 = gmList[2] if len(gmList) > 2 else 0
+    count = gmList[3] if len(gmList) > 3 else 0
+    cmpValue1 = gmList[4] if len(gmList) > 4 else 0
+    cmpValue2 = gmList[5] if len(gmList) > 5 else 0
+    value1 = gmList[6] if len(gmList) > 6 else 0
+    value2 = gmList[7] if len(gmList) > 7 else 0
+    value3 = gmList[8] if len(gmList) > 8 else 0
+    value4 = gmList[9] if len(gmList) > 9 else 0
+    value5 = gmList[10] if len(gmList) > 10 else 0
+    
+    id2 = 0
+    type2 = 0
+    name2 = ""
+    cmpValue3 = 0
+    
+    billboardMgr = DBDataMgr.GetBillboardMgr()
+    billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+    curDataCount = billboardObj.GetCount()
+    maxDataCount = billboardObj.GetMaxCount()
+    
+    count = min(count, maxDataCount - curDataCount)
+    FakeName = GameWorld.GbkToCode("假名字")
+    
+    for i in xrange(count):
+        dataPlayerID = curDataCount + 1 + i
+        dataPlayerName = "%s%s" % (FakeName, dataPlayerID)
+        dataCmpValue1 = max(0, cmpValue1 - i)
+        dataCmpValue2 = max(0, cmpValue2 - i)
+        
+        dataID = dataPlayerID
+        name1 = dataPlayerName
+        cmpValue = dataCmpValue1
+        cmpValue2 = dataCmpValue2
+        PlayerBillboard.UpdateBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, 
+                                        cmpValue, cmpValue2, cmpValue3, groupValue2, id2, False, 
+                                        value3=value3, value4=value4, value5=value5)
+        
+    billboardObj.SortData()
+    
+    billTypeSign = __GetBillTypeSign(billboardType, groupValue1, groupValue2)
+    GameWorld.DebugAnswer(curPlayer, "插入假榜单(%s): %s 条" % (billTypeSign, count))
+    return
+
+def __delFackData(curPlayer, gmList):
+    ## 删除榜单假数据
+    billboardType = gmList[0]
+    groupValue1 = gmList[1] if len(gmList) > 1 else 0
+    groupValue2 = gmList[2] if len(gmList) > 2 else 0
+    billboardMgr = DBDataMgr.GetBillboardMgr()
+    billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+    curDataCount = billboardObj.GetCount()
+    maxDataCount = billboardObj.GetMaxCount()
+    
+    delCount = 0
+    for index in range(curDataCount)[::-1]:
+        billData = billboardObj.At(index)
+        if billData.GetID() <= maxDataCount:
+            billboardObj.DeleteByIndex(index)
+            delCount += 1
+            
+    billTypeSign = __GetBillTypeSign(billboardType, groupValue1, groupValue2)
+    GameWorld.DebugAnswer(curPlayer, "删除假榜单(%s): %s 条, 剩: %s" % (billTypeSign, delCount, billboardObj.GetCount()))
+    return
+
+def __GetBillTypeSign(billboardType, groupValue1, groupValue2):
+    billTypeSign = "%s" % billboardType
+    if groupValue1:
+        billTypeSign = "%s-%s" % (billTypeSign, groupValue1)
+    if groupValue2:
+        billTypeSign = "%s-%s" % (billTypeSign, groupValue2)
+    return billTypeSign
+
+def __logFackData(curPlayer, gmList):
+    ## 输出排行榜数据: Billboard p 类型 分组值1 分组值2
+    if len(gmList) <= 1:
+        GameWorld.DebugAnswer(curPlayer, "榜单数据条数总览")
+        billboardMgr = DBDataMgr.GetBillboardMgr()
+        for bType in ShareDefine.BillboardTypeAllList:
+            groupList = billboardMgr.GetBillboardGroupList(bType)
+            for bType, groupValue1, groupValue2 in groupList:
+                billboardObj = billboardMgr.GetBillboard(bType, groupValue1, groupValue2)
+                curDataCount = billboardObj.GetCount()
+                maxDataCount = billboardObj.GetMaxCount()
+                if not curDataCount:
+                    continue
+                billTypeSign = __GetBillTypeSign(bType, groupValue1, groupValue2)
+                GameWorld.DebugAnswer(curPlayer, "榜单数据(%s)条数: %s/%s" % (billTypeSign, curDataCount, maxDataCount))
+        return
+    
+    billboardType = gmList[1]
+    groupValue1 = gmList[2] if len(gmList) > 2 else 0
+    groupValue2 = gmList[3] if len(gmList) > 3 else 0
+    billboardMgr = DBDataMgr.GetBillboardMgr()
+    billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+    billboardObj.SortDelayDo()
+    curDataCount = billboardObj.GetCount()
+    maxDataCount = billboardObj.GetMaxCount()
+    idOrderDict = billboardObj.GetIDOrderDict()
+    
+    billTypeSign = __GetBillTypeSign(billboardType, groupValue1, groupValue2)
+    GameWorld.DebugAnswer(curPlayer, "榜单数据(%s)条数: %s/%s 详见日志" % (billTypeSign, curDataCount, maxDataCount))
+    for index in range(curDataCount):
+        bbData = billboardObj.At(index)
+        dataID = bbData.GetID()
+        rank = idOrderDict.get(dataID, 0)
+        
+        valueList = [getattr(bbData, "GetValue%s" % num)() for num in range(1, 9)]
+        GameWorld.DebugLog("%s,rank=%s,ID=%s,CmpValue=%s,CmpValue2=%s,Value=%s" 
+                           % (index, rank, dataID, bbData.GetCmpValue(), bbData.GetCmpValue2(), valueList), curPlayer.GetPlayerID())
+        
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index 77f4ad0..7cde81b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -866,6 +866,8 @@
 # @remarks 获得服务器系统时间
 def GetCurrentTime():
     return datetime.datetime.today()
+def GetServerTime():
+    return datetime.datetime.today()
 #    ctime = GetGameWorld().GetGameServerEventTime()
 #    
 #    if not ctime:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index fd2d636..5eb0616 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -1541,9 +1541,6 @@
         #更改镖车记录的部分主人信息
         PlayerTruck.ChangeTruckNoteInfo(curPlayer)
         
-        #更新镖车进排行榜
-        PlayerBillboard.UpdateBillboardPlayerTruck(curPlayer.GetPlayerID(), curPlayer.GetName(), curPlayer.GetOperateInfo(),
-                                                   curPlayer.GetLV(), truckLv, curPlayer.GetMapID())
 
     #---初始化自己的召唤兽---
     #===========================================================================
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 b07fc85..e67af45 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
@@ -9,20 +9,43 @@
 # @date 2018-03-06
 # @version 1.0
 #
-# 详细描述: 排行榜
+# 详细描述: 排行榜,本服、跨服通用
 #
 #-------------------------------------------------------------------------------
 #"""Version = 2018-03-06 11:00"""
 #-------------------------------------------------------------------------------
 
-import ShareDefine
-import GameWorld
 import ChConfig
+import GameWorld
+import ShareDefine
 import PlayerControl
 import OpenServerCampaign
-import CrossRealmPlayer
+import ChPyNetSendPack
+import NetPackCommon
+import IpyGameDataPY
 import GameFuncComm
-import EventReport
+import DBDataMgr
+
+import time
+
+def OnDay():
+    
+    drBillboardTypeList = []
+    if GameWorld.IsCrossServer():
+        drBillboardTypeList = ShareDefine.CrossBillboardTypeList
+    else:
+        drBillboardTypeList = IpyGameDataPY.GetFuncEvalCfg("BillboardSet", 1)
+        
+    billboardMgr = DBDataMgr.GetBillboardMgr()
+    for billboardType in drBillboardTypeList:
+        if billboardType in [ShareDefine.Def_CBT_BossTrialSubmitBak, ShareDefine.Def_CBT_BossTrialSubmitFamilyBak, ShareDefine.Def_CBT_CrossRealmPK]:
+            continue
+        groupList = billboardMgr.GetBillboardGroupList(billboardType)
+        for billboardType, groupValue1, groupValue2 in groupList:
+            billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+            billboardObj.SaveDRData("OnDay")
+            
+    return
 
 def DoBillboardOpen(curPlayer):
     ## 排行榜开启时需要处理的
@@ -30,11 +53,14 @@
     OpenServerCampaign.DoBillboardOpen(curPlayer) # 同步开服活动榜单
     return
 
+def BillboardOnLogin(curPlayer):
+    # 上线默认同步排行榜
+    UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故上线不再同步
+    return
+
 def GetBillboardOperateInfo(curPlayer):
     # 排行榜中所保存的运营商相关信息
     platform = curPlayer.GetAccID()
-    if platform in ["tencent"]:
-        return curPlayer.GetOperateInfo()
     return platform
 
 def GetBillboardJob(curPlayer): return curPlayer.GetJob()
@@ -44,7 +70,6 @@
     if GameWorld.IsCrossServer():
         # 跨服服务器不用更新本服榜
         return
-    #UpdateTotalRechargeBillboard(curPlayer)
     
     UpdatePlayerLVBillboard(curPlayer) # 等级榜
     UpdatePlayerFPTotalBillboard(curPlayer, True) # 战斗力榜
@@ -55,116 +80,13 @@
     if isAll:
         UpdateRuneTowerBillboard(curPlayer)
         
-        #UpdateTJGBillboard(curPlayer, minuteExp) 脱机效率可不更新
-        
-    EventReport.WriteEvent_FightPower(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, value1=0, value2=0, exInfo=[], autoSort=False, **kwargs):
-    ## 更新玩家排行榜
-    
-    #if not cmpValue and not cmpValue2 and not cmpValue3:
-    #    return
-    
-    if not __CanPlayerBillboardComm(curPlayer):
-        return
-    
-    playerJob = GetBillboardJob(curPlayer)
-    playerID = curPlayer.GetID()
-    playerName = curPlayer.GetName()
-    playerOpInfo = GetBillboardOperateInfo(curPlayer)
-    kwargs["value3"] = curPlayer.GetFace()
-    kwargs["value4"] = curPlayer.GetFacePic()
-    if bType in ShareDefine.BTValue1_OfficialRankList:
-        value1 = curPlayer.GetOfficialRank()
-    GameServer_UpdateBillboard(bType, playerJob, playerID, playerName, playerOpInfo,
-                               value1, value2, cmpValue, cmpValue2, cmpValue3, 0, exInfo, autoSort, **kwargs)
-    return
-
-def GameServer_UpdateBillboard(bType, bType2, bID, bName, bName2, value1, value2, cmpValue, cmpValue2=0, cmpValue3=0, bID2=0, exInfo=[], autoSort=False, **kwargs):
-    bData = {"Type":bType, "Type2":bType2, "ID":bID, "ID2":bID2, "Name1":bName, "Name2":bName2, "ExInfo":exInfo, 
-             "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3, "autoSort":autoSort}
-    if "value3" in kwargs:
-        bData["Value3"] = kwargs["value3"]
-    if "value4" in kwargs:
-        bData["Value4"] = kwargs["value4"]
-    if "value5" in kwargs:
-        bData["Value5"] = kwargs["value5"]
-    if "value6" in kwargs:
-        bData["Value6"] = kwargs["value6"]
-    if "value7" in kwargs:
-        bData["Value7"] = kwargs["value7"]
-    if "value8" in kwargs:
-        bData["Value8"] = kwargs["value8"]
-    if "userData" in kwargs:
-        bData["UserData"] = kwargs["userData"]
-    sendMsg = "%s" % (bData) 
-    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "UpdateBillboard", sendMsg, len(sendMsg))
-    GameWorld.DebugLog("同步GameServer排行榜:bType=%s,cmpValue=%s,cmpValue2=%s %s" % (bType, cmpValue, cmpValue2, sendMsg), bID)
-    return
-
-def UpdatePlayerCrossBillboard(curPlayer, bType, groupValue1, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0, 
-                               groupValue2=0, **kwargs):
-    ## 更新玩家跨服排行榜
-    
-    #if not cmpValue and not cmpValue2 and not cmpValue3:
-    #    return
-    
-    #if not __CanPlayerBillboardComm(curPlayer):
-    #    return
-    
-    playerJob = GetBillboardJob(curPlayer)
-    playerID = curPlayer.GetID()
-    playerName = CrossRealmPlayer.GetCrossPlayerName(curPlayer)
-    playerOpInfo = GetBillboardOperateInfo(curPlayer)
-    kwargs["value3"] = curPlayer.GetFace()
-    kwargs["value4"] = curPlayer.GetFacePic()
-    if bType in ShareDefine.BTValue1_OfficialRankList:
-        value1 = curPlayer.GetOfficialRank()
-    id2 = 0
-    GameServer_UpdateCrossBillboard(bType, groupValue1, playerID, playerName, playerOpInfo, playerJob, value1, value2, 
-                                    cmpValue, cmpValue2, cmpValue3, groupValue2, id2, **kwargs)
-    return
-
-def GameServer_UpdateCrossBillboard(bType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, 
-                                    cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, **kwargs):
-    bData = {"Type":bType, "GroupValue1":groupValue1, "Type2":type2, "ID":dataID, "ID2":id2, "Name1":name1, "Name2":name2, 
-             "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3, "GroupValue2":groupValue2}
-    if "value3" in kwargs:
-        bData["Value3"] = kwargs["value3"]
-    if "value4" in kwargs:
-        bData["Value4"] = kwargs["value4"]
-    if "value5" in kwargs:
-        bData["Value5"] = kwargs["value5"]
-    if "value6" in kwargs:
-        bData["Value6"] = kwargs["value6"]
-    if "value7" in kwargs:
-        bData["Value7"] = kwargs["value7"]
-    if "value8" in kwargs:
-        bData["Value8"] = kwargs["value8"]
-    if "userData" in kwargs:
-        bData["UserData"] = kwargs["userData"]
-    sendMsg = "%s" % (bData) 
-    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "UpdateCrossBillboard", sendMsg, len(sendMsg))
-    GameWorld.DebugLog("同步GameServer跨服排行榜:bType=%s,groupValue1=%s,groupValue2=%s,cmpValue=%s, %s" 
-                       % (bType, groupValue1, groupValue2, cmpValue, sendMsg), dataID)
     return
 
 def UpdatePlayerFPTotalBillboard(curPlayer, isForceUpdate=False, isCheckRule=True):
     ##更新玩家总战斗力
     
     playerFightPower = PlayerControl.GetFightPower(curPlayer)
-    if not __CheckFightPowerCanUpdate(curPlayer, ChConfig.Def_PDict_FightPower_Total, playerFightPower, 
+    if not __CheckFightPowerCanUpdate(curPlayer, ChConfig.Def_PDict_FightPower_Total, playerFightPower,
                                       isForceUpdate, isCheckRule, ChConfig.Def_PDict_FightPower_TotalEx):
         return
     
@@ -174,11 +96,29 @@
                                        ChConfig.Def_PDictType_FightPower)
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FightPower_TotalEx, fightPowerEx,
                                        ChConfig.Def_PDictType_FightPower)
-    familyID = curPlayer.GetFamilyID()
+    
     GameWorld.DebugLog("更新总战斗力:playerFightPower=%s" % (playerFightPower), curPlayer.GetPlayerID())
     
-    UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_FightPower, fightPowerEx, fightPower, exInfo=[familyID])
-    #EventReport.WriteEvent_FightPower(curPlayer)
+    UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_FightPower, fightPowerEx, fightPower)
+    
+#    if bType == ShareDefine.Def_BT_FightPower:
+#        playerID = bID
+#        fightPowerTotal = cmpValue * ChConfig.Def_PerPointValue + cmpValue2
+#        familyID = exInfo[0]
+#        playerJob = bType2
+#        
+#        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+#        if curPlayer:
+#            PlayerControl.SetFightPower(curPlayer, fightPowerTotal)
+#            
+#        #更新战盟成员战力
+#        PlayerFamily.UpdFamilyMemberFightPower(familyID, playerID, fightPowerTotal)
+#        
+#        #职业战力榜
+#        job = playerJob % 10
+#        if job in ShareDefine.JobFightPowerBillboardDict:
+#            jobBType = ShareDefine.JobFightPowerBillboardDict[job]
+#            UpdatePlayerBillboard(bID, bName, bName2, jobBType, bType2, value1, value2, cmpValue, autoSort, cmpValue2, **kwargs)
     return
 
 def __CheckFightPowerCanUpdate(curPlayer, key, fightPower, isForceUpdate=False, isCheckRule=True, key2=None):
@@ -252,16 +192,6 @@
     UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_TrialTower, passLV) 
     return
 
-
-def UpdateTJGBillboard(curPlayer, minuteExp):
-    ##脱机效率榜
-    if not minuteExp:
-        return
-    expPoint = minuteExp / ChConfig.Def_PerPointValue
-    exp = minuteExp % ChConfig.Def_PerPointValue
-    UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_OffLineEfficient, expPoint, exp)
-    return
-
 def UpdateRealmBillboard(curPlayer):
     ##境界榜
     if not curPlayer.GetOfficialRank():
@@ -269,54 +199,264 @@
     UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_Realm, curPlayer.GetOfficialRank())
     return
 
-
-###################################### 以下代码暂时没用,修改时再整合 ################################################
-
-##玩家登录排行处理
-# @param curPlayer 玩家实例
-# @return 
-def BillboardOnLogin(curPlayer):
-    # 上线默认同步排行榜
-    UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故上线不再同步
-    return
-
-## 更新当前镖车信息
-#  @param playerID: 玩家ID
-#  @param playerName: 玩家名字
-#  @param playerOpInfo: 玩家平台信息
-#  @param playerLV: 玩家等级
-#  @param truckLV: 镖车等级
-#  @param truckMapID: 镖车所在地图ID
-#  @return: 
-def UpdateBillboardPlayerTruck(playerID, playerName, playerOpInfo, playerLV, truckLV, truckMapID):
+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
     
-    #当truckMapID为0时表示在排行在删除该镖车的记录
+    return True
+
+def UpdatePlayerBillboard(curPlayer, bType, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0, autoSort=False, **kwargs):
+    ## 更新玩家排行榜
     
-    #[玩家ID, 玩家名字, 玩家等级, 镖车等级, 镖车位置]
-    cmdList = [playerID, playerName, playerOpInfo, playerLV, truckLV, truckMapID]
-    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "UpdateBillboardPlayerTruck",
-                                                              '%s' % (cmdList), len(str(cmdList)))
-    return
+    #if not cmpValue and not cmpValue2 and not cmpValue3:
+    #    return
     
-##更新玩家充值排行榜
-# @param curPlayer 玩家实例
-# @return 任务实例
-# @remarks 
-def UpdateTotalRechargeBillboard(curPlayer):
-#    if GameWorld.IsGM(curPlayer):
-#        #GM不上榜
-#        return
-    totalChangeCoinPoint = curPlayer.GetChangeCoinPointTotal()
-     
-    #排行榜需要数据[玩家ID, 玩家名字, 玩家职业, 玩家等级]
+    if not __CanPlayerBillboardComm(curPlayer):
+        return
+    
+    playerJob = GetBillboardJob(curPlayer)
     playerID = curPlayer.GetID()
     playerName = curPlayer.GetName()
-    playerOpInfo = curPlayer.GetOperateInfo()
-    playerJob = curPlayer.GetJob()
-    playerLV = curPlayer.GetLV()
-    
-    sendMsg = '%s' % ([playerID, playerName, playerOpInfo, playerJob, playerLV, totalChangeCoinPoint]) 
-    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'UpdateTotalRechargeBillboard', \
-            sendMsg, len(sendMsg))
+    playerOpInfo = GetBillboardOperateInfo(curPlayer)
+    kwargs["value3"] = curPlayer.GetFace()
+    kwargs["value4"] = curPlayer.GetFacePic()
+    if bType in ShareDefine.BTValue1_OfficialRankList:
+        value1 = curPlayer.GetOfficialRank()
+        
+    groupValue1 = 0
+    UpdateBillboard(bType, groupValue1, playerID, playerName, playerOpInfo, playerJob, value1, value2, 
+                    cmpValue, cmpValue2, cmpValue3, autoSort=autoSort, **kwargs)
     return
 
+def UpdateBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue,
+                    cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True, **kwargs):
+    ''' 更新跨服排行榜
+    @param billboardType: 排行榜索引类型,同个榜单类型可以有多个分组榜单数据,独立排序
+    @param groupValue1: 榜单分组1
+    @param dataID: 榜单唯一数据ID,如玩家ID等
+    @param name1: 显示名称1,不影响排序
+    @param name2: 显示名称2,不影响排序
+    @param type2: 榜单数据类型2,自定义,一般为职业等二级分类,不影响排序
+    @param value1: 显示值1,不影响排序
+    @param value2: 显示值2,不影响排序
+    @param cmpValue: 比较值1
+    @param cmpValue2: 比较值2
+    @param cmpValue3: 比较值3,没设定的话默认为时间戳比较值
+    @param groupValue1: 榜单分组2
+    @param id2: 扩展数据ID2
+    @param autoSort: 是否排序,默认True
+    @return: 是否上榜更新榜单
+    '''
+    if GameWorld.IsCrossServer():
+        if billboardType not in ShareDefine.CrossBillboardTypeList:
+            return
+    else:
+        if billboardType not in ShareDefine.BillboardTypeList:
+            return
+        
+    if not dataID:
+        return
+    
+    billboardMgr = DBDataMgr.GetBillboardMgr()
+    billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
+    billboardData = billboardObj.FindByID(dataID)
+    isNewData = False
+    if not billboardData:
+        isNewData = True
+        if billboardObj.IsFull():
+            # 与最后一名对比
+            lastBillBoardData = __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj)
+            if not lastBillBoardData:
+                GameWorld.DebugLog("    榜单值不超过最后一名,不上榜! ")
+                return
+            billboardData = lastBillBoardData
+            billboardData.Clear()
+        else:
+            billboardData = billboardObj.AddNewBillboardData()
+            if not billboardData:
+                return
+            
+    cmpValueChange = isNewData or billboardData.GetCmpValue() != cmpValue or billboardData.GetCmpValue2() != cmpValue2 \
+        or (cmpValue3 and billboardData.GetCmpValue3() != cmpValue3)
+        
+    # 没设置值默认为时间time,先上榜的排前面
+    if cmpValue3 == 0:
+        # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
+        if cmpValueChange:
+            calcTime = GameWorld.ChangeTimeStrToNum("2090-01-01 00:00:00")
+            cmpValue3 = max(0, calcTime - int(time.time())) # 比较值3如果没指定值则默认存当前更新的time
+        else:
+            cmpValue3 = billboardData.GetCmpValue3()
+            
+    # 更新所有值
+    billboardData.SetType(billboardType)
+    billboardData.SetGroupValue1(groupValue1)
+    billboardData.SetGroupValue2(groupValue2)
+    billboardData.SetID(dataID)
+    billboardData.SetID2(id2)
+    billboardData.SetName1(name1)
+    billboardData.SetName2(name2)
+    billboardData.SetType2(type2)
+    billboardData.SetValue1(value1)
+    billboardData.SetValue2(value2)
+    billboardData.SetValue3(kwargs.get("value3", 0))
+    billboardData.SetValue4(kwargs.get("value4", 0))
+    billboardData.SetValue5(kwargs.get("value5", 0))
+    billboardData.SetValue6(kwargs.get("value6", 0))
+    billboardData.SetValue7(kwargs.get("value7", 0))
+    billboardData.SetValue8(kwargs.get("value8", 0))
+    billboardData.SetUserData(kwargs.get("userData", ""))
+    billboardData.SetCmpValue(cmpValue)
+    billboardData.SetCmpValue2(cmpValue2)
+    billboardData.SetCmpValue3(cmpValue3)
+    
+    GameWorld.DebugLog("更新跨服排行榜值: billboardType=%s,groupValue1=%s,groupValue2=%s,dataID=%s,isNewData=%s,cmpValueChange=%s,type2=%s,value1=%s,value2=%s,cmpValue=%s,cmpValue2=%s,cmpValue3=%s,%s" 
+                       % (billboardType, groupValue1, groupValue2, dataID, isNewData, cmpValueChange,
+                          type2, value1, value2, cmpValue, cmpValue2, cmpValue3, kwargs), dataID)
+    if not autoSort:
+        if isNewData or cmpValueChange:
+            billboardObj.SetSortDelay()
+    else:
+        billboardObj.SortData()
+        
+    return True
+
+def __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj):
+    ## 比较是否超过最后一名
+    # @return: 超过则返回最后一名数据实例,否则返回None
+    if not billboardObj.GetCount():
+        return
+    lastBillBoardData = billboardObj.At(billboardObj.GetCount() - 1)
+    if cmpValue < lastBillBoardData.GetCmpValue():
+        #无法上榜
+        return
+    elif cmpValue == lastBillBoardData.GetCmpValue(): 
+        if cmpValue2 < lastBillBoardData.GetCmpValue2():
+            return
+        elif cmpValue2 == lastBillBoardData.GetCmpValue2():
+            if cmpValue3 <= lastBillBoardData.GetCmpValue3():
+                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
+#{
+#    tagHead        Head;
+#    BYTE        Type;        //榜单类型
+#    DWORD        GroupValue1;    //分组值1
+#    DWORD        GroupValue2;    //分组值2,与分组值1组合归为同组榜单数据
+#    WORD        StartIndex;    //查看的起始名次索引, 默认0
+#    BYTE        ViewCnt;        //查看条数,默认20,单次最大不超过100
+#    DWORD        ViewID;        //附带查看指定ID所在名次前后数据,如玩家ID、家族ID等
+#};
+def OnViewBillboard(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    billboardType, groupValue1, groupValue2 = clientData.Type, clientData.GroupValue1, clientData.GroupValue2
+    startIndex = clientData.StartIndex
+    viewCnt = clientData.ViewCnt
+    viewID = clientData.ViewID
+    
+    if billboardType in ShareDefine.CrossBillboardTypeList:
+        # 跨服榜单直接查跨服服务器,待扩展
+        return
+    
+    clientPack = GetPack_ViewBillboardRet(billboardType, groupValue1, groupValue2, startIndex, viewCnt, viewID)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
+
+def GetPack_ViewBillboardRet(bbType, groupValue1, groupValue2, startIndex=0, viewCnt=20, viewID=0):
+    ## 获取查看榜单返回信息封包,本服跨服通用
+    
+    billboardMgr = DBDataMgr.GetBillboardMgr()
+    billboardObj = billboardMgr.GetBillboard(bbType, groupValue1, groupValue2)
+    billboardObj.SortDelayDo()
+    idOrderDict = billboardObj.GetIDOrderDict()
+    count = billboardObj.GetCount()
+    
+    maxIndex = count - 1
+    startIndex = max(min(startIndex, maxIndex), 0)
+    viewCnt = 20 if not viewCnt else min(viewCnt, 100) # 默认20,最多100
+    endIndex = min(startIndex + viewCnt - 1, maxIndex)
+    viewRange = [] if not count else range(startIndex, endIndex + 1)
+    
+    viewIDRange = []
+    # 查看viewID前后名次
+    if viewID:
+        viewBFCnt = 3 # 查看ViewID返回前后数据条数,一般设置为奇数
+        viewIDIndex = billboardObj.IndexOfByID(viewID)
+        if viewIDIndex != -1:
+            # 前x后x
+            viewIDStartIndex = max(0, viewIDIndex - viewBFCnt / 2)
+            viewIDEndIndex = min(viewIDIndex + viewBFCnt / 2, maxIndex)
+            viewIDRange = range(viewIDStartIndex, viewIDEndIndex + 1)
+            
+    clientPack = ChPyNetSendPack.tagMCViewBillboardRet()
+    clientPack.Type = bbType
+    clientPack.GroupValue1 = groupValue1
+    clientPack.GroupValue2 = groupValue2
+    clientPack.DataTotal = count
+    clientPack.PageDataList = []
+    for index in viewRange:
+        billboardData = billboardObj.At(index)
+        viewData = ChPyNetSendPack.tagMCViewBillboardData()
+        viewData.Index = index
+        viewData.Rank = idOrderDict.get(billboardData.GetID(), 0)
+        viewData.ID = billboardData.GetID()
+        viewData.ID2 = billboardData.GetID2()
+        viewData.Name1 = billboardData.GetName1()
+        viewData.Name2 = billboardData.GetName2()
+        viewData.Type2 = billboardData.GetType2()
+        viewData.Value1 = billboardData.GetValue1()
+        viewData.Value2 = billboardData.GetValue2()
+        viewData.Value3 = billboardData.GetValue3()
+        viewData.Value4 = billboardData.GetValue4()
+        viewData.Value5 = billboardData.GetValue5()
+        viewData.Value6 = billboardData.GetValue6()
+        viewData.Value7 = billboardData.GetValue7()
+        viewData.Value8 = billboardData.GetValue8()
+        viewData.CmpValue = billboardData.GetCmpValue()
+        viewData.CmpValue2 = billboardData.GetCmpValue2()
+        viewData.CmpValue3 = billboardData.GetCmpValue3()
+        viewData.UserData = billboardData.GetUserData()
+        viewData.DataLen = len(viewData.UserData)
+        clientPack.PageDataList.append(viewData)
+    clientPack.PageDataCnt = len(clientPack.PageDataList)
+
+    clientPack.ViewID = viewID
+    clientPack.ViewIDDataList = []
+    for index in viewIDRange:
+        billboardData = billboardObj.At(index)
+        viewData = ChPyNetSendPack.tagMCViewBillboardData()
+        viewData.Index = index
+        viewData.Rank = idOrderDict.get(billboardData.GetID(), 0)
+        viewData.ID = billboardData.GetID()
+        viewData.ID2 = billboardData.GetID2()
+        viewData.Name1 = billboardData.GetName1()
+        viewData.Name2 = billboardData.GetName2()
+        viewData.Type2 = billboardData.GetType2()
+        viewData.Value1 = billboardData.GetValue1()
+        viewData.Value2 = billboardData.GetValue2()
+        viewData.Value3 = billboardData.GetValue3()
+        viewData.Value4 = billboardData.GetValue4()
+        viewData.Value5 = billboardData.GetValue5()
+        viewData.Value6 = billboardData.GetValue6()
+        viewData.Value7 = billboardData.GetValue7()
+        viewData.Value8 = billboardData.GetValue8()
+        viewData.CmpValue = billboardData.GetCmpValue()
+        viewData.CmpValue2 = billboardData.GetCmpValue2()
+        viewData.CmpValue3 = billboardData.GetCmpValue3()
+        viewData.UserData = billboardData.GetUserData()
+        viewData.DataLen = len(viewData.UserData)
+        clientPack.ViewIDDataList.append(viewData)
+    clientPack.ViewIDDataCnt = len(clientPack.ViewIDDataList)
+    return clientPack
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 5f70c9b..766ae61 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -124,11 +124,11 @@
 import PlayerAssist
 import PlayerArena
 import PyGameData
-import PlayerTJG
 import PlayerGuaji
 import PlayerXiangong
 import PlayerFuncTeam
 import PlayerMineArea
+import PlayerBillboard
 import PlayerMail
 
 import datetime
@@ -166,6 +166,8 @@
         PlayerOnDayEx(curPlayer)
     
     DoLogic_OnDayEx(tick)
+    
+    PlayerBillboard.OnDay()
     return
 
 def DoLogic_OnDayEx(tick):
@@ -426,7 +428,6 @@
         #特殊时间点过天的,一般是游戏功能,此时立即同步一次跨服玩家数据
         CrossPlayerData.SendMergePlayerDataNow(curPlayer)
         
-    #PlayerTJG.TJGOnDay(curPlayer, onEventType)
     # 以下为支持两种重置模式切换配置的
     FBCommon.FBOnDay(curPlayer, onEventType)
     
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
index c81b550..b205439 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
@@ -718,7 +718,7 @@
     totalExp = exp2 * ChConfig.Def_PerPointValue + exp1
     aveMinuteExp = int(totalExp * 1.0 / max(1, times / 60)) # 平均每分钟经验
     GameWorld.DebugLog('    脱机效率榜  aveMinuteExp=%s, totalExp=%s,times=%s' % (aveMinuteExp, totalExp, times))
-    PlayerBillboard.UpdateTJGBillboard(curPlayer, aveMinuteExp)
+    #PlayerBillboard.UpdateTJGBillboard(curPlayer, aveMinuteExp)
     
     sendPack = ChPyNetSendPack.tagMCTJGInfo()
     sendPack.Clear()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTruck.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTruck.py
index 47792f0..19c179f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTruck.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTruck.py
@@ -229,8 +229,8 @@
     DataRecordPack.DR_Truck(curPlayer, "Star", {"LV":truckLv})
     
     #更新镖车进排行榜
-    PlayerBillboard.UpdateBillboardPlayerTruck(curPlayer.GetPlayerID(), curPlayer.GetName(), curPlayer.GetOperateInfo(),
-                                               curPlayer.GetLV(), truckLv, curPlayer.GetMapID())
+    #PlayerBillboard.UpdateBillboardPlayerTruck(curPlayer.GetPlayerID(), curPlayer.GetName(), curPlayer.GetOperateInfo(),
+    #                                           curPlayer.GetLV(), truckLv, curPlayer.GetMapID())
     
     #拉镖活跃度
     #PlayerActivity.AddActivityFinishCnt(curPlayer, ShareDefine.ActivityNum_Truck)
@@ -411,7 +411,7 @@
         curTruck.SetIsDisappear(1)
         
         ##删除排行榜上的镖车信息
-        PlayerBillboard.UpdateBillboardPlayerTruck(curTruck.GetOwnerID(), "", "", "", "", 0)
+        #PlayerBillboard.UpdateBillboardPlayerTruck(curTruck.GetOwnerID(), "", "", "", "", 0)
             
 #        curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTruck)
 #
@@ -519,7 +519,7 @@
     curTruck.Disappear()
     
     #删除排行榜上的镖车信息
-    PlayerBillboard.UpdateBillboardPlayerTruck(curPlayer.GetID(), "", "", "", "", 0)
+    #PlayerBillboard.UpdateBillboardPlayerTruck(curPlayer.GetID(), "", "", "", "", 0)
     
     GameWorld.Log("删除玩家骠车" , curPlayer.GetPlayerID())
     #GameWorld.Log("通知GameServer骠车消失!")
@@ -796,7 +796,7 @@
     truckOwnerID = curTruck.GetOwnerID()
     
     #已经被打劫下榜
-    PlayerBillboard.UpdateBillboardPlayerTruck(truckOwnerID, "", "", "", "", 0)
+    #PlayerBillboard.UpdateBillboardPlayerTruck(truckOwnerID, "", "", "", "", 0)
     #-----------------------
     
     #获取镖车主人
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index f4893a8..16ad3e8 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -944,6 +944,8 @@
 Def_CBT_FamilyGCZRoundHurt, # 仙盟攻城战 - 本轮分组仙盟伤害榜  169 (zoneID, batType*100+groupNum)
 ) = range(150, 169 + 1)
 
+BillboardTypeAllList = BillboardTypeList + CrossBillboardTypeList
+
 #职业对应战力排行榜类型
 JobFightPowerBillboardDict = {
                               PlayerJob_Warrior:Def_BT_FightPower_Warrior,

--
Gitblit v1.8.0