From 9a60fccaf9365a2a92f52835866d595ba14c575b Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 20 六月 2024 21:13:46 +0800
Subject: [PATCH] 10185 【越南】【港台】【主干】BOSS凭证修改

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerBillboard.py                         |  108 +
 ServerPython/CoreServerGroup/GameServer/Script/DataRecordPack.py                                 |   11 
 ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py                                  |   75 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py           |  515 +++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py    |   51 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                |  515 +++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_GetFamilyInfo.py                  |    1 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py                                      |    4 
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboard.py                 |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py             |   22 
 ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py                                       |    7 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py              |   70 +
 PySysDB/PySysDBPY.h                                                                              |    7 
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardData.py                      |   10 
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                    |   19 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActBossTrial.py |  220 ++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py                           |   12 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py          |   53 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py               |   19 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                             |    9 
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardDataCross.py                 |    9 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py                   |    7 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py                      |  472 +++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py                            |   68 +
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboardCross.py            |    7 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py                |   30 
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CreateFamily.py                       |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py                 |   10 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py                  |  108 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py |    9 
 PySysDB/PySysDBG.h                                                                               |   29 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                  |    2 
 32 files changed, 2,266 insertions(+), 221 deletions(-)

diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h
index e78dbb8..52d3e7a 100644
--- a/PySysDB/PySysDBG.h
+++ b/PySysDB/PySysDBG.h
@@ -549,13 +549,15 @@
 	BYTE		ActNum;	//活动分组编号, 活动类型 * 10 + 不同界面编号
 	char		StartDate;	//开启日期
 	char		EndDate;	//结束日期
+	char		JoinStartTime;	//参与开始时间点
+	char		JoinEndTime;	//参与结束时间点
 	dict		NotifyInfoStart;	//全服提示信息 - 相对开始时间
 	dict		NotifyInfoEnd;	//全服提示信息 - 相对结束时间
 	list		NotifyInfoLoop;	//全服提示信息 - 循环广播[间隔分钟, 广播key]
 	BYTE		IsDayReset;	//是否每天重置
 	BYTE		ResetType;	//重置类型,0-0点重置;1-5点重置
 	list		TemplateIDList;	//榜单模板编号列表
-	char		MailKey;	//奖励邮件模板
+	list		FamilyTemplateIDList;	//仙盟榜单模板编号列表
 };
 
 //Boss历练榜单模版表
@@ -564,7 +566,30 @@
 {
 	DWORD		_TemplateID;	//模板编号
 	BYTE		Rank;	//名次
-	list		AwardItemList;	//奖励物品信息列表 [[物品ID,个数,是否拍品], ...]
+	list		AwardItemList;	//奖励物品列表[[物品ID,个数,是否拍品], ...] 仙盟榜时为盟主奖励,如果没有配置,则统一取成员奖励
+	list		MemAwardItemList;	//仙盟榜成员奖励物品信息列表[[物品ID,个数,是否拍品], ...]
+};
+
+//Boss历练跨服活动表
+
+struct tagCrossActBossTrial
+{
+	DWORD		_CfgID;	//配置ID
+	char		ActGroupName;	//活动组名(同组活动的名字需相同)
+	BYTE		ZoneID;		//组内分组编号
+	list		ServerIDRangeList;	//活动的账号服务器ID范围列表 [[serverIDA, serverIDB], ...]
+	char		StartDate;	//开启日期
+	char		EndDate;	//结束日期
+	char		JoinStartTime;	//参与开始时间点
+	char		JoinEndTime;	//参与结束时间点
+	dict		NotifyInfoStart;	//全服提示信息 - 相对开始时间
+	dict		NotifyInfoEnd;	//全服提示信息 - 相对结束时间
+	list		NotifyInfoLoop;	//全服提示信息 - 循环广播[循环分钟, 广播key, [广播参数列表可选]]
+	BYTE		IsDayReset;	//是否每天重置
+	BYTE		ResetType;	//重置类型,0-0点重置;1-5点重置
+	list		RankLimitList;	//上榜个数限制 个人|仙盟
+	WORD		PersonalTemplateID;	//个人排行模板编号
+	WORD		FamilyTemplateID;	//仙盟排行模板编号
 };
 
 //仙匣秘境活动时间表
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 220f5eb..28ab9cc 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -1780,11 +1780,15 @@
 	DWORD		_CfgID;	//配置ID
 	char		StartDate;	//开启日期
 	char		EndDate;	//结束日期
+	char		JoinStartTime;	//参与开始时间点
+	char		JoinEndTime;	//参与结束时间点
 	WORD		LVLimit;	//限制等级
 	BYTE		IsDayReset;	//是否每天重置
 	BYTE		ResetType;	//重置类型,0-0点重置;1-5点重置
 	dict		SubmitItemAwardInfo;	//提交凭证个数对应奖励
+	BYTE		SubmitAwardResetType;	//提交凭证每日重置类型,0-跟随活动; 1-0点重置;2-5点重置
 	list		TemplateIDList;	//榜单模板编号列表
+	list		FamilyTemplateIDList;	//仙盟榜单模板编号列表
 };
 
 //Boss历练榜单模版表
@@ -1793,7 +1797,8 @@
 {
 	DWORD		_TemplateID;	//模板编号
 	BYTE		Rank;	//名次
-	list		AwardItemList;	//奖励物品信息列表 [[物品ID,个数,是否拍品], ...]
+	list		AwardItemList;	//奖励物品列表[[物品ID,个数,是否拍品], ...] 仙盟榜时为盟主奖励,如果没有配置,则统一取成员奖励
+	list		MemAwardItemList;	//仙盟榜成员奖励物品信息列表[[物品ID,个数,是否拍品], ...]
 };
 
 //仙匣秘境活动时间表
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
index 0b90a68..4444892 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -376,6 +376,7 @@
 Def_WorldKey_IsGameWorldInit = 'IsGameWorldInit'             #GameWold是否初始化完成
 Def_WorldKey_BossIsGeTui = "BossGeTui%s"                     #当前复活通知
 Def_WorldKey_OperationActionState = "State_%s"               #运营活动状态,参数为(运营活动名)
+Def_WorldKey_OperationActionStateJoin = "StateJoin_%s"       #运营活动可参与状态,参数为(运营活动名)
 Def_WorldKey_BossRebornNeedPoint = "BossRebornNeedPoint"     #boss复活需要总点数
 Def_WorldKey_CrossBossIsAlive = 'CrossBossIsAlive_%s_%s'     #跨服boss是否活着,参数(zoneID, bossID)
 Def_WorldKey_GameWorldInitOK = 'GameWorldInitOK'             #GameWold是否初始化完成OK
@@ -601,8 +602,10 @@
             ShareDefine.Def_BT_CharmTotal               : 100,           #魅力总榜
             ShareDefine.Def_BT_CharmWeek                : 100,           #魅力周榜
             ShareDefine.Def_BT_CharmDay                 : 100,           #魅力日榜
-            ShareDefine.Def_BT_BossTrialSubmit          : 1000,          #boss凭证 (boss历练活动)
-            ShareDefine.Def_BT_BossTrialSubmitBak       : 1000,          #boss凭证 (boss历练活动 - 上一期)
+            ShareDefine.Def_BT_BossTrialSubmit          : 100,           #boss凭证 (boss历练活动)
+            ShareDefine.Def_BT_BossTrialSubmitBak       : 100,           #boss凭证 (boss历练活动 - 上一期)
+            ShareDefine.Def_BT_BossTrialSubmitFamily    : 100,           #boss凭证仙盟 (boss历练活动)
+            ShareDefine.Def_BT_BossTrialSubmitFamilyBak : 100,           #boss凭证仙盟 (boss历练活动 - 上一期)
             }
 
 #排行榜保存类型(和BillboardType匹配), 默认保存, 如果不保存,可配置进去
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index ee24a33..a181783 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -4451,9 +4451,17 @@
     Type2 = 0    #(BYTE Type2)//附加类型,用来表示排序对象的类型,比如,玩家所属职业门派,宠物类型等
     Value1 = 0    #(DWORD Value1)//排序依赖的值,比如,等级
     Value2 = 0    #(DWORD Value2)//排序依赖的值,比如,战斗力
+    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):
@@ -4470,9 +4478,17 @@
         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):
@@ -4484,9 +4500,17 @@
         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):
@@ -4502,6 +4526,14 @@
         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
 
@@ -4515,9 +4547,17 @@
         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):
@@ -4530,9 +4570,17 @@
                                 Type2:%d,
                                 Value1:%d,
                                 Value2:%d,
+                                Value3:%d,
+                                Value4:%d,
+                                Value5:%d,
+                                Value6:%d,
+                                Value7:%d,
+                                Value8:%d,
                                 CmpValue:%d,
                                 CmpValue2:%d,
-                                CmpValue3:%d
+                                CmpValue3:%d,
+                                DataLen:%d,
+                                UserData:%s
                                 '''\
                                 %(
                                 self.OrderIndex,
@@ -4543,9 +4591,17 @@
                                 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.CmpValue3,
+                                self.DataLen,
+                                self.UserData
                                 )
         return DumpString
 
@@ -14728,9 +14784,17 @@
     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):
@@ -14745,9 +14809,17 @@
         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):
@@ -14757,9 +14829,17 @@
         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):
@@ -14773,6 +14853,14 @@
         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
 
@@ -14784,9 +14872,17 @@
         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):
@@ -14797,9 +14893,17 @@
                                 Type2:%d,
                                 Value1:%d,
                                 Value2:%d,
+                                Value3:%d,
+                                Value4:%d,
+                                Value5:%d,
+                                Value6:%d,
+                                Value7:%d,
+                                Value8:%d,
                                 CmpValue:%d,
                                 CmpValue2:%d,
-                                CmpValue3:%d
+                                CmpValue3:%d,
+                                DataLen:%d,
+                                UserData:%s
                                 '''\
                                 %(
                                 self.ID,
@@ -14808,9 +14912,17 @@
                                 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.CmpValue3,
+                                self.DataLen,
+                                self.UserData
                                 )
         return DumpString
 
@@ -31262,7 +31374,9 @@
 class  tagMCActBossTrialBillard(Structure):
     Rank = 0    #(DWORD Rank)// 名次,1-代表第一名;支持夸段,如1,3 代表第1名,第2~3名
     Count = 0    #(BYTE Count)// 奖励物品数
-    AwardItemList = list()    #(vector<tagMCActBossTrialItem> AwardItemList)// 奖励物品列表
+    AwardItemList = list()    #(vector<tagMCActBossTrialItem> AwardItemList)// 奖励物品列表,当仙盟榜时,如果有该奖励则代表盟主奖励,否则默认均为成员奖励
+    MemCount = 0    #(BYTE MemCount)// 成员奖励物品数
+    MemAwardItemList = list()    #(vector<tagMCActBossTrialItem> MemAwardItemList)// 成员奖励物品列表,仅仙盟榜时有效
     data = None
 
     def __init__(self):
@@ -31277,12 +31391,19 @@
             temAwardItemList = tagMCActBossTrialItem()
             _pos = temAwardItemList.ReadData(_lpData, _pos)
             self.AwardItemList.append(temAwardItemList)
+        self.MemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemCount):
+            temMemAwardItemList = tagMCActBossTrialItem()
+            _pos = temMemAwardItemList.ReadData(_lpData, _pos)
+            self.MemAwardItemList.append(temMemAwardItemList)
         return _pos
 
     def Clear(self):
         self.Rank = 0
         self.Count = 0
         self.AwardItemList = list()
+        self.MemCount = 0
+        self.MemAwardItemList = list()
         return
 
     def GetLength(self):
@@ -31291,6 +31412,9 @@
         length += 1
         for i in range(self.Count):
             length += self.AwardItemList[i].GetLength()
+        length += 1
+        for i in range(self.MemCount):
+            length += self.MemAwardItemList[i].GetLength()
 
         return length
 
@@ -31300,17 +31424,24 @@
         data = CommFunc.WriteBYTE(data, self.Count)
         for i in range(self.Count):
             data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.MemCount)
+        for i in range(self.MemCount):
+            data = CommFunc.WriteString(data, self.MemAwardItemList[i].GetLength(), self.MemAwardItemList[i].GetBuffer())
         return data
 
     def OutputString(self):
         DumpString = '''
                                 Rank:%d,
                                 Count:%d,
-                                AwardItemList:%s
+                                AwardItemList:%s,
+                                MemCount:%d,
+                                MemAwardItemList:%s
                                 '''\
                                 %(
                                 self.Rank,
                                 self.Count,
+                                "...",
+                                self.MemCount,
                                 "..."
                                 )
         return DumpString
@@ -31385,13 +31516,18 @@
     ActNum = 0    #(BYTE ActNum)// 活动编号
     StartDate = ""    #(char StartDate[10])// 开始日期 y-m-d
     EndtDate = ""    #(char EndtDate[10])// 结束日期 y-m-d
+    JoinStartTime = ""    #(char JoinStartTime[5])// 参与开始时间点 mm:ss
+    JoinEndTime = ""    #(char JoinEndTime[5])// 参与结束时间点 mm:ss
     IsDayReset = 0    #(BYTE IsDayReset)// 是否每天重置
     ResetType = 0    #(BYTE ResetType)// 重置类型,0-0点重置;1-5点重置
     LimitLV = 0    #(WORD LimitLV)// 限制等级
+    SubResetType = 0    #(BYTE SubResetType)// 提交凭证奖励重置类型,0-跟随活动; 1-0点重置;2-5点重置
     SubmitCount = 0    #(BYTE SubmitCount)
     SubmitInfoList = list()    #(vector<tagMCActBossTrialSubmitInfo> SubmitInfoList)// 提交凭证信息列表
-    BillardCount = 0    #(BYTE BillardCount)
-    BillboardInfoList = list()    #(vector<tagMCActBossTrialBillard> BillboardInfoList)// 榜单信息列表
+    PersonalBillCount = 0    #(BYTE PersonalBillCount)
+    PersonalBillboardInfoList = list()    #(vector<tagMCActBossTrialBillard> PersonalBillboardInfoList)// 个人榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
+    FamilyBillCount = 0    #(BYTE FamilyBillCount)
+    FamilyBillboardInfoList = list()    #(vector<tagMCActBossTrialBillard> FamilyBillboardInfoList)// 仙盟榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
     data = None
 
     def __init__(self):
@@ -31406,19 +31542,27 @@
         self.ActNum,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
         self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.JoinStartTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.JoinEndTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
         self.IsDayReset,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.ResetType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.LimitLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.SubResetType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.SubmitCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         for i in range(self.SubmitCount):
             temSubmitInfoList = tagMCActBossTrialSubmitInfo()
             _pos = temSubmitInfoList.ReadData(_lpData, _pos)
             self.SubmitInfoList.append(temSubmitInfoList)
-        self.BillardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
-        for i in range(self.BillardCount):
-            temBillboardInfoList = tagMCActBossTrialBillard()
-            _pos = temBillboardInfoList.ReadData(_lpData, _pos)
-            self.BillboardInfoList.append(temBillboardInfoList)
+        self.PersonalBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.PersonalBillCount):
+            temPersonalBillboardInfoList = tagMCActBossTrialBillard()
+            _pos = temPersonalBillboardInfoList.ReadData(_lpData, _pos)
+            self.PersonalBillboardInfoList.append(temPersonalBillboardInfoList)
+        self.FamilyBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.FamilyBillCount):
+            temFamilyBillboardInfoList = tagMCActBossTrialBillard()
+            _pos = temFamilyBillboardInfoList.ReadData(_lpData, _pos)
+            self.FamilyBillboardInfoList.append(temFamilyBillboardInfoList)
         return _pos
 
     def Clear(self):
@@ -31429,13 +31573,18 @@
         self.ActNum = 0
         self.StartDate = ""
         self.EndtDate = ""
+        self.JoinStartTime = ""
+        self.JoinEndTime = ""
         self.IsDayReset = 0
         self.ResetType = 0
         self.LimitLV = 0
+        self.SubResetType = 0
         self.SubmitCount = 0
         self.SubmitInfoList = list()
-        self.BillardCount = 0
-        self.BillboardInfoList = list()
+        self.PersonalBillCount = 0
+        self.PersonalBillboardInfoList = list()
+        self.FamilyBillCount = 0
+        self.FamilyBillboardInfoList = list()
         return
 
     def GetLength(self):
@@ -31444,15 +31593,21 @@
         length += 1
         length += 10
         length += 10
+        length += 5
+        length += 5
         length += 1
         length += 1
         length += 2
         length += 1
+        length += 1
         for i in range(self.SubmitCount):
             length += self.SubmitInfoList[i].GetLength()
         length += 1
-        for i in range(self.BillardCount):
-            length += self.BillboardInfoList[i].GetLength()
+        for i in range(self.PersonalBillCount):
+            length += self.PersonalBillboardInfoList[i].GetLength()
+        length += 1
+        for i in range(self.FamilyBillCount):
+            length += self.FamilyBillboardInfoList[i].GetLength()
 
         return length
 
@@ -31462,15 +31617,21 @@
         data = CommFunc.WriteBYTE(data, self.ActNum)
         data = CommFunc.WriteString(data, 10, self.StartDate)
         data = CommFunc.WriteString(data, 10, self.EndtDate)
+        data = CommFunc.WriteString(data, 5, self.JoinStartTime)
+        data = CommFunc.WriteString(data, 5, self.JoinEndTime)
         data = CommFunc.WriteBYTE(data, self.IsDayReset)
         data = CommFunc.WriteBYTE(data, self.ResetType)
         data = CommFunc.WriteWORD(data, self.LimitLV)
+        data = CommFunc.WriteBYTE(data, self.SubResetType)
         data = CommFunc.WriteBYTE(data, self.SubmitCount)
         for i in range(self.SubmitCount):
             data = CommFunc.WriteString(data, self.SubmitInfoList[i].GetLength(), self.SubmitInfoList[i].GetBuffer())
-        data = CommFunc.WriteBYTE(data, self.BillardCount)
-        for i in range(self.BillardCount):
-            data = CommFunc.WriteString(data, self.BillboardInfoList[i].GetLength(), self.BillboardInfoList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.PersonalBillCount)
+        for i in range(self.PersonalBillCount):
+            data = CommFunc.WriteString(data, self.PersonalBillboardInfoList[i].GetLength(), self.PersonalBillboardInfoList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.FamilyBillCount)
+        for i in range(self.FamilyBillCount):
+            data = CommFunc.WriteString(data, self.FamilyBillboardInfoList[i].GetLength(), self.FamilyBillboardInfoList[i].GetBuffer())
         return data
 
     def OutputString(self):
@@ -31479,25 +31640,35 @@
                                 ActNum:%d,
                                 StartDate:%s,
                                 EndtDate:%s,
+                                JoinStartTime:%s,
+                                JoinEndTime:%s,
                                 IsDayReset:%d,
                                 ResetType:%d,
                                 LimitLV:%d,
+                                SubResetType:%d,
                                 SubmitCount:%d,
                                 SubmitInfoList:%s,
-                                BillardCount:%d,
-                                BillboardInfoList:%s
+                                PersonalBillCount:%d,
+                                PersonalBillboardInfoList:%s,
+                                FamilyBillCount:%d,
+                                FamilyBillboardInfoList:%s
                                 '''\
                                 %(
                                 self.Head.OutputString(),
                                 self.ActNum,
                                 self.StartDate,
                                 self.EndtDate,
+                                self.JoinStartTime,
+                                self.JoinEndTime,
                                 self.IsDayReset,
                                 self.ResetType,
                                 self.LimitLV,
+                                self.SubResetType,
                                 self.SubmitCount,
                                 "...",
-                                self.BillardCount,
+                                self.PersonalBillCount,
+                                "...",
+                                self.FamilyBillCount,
                                 "..."
                                 )
         return DumpString
@@ -31516,8 +31687,9 @@
                   ("Cmd", c_ubyte),
                   ("SubCmd", c_ubyte),
                   ("ActNum", c_ubyte),    # 活动编号
-                  ("SubmitCount", c_ushort),    # 已提交凭证个数
-                  ("SubmitCountAward", c_int),    # 提交凭证奖励领奖状态
+                  ("SubmitCount", c_int),    # 已提交凭证个数,总个数
+                  ("SubmitAwardCount", c_int),    # 已提交凭证个数,关联提交奖励的个数,领奖使用该个数判断
+                  ("SubmitAwardState", c_int),    # 提交凭证奖励领奖状态
                   ]
 
     def __init__(self):
@@ -31536,7 +31708,8 @@
         self.SubCmd = 0x68
         self.ActNum = 0
         self.SubmitCount = 0
-        self.SubmitCountAward = 0
+        self.SubmitAwardCount = 0
+        self.SubmitAwardState = 0
         return
 
     def GetLength(self):
@@ -31551,14 +31724,16 @@
                                 SubCmd:%s,
                                 ActNum:%d,
                                 SubmitCount:%d,
-                                SubmitCountAward:%d
+                                SubmitAwardCount:%d,
+                                SubmitAwardState:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
                                 self.ActNum,
                                 self.SubmitCount,
-                                self.SubmitCountAward
+                                self.SubmitAwardCount,
+                                self.SubmitAwardState
                                 )
         return DumpString
 
@@ -38327,6 +38502,290 @@
 
 
 #------------------------------------------------------
+# AA 76 Boss历练跨服活动信息 #tagMCCrossActBossTrialInfo
+
+class  tagMCCrossActBossTrialItem(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("ItemID", c_int),    
+                  ("ItemCount", c_ushort),    
+                  ("IsBind", c_ubyte),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        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.ItemID = 0
+        self.ItemCount = 0
+        self.IsBind = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCCrossActBossTrialItem)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// AA 76 Boss历练跨服活动信息 //tagMCCrossActBossTrialInfo:
+                                ItemID:%d,
+                                ItemCount:%d,
+                                IsBind:%d
+                                '''\
+                                %(
+                                self.ItemID,
+                                self.ItemCount,
+                                self.IsBind
+                                )
+        return DumpString
+
+
+class  tagMCCrossActBossTrialBillard(Structure):
+    Rank = 0    #(DWORD Rank)// 名次,1-代表第一名;支持夸段,如1,3 代表第1名,第2~3名
+    Count = 0    #(BYTE Count)// 奖励物品数
+    AwardItemList = list()    #(vector<tagMCCrossActBossTrialItem> AwardItemList)// 奖励物品列表,当仙盟榜时,如果有该奖励则代表盟主奖励,否则默认均为成员奖励
+    MemCount = 0    #(BYTE MemCount)// 成员奖励物品数
+    MemAwardItemList = list()    #(vector<tagMCCrossActBossTrialItem> MemAwardItemList)// 成员奖励物品列表,仅仙盟榜时有效
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.Rank,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.Count):
+            temAwardItemList = tagMCCrossActBossTrialItem()
+            _pos = temAwardItemList.ReadData(_lpData, _pos)
+            self.AwardItemList.append(temAwardItemList)
+        self.MemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemCount):
+            temMemAwardItemList = tagMCCrossActBossTrialItem()
+            _pos = temMemAwardItemList.ReadData(_lpData, _pos)
+            self.MemAwardItemList.append(temMemAwardItemList)
+        return _pos
+
+    def Clear(self):
+        self.Rank = 0
+        self.Count = 0
+        self.AwardItemList = list()
+        self.MemCount = 0
+        self.MemAwardItemList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 1
+        for i in range(self.Count):
+            length += self.AwardItemList[i].GetLength()
+        length += 1
+        for i in range(self.MemCount):
+            length += self.MemAwardItemList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.Rank)
+        data = CommFunc.WriteBYTE(data, self.Count)
+        for i in range(self.Count):
+            data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.MemCount)
+        for i in range(self.MemCount):
+            data = CommFunc.WriteString(data, self.MemAwardItemList[i].GetLength(), self.MemAwardItemList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Rank:%d,
+                                Count:%d,
+                                AwardItemList:%s,
+                                MemCount:%d,
+                                MemAwardItemList:%s
+                                '''\
+                                %(
+                                self.Rank,
+                                self.Count,
+                                "...",
+                                self.MemCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagMCCrossActBossTrialInfo(Structure):
+    Head = tagHead()
+    ServerInfoLen = 0    #(BYTE ServerInfoLen)
+    ServerIDRangeInfo = ""    #(String ServerIDRangeInfo)//开放该活动的服务器ID范围列表,json格式 [[IDA, IDB], ...], [] 为全服
+    GroupValue1 = 0    #(BYTE GroupValue1)// 活动榜单分组值1,用于查询对应榜单
+    StartDate = ""    #(char StartDate[10])// 开始日期 y-m-d
+    EndtDate = ""    #(char EndtDate[10])// 结束日期 y-m-d
+    JoinStartTime = ""    #(char JoinStartTime[5])// 参与开始时间点 mm:ss
+    JoinEndTime = ""    #(char JoinEndTime[5])// 参与结束时间点 mm:ss
+    IsDayReset = 0    #(BYTE IsDayReset)// 是否每天重置
+    ResetType = 0    #(BYTE ResetType)// 重置类型,0-0点重置;1-5点重置
+    RankLimitPersonal = 0    #(WORD RankLimitPersonal)// 个人榜上榜个数保底限制;
+    RankLimitFamily = 0    #(WORD RankLimitFamily)// 仙盟榜上榜个数保底限制;
+    PersonalBillCount = 0    #(BYTE PersonalBillCount)
+    PersonalBillboardInfoList = list()    #(vector<tagMCCrossActBossTrialBillard> PersonalBillboardInfoList)// 个人榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
+    FamilyBillCount = 0    #(BYTE FamilyBillCount)
+    FamilyBillboardInfoList = list()    #(vector<tagMCCrossActBossTrialBillard> FamilyBillboardInfoList)// 仙盟榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x76
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.ServerInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.ServerIDRangeInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ServerInfoLen)
+        self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.JoinStartTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.JoinEndTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.IsDayReset,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.ResetType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RankLimitPersonal,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.RankLimitFamily,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.PersonalBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.PersonalBillCount):
+            temPersonalBillboardInfoList = tagMCCrossActBossTrialBillard()
+            _pos = temPersonalBillboardInfoList.ReadData(_lpData, _pos)
+            self.PersonalBillboardInfoList.append(temPersonalBillboardInfoList)
+        self.FamilyBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.FamilyBillCount):
+            temFamilyBillboardInfoList = tagMCCrossActBossTrialBillard()
+            _pos = temFamilyBillboardInfoList.ReadData(_lpData, _pos)
+            self.FamilyBillboardInfoList.append(temFamilyBillboardInfoList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x76
+        self.ServerInfoLen = 0
+        self.ServerIDRangeInfo = ""
+        self.GroupValue1 = 0
+        self.StartDate = ""
+        self.EndtDate = ""
+        self.JoinStartTime = ""
+        self.JoinEndTime = ""
+        self.IsDayReset = 0
+        self.ResetType = 0
+        self.RankLimitPersonal = 0
+        self.RankLimitFamily = 0
+        self.PersonalBillCount = 0
+        self.PersonalBillboardInfoList = list()
+        self.FamilyBillCount = 0
+        self.FamilyBillboardInfoList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += len(self.ServerIDRangeInfo)
+        length += 1
+        length += 10
+        length += 10
+        length += 5
+        length += 5
+        length += 1
+        length += 1
+        length += 2
+        length += 2
+        length += 1
+        for i in range(self.PersonalBillCount):
+            length += self.PersonalBillboardInfoList[i].GetLength()
+        length += 1
+        for i in range(self.FamilyBillCount):
+            length += self.FamilyBillboardInfoList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.ServerInfoLen)
+        data = CommFunc.WriteString(data, self.ServerInfoLen, self.ServerIDRangeInfo)
+        data = CommFunc.WriteBYTE(data, self.GroupValue1)
+        data = CommFunc.WriteString(data, 10, self.StartDate)
+        data = CommFunc.WriteString(data, 10, self.EndtDate)
+        data = CommFunc.WriteString(data, 5, self.JoinStartTime)
+        data = CommFunc.WriteString(data, 5, self.JoinEndTime)
+        data = CommFunc.WriteBYTE(data, self.IsDayReset)
+        data = CommFunc.WriteBYTE(data, self.ResetType)
+        data = CommFunc.WriteWORD(data, self.RankLimitPersonal)
+        data = CommFunc.WriteWORD(data, self.RankLimitFamily)
+        data = CommFunc.WriteBYTE(data, self.PersonalBillCount)
+        for i in range(self.PersonalBillCount):
+            data = CommFunc.WriteString(data, self.PersonalBillboardInfoList[i].GetLength(), self.PersonalBillboardInfoList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.FamilyBillCount)
+        for i in range(self.FamilyBillCount):
+            data = CommFunc.WriteString(data, self.FamilyBillboardInfoList[i].GetLength(), self.FamilyBillboardInfoList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                ServerInfoLen:%d,
+                                ServerIDRangeInfo:%s,
+                                GroupValue1:%d,
+                                StartDate:%s,
+                                EndtDate:%s,
+                                JoinStartTime:%s,
+                                JoinEndTime:%s,
+                                IsDayReset:%d,
+                                ResetType:%d,
+                                RankLimitPersonal:%d,
+                                RankLimitFamily:%d,
+                                PersonalBillCount:%d,
+                                PersonalBillboardInfoList:%s,
+                                FamilyBillCount:%d,
+                                FamilyBillboardInfoList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.ServerInfoLen,
+                                self.ServerIDRangeInfo,
+                                self.GroupValue1,
+                                self.StartDate,
+                                self.EndtDate,
+                                self.JoinStartTime,
+                                self.JoinEndTime,
+                                self.IsDayReset,
+                                self.ResetType,
+                                self.RankLimitPersonal,
+                                self.RankLimitFamily,
+                                self.PersonalBillCount,
+                                "...",
+                                self.FamilyBillCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCCrossActBossTrialInfo=tagMCCrossActBossTrialInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCrossActBossTrialInfo.Head.Cmd,m_NAtagMCCrossActBossTrialInfo.Head.SubCmd))] = m_NAtagMCCrossActBossTrialInfo
+
+
+#------------------------------------------------------
 # AA 25 每日礼包活动信息 #tagMCDailyGiftbagInfo
 
 class  tagMCDailyGiftbagItem(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/DataRecordPack.py b/ServerPython/CoreServerGroup/GameServer/Script/DataRecordPack.py
index 2bbb35f..0d2dc6a 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/DataRecordPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/DataRecordPack.py
@@ -261,14 +261,23 @@
         type2 = billBoardData.GetType2()
         value1 = billBoardData.GetValue1()
         value2 = billBoardData.GetValue2()
+        value3 = billBoardData.GetValue3()
+        value4 = billBoardData.GetValue4()
+        value5 = billBoardData.GetValue5()
+        value6 = billBoardData.GetValue6()
+        value7 = billBoardData.GetValue7()
+        value8 = billBoardData.GetValue8()
         cmpValue = billBoardData.GetCmpValue()
         cmpValue2 = billBoardData.GetCmpValue2()
         cmpValue3 = billBoardData.GetCmpValue3()
+        userData = billBoardData.GetUserData()
         
         dataDict = {"BillboardType":billboardType,
                     "Place":index,  "ObjID":objID, "ObjID2":objID2, "Name1":name1, 
                     "Name2":name2,  "Type2":type2, "Value1":value1, "Value2":value2,
-                    "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3,
+                    "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3, 
+                    "Value3":value3, "Value4":value4, "Value5":value5, "Value6":value6, 
+                    "Value7":value7, "Value8":value8, "UserData":userData
                     }
         
         dataDict.update(addDataDict)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardData.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardData.py
index 62f6ba8..c9ecf28 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardData.py
@@ -23,11 +23,11 @@
     GameWorld.DebugAnswer(curPlayer, "---------- %s" % GameWorld.GetCurrentDataTimeStr())
     if errInfo:
         GameWorld.DebugAnswer(curPlayer, errInfo)
-    GameWorld.DebugAnswer(curPlayer, "新增榜单假数据: BillboardData 类型 条数 比较值1 可选参数(比较值2 常规值1 常规值2)")
+    GameWorld.DebugAnswer(curPlayer, "新增榜单假数据: BillboardData 类型 条数 比较值1 可选参数(比较值2 常规值1~5)")
     GameWorld.DebugAnswer(curPlayer, "删除榜单假数据: BillboardData 类型")
     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-升星")
-    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:17-仙界盛典,23-仙界盛典2,33-boss凭证")
+    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:17-仙界盛典,23-仙界盛典2,33-boss凭证,36-boss凭证仙盟")
     GameWorld.DebugAnswer(curPlayer, "魅力榜单类型:30-总榜,31-周榜,32-日榜")
     return
 
@@ -72,6 +72,9 @@
     cmpValue2 = gmList[3] if len(gmList) > 3 else 0
     value1 = gmList[4] if len(gmList) > 4 else 0
     value2 = gmList[5] if len(gmList) > 5 else 0
+    value3 = gmList[6] if len(gmList) > 6 else 0
+    value4 = gmList[7] if len(gmList) > 7 else 0
+    value5 = gmList[8] if len(gmList) > 8 else 0
     
     autoSort = False
     bType2 = 0
@@ -85,7 +88,8 @@
         dataPlayerName = "%s%s" % (FakeName, i)
         dataCmpValue1 = max(0, cmpValue1 - i)
         dataCmpValue2 = max(0, cmpValue2 - i)
-        PlayerBillboard.UpdatePlayerBillboard(dataPlayerID, dataPlayerName, curPlayerOpInfo, billboardIndex, bType2, value1, value2, dataCmpValue1, autoSort, dataCmpValue2)
+        PlayerBillboard.UpdatePlayerBillboard(dataPlayerID, dataPlayerName, curPlayerOpInfo, billboardIndex, bType2, value1, value2, dataCmpValue1, autoSort, dataCmpValue2, 
+                                              value3=value3, value4=value4, value5=value5)
         
     billBoard.Sort()
     
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardDataCross.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardDataCross.py
index 7067e3a..6b0f18d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardDataCross.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/BillboardDataCross.py
@@ -24,7 +24,7 @@
     GameWorld.DebugAnswer(curPlayer, "---------- %s" % GameWorld.GetCurrentDataTimeStr())
     if errInfo:
         GameWorld.DebugAnswer(curPlayer, errInfo)
-    GameWorld.DebugAnswer(curPlayer, "新增跨服榜单假数据: BillboardDataCross 类型  分组值1 分组值2 条数 比较值1 可选参数(比较值2 常规值1 常规值2)")
+    GameWorld.DebugAnswer(curPlayer, "新增跨服榜单假数据: BillboardDataCross 类型  分组值1 分组值2 条数 比较值1 可选参数(比较值2 常规值1~5)")
     GameWorld.DebugAnswer(curPlayer, "删除跨服榜单假数据: BillboardDataCross 类型 分组值1 分组值2")
     GameWorld.DebugAnswer(curPlayer, "跨服运营活动榜类型:150-充值(分组值1配置ID)")
     return
@@ -80,6 +80,9 @@
     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
@@ -99,7 +102,9 @@
         name1 = dataPlayerName
         cmpValue = dataCmpValue1
         cmpValue2 = dataCmpValue2
-        CrossBillboard.UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, cmpValue2, cmpValue3, groupValue2, id2)
+        CrossBillboard.UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, 
+                                         cmpValue, cmpValue2, cmpValue3, groupValue2, id2,
+                                         value3=value3, value4=value4, value5=value5)
         
     GameWorld.Log("插入虚假榜单(%s-%s-%s): %s 条" % (billboardType, groupValue1, groupValue2, count))
     return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CreateFamily.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CreateFamily.py
index 7f5a044..0d572b6 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CreateFamily.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CreateFamily.py
@@ -79,6 +79,7 @@
         
         succCreatCount += 1
         #---创建假仙盟---
+        curFamily.SetServerID(GameWorld.GetServerGroupID())
         curFamily.SetCreateTime(creatTime)
         curFamily.SetLV(familyLV)
         curFamily.SetAcceptJoin(ShareDefine.FamilyAcceptJoin_Refuse) # 设置拒绝申请
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_GetFamilyInfo.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_GetFamilyInfo.py
index 74084f4..9b8ed64 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_GetFamilyInfo.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_GetFamilyInfo.py
@@ -125,6 +125,7 @@
                   'Broadcast':curFamily.GetBroadcast(),
                   'MemberCnt':memberCnt,
                   'OnLineCnt':onlineCnt,
+                  'ServerID':curFamily.GetServerID(),
                   }
     if memberInfo:
         familyInfo['MemberInfo'] = memberInfo
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboard.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboard.py
index ecc05cc..6c24b99 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboard.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboard.py
@@ -72,9 +72,16 @@
                         "Type2":billBoardData.GetType2(),
                         "Value1":billBoardData.GetValue1(),
                         "Value2":billBoardData.GetValue2(),
+                        "Value3":billBoardData.GetValue3(),
+                        "Value4":billBoardData.GetValue4(),
+                        "Value5":billBoardData.GetValue5(),
+                        "Value6":billBoardData.GetValue6(),
+                        "Value7":billBoardData.GetValue7(),
+                        "Value8":billBoardData.GetValue8(),
                         "CmpValue":billBoardData.GetCmpValue(),
                         "CmpValue2":billBoardData.GetCmpValue2(),
                         "CmpValue3":billBoardData.GetCmpValue3(),
+                        "UserData":billBoardData.GetUserData(),
                          }
         
         billBoardInfo.append(billBoardDict)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboardCross.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboardCross.py
index 83a35a7..89a9e26 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboardCross.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_QueryBillboardCross.py
@@ -67,9 +67,16 @@
                              "Type2":billboardData.Type2,
                              "Value1":billboardData.Value1,
                              "Value2":billboardData.Value2,
+                             "Value3":billboardData.Value3,
+                             "Value4":billboardData.Value4,
+                             "Value5":billboardData.Value5,
+                             "Value6":billboardData.Value6,
+                             "Value7":billboardData.Value7,
+                             "Value8":billboardData.Value8,
                              "CmpValue":billboardData.CmpValue,
                              "CmpValue2":billboardData.CmpValue2,
                              "CmpValue3":billboardData.CmpValue3,
+                             "UserData":billboardData.UserData,
                              }
             
             # 20210120 后台没做区分不同版本,暂时用游戏版本代码做返回值区分;(BT版存的是元,主干港台版存的是分,美元支持到分)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
index cc413cf..513bc0e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
@@ -457,8 +457,8 @@
 ##获取玩家所属区服ID
 # @param curPlayer
 # @return
-def GetPlayerServerID(curPlayer):
-    accID = curPlayer.GetAccID()
+def GetPlayerServerID(curPlayer): return GetAccIDServerID(curPlayer.GetAccID())
+def GetAccIDServerID(accID):
     infoList = accID.split(Def_AccID_Split_Sign)
     return 0 if len(infoList) < 3 else int(infoList[-1][1:])
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py
index 02a95d7..7652dfe 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py
@@ -22,6 +22,7 @@
 import PlayerControl
 import IpyGameDataPY
 import CrossActCTGBillboard
+import PlayerActBossTrial
 import CrossRealmMsg
 import PyGameData
 import PlayerFB
@@ -58,6 +59,7 @@
                 # 非活动中的,已经结算过了,不需要存储
                 continue
             state = actInfo.get(ShareDefine.ActKey_State, 0)
+            stateJoin = actInfo.get(ShareDefine.ActKey_StateJoin, 0)
             actID = actInfo.get(ShareDefine.ActKey_ID, 0)
             templateID = actInfo.get(ShareDefine.ActKey_TemplateID, 0)
             serverIDRangeList = actInfo.get(ShareDefine.ActKey_ServerIDRangeList, "")
@@ -68,8 +70,9 @@
             recData.SetValue2(state)
             recData.SetValue3(actID)
             recData.SetValue4(templateID)
-            GameWorld.Log("    actName=%s,cfgID=%s,state=%s,actID=%s,templateID=%s,serverIDRangeList=%s" 
-                          % (actName, cfgID, state, actID, templateID, serverIDRangeList))
+            recData.SetValue5(stateJoin)
+            GameWorld.Log("    actName=%s,cfgID=%s,state=%s,stateJoin=%s,actID=%s,templateID=%s,serverIDRangeList=%s" 
+                          % (actName, cfgID, state, stateJoin, actID, templateID, serverIDRangeList))
             
     return
 
@@ -113,14 +116,24 @@
     GameWorld.DebugLog("找不到服务器组ID对应跨服活动分区! actName=%s, serverGroupID=%s" % (actName, serverGroupID))
     return
 
-def GetCrossActInfoByCfgID(actName, cfgID):
+def GetCrossActInfoByCfgID(actName, cfgID, zoneID=None):
+    ## 获取cfgID对应的跨服活动状态信息,可选验证zoneID是否匹配
     crossActInfoDict = GetCrossActInfoDict()
     if actName not in crossActInfoDict:
         return
     curActInfoDict = crossActInfoDict[actName]
     if cfgID not in curActInfoDict:
         return
-    return curActInfoDict[cfgID]
+    actInfo = curActInfoDict[cfgID]
+    if zoneID:
+        # 验证分区ID是否正确
+        ipyDataDict = actInfo.get(ShareDefine.ActKey_IpyDataInfo, {})
+        if not ipyDataDict:
+            return
+        ipyZoneID = ipyDataDict.get("ZoneID", 0)
+        if zoneID != ipyZoneID:
+            return
+    return actInfo
 
 def GetCrossActInfoDict():
     if PyGameData.g_crossActInfoDict == None:
@@ -138,6 +151,7 @@
             state = recData.GetValue2()
             actID = recData.GetValue3()
             templateID = recData.GetValue4()
+            stateJoin = recData.GetValue5()
             if not state:
                 continue
             if actName not in PyGameData.g_crossActInfoDict:
@@ -145,7 +159,8 @@
             actInfoDict = PyGameData.g_crossActInfoDict[actName]
             # 活动ID、状态、模板信息单独存储,重置活动判断用
             dbInfo = {ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_State:state, ShareDefine.ActKey_TemplateID:templateID, 
-                      ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ServerIDRangeList:serverIDRangeList}
+                      ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ServerIDRangeList:serverIDRangeList, 
+                      ShareDefine.ActKey_StateJoin:stateJoin}
             actInfo = {}
             actInfo.update(dbInfo)
             actInfo[ShareDefine.ActKey_DBInfo] = dbInfo
@@ -282,6 +297,13 @@
                 startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
                 GameWorld.Log("        星期X转化为日期: %s ~ %s" % (startDateStr, endDateStr))
                 
+            if hasattr(ipyData, "GetJoinStartTime") and hasattr(ipyData, "GetJoinEndTime"):
+                joinStartTimeStr = ipyData.GetJoinStartTime()
+                joinEndTimeStr = ipyData.GetJoinEndTime()
+            else:
+                joinStartTimeStr = ""
+                joinEndTimeStr = ""
+                
             if hasattr(ipyData, "GetStartTimeList") and hasattr(ipyData, "GetEndTimeList"):
                 startHMStrList = ipyData.GetStartTimeList()
                 endHMStrList = ipyData.GetEndTimeList()
@@ -297,6 +319,7 @@
                 GameWorld.ErrLog("        活动配置开始及结束时间个数不匹配! actName=%s,cfgID=%s,startHMStrList=%s,endHMStrList=%s" 
                                  % (actName, cfgID, startHMStrList, endHMStrList))
                 
+            isDayReset = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()    
             resetType = 0 if not hasattr(ipyData, "GetResetType") else ipyData.GetResetType() # 重置类型,0-0点重置;1-5点重置
             if resetType == 1:
                 startDayDate = datetime.datetime.strptime("%s 05:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
@@ -354,6 +377,17 @@
             GameWorld.Log("        startList=%s" % (startList))
             GameWorld.Log("        end  List=%s" % (endList))
             
+            joinStartTimeList, joinEndTimeList = [], [] # 可指定活动可参与的时间点,不影响活动状态,只影响活动某些功能的参与时机,如上榜类
+            if joinStartTimeStr:
+                if isDayReset:
+                    joinStartTimeList.append(datetime.datetime.strptime("%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, joinStartTimeStr), ChConfig.TYPE_Time_Format))
+                    joinEndTimeList.append(datetime.datetime.strptime("%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, joinEndTimeStr), ChConfig.TYPE_Time_Format))
+                else:
+                    joinStartTimeList.append(datetime.datetime.strptime("%s %s:00" % (startDateStr, joinStartTimeStr), ChConfig.TYPE_Time_Format))
+                    joinEndTimeList.append(datetime.datetime.strptime("%s %s:00" % (endDateStr, joinEndTimeStr), ChConfig.TYPE_Time_Format))                    
+            GameWorld.Log("        joinStartTimeList=%s" % (joinStartTimeList))
+            GameWorld.Log("        joinEndTime  List=%s" % (joinEndTimeList))
+            
             for dtIndex, startDateTime in enumerate(startList):
                 endDateTime = endList[dtIndex]
                 # 广播 - 相对实际开始时间
@@ -392,7 +426,7 @@
                 
             if actName not in actTimeInfoDict:
                 actTimeInfoDict[actName] = {}
-            actTimeInfoDict[actName][cfgID] = [ipyData, startList, endList, notifyDict]
+            actTimeInfoDict[actName][cfgID] = [ipyData, startList, endList, notifyDict, joinStartTimeList, joinEndTimeList]
             if actName not in actCfgIDInfoDict:
                 actCfgIDInfoDict[actName] = [[], []]
             endCfgIDList, actCfgIDList = actCfgIDInfoDict[actName]
@@ -446,7 +480,6 @@
                     
                 dayIndex = (curDateTime - startDayDate).days
                 actIDDateTime = startDayDate
-                isDayReset = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
                 # 按时段开的默认每天重置
                 if isDayReset or (startHMStrList and endHMStrList):
                     actIDDateTime += datetime.timedelta(days=dayIndex)
@@ -505,10 +538,11 @@
         for cfgID in cfgIDList:
             if cfgID not in timeInfoDict:
                 continue
-            ipyData, startList, endList, notifyDict = timeInfoDict[cfgID]
+            ipyData, startList, endList, notifyDict, joinStartTimeList, joinEndTimeList = timeInfoDict[cfgID]
             
             isEnd = True
             state = 0 # 默认关闭
+            stateJoin = 0 # 可参与状态
             cfgID = ipyData.GetCfgID()
             groupName = ipyData.GetActGroupName()
             zoneID = ipyData.GetZoneID()
@@ -527,6 +561,15 @@
                 if endList:
                     isEnd = (curDateTime >= endList[-1])
                     
+                if joinStartTimeList:
+                    for jIndex, joinStartDateTime in enumerate(joinStartTimeList):
+                        endJoinDateTime = joinEndTimeList[jIndex]
+                        if joinStartDateTime <= curDateTime < endJoinDateTime:
+                            stateJoin = state
+                            break
+                else:
+                    stateJoin = state
+                    
             serverIDRangeList = actInfoDict.get(ShareDefine.ActKey_ServerIDRangeList)
             # 全服广播提示信息
             if curDateTime in notifyDict:
@@ -540,6 +583,7 @@
                 
             dbInfo = actInfoDict.get(ShareDefine.ActKey_DBInfo, {})
             dbState = dbInfo.get(ShareDefine.ActKey_State, 0)
+            dbStateJoin = dbInfo.get(ShareDefine.ActKey_StateJoin, 0)
             dbCfgID = dbInfo.get(ShareDefine.ActKey_CfgID, 0)
             dbActID = dbInfo.get(ShareDefine.ActKey_ID, 0)
             dbTemplateID = dbInfo.get(ShareDefine.ActKey_TemplateID, 0)
@@ -551,7 +595,7 @@
                 
             actID = actInfoDict.get(ShareDefine.ActKey_ID, 0)
             templateID = actInfoDict.get(ShareDefine.ActKey_TemplateID, 0)
-            if not isReload and dbState == state and dbActID == actID and not forceReset:
+            if not isReload and dbState == state and dbStateJoin == stateJoin and dbActID == actID and not forceReset:
                 #已经是这个状态了
                 continue
             GameWorld.Log("跨服运营活动状态: actName=%s,cfgID=%s,groupName=%s,zoneID=%s,dbState=%s -> state=%s,isEnd=%s, dbActID=%s -> actID=%s,forceReset=%s" 
@@ -559,8 +603,10 @@
             
             # 更新状态
             actInfoDict[ShareDefine.ActKey_State] = state
+            actInfoDict[ShareDefine.ActKey_StateJoin] = stateJoin
             dbInfo = {ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_State:state, ShareDefine.ActKey_TemplateID:templateID, 
-                      ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ServerIDRangeList:serverIDRangeList}
+                      ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ServerIDRangeList:serverIDRangeList, 
+                      ShareDefine.ActKey_StateJoin:stateJoin}
             actInfoDict[ShareDefine.ActKey_DBInfo] = dbInfo
             #GameWorld.Log("    活动状态同步信息: actName=%s,cfgID=%s,groupName=%s,zoneID=%s,actInfoDict=%s" % (actName, cfgID, groupName, zoneID, actInfoDict))
             if actName not in sysnCrossActInfoDict:
@@ -573,6 +619,9 @@
                 
                 if actName == ShareDefine.CrossActName_CTGBillboard:
                     CrossActCTGBillboard.OnActIDChange(cfgID, dbTemplateID, state)
+                    
+                if actName == ShareDefine.CrossActName_BossTrial:
+                    PlayerActBossTrial.OnCrossActIDChange(cfgID, state)
                     
                 else:
                     actChangeList.append([actName, ipyData, state, cfgID, groupName, zoneID, dbActID, actID, forceReset, dbTemplateID])
@@ -587,6 +636,7 @@
                               % (actName, cfgID, groupName, zoneID, dbState, state, actIDChange, dbTemplateID))
                 actStateChangeList.append([actName, ipyData, dbState, state, cfgID, groupName, zoneID, actIDChange, dbTemplateID])
                 
+            GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossActInfo % actName, crossActInfoDict[actName])
             # 非活动中的处理完关闭后,最后删除
             if not state and isEnd:
                 del crossActInfoDict[actName][cfgID]
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
index 56014c3..aee6b1f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
@@ -28,8 +28,8 @@
 import operator
 import time
 
-Def_CrossBillboard_MaxDataCount = 100 # 跨服榜单数据最大条数暂固定最大为100条,如有需要调整需针对实际情况进行评估(如数据同步、同步封包等)
-    
+Def_CrossBillboard_MaxDataCount = 200 # 跨服榜单数据最大条数暂固定最大为100条,如有需要调整需针对实际情况进行评估(如数据同步、同步封包等)
+
 class CrossBillboardManager(object):
     ## 跨服排行榜管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
     
@@ -171,8 +171,11 @@
                         "ID":billboardData.ID, "ID2":billboardData.ID2,
                         "Name1":billboardData.Name1, "Name2":billboardData.Name2,
                         "Value1":billboardData.Value1, "Value2":billboardData.Value2,
+                        "Value3":billboardData.Value3, "Value4":billboardData.Value4,
+                        "Value5":billboardData.Value5, "Value6":billboardData.Value6,
+                        "Value7":billboardData.Value7, "Value8":billboardData.Value8,
                         "CmpValue":billboardData.CmpValue, "CmpValue2":billboardData.CmpValue2, 
-                        "CmpValue3":billboardData.CmpValue3}
+                        "CmpValue3":billboardData.CmpValue3, "UserData":billboardData.UserData}
             DataRecordPack.SendEventPack(eventTypeName, dataDict)
         return
     
@@ -221,7 +224,7 @@
             self.__billboardList = self.__billboardList[:len(syncBillboardList)] # 直接用本服以后的排行数据实例clear后覆盖更新,不足的创建新实例
             self.__idOrderDict = {}
             for i, syncData in enumerate(syncBillboardList):
-                ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3 = syncData
+                ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData = syncData
                 if i < len(self.__billboardList):
                     billboardData = self.__billboardList[i]
                     billboardData.clear()
@@ -239,6 +242,14 @@
                 billboardData.Type2 = Type2
                 billboardData.Value1 = Value1
                 billboardData.Value2 = Value2
+                billboardData.Value3 = Value3
+                billboardData.Value4 = Value4
+                billboardData.Value5 = Value5
+                billboardData.Value6 = Value6
+                billboardData.Value7 = Value7
+                billboardData.Value8 = Value8
+                billboardData.UserData = UserData
+                billboardData.DataLen = len(billboardData.UserData)
                 billboardData.CmpValue = CmpValue
                 billboardData.CmpValue2 = CmpValue2
                 billboardData.CmpValue3 = CmpValue3
@@ -282,6 +293,14 @@
             tobillboardData.Type2 = frbillboardData.Type2
             tobillboardData.Value1 = frbillboardData.Value1
             tobillboardData.Value2 = frbillboardData.Value2
+            tobillboardData.Value3 = frbillboardData.Value3
+            tobillboardData.Value4 = frbillboardData.Value4
+            tobillboardData.Value5 = frbillboardData.Value5
+            tobillboardData.Value6 = frbillboardData.Value6
+            tobillboardData.Value7 = frbillboardData.Value7
+            tobillboardData.Value8 = frbillboardData.Value8
+            tobillboardData.UserData = frbillboardData.UserData
+            tobillboardData.DataLen = len(tobillboardData.UserData)
             tobillboardData.CmpValue = frbillboardData.CmpValue
             tobillboardData.CmpValue2 = frbillboardData.CmpValue2
             tobillboardData.CmpValue3 = frbillboardData.CmpValue3
@@ -357,10 +376,17 @@
             Type2 = billboardData.Type2
             Value1 = billboardData.Value1
             Value2 = billboardData.Value2
+            Value3 = billboardData.Value3
+            Value4 = billboardData.Value4
+            Value5 = billboardData.Value5
+            Value6 = billboardData.Value6
+            Value7 = billboardData.Value7
+            Value8 = billboardData.Value8
+            UserData = billboardData.UserData
             CmpValue = billboardData.CmpValue
             CmpValue2 = billboardData.CmpValue2
             CmpValue3 = billboardData.CmpValue3
-            syncBillboardList.append([ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3])
+            syncBillboardList.append([ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData])
         msgData["BillboardDataList"] = syncBillboardList
         
     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_SyncBillboard, msgData, serverGroupIDList)
@@ -419,9 +445,17 @@
         billboardInfoData.Type2 = billboardData.Type2
         billboardInfoData.Value1 = billboardData.Value1
         billboardInfoData.Value2 = billboardData.Value2
+        billboardInfoData.Value3 = billboardData.Value3
+        billboardInfoData.Value4 = billboardData.Value4
+        billboardInfoData.Value5 = billboardData.Value5
+        billboardInfoData.Value6 = billboardData.Value6
+        billboardInfoData.Value7 = billboardData.Value7
+        billboardInfoData.Value8 = billboardData.Value8
         billboardInfoData.CmpValue = billboardData.CmpValue
         billboardInfoData.CmpValue2 = billboardData.CmpValue2
         billboardInfoData.CmpValue3 = billboardData.CmpValue3
+        billboardInfoData.UserData = billboardData.UserData
+        billboardInfoData.DataLen = len(billboardInfoData.UserData)
         billboardInfo.CrossBillboardDataList.append(billboardInfoData)
     billboardInfo.BillboardCount = len(billboardInfo.CrossBillboardDataList)
     NetPackCommon.SendFakePack(curPlayer, billboardInfo)
@@ -454,9 +488,16 @@
     name2 = 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", "")
     
     billboardMgr = PyDataManager.GetCrossBillboardManager()
     billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
@@ -465,8 +506,11 @@
         if cmpValue == billboardData.CmpValue and cmpValue2 == billboardData.CmpValue2 \
             and (not cmpValue3 or cmpValue3 == billboardData.CmpValue3) \
             and value1 == billboardData.Value1 and value2 == billboardData.Value2 \
+            and value3 == billboardData.Value3 and value4 == billboardData.Value4 \
+            and value5 == billboardData.Value1 and value6 == billboardData.Value6 \
+            and value7 == billboardData.Value1 and value8 == billboardData.Value8 \
             and name1 == billboardData.Name1 and name2 == billboardData.Name2 \
-            and type2 == billboardData.Type2 and id2 == billboardData.ID2:
+            and type2 == billboardData.Type2 and id2 == billboardData.ID2 and userData == billboardData.UserData:
             GameWorld.DebugLog("    榜单值相同,不同步跨服服务器! ")
             return
         
@@ -499,16 +543,46 @@
     name2 = 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", "")
+    kwargs = {"value3":value3, "value4":value4, "value5":value5, "value6":value6, "value7":value7, "value8":value8, "userData":userData}
     
     UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2,
-                      cmpValue, cmpValue2, cmpValue3, groupValue2, id2)
+                      cmpValue, cmpValue2, cmpValue3, groupValue2, id2, **kwargs)
+    return
+
+def UpdCrossBillboardFamily(bType, groupValue1, familyBillInfo, cmpValue, cmpValue2=0, autoSort=True):
+    ## 更新跨服仙盟榜单
+    if not familyBillInfo:
+        return
+    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
+    
+    UpdCrossBillboard(bType, groupValue1, familyID, familyName, name2, type2, value1, value2, cmpValue, cmpValue2, 
+                      id2=id2, autoSort=autoSort, value3=value3, value4=value4, value5=value5)
     return
 
 def UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue,
-                      cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True, noSortAndSync=False):
+                      cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True, noSortAndSync=False,
+                      **kwargs):
     ''' 更新跨服排行榜
     @param billboardType: 排行榜索引类型,同个榜单类型可以有多个分组榜单数据,独立排序
     @param groupValue1: 榜单分组1
@@ -551,17 +625,16 @@
             if not billboardObj.AddBillboardData(billboardData):
                 return
             
+    cmpValueChange = isNewData or billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2 or billboardData.CmpValue3 != cmpValue3
     # 没设置值默认为时间time,先上榜的排前面
     if cmpValue3 == 0:
         # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
-        if isNewData or billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2:
+        if cmpValueChange:
             calcTime = GameWorld.ChangeTimeStrToNum("2090-01-01 00:00:00")
             cmpValue3 = max(0, calcTime - int(time.time())) # 比较值3如果没指定值则默认存当前更新的time
         else:
             cmpValue3 = billboardData.CmpValue3
             
-    cmpValueChange = billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2 or billboardData.CmpValue3 != cmpValue3
-    
     # 更新所有值
     billboardData.GroupValue1 = groupValue1
     billboardData.GroupValue2 = groupValue2
@@ -573,14 +646,21 @@
     billboardData.Type2 = type2
     billboardData.Value1 = value1
     billboardData.Value2 = value2
+    billboardData.Value3 = kwargs.get("value3", 0)
+    billboardData.Value4 = kwargs.get("value4", 0)
+    billboardData.Value5 = kwargs.get("value5", 0)
+    billboardData.Value6 = kwargs.get("value6", 0)
+    billboardData.Value7 = kwargs.get("value7", 0)
+    billboardData.Value8 = kwargs.get("value8", 0)
+    billboardData.UserData = kwargs.get("userData", "")    
+    billboardData.DataLen = len(billboardData.UserData)    
     billboardData.CmpValue = cmpValue
     billboardData.CmpValue2 = cmpValue2
     billboardData.CmpValue3 = 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" 
+    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), dataID)
-    
+                          type2, value1, value2, cmpValue, cmpValue2, cmpValue3, kwargs), dataID)
     if noSortAndSync:
         return True
     if autoSort and cmpValueChange:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
index 3295f48..0458197 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -23,6 +23,7 @@
 import IPY_GameServer
 import CrossRealmPlayer
 import PlayerCompensation
+import PlayerActBossTrial
 import CrossActionControl
 import CrossActAllRecharge
 import CrossFamilyFlagwar
@@ -167,6 +168,9 @@
             
         elif msgType == ShareDefine.ClientServerMsg_CrossYaomoBossHurtAward:
             CrossYaomoBoss.ClientServerMsg_CrossYaomoBossHurtAward(serverGroupID, msgData)
+            
+        elif msgType == ShareDefine.ClientServerMsg_BossTrialSubmit:
+            PlayerActBossTrial.ClientServerMsg_BossTrialSubmit(serverGroupID, msgData)
             
         # 需要发送到地图服务器处理的
         elif msgType in [ShareDefine.ClientServerMsg_Reborn, ShareDefine.ClientServerMsg_CollectNPC]:
@@ -355,6 +359,9 @@
         elif msgType == ShareDefine.CrossServerMsg_FamilyFlagwarOver:
             CrossFamilyFlagwar.CrossServerMsg_FamilyFlagwarOver(msgData)
             
+        elif msgType == ShareDefine.CrossServerMsg_CrossBossTrialFamilyAward:
+            PlayerActBossTrial.CrossServerMsg_CrossBossTrialFamilyAward(msgData)
+            
         elif msgType == ShareDefine.CrossServerMsg_ChampionshipState:
             CrossChampionship.CrossServerMsg_ChampionshipState(msgData)
             
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
index 1aee5ee..046d843 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
@@ -109,10 +109,11 @@
 def SendMapServerOperationActionState():
     # 地图启动成功时通知本日运行活动相关状态
     
+    CrossActionControl.SendMapServerCrossActionState()
+    
     if GameWorld.IsCrossServer():
         # 跨服不处理运营活动
         return
-    CrossActionControl.SendMapServerCrossActionState()
     
     isReload, OperationActionInfo = __GetOperationActionInfo()
     mapServerInfoDict = OperationActionInfo[OperationAction_MapServerInfo]
@@ -374,6 +375,13 @@
                 GameWorld.Log("        非法配置,未知活动类型,不处理! cfgID=%s,actNum=%s" % (cfgID, actNum))
                 continue
             
+            if hasattr(ipyData, "GetJoinStartTime") and hasattr(ipyData, "GetJoinEndTime"):
+                joinStartTimeStr = ipyData.GetJoinStartTime()
+                joinEndTimeStr = ipyData.GetJoinEndTime()
+            else:
+                joinStartTimeStr = ""
+                joinEndTimeStr = ""
+                
             if hasattr(ipyData, "GetStartTimeList") and hasattr(ipyData, "GetEndTimeList"):
                 startHMStrList = ipyData.GetStartTimeList()
                 endHMStrList = ipyData.GetEndTimeList()
@@ -390,6 +398,7 @@
                                  % (actName, cfgID, startHMStrList, endHMStrList))
                 continue
             
+            isDayRest = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
             resetType = 0 if not hasattr(ipyData, "GetResetType") else ipyData.GetResetType() # 重置类型,0-0点重置;1-5点重置
             if resetType == 1:
                 startDayDate = datetime.datetime.strptime("%s 05:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
@@ -497,6 +506,17 @@
             GameWorld.Log("        startList=%s" % (startList))
             GameWorld.Log("        end  List=%s" % (endList))
             
+            joinStartTimeList, joinEndTimeList = [], [] # 可指定活动可参与的时间点,不影响活动状态,只影响活动某些功能的参与时机,如上榜类
+            if joinStartTimeStr:
+                if isDayRest:
+                    joinStartTimeList.append(datetime.datetime.strptime("%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, joinStartTimeStr), ChConfig.TYPE_Time_Format))
+                    joinEndTimeList.append(datetime.datetime.strptime("%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, joinEndTimeStr), ChConfig.TYPE_Time_Format))
+                else:
+                    joinStartTimeList.append(datetime.datetime.strptime("%s %s:00" % (startDateStr, joinStartTimeStr), ChConfig.TYPE_Time_Format))
+                    joinEndTimeList.append(datetime.datetime.strptime("%s %s:00" % (endDateStr, joinEndTimeStr), ChConfig.TYPE_Time_Format))                    
+            GameWorld.Log("        joinStartTimeList=%s" % (joinStartTimeList))
+            GameWorld.Log("        joinEndTime  List=%s" % (joinEndTimeList))
+            
             for dtIndex, startDateTime in enumerate(startList):
                 endDateTime = endList[dtIndex]
                 # 广播 - 相对实际开始时间
@@ -542,9 +562,9 @@
             if actName in ShareDefine.MultiActNumOperationActNameList:
                 if actName not in operationTodayActionDict:
                     operationTodayActionDict[actName] = {} # 今日有需要处理的才初始化
-                operationTodayActionDict[actName][actNum] = [ipyData, startList, endList, notifyDict]
+                operationTodayActionDict[actName][actNum] = [ipyData, startList, endList, notifyDict, joinStartTimeList, joinEndTimeList]
             else:
-                operationTodayActionDict[actName] = [ipyData, startList, endList, notifyDict]
+                operationTodayActionDict[actName] = [ipyData, startList, endList, notifyDict, joinStartTimeList, joinEndTimeList]
                 
             if isActTime:
                 activityInfoDict = {ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ActNum:actNum}
@@ -558,7 +578,6 @@
                     
                 dayIndex = (curDateTime - startDayDate).days
                 actIDDateTime = startDayDate
-                isDayRest = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
                 # 按时段开的默认每天重置
                 if isDayRest or (startHMStrList and endHMStrList):
                     actIDDateTime += datetime.timedelta(days=dayIndex)
@@ -722,6 +741,7 @@
         for sendMapServerMsgDict in curActMapInfoDictList:
             
             state = 0 # 默认关闭
+            stateJoin = 0 # 可参与状态
             ipyData = None
             
             actNum = sendMapServerMsgDict.get(ShareDefine.ActKey_ActNum, 0)
@@ -734,12 +754,12 @@
                 else:
                     todayActInfoList = operationTodayActionDict[actName]
                     
-                if isinstance(todayActInfoList, list) and len(todayActInfoList) == 4:
+                if isinstance(todayActInfoList, list) and len(todayActInfoList) == 6:
                     #startList = [] # [startDateTime, ...]
                     #endList = [] # [endDateTime, ...]
                     #notifyDict = {} # {notifyDateTime:[notifyKey, [参数]], ...}
                     #ipyData 可能为 None
-                    ipyData, startList, endList, notifyDict = todayActInfoList
+                    ipyData, startList, endList, notifyDict, joinStartTimeList, joinEndTimeList = todayActInfoList
                     
                     # 状态
                     for dIndex, startDateTime in enumerate(startList):
@@ -747,6 +767,15 @@
                         if startDateTime <= curDateTime < endDateTime:
                             state = dIndex + 1 # 代表第几个时间段
                             break
+                        
+                    if joinStartTimeList:
+                        for jIndex, joinStartDateTime in enumerate(joinStartTimeList):
+                            endJoinDateTime = joinEndTimeList[jIndex]
+                            if joinStartDateTime <= curDateTime < endJoinDateTime:
+                                stateJoin = state
+                                break
+                    else:
+                        stateJoin = state
                         
                     # 全服广播提示信息
                     if curDateTime in notifyDict:
@@ -757,12 +786,19 @@
             if actName in ShareDefine.MultiActNumOperationActNameList:
                 dictName += "_%s" % actNum
             preState = gameWorld.GetDictByKey(dictName)
-            if not isReload and preState == state:
+            
+            dictNameJoin = ChConfig.Def_WorldKey_OperationActionStateJoin % actName
+            if actName in ShareDefine.MultiActNumOperationActNameList:
+                dictNameJoin += "_%s" % actNum
+            preStateJoin = gameWorld.GetDictByKey(dictNameJoin)
+            
+            if not isReload and preState == state and preStateJoin == stateJoin:
                 #已经是这个状态了
                 continue
-            GameWorld.Log("运营活动变更: actName=%s,actNum=%s,preState=%s,state=%s,dictName=%s" % (actName, actNum, preState, state, dictName))
+            GameWorld.Log("运营活动变更: actName=%s,actNum=%s,preState=%s,state=%s,preStateJoin=%s,stateJoin=%s" % (actName, actNum, preState, state, preStateJoin, stateJoin))
             #更新字典值
             gameWorld.SetDict(dictName, state)
+            gameWorld.SetDict(dictNameJoin, stateJoin)
             
             dbOperationActIDKey = PlayerDBGSEvent.Def_OperationActID % actName
             dbOperationActWorldLVKey = PlayerDBGSEvent.Def_OActWorldLV % actName
@@ -859,6 +895,7 @@
             #GameWorld.SendMapServerMsgEx(dictName, state) # 运营活动不单独通知活动状态,需与活动信息整合后一起通知
             
             sendMapServerMsgDict[ShareDefine.ActKey_State] = state
+            sendMapServerMsgDict[ShareDefine.ActKey_StateJoin] = stateJoin
             GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_OperationActionInfo % actName, sendMapServerMsgDict)
             
             GameWorld.Log("    sendMapServerMsgDict: %s" % (sendMapServerMsgDict))
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
index 9d78eee..d0be780 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -1257,7 +1257,7 @@
 def InitGameWorld(tick):
     #标记GameWorld初始化完成
     GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_IsGameWorldInit, int(time.time()))
-    PlayerControl.LoadDBPlayer()
+    LoadDBPlayer()
     #初始化游戏时钟
     GameWorld.GetGameWorld().SetTickTypeCount(ChConfig.TYPE_Tick_Count)
     #初始话开服时间、星期几
@@ -1273,8 +1273,8 @@
     GameWorld.GetGameWorld().GetDBGoldOrderFormMgr().Sort()
     #排序排行榜
     PlayerBillboard.SortServerBillboard()
-    #排序仙盟
-    PlayerFamily.DoFamilySort()
+    #仙盟
+    PlayerFamily.OnGameServerInitOK()
     GameWorldActionControl.Dispose_FBStateTime()
     #仙盟联赛
     GameWorldFamilyWar.OnGameServerInitOK()
@@ -1329,6 +1329,20 @@
         GameWorld.SendGameError("GameWarning", "InitGameWorld later than AllMapServerInitOK")
         AllMapServerInitOK(tick)
         
+    return
+
+def LoadDBPlayer():
+    if GameWorld.IsCrossServer():
+        return
+    PlayerDBOper.FindDBOper(PlayerDBOper.Table_DBPlayer, {}, {"PlayerID":1, "AccID":1, "_id":0}, LoadDBPlayerRet)
+    return
+
+def LoadDBPlayerRet(resultSetList, extendValueList):
+    for resultDict in resultSetList:
+        PyGameData.g_dbPlayerIDMap[resultDict["PlayerID"]] = resultDict["AccID"]
+    GameWorld.Log("启动服务器加载DBPlayer玩家账号ID对应关系! %s, %s" % (len(PyGameData.g_dbPlayerIDMap), PyGameData.g_dbPlayerIDMap))
+    
+    PlayerFamily.OnLoadDBPlayerOK()
     return
 
 def DoCheckNewServerOpen(tick):
@@ -1546,14 +1560,8 @@
     # 删除过期的通用数据
     __DelOutofdayRecData(universalRecMgr)
     
-    # 仙盟联赛重置
-    GameWorldFamilyWar.DoFamilyWarReset()
-    # 重置所有仙盟联赛评级
-    familyManager = GameWorld.GetFamilyManager()
-    for i in xrange(familyManager.GetCount()):
-        family = familyManager.GetAt(i)
-        PlayerFamily.SetFamilyWarRank(family, 0)
-    PlayerFamily.DoFamilySort()
+    # 仙盟
+    PlayerFamily.OnMixServerInit()
     
     # 设置合服首次启动加载成功
     PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServerInitOK, 1)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
index b400296..965a101 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -457,19 +457,41 @@
                         ("BYTE", "ActNum", 0),
                         ("char", "StartDate", 0),
                         ("char", "EndDate", 0),
+                        ("char", "JoinStartTime", 0),
+                        ("char", "JoinEndTime", 0),
                         ("dict", "NotifyInfoStart", 0),
                         ("dict", "NotifyInfoEnd", 0),
                         ("list", "NotifyInfoLoop", 0),
                         ("BYTE", "IsDayReset", 0),
                         ("BYTE", "ResetType", 0),
                         ("list", "TemplateIDList", 0),
-                        ("char", "MailKey", 0),
+                        ("list", "FamilyTemplateIDList", 0),
                         ),
 
                 "ActBossTrialTemplate":(
                         ("DWORD", "TemplateID", 1),
                         ("BYTE", "Rank", 0),
                         ("list", "AwardItemList", 0),
+                        ("list", "MemAwardItemList", 0),
+                        ),
+
+                "CrossActBossTrial":(
+                        ("DWORD", "CfgID", 1),
+                        ("char", "ActGroupName", 0),
+                        ("BYTE", "ZoneID", 0),
+                        ("list", "ServerIDRangeList", 0),
+                        ("char", "StartDate", 0),
+                        ("char", "EndDate", 0),
+                        ("char", "JoinStartTime", 0),
+                        ("char", "JoinEndTime", 0),
+                        ("dict", "NotifyInfoStart", 0),
+                        ("dict", "NotifyInfoEnd", 0),
+                        ("list", "NotifyInfoLoop", 0),
+                        ("BYTE", "IsDayReset", 0),
+                        ("BYTE", "ResetType", 0),
+                        ("list", "RankLimitList", 0),
+                        ("WORD", "PersonalTemplateID", 0),
+                        ("WORD", "FamilyTemplateID", 0),
                         ),
 
                 "ActXianXiaMJ":(
@@ -1638,13 +1660,15 @@
     def GetActNum(self): return self.attrTuple[3] # 活动分组编号, 活动类型 * 10 + 不同界面编号 BYTE
     def GetStartDate(self): return self.attrTuple[4] # 开启日期 char
     def GetEndDate(self): return self.attrTuple[5] # 结束日期 char
-    def GetNotifyInfoStart(self): return self.attrTuple[6] # 全服提示信息 - 相对开始时间 dict
-    def GetNotifyInfoEnd(self): return self.attrTuple[7] # 全服提示信息 - 相对结束时间 dict
-    def GetNotifyInfoLoop(self): return self.attrTuple[8] # 全服提示信息 - 循环广播[间隔分钟, 广播key] list
-    def GetIsDayReset(self): return self.attrTuple[9] # 是否每天重置 BYTE
-    def GetResetType(self): return self.attrTuple[10] # 重置类型,0-0点重置;1-5点重置 BYTE
-    def GetTemplateIDList(self): return self.attrTuple[11] # 榜单模板编号列表 list
-    def GetMailKey(self): return self.attrTuple[12] # 奖励邮件模板 char
+    def GetJoinStartTime(self): return self.attrTuple[6] # 参与开始时间点 char
+    def GetJoinEndTime(self): return self.attrTuple[7] # 参与结束时间点 char
+    def GetNotifyInfoStart(self): return self.attrTuple[8] # 全服提示信息 - 相对开始时间 dict
+    def GetNotifyInfoEnd(self): return self.attrTuple[9] # 全服提示信息 - 相对结束时间 dict
+    def GetNotifyInfoLoop(self): return self.attrTuple[10] # 全服提示信息 - 循环广播[间隔分钟, 广播key] list
+    def GetIsDayReset(self): return self.attrTuple[11] # 是否每天重置 BYTE
+    def GetResetType(self): return self.attrTuple[12] # 重置类型,0-0点重置;1-5点重置 BYTE
+    def GetTemplateIDList(self): return self.attrTuple[13] # 榜单模板编号列表 list
+    def GetFamilyTemplateIDList(self): return self.attrTuple[14] # 仙盟榜单模板编号列表 list
 
 # Boss历练榜单模版表
 class IPY_ActBossTrialTemplate():
@@ -1655,7 +1679,32 @@
         
     def GetTemplateID(self): return self.attrTuple[0] # 模板编号 DWORD
     def GetRank(self): return self.attrTuple[1] # 名次 BYTE
-    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品信息列表 [[物品ID,个数,是否拍品], ...] list
+    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] 仙盟榜时为盟主奖励,如果没有配置,则统一取成员奖励 list
+    def GetMemAwardItemList(self): return self.attrTuple[3] # 仙盟榜成员奖励物品信息列表[[物品ID,个数,是否拍品], ...] list
+
+# Boss历练跨服活动表
+class IPY_CrossActBossTrial():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetCfgID(self): return self.attrTuple[0] # 配置ID DWORD
+    def GetActGroupName(self): return self.attrTuple[1] # 活动组名(同组活动的名字需相同) char
+    def GetZoneID(self): return self.attrTuple[2] # 组内分组编号 BYTE
+    def GetServerIDRangeList(self): return self.attrTuple[3] # 活动的账号服务器ID范围列表 [[serverIDA, serverIDB], ...] list
+    def GetStartDate(self): return self.attrTuple[4] # 开启日期 char
+    def GetEndDate(self): return self.attrTuple[5] # 结束日期 char
+    def GetJoinStartTime(self): return self.attrTuple[6] # 参与开始时间点 char
+    def GetJoinEndTime(self): return self.attrTuple[7] # 参与结束时间点 char
+    def GetNotifyInfoStart(self): return self.attrTuple[8] # 全服提示信息 - 相对开始时间 dict
+    def GetNotifyInfoEnd(self): return self.attrTuple[9] # 全服提示信息 - 相对结束时间 dict
+    def GetNotifyInfoLoop(self): return self.attrTuple[10] # 全服提示信息 - 循环广播[循环分钟, 广播key, [广播参数列表可选]] list
+    def GetIsDayReset(self): return self.attrTuple[11] # 是否每天重置 BYTE
+    def GetResetType(self): return self.attrTuple[12] # 重置类型,0-0点重置;1-5点重置 BYTE
+    def GetRankLimitList(self): return self.attrTuple[13] # 上榜个数限制 个人|仙盟 list
+    def GetPersonalTemplateID(self): return self.attrTuple[14] # 个人排行模板编号 WORD
+    def GetFamilyTemplateID(self): return self.attrTuple[15] # 仙盟排行模板编号 WORD
 
 # 仙匣秘境活动时间表
 class IPY_ActXianXiaMJ():
@@ -2529,6 +2578,7 @@
         self.__LoadFileData("ActGarbageSorting", onlyCheck)
         self.__LoadFileData("ActBossTrial", onlyCheck)
         self.__LoadFileData("ActBossTrialTemplate", onlyCheck)
+        self.__LoadFileData("CrossActBossTrial", onlyCheck)
         self.__LoadFileData("ActXianXiaMJ", onlyCheck)
         self.__LoadFileData("ActGodGift", onlyCheck)
         self.__LoadFileData("ActHorsePetFeast", onlyCheck)
@@ -3084,6 +3134,13 @@
         self.CheckLoadData("ActBossTrialTemplate")
         return self.ipyActBossTrialTemplateCache[index]
 
+    def GetCrossActBossTrialCount(self):
+        self.CheckLoadData("CrossActBossTrial")
+        return self.ipyCrossActBossTrialLen
+    def GetCrossActBossTrialByIndex(self, index):
+        self.CheckLoadData("CrossActBossTrial")
+        return self.ipyCrossActBossTrialCache[index]
+
     def GetActXianXiaMJCount(self):
         self.CheckLoadData("ActXianXiaMJ")
         return self.ipyActXianXiaMJLen
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py
index cd21cb0..b97f0b2 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py
@@ -21,27 +21,41 @@
 import PlayerBillboard
 import IpyGameDataPY
 import GameWorld
-
-BillboardType = ShareDefine.Def_BT_BossTrialSubmit
+import CrossRealmMsg
+import CrossActionControl
+import CrossBillboard
+import PlayerFamily
+import PyDataManager
 
 def OnActStart(actNum):
     ## 活动开启
-    PlayerBillboard.ClearBillboardByIndex(BillboardType)
+    PlayerBillboard.ClearBillboardByIndex(ShareDefine.Def_BT_BossTrialSubmit)
+    PlayerBillboard.ClearBillboardByIndex(ShareDefine.Def_BT_BossTrialSubmitFamily)
+    
+    familyActionMgr = GameWorld.GetFamilyActionManager()
+    familyManager = GameWorld.GetFamilyManager()
+    for i in range(0, familyManager.GetCount()):
+        family = familyManager.GetAt(i)
+        familyID = family.GetID()
+        familyActionMgr.DelFamilyAction(familyID, ShareDefine.Def_ActionType_BossTrialSubmit)
+        
     return
 
 def OnActEnd(actNum, ipyData, dayIndex):
     ## 活动结束
+    OnGiveFamilyOrderAwawrd(actNum, ipyData, dayIndex)
     cfgID = ipyData.GetCfgID() if ipyData else 0
     # 发放排行奖励
-    GameWorld.Log("=== boss历练活动结束!发放榜单奖励! === actNum=%s,cfgID=%s,dayIndex=%s" % (actNum, cfgID, dayIndex))
+    GameWorld.Log("=== boss历练活动结束!发放本服个人榜单奖励! === actNum=%s,cfgID=%s,dayIndex=%s" % (actNum, cfgID, dayIndex))
     if not cfgID:
         return
+    BillboardType = ShareDefine.Def_BT_BossTrialSubmit
     billBoard = GameWorld.GetBillboard().FindBillboard(BillboardType)
     if not billBoard:
         return
-    mailKey = ipyData.GetMailKey()
     templateID = GameWorld.GetTemplateID(ipyData, cfgID, dayIndex)
     if not templateID:
+        GameWorld.Log("本次活动没有个人榜奖励!")
         return
     tempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
     if not tempIpyDataList:
@@ -68,13 +82,457 @@
         name2 = billBoardData.GetName2()
         cmpValue = billBoardData.GetCmpValue()
         
-        GameWorld.Log("    发放boss历练榜单奖励: rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s, %s" 
+        GameWorld.Log("    发放boss历练个人榜单奖励: rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s, %s" 
                       % (rank, playerID, cmpValue, awardItemList, name2))
         
-        PlayerCompensation.SendMailByKey(mailKey, [playerID], awardItemList, [rank])
+        PlayerCompensation.SendMailByKey("BossTrialMail10", [playerID], awardItemList, [rank])
         
     DataRecordPack.DR_BillboardData(BillboardType, "BossTrial", {"actNum":actNum, "cfgID":cfgID, "dayIndex":dayIndex, "templateID":templateID})
     PlayerBillboard.CopyBillboard(ShareDefine.Def_BT_BossTrialSubmitBak, BillboardType)
     PlayerBillboard.ClearBillboardByIndex(BillboardType)
     GameWorld.Log("=================================================================================")
     return
+
+def OnGiveFamilyOrderAwawrd(actNum, ipyData, dayIndex):
+    cfgID = ipyData.GetCfgID() if ipyData else 0
+    # 发放排行奖励
+    GameWorld.Log("=== boss历练活动结束!发放本服仙盟榜单奖励! === actNum=%s,cfgID=%s,dayIndex=%s" % (actNum, cfgID, dayIndex))
+    if not cfgID:
+        return
+    BillboardType = ShareDefine.Def_BT_BossTrialSubmitFamily
+    billBoard = GameWorld.GetBillboard().FindBillboard(BillboardType)
+    if not billBoard:
+        return
+    templateIDList = ipyData.GetFamilyTemplateIDList()
+    templateID = templateIDList[-1] if dayIndex >= len(templateIDList) else templateIDList[dayIndex]
+    if not templateID:
+        GameWorld.Log("本次活动没有仙盟榜奖励!")
+        return
+    tempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
+    if not tempIpyDataList:
+        return
+    
+    rankAwardDict = {}
+    for tempIpyData in tempIpyDataList:
+        rankAwardDict[tempIpyData.GetRank()] = [tempIpyData.GetAwardItemList(), tempIpyData.GetMemAwardItemList()]
+        
+    GameWorld.Log("    templateID=%s,rankAwardDict=%s" % (templateID, rankAwardDict))
+    billBoard.Sort()
+    
+    familyManager = GameWorld.GetFamilyManager()
+    for index in xrange(billBoard.GetCount()):
+        billBoardData = billBoard.At(index)
+        if not billBoardData:
+            continue
+        
+        familyRank = index + 1
+        awardInfo = GameWorld.GetOrderValueByDict(rankAwardDict, familyRank, False)
+        if not awardInfo:
+            break
+        leaderAwardItemList, memAwardItemList = awardInfo
+                
+        familyID = billBoardData.GetID()
+        cmpValue = billBoardData.GetCmpValue()
+        
+        family = familyManager.FindFamily(familyID)
+        if not family:
+            continue
+        
+        familyActionData = GetFamilyBossTrialSubmitActionData(familyID, False)
+        if not familyActionData:
+            continue
+        awardState = GetFamilyAwardState(familyActionData)
+        awardIndex = 0 # 本服奖励状态索引
+        if awardState&pow(2, awardIndex):
+            GameWorld.ErrLog("该仙盟本服榜奖励已发放! familyID=%s" % familyID)
+            continue
+        updAwardState = awardState|pow(2, awardIndex)
+        SetFamilyAwardState(familyActionData, updAwardState)
+        
+        memSubCountDict = GetFamilyMemSubCountDict(familyActionData)
+        
+        leaderID = family.GetLeaderID()
+        awardMemIDList = []
+        for index in xrange(family.GetCount()):
+            member = family.GetAt(index)
+            memPlayerID = member.GetPlayerID()
+            if memPlayerID == leaderID:
+                continue
+            awardMemIDList.append(memPlayerID)
+            
+        paramList = [familyRank]
+        if not leaderAwardItemList:
+            awardMemIDList.append(leaderID)
+        else:
+            PlayerCompensation.SendMailByKey("BossTrialFamilyLeader", [leaderID], leaderAwardItemList, paramList)
+            
+        PlayerCompensation.SendMailByKey("BossTrialFamilyMember", awardMemIDList, memAwardItemList, paramList)
+        GameWorld.Log("发放boss历练活动仙盟榜单奖励本服: familyID=%s,名次=%s,总提交个数=%s,updAwardState=%s,awardMemIDList=%s,memSubCountDict=%s" 
+                      % (familyID, familyRank, cmpValue, updAwardState, awardMemIDList, memSubCountDict))
+        
+    DataRecordPack.DR_BillboardData(BillboardType, "BossTrial", {"actNum":actNum, "cfgID":cfgID, "dayIndex":dayIndex, "templateID":templateID})
+    PlayerBillboard.CopyBillboard(ShareDefine.Def_BT_BossTrialSubmitFamilyBak, BillboardType)
+    PlayerBillboard.ClearBillboardByIndex(BillboardType)
+    GameWorld.Log("=================================================================================")
+    return
+
+def MapServer_BossTrial(curPlayer, msgList):
+    mapID = curPlayer.GetRealMapID()
+    playerID = curPlayer.GetPlayerID()
+    GameWorld.DebugLog("MapServer_BossTrial mapID=%s,msgList=%s" % (mapID, msgList), playerID)
+    if not msgList:
+        return
+    
+    msgType, dataMsg = msgList
+    ret = None
+    
+    if msgType == "BossTrialSubmit":
+        ret = __OnBossTrialSubmit(curPlayer, dataMsg)
+        
+    if ret == None:
+        return
+    return msgList + (ret if isinstance(ret, list) else [ret])
+
+def __OnBossTrialSubmit(curPlayer, dataMsg):
+    ## 地图提交boss凭证
+    playerID = curPlayer.GetPlayerID()
+    accID = curPlayer.GetAccID()
+    playerName = curPlayer.GetName()
+    job = curPlayer.GetJob()
+    realmLV = curPlayer.GetOfficialRank()
+    familyID = curPlayer.GetFamilyID()
+    submitCount, updSubmitCount = dataMsg
+    
+    curFamily, familySubmitTotal = __DoBossTrialSubmitFamilyAction(curPlayer, submitCount)
+    familyBillInfo = {}
+    
+    #更新本服仙盟提交榜单
+    if familyID and curFamily and familySubmitTotal:
+        familyBillInfo = PlayerFamily.GetFamilyBillboardInfo(curFamily)
+        familyBillInfo["familySubmitTotal"] = familySubmitTotal
+        PlayerBillboard.UpdateFamilyBillboard(ShareDefine.Def_BT_BossTrialSubmitFamily, familyBillInfo, familySubmitTotal)
+        
+    #同步跨服
+    playerInfo = {"playerID":playerID, "playerName":playerName, "accID":accID, "job":job, "realmLV":realmLV,
+                  "playerSubmitTotal":updSubmitCount}
+    SyncBossTrialSubmitToCrossServer(curPlayer, playerInfo, familyBillInfo)
+    return
+
+def __DoBossTrialSubmitFamilyAction(curPlayer, submitCount):
+    ## 执行提交凭证到仙盟Action数据
+    
+    curFamily = None
+    familySubmitTotal = 0
+    playerID = curPlayer.GetPlayerID()
+    familyID = curPlayer.GetFamilyID()
+    if not familyID:
+        return curFamily, familySubmitTotal
+    
+    familyManager = GameWorld.GetFamilyManager()
+    curFamily = familyManager.FindFamily(familyID)
+    if not curFamily:
+        return curFamily, familySubmitTotal
+    
+    familyActionData = GetFamilyBossTrialSubmitActionData(familyID, True)
+    
+    familySubmitTotal = GetFamilySubmitTotal(familyActionData) + submitCount
+    SetFamilySubmitTotal(familyActionData, familySubmitTotal)
+    
+    memSubCountDict = GetFamilyMemSubCountDict(familyActionData)
+    memSubCountDict[playerID] = memSubCountDict.get(playerID, 0) + submitCount
+    SetFamilyMemSubCountDict(familyActionData, memSubCountDict)
+    
+    return curFamily, familySubmitTotal
+
+def GetFamilyBossTrialSubmitActionData(familyID, isAdd=False):
+    ## 获取仙盟boss凭证提交
+    familyActionObj = None
+    actionType = ShareDefine.Def_ActionType_BossTrialSubmit
+    familyAction = GameWorld.GetFamilyActionManager().GetFamilyAction(familyID, actionType)
+    if not familyAction.Count():
+        if isAdd:
+            familyActionObj = familyAction.AddAction()
+            familyActionObj.SetFamilyId(familyID)
+            familyActionObj.SetActionType(actionType)
+    else:
+        familyActionObj = familyAction.At(0)
+        
+    return familyActionObj
+
+def GetFamilySubmitTotalByID(familyID):
+    ## 获取仙盟提交的凭证总数
+    familyActionData = GetFamilyBossTrialSubmitActionData(familyID, False)
+    if not familyActionData:
+        return 0
+    return GetFamilySubmitTotal(familyActionData)
+
+def GetFamilySubmitTotal(familyActionData): return familyActionData.GetValue1()
+def SetFamilySubmitTotal(familyActionData, submitTotal): familyActionData.SetValue1(submitTotal)
+def GetFamilyAwardState(familyActionData): return familyActionData.GetValue2()
+def SetFamilyAwardState(familyActionData, state): return familyActionData.SetValue2(state)
+
+def GetFamilyMemSubCountDict(familyActionData):
+    memSubCountDict = {}
+    useData = familyActionData.GetUseData()
+    if useData:
+        try:
+            memSubCountDict = eval(useData)
+        except:
+            memSubCountDict = {}
+    return memSubCountDict
+def SetFamilyMemSubCountDict(familyActionData, memSubCountDict):
+    useData = str(memSubCountDict).replace(" ", "")
+    familyActionData.SetUseData(useData, len(useData))
+    return
+
+def SyncBossTrialSubmitToCrossServer(curPlayer, playerInfo, familyInfo):
+    ## 同步boss凭证提交总数到跨服服务器
+    actInfo = CrossActionControl.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_BossTrial)
+    if not actInfo.get(ShareDefine.ActKey_State):
+        return
+    cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
+    ipyDataDict = actInfo.get(ShareDefine.ActKey_IpyDataInfo, {})
+    if not ipyDataDict:
+        return
+    zoneID = ipyDataDict.get("ZoneID")
+    if not cfgID or not zoneID:
+        return
+    
+    dataMsg = {"cfgID":cfgID, "zoneID":zoneID, "playerInfo":playerInfo, "familyInfo":familyInfo}
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BossTrialSubmit, dataMsg)
+    return
+
+def CrossServerMsg_CrossBossTrialFamilyAward(msgData):
+    ## 收到跨服通知  - 结算跨服仙盟榜奖励
+    cfgID = msgData["cfgID"]
+    zoneID = msgData["zoneID"]
+    templateID = msgData["templateID"]
+    awardFamilyList = msgData["awardFamilyList"]
+    
+    GameWorld.Log("收到跨服同步的结算boss历练活动跨服仙盟榜奖励: cfgID=%s,zoneID=%s,templateID=%s" % (cfgID, zoneID, templateID))
+    
+    familyManager = GameWorld.GetFamilyManager()
+    
+    for familyInfo in awardFamilyList:
+        familyID, familyRank, familySubmitTotal, leaderAwardItemList, memAwardItemList = familyInfo
+        family = familyManager.FindFamily(familyID)
+        if not family:
+            GameWorld.DebugLog("非本服仙盟或已解散! familyID=%s" % familyID)
+            continue
+        
+        familyActionData = GetFamilyBossTrialSubmitActionData(familyID, False)
+        if not familyActionData:
+            continue
+        awardState = GetFamilyAwardState(familyActionData)
+        awardIndex = 1 #跨服奖励状态索引
+        if awardState&pow(2, awardIndex):
+            GameWorld.ErrLog("该仙盟跨服榜奖励已发放! familyID=%s" % familyID)
+            continue
+        updAwardState = awardState|pow(2, awardIndex)
+        SetFamilyAwardState(familyActionData, updAwardState)
+        
+        memSubCountDict = GetFamilyMemSubCountDict(familyActionData)
+        
+        leaderID = family.GetLeaderID()
+        awardMemIDList = []
+        for index in xrange(family.GetCount()):
+            member = family.GetAt(index)
+            memPlayerID = member.GetPlayerID()
+            if memPlayerID == leaderID:
+                continue
+            awardMemIDList.append(memPlayerID)
+            
+        paramList = [familyRank]
+        if not leaderAwardItemList:
+            awardMemIDList.append(leaderID)
+        else:
+            PlayerCompensation.SendMailByKey("BossTrialCrossFamilyLeader", [leaderID], leaderAwardItemList, paramList)
+            
+        PlayerCompensation.SendMailByKey("BossTrialCrossFamilyMember", awardMemIDList, memAwardItemList, paramList)
+        GameWorld.Log("发放boss历练活动仙盟榜单奖励跨服: familyID=%s,名次=%s,总提交个数=%s,updAwardState=%s,awardMemIDList=%s,memSubCountDict=%s" 
+                      % (familyID, familyRank, familySubmitTotal, updAwardState, awardMemIDList, memSubCountDict))
+        
+    return
+
+##------------------------------------------ 跨服boss历练活动 ---------------------------------------
+
+def ClientServerMsg_BossTrialSubmit(serverGroupID, msgData):
+    ## 收到子服 - 提交boss凭证
+    
+    cfgID = msgData["cfgID"]
+    zoneID = msgData["zoneID"]
+    playerInfo = msgData["playerInfo"]
+    familyInfo = msgData["familyInfo"]
+    
+    actInfo = CrossActionControl.GetCrossActInfoByCfgID(ShareDefine.CrossActName_BossTrial, cfgID, zoneID)
+    if not actInfo or not actInfo[ShareDefine.ActKey_State]:
+        GameWorld.ErrLog("跨服boss历练非活动中,无法提交! cfgID=%s, zoneID=%s" % (cfgID, zoneID))
+        return
+    if not actInfo[ShareDefine.ActKey_StateJoin]:
+        GameWorld.ErrLog("跨服boss历练非可参与状态,无法提交! cfgID=%s, zoneID=%s" % (cfgID, zoneID))
+        return
+    ipyData = IpyGameDataPY.GetIpyGameData("CrossActBossTrial", cfgID)
+    if not ipyData:
+        return
+    personlLimit, familyLimit = ipyData.GetRankLimitList()
+    
+    playerID = playerInfo["playerID"]
+    playerName = playerInfo["playerName"]
+    job = playerInfo["job"]
+    accID = playerInfo["accID"]
+    realmLV = playerInfo["realmLV"]
+    playerSubmitTotal = playerInfo["playerSubmitTotal"]
+    
+    groupValue1 = zoneID
+    
+    if playerSubmitTotal >= personlLimit:
+        name2, type2, value1, value2 = accID, job, realmLV, 0
+        CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BossTrialSubmit, groupValue1, playerID, playerName, 
+                                         name2, type2, value1, value2, playerSubmitTotal)
+        
+    if familyInfo and familyInfo.get("familySubmitTotal", 0) >= familyLimit:
+        familySubmitTotal = familyInfo["familySubmitTotal"]
+        CrossBillboard.UpdCrossBillboardFamily(ShareDefine.Def_CBT_BossTrialSubmitFamily, groupValue1, familyInfo, familySubmitTotal)
+        
+    return
+
+def OnCrossActIDChange(cfgID, state):
+    ## 活动ID变更
+    
+    # 先结算活动
+    zoneID = 0
+    ipyData = IpyGameDataPY.GetIpyGameData("CrossActBossTrial", cfgID)
+    if ipyData:
+        zoneID = ipyData.GetZoneID()
+        
+        PersonalTemplateID = ipyData.GetPersonalTemplateID()
+        FamilyTemplateID = ipyData.GetFamilyTemplateID()
+        
+        if PersonalTemplateID:
+            __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID)
+            
+        if FamilyTemplateID:
+            __GiveCrossOrderAwardFamily(cfgID, zoneID, FamilyTemplateID)
+            
+    # 如果有新活动,处理新活动
+    if not state:
+        return
+    
+    if zoneID:
+        groupValue1 = zoneID
+        billboardMgr = PyDataManager.GetCrossBillboardManager()
+        billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_BossTrialSubmit, groupValue1)
+        billboardObj.ClearData() # 新活动重置榜单数据
+        
+        billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_BossTrialSubmitFamily, groupValue1)
+        billboardObj.ClearData() # 新活动重置榜单数据
+        
+    return
+    
+def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID):
+    
+    groupValue1 = zoneID
+    billboardType = ShareDefine.Def_CBT_BossTrialSubmit
+    billboardMgr = PyDataManager.GetCrossBillboardManager()
+    billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1)
+    billboardDataCount = billboardObj.GetCount()
+    if not billboardDataCount:
+        GameWorld.Log("跨服Boss凭证个人排行数据为空! billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s" % (billboardType, cfgID, zoneID, templateID))
+        return
+    
+    # 结算时排序并保存榜单数据流向
+    billboardObj.SortData()
+    
+    GameWorld.Log("结算跨服Boss凭证个人排行奖励: billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s,billboardDataCount=%s" 
+                  % (billboardType, cfgID, zoneID, templateID, billboardDataCount))
+    
+    orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
+    if not orderIpyDataList:
+        return
+    
+    rankPre = 0
+    billboardIndex = 0
+    for ipyData in orderIpyDataList:
+        rank = ipyData.GetRank()
+        awardItemList = ipyData.GetAwardItemList()
+        orderCountTotal = rank - rankPre # 奖励名次数量
+        rankPre = rank
+        orderCount = 0
+        
+        for index in xrange(billboardIndex, billboardDataCount):
+            if orderCount >= orderCountTotal:
+                break
+            
+            billboardData = billboardObj.At(index)
+            playerID = billboardData.ID
+            name2 = billboardData.Name2
+            cmpValue = billboardData.CmpValue
+            
+            playerRank = index + 1
+            GameWorld.Log("    发放boss历练个人榜单奖励: rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s, %s" 
+                          % (rank, playerID, cmpValue, awardItemList, name2))
+            PlayerCompensation.SendMailByKey("BossTrialCrossPlayer", [playerID], awardItemList, [playerRank], crossMail=True)
+            
+            orderCount += 1
+            billboardIndex += 1
+            
+    # 结算完备份、清除榜单数据
+    CrossBillboard.CopyBillboard(billboardType, ShareDefine.Def_CBT_BossTrialSubmitBak)
+    billboardObj.ClearData()
+    return
+
+def __GiveCrossOrderAwardFamily(cfgID, zoneID, templateID):
+    
+    groupValue1 = zoneID
+    billboardType = ShareDefine.Def_CBT_BossTrialSubmitFamily
+    billboardMgr = PyDataManager.GetCrossBillboardManager()
+    billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1)
+    billboardDataCount = billboardObj.GetCount()
+    if not billboardDataCount:
+        GameWorld.Log("跨服Boss凭证仙盟排行数据为空! billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s" % (billboardType, cfgID, zoneID, templateID))
+        return
+    
+    # 结算时排序并保存榜单数据流向
+    billboardObj.SortData()
+    
+    GameWorld.Log("结算跨服Boss凭证仙盟排行奖励: billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s,billboardDataCount=%s" 
+                  % (billboardType, cfgID, zoneID, templateID, billboardDataCount))
+    
+    orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
+    if not orderIpyDataList:
+        return
+    
+    awardFamilyList = []
+    rankPre = 0
+    billboardIndex = 0
+    for ipyData in orderIpyDataList:
+        rank = ipyData.GetRank()
+        leaderAwardItemList = ipyData.GetAwardItemList()
+        memAwardItemList = ipyData.GetMemAwardItemList()
+        orderCountTotal = rank - rankPre # 奖励名次数量
+        rankPre = rank
+        orderCount = 0
+        
+        for index in xrange(billboardIndex, billboardDataCount):
+            if orderCount >= orderCountTotal:
+                break
+            
+            billboardData = billboardObj.At(index)
+            familyID = billboardData.ID
+            familySubmitTotal = billboardData.CmpValue
+            
+            familyRank = index + 1
+            GameWorld.Log("    familyID=%s,名次=%s,总提交个数=%s" % (familyID, familyRank, familySubmitTotal))
+            awardFamilyList.append([familyID, familyRank, familySubmitTotal, leaderAwardItemList, memAwardItemList])
+            orderCount += 1
+            billboardIndex += 1
+            
+    # 广播子服发放奖励
+    sendMsg = {"cfgID":cfgID, "zoneID":zoneID, "templateID":templateID, "awardFamilyList":awardFamilyList}
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossTrialFamilyAward, sendMsg)
+    
+    # 结算完备份、清除榜单数据
+    CrossBillboard.CopyBillboard(billboardType, ShareDefine.Def_CBT_BossTrialSubmitFamilyBak)
+    billboardObj.ClearData()
+    return
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerBillboard.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerBillboard.py
index 530252d..c28f355 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerBillboard.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerBillboard.py
@@ -138,9 +138,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)
@@ -157,9 +164,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))
 
@@ -430,9 +445,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)
         
@@ -455,13 +478,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:
@@ -482,7 +513,7 @@
         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)
+    UpdatePlayerBillboard(bID, bName, bName2, bType, bType2, value1, value2, cmpValue, autoSort, cmpValue2, cmpValue3, **kwargs)
     
     exInfo = billInfoDict["ExInfo"]
     # 以下为榜单附加特殊处理
@@ -503,7 +534,7 @@
         job = playerJob % 10
         if job in ShareDefine.JobFightPowerBillboardDict:
             jobBType = ShareDefine.JobFightPowerBillboardDict[job]
-            UpdatePlayerBillboard(bID, bName, bName2, jobBType, bType2, value1, value2, cmpValue, autoSort, cmpValue2)
+            UpdatePlayerBillboard(bID, bName, bName2, jobBType, bType2, value1, value2, cmpValue, autoSort, cmpValue2, **kwargs)
             
     return
 
@@ -528,6 +559,25 @@
     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):
     ## 更新玩家排行榜
@@ -608,8 +658,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)
     
@@ -618,47 +668,45 @@
         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)
-        if playerBillBoardData.GetType2() != billboardType:
-            playerBillBoardData.SetType2(billboardType)
-            GameWorld.DebugLog("    更新Type2=%s" % billboardType, curPlayerID)
-        return False
-    
-    # 没设置值默认为时间time,先上榜的排前面
-    if cmpValue3 == 0:
-        # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
-        if isNewData or playerBillBoardData.GetCmpValue() != cmpValue or playerBillBoardData.GetCmpValue2() != cmpValue2:
+    cmpValueChange = False
+    if isNewData or playerBillBoardData.GetCmpValue() != cmpValue or playerBillBoardData.GetCmpValue2() != cmpValue2 \
+        or playerBillBoardData.GetCmpValue3() != cmpValue3:
+        cmpValueChange = True
+        if cmpValue3 == 0:
+            # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
             calcTime = GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
             cmpValue3 = max(0, calcTime - int(time.time())) # 比较值3如果没指定值则默认存当前更新的time
-
+            
     #设置排行榜数据
     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,%s" 
+                       % (billboardIndex, type2, value1, value2, cmpValue, cmpValue2, cmpValue3, isNewData, 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)
     if not autoSort:
         #不自动排序
         GameWorld.GetGameWorld().SetDict(Def_Key_BillboardNeedSort % billboardIndex, 1) # 设置需要下次查看需要先排序
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
index dce2503..ce08d9f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
@@ -208,18 +208,6 @@
     return NotifyCodeList
 
 #------------------------------------------------------------------------------ 
-def LoadDBPlayer():
-    if GameWorld.IsCrossServer():
-        return
-    PlayerDBOper.FindDBOper(PlayerDBOper.Table_DBPlayer, {}, {"PlayerID":1, "AccID":1, "_id":0}, LoadDBPlayerRet)
-    return
-
-def LoadDBPlayerRet(resultSetList, extendValueList):
-    for resultDict in resultSetList:
-        PyGameData.g_dbPlayerIDMap[resultDict["PlayerID"]] = resultDict["AccID"]
-    GameWorld.Log("启动服务器加载DBPlayer玩家账号ID对应关系! %s, %s" % (len(PyGameData.g_dbPlayerIDMap), PyGameData.g_dbPlayerIDMap))
-    return
-
 def GetDBPlayerAccIDByID(playerID):
     ## 获取玩家表账号ID - 根据玩家ID, 可用于判断是否本服玩家
     return PyGameData.g_dbPlayerIDMap.get(playerID, "")
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py
index abb5903..ba8dc6b 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py
@@ -35,6 +35,8 @@
 import NetPackCommon
 import PyDataManager
 import PyGameData
+import PlayerBillboard
+import PlayerActBossTrial
 import PlayerCompensation
 import PlayerFamilyParty
 import PlayerFamilySWRH
@@ -73,6 +75,9 @@
     if not family:
         return 0
     return GetFamilyTotalFightPower(family)
+# 徽章
+def GetFamilyEmblem(curFamily): return curFamily.GetExtra6()
+def SetFamilyEmblem(curFamily, value): return curFamily.SetExtra6(value)
 
 # 公告修改次数
 def GetFamilyBroadcastCnt(curFamily): return curFamily.GetExtra3()
@@ -98,6 +103,53 @@
 def GetMemberJoinTime(curMember): return curMember.GetExattr4()
 def SetMemberJoinTime(curMember, joinTime): return curMember.SetExattr4(joinTime)
 #----------------------------------------------------------------------
+
+def OnGameServerInitOK():
+    ## 服务器启动成功处理
+    DoFamilySort()
+    return
+
+def OnMixServerInit():
+    ## 合服后首次启动成功处理
+    
+    # 仙盟联赛重置
+    GameWorldFamilyWar.DoFamilyWarReset()
+    # 重置所有仙盟联赛评级
+    familyManager = GameWorld.GetFamilyManager()
+    for i in xrange(familyManager.GetCount()):
+        family = familyManager.GetAt(i)
+        SetFamilyWarRank(family, 0)
+        
+        # 仙盟榜相关榜单重新上榜
+        familyID = family.GetID()
+        familyBillInfo = GetFamilyBillboardInfo(family)
+        
+        familySubmitTotal = PlayerActBossTrial.GetFamilySubmitTotalByID(familyID)
+        PlayerBillboard.UpdateFamilyBillboard(ShareDefine.Def_BT_BossTrialSubmitFamily, familyBillInfo, familySubmitTotal)
+        
+    DoFamilySort()
+    return
+
+def OnLoadDBPlayerOK():
+    ## 服务器启动加载DB玩家成功处理
+    
+    # 检查仙盟ServerID
+    familyManager = GameWorld.GetFamilyManager()
+    for i in xrange(familyManager.GetCount()):
+        family = familyManager.GetAt(i)
+        if family.GetServerID():
+            continue
+        familyID = family.GetID()
+        # 没有则默认取盟主的
+        leaderID = family.GetLeaderID()
+        leaderAccID = PlayerControl.GetDBPlayerAccIDByID(leaderID)
+        if not leaderAccID:
+            continue
+        serverID = GameWorld.GetAccIDServerID(leaderAccID)
+        family.SetServerID(serverID)
+        GameWorld.Log("启动更新仙盟所属服务器ID: familyID=%s,serverID=%s,leaderID=%s,%s" % (familyID, serverID, leaderID, leaderAccID))
+        
+    return
 
 def RandomFakeFamily():
     '''随机3个假仙盟'''
@@ -277,6 +329,7 @@
         return
     GameWorld.Log("创建仙盟: familyID=%s,playerID=%s" % (curFamily.GetID(), curPlayerID))
     #---创建家族---
+    curFamily.SetServerID(GameWorld.GetAccIDServerID(curPlayer.GetAccID()))
     curFamily.SetCreateTime(GameWorld.GetCurrentDataTimeStr())
     curFamily.SetLV(1)
     curFamily.SetAcceptJoin(ShareDefine.FamilyAcceptJoin_Agree)     #设置收人方式为直接通过申请
@@ -3710,3 +3763,18 @@
 
 ##--------------------------------------------------------------------------------------------------
 
+def GetFamilyBillboardInfo(curFamily):
+    ## 获取仙盟榜单信息 区服ID、徽章、仙盟名、盟主名、仙盟总战力、仙盟等级
+    familyID = curFamily.GetID()
+    name = curFamily.GetName()
+    id2 = curFamily.GetLeaderID()
+    name2 = curFamily.GetLeaderName()
+    fightPower = GetFamilyTotalFightPower(curFamily)
+    value1 = fightPower / ChConfig.Def_PerPointValue
+    value2 = fightPower % ChConfig.Def_PerPointValue
+    value3 = GetFamilyEmblem(curFamily)
+    value4 = curFamily.GetLV()
+    value5 = curFamily.GetServerID()
+    return {"id":familyID, "name":name, "id2":id2, "name2":name2, "value1":value1, "value2":value2, 
+            "value3":value3, "value4":value4, "value5":value5}
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index 18822d5..cb7b7c8 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -76,6 +76,7 @@
 import CrossBattlefield
 import CrossFamilyFlagwar
 import CrossActAllRecharge
+import PlayerActBossTrial
 import ChPyNetSendPack
 import NetPackCommon
 import AuctionHouse
@@ -692,6 +693,14 @@
         CrossActAllRecharge.MapServer_CrossActAllRecharge(curPlayer, eval(resultName))
         return
     
+    # Boss历练
+    if callName == "BossTrial":
+        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
+        if not curPlayer:
+            return
+        PlayerActBossTrial.MapServer_BossTrial(curPlayer, eval(resultName))
+        return
+    
     #py喇叭聊天
     if callName == 'PYSpeaker':
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 6f8cbb3..2cd0f53 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -344,15 +344,17 @@
 CrossActName_CTGBillboard = "CrossActCTGBillboard" # 充值排行榜
 CrossActName_AllRecharge = "CrossActAllRecharge" # 全民充值
 CrossActName_LuckyCloudBuy = "CrossActLuckyCloudBuy" # 幸运云购
+CrossActName_BossTrial = "CrossActBossTrial" # Boss历练 - 跨服
 
 #跨服运营活动列表
-CrossActNameList = [CrossActName_CTGBillboard, CrossActName_AllRecharge, CrossActName_LuckyCloudBuy]
+CrossActNameList = [CrossActName_CTGBillboard, CrossActName_AllRecharge, CrossActName_LuckyCloudBuy, CrossActName_BossTrial]
 #需要锁定活动分区分配直到活动结束的跨服运营活动,即使热更分区配置,也不会改变正在活动中的分区设定,直到活动结束
 CrossActLockServerGroupIDList = [CrossActName_CTGBillboard, CrossActName_AllRecharge]
 
 #活动信息字典key定义
 ActKey_ID = "ID" # 活动ID,唯一标识的ID,一般是活动开启的time值
 ActKey_State = "State" # 活动状态 0-未开启, >0开启中,也代表当日的第几个时间段
+ActKey_StateJoin = "StateJoin" # 活动某些功能可参与状态 0-还不可参与, >0可参与,一般可参与时该状态等于state
 ActKey_CfgID = "CfgID" # 活动表配置ID
 ActKey_ActNum = "ActNum" # 活动分组编号
 ActKey_DayIndex = "DayIndex" # 当前活动天索引,0开始,代表第1天
@@ -806,9 +808,11 @@
     Def_BT_BossTrialSubmit,                   #提交boss凭证榜 (boss历练活动)
     Def_BT_AlineInvade,                       #异兽入侵
     Def_BT_BossTrialSubmitBak,                #提交boss凭证榜 (boss历练活动 - 上一期) 35
+    Def_BT_BossTrialSubmitFamily,             #提交boss凭证仙盟榜 (boss历练活动)
+    Def_BT_BossTrialSubmitFamilyBak,          #提交boss凭证仙盟榜 (boss历练活动 - 上一期)
     
     Def_BT_Max, #排行榜最大类型
-) = range(0, 35 + 2) 
+) = range(0, 37 + 2) 
 
 ''' 跨服排行榜类型, 从 150 开始
 与本服榜单存储的是不一样的数据库表格,理论上类型可以和本服榜单类型重复,为了做下区分防误导,跨服榜单从 150 开始
@@ -824,7 +828,11 @@
 Def_CBT_YaomoBossHurt, # 跨服妖魔boss最新一次伤血排名  155
 Def_CBT_FamilyFlagwar, # 逐鹿万界 - 单场榜  156
 Def_CBT_FamilyFlagwarWeek, # 逐鹿万界 - 周总榜  157
-) = range(150, 157 + 1)
+Def_CBT_BossTrialSubmit, # boss凭证 - 个人榜  158
+Def_CBT_BossTrialSubmitBak, # boss凭证 - 个人榜 上一期  159
+Def_CBT_BossTrialSubmitFamily, # boss凭证 - 仙盟榜  160
+Def_CBT_BossTrialSubmitFamilyBak, # boss凭证 - 仙盟榜 上一期  161
+) = range(150, 161 + 1)
 
 #职业对应战力排行榜类型
 JobFightPowerBillboardDict = {
@@ -1366,7 +1374,8 @@
                       Def_ActionType_XXX10,    #10
                       Def_ActionType_OfficerModelEquip,    #记录家族有职位的成员模型装备信息11
                       Def_ActionType_FamilyEvent,    #记录家族事件12
-                      ) = range(0, 13)
+                      Def_ActionType_BossTrialSubmit,    #boss凭证提交 13
+                      ) = range(0, 14)
 
 # 家族行为事件类型定义; Def_ActionType_FamilyEvent; 存与事件记录Value1
 # 通用:time-时间;name-玩家;value1-事件类型
@@ -1506,6 +1515,7 @@
 CrossServerMsg_CrossDailyActionState = "CrossDailyActionState" # 跨服日常任务状态信息
 CrossServerMsg_CrossYaomoBossHurtInfo = "CrossYaomoBossHurtInfo" # 跨服妖魔boss玩家伤害信息
 CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
+CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
 
 # 子服发送跨服信息定义
 ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
@@ -1542,6 +1552,7 @@
 ClientServerMsg_ChampionshipWorship = "ChampionshipWorship" # 跨服排位膜拜
 ClientServerMsg_ActAllRechargeValue = "ActAllRechargeValue" # 跨服全民充值额度
 ClientServerMsg_CrossYaomoBossHurtAward = "CrossYaomoBossHurtAward" # 跨服妖魔boss玩家伤害领奖
+ClientServerMsg_BossTrialSubmit = "BossTrialSubmit" # boss凭证提交
 
 #跨服广播类型定义
 CrossNotify_CrossAct = "CrossAct"
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index a939dd3..cc1d717 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -4013,8 +4013,10 @@
 Def_PDict_ZhuXianBossHelpCnt = "ZhuXianBossHelpCnt"  # 协助次数
 
 #boss历练
+Def_PDict_CA_BossTrialID = "CA_BossTrialID"  # 玩家身上的活动ID,唯一标识,取活动开始日期time值
 Def_PDict_BossTrialID = "BossTrialID_%s"  # 玩家身上的活动ID,唯一标识,取活动开始日期time,参数(活动编号)
 Def_PDict_BossTrialSubmitCount = "BossTrialSubmitCount_%s"  # 提交凭证物品个数,参数(活动编号)
+Def_PDict_BossTrialSubmitAwardCount = "BossTrialAwardCount_%s"  # 关联提交凭证奖励提交物品个数,参数(活动编号)
 Def_PDict_BossTrialSubmitAward = "BossTrialSubmitAward_%s"  # 提交凭证奖励状态,参数(活动编号)
 
 #幸运鉴宝
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index ee24a33..a181783 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -4451,9 +4451,17 @@
     Type2 = 0    #(BYTE Type2)//附加类型,用来表示排序对象的类型,比如,玩家所属职业门派,宠物类型等
     Value1 = 0    #(DWORD Value1)//排序依赖的值,比如,等级
     Value2 = 0    #(DWORD Value2)//排序依赖的值,比如,战斗力
+    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):
@@ -4470,9 +4478,17 @@
         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):
@@ -4484,9 +4500,17 @@
         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):
@@ -4502,6 +4526,14 @@
         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
 
@@ -4515,9 +4547,17 @@
         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):
@@ -4530,9 +4570,17 @@
                                 Type2:%d,
                                 Value1:%d,
                                 Value2:%d,
+                                Value3:%d,
+                                Value4:%d,
+                                Value5:%d,
+                                Value6:%d,
+                                Value7:%d,
+                                Value8:%d,
                                 CmpValue:%d,
                                 CmpValue2:%d,
-                                CmpValue3:%d
+                                CmpValue3:%d,
+                                DataLen:%d,
+                                UserData:%s
                                 '''\
                                 %(
                                 self.OrderIndex,
@@ -4543,9 +4591,17 @@
                                 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.CmpValue3,
+                                self.DataLen,
+                                self.UserData
                                 )
         return DumpString
 
@@ -14728,9 +14784,17 @@
     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):
@@ -14745,9 +14809,17 @@
         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):
@@ -14757,9 +14829,17 @@
         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):
@@ -14773,6 +14853,14 @@
         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
 
@@ -14784,9 +14872,17 @@
         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):
@@ -14797,9 +14893,17 @@
                                 Type2:%d,
                                 Value1:%d,
                                 Value2:%d,
+                                Value3:%d,
+                                Value4:%d,
+                                Value5:%d,
+                                Value6:%d,
+                                Value7:%d,
+                                Value8:%d,
                                 CmpValue:%d,
                                 CmpValue2:%d,
-                                CmpValue3:%d
+                                CmpValue3:%d,
+                                DataLen:%d,
+                                UserData:%s
                                 '''\
                                 %(
                                 self.ID,
@@ -14808,9 +14912,17 @@
                                 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.CmpValue3,
+                                self.DataLen,
+                                self.UserData
                                 )
         return DumpString
 
@@ -31262,7 +31374,9 @@
 class  tagMCActBossTrialBillard(Structure):
     Rank = 0    #(DWORD Rank)// 名次,1-代表第一名;支持夸段,如1,3 代表第1名,第2~3名
     Count = 0    #(BYTE Count)// 奖励物品数
-    AwardItemList = list()    #(vector<tagMCActBossTrialItem> AwardItemList)// 奖励物品列表
+    AwardItemList = list()    #(vector<tagMCActBossTrialItem> AwardItemList)// 奖励物品列表,当仙盟榜时,如果有该奖励则代表盟主奖励,否则默认均为成员奖励
+    MemCount = 0    #(BYTE MemCount)// 成员奖励物品数
+    MemAwardItemList = list()    #(vector<tagMCActBossTrialItem> MemAwardItemList)// 成员奖励物品列表,仅仙盟榜时有效
     data = None
 
     def __init__(self):
@@ -31277,12 +31391,19 @@
             temAwardItemList = tagMCActBossTrialItem()
             _pos = temAwardItemList.ReadData(_lpData, _pos)
             self.AwardItemList.append(temAwardItemList)
+        self.MemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemCount):
+            temMemAwardItemList = tagMCActBossTrialItem()
+            _pos = temMemAwardItemList.ReadData(_lpData, _pos)
+            self.MemAwardItemList.append(temMemAwardItemList)
         return _pos
 
     def Clear(self):
         self.Rank = 0
         self.Count = 0
         self.AwardItemList = list()
+        self.MemCount = 0
+        self.MemAwardItemList = list()
         return
 
     def GetLength(self):
@@ -31291,6 +31412,9 @@
         length += 1
         for i in range(self.Count):
             length += self.AwardItemList[i].GetLength()
+        length += 1
+        for i in range(self.MemCount):
+            length += self.MemAwardItemList[i].GetLength()
 
         return length
 
@@ -31300,17 +31424,24 @@
         data = CommFunc.WriteBYTE(data, self.Count)
         for i in range(self.Count):
             data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.MemCount)
+        for i in range(self.MemCount):
+            data = CommFunc.WriteString(data, self.MemAwardItemList[i].GetLength(), self.MemAwardItemList[i].GetBuffer())
         return data
 
     def OutputString(self):
         DumpString = '''
                                 Rank:%d,
                                 Count:%d,
-                                AwardItemList:%s
+                                AwardItemList:%s,
+                                MemCount:%d,
+                                MemAwardItemList:%s
                                 '''\
                                 %(
                                 self.Rank,
                                 self.Count,
+                                "...",
+                                self.MemCount,
                                 "..."
                                 )
         return DumpString
@@ -31385,13 +31516,18 @@
     ActNum = 0    #(BYTE ActNum)// 活动编号
     StartDate = ""    #(char StartDate[10])// 开始日期 y-m-d
     EndtDate = ""    #(char EndtDate[10])// 结束日期 y-m-d
+    JoinStartTime = ""    #(char JoinStartTime[5])// 参与开始时间点 mm:ss
+    JoinEndTime = ""    #(char JoinEndTime[5])// 参与结束时间点 mm:ss
     IsDayReset = 0    #(BYTE IsDayReset)// 是否每天重置
     ResetType = 0    #(BYTE ResetType)// 重置类型,0-0点重置;1-5点重置
     LimitLV = 0    #(WORD LimitLV)// 限制等级
+    SubResetType = 0    #(BYTE SubResetType)// 提交凭证奖励重置类型,0-跟随活动; 1-0点重置;2-5点重置
     SubmitCount = 0    #(BYTE SubmitCount)
     SubmitInfoList = list()    #(vector<tagMCActBossTrialSubmitInfo> SubmitInfoList)// 提交凭证信息列表
-    BillardCount = 0    #(BYTE BillardCount)
-    BillboardInfoList = list()    #(vector<tagMCActBossTrialBillard> BillboardInfoList)// 榜单信息列表
+    PersonalBillCount = 0    #(BYTE PersonalBillCount)
+    PersonalBillboardInfoList = list()    #(vector<tagMCActBossTrialBillard> PersonalBillboardInfoList)// 个人榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
+    FamilyBillCount = 0    #(BYTE FamilyBillCount)
+    FamilyBillboardInfoList = list()    #(vector<tagMCActBossTrialBillard> FamilyBillboardInfoList)// 仙盟榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
     data = None
 
     def __init__(self):
@@ -31406,19 +31542,27 @@
         self.ActNum,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
         self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.JoinStartTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.JoinEndTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
         self.IsDayReset,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.ResetType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.LimitLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.SubResetType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.SubmitCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         for i in range(self.SubmitCount):
             temSubmitInfoList = tagMCActBossTrialSubmitInfo()
             _pos = temSubmitInfoList.ReadData(_lpData, _pos)
             self.SubmitInfoList.append(temSubmitInfoList)
-        self.BillardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
-        for i in range(self.BillardCount):
-            temBillboardInfoList = tagMCActBossTrialBillard()
-            _pos = temBillboardInfoList.ReadData(_lpData, _pos)
-            self.BillboardInfoList.append(temBillboardInfoList)
+        self.PersonalBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.PersonalBillCount):
+            temPersonalBillboardInfoList = tagMCActBossTrialBillard()
+            _pos = temPersonalBillboardInfoList.ReadData(_lpData, _pos)
+            self.PersonalBillboardInfoList.append(temPersonalBillboardInfoList)
+        self.FamilyBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.FamilyBillCount):
+            temFamilyBillboardInfoList = tagMCActBossTrialBillard()
+            _pos = temFamilyBillboardInfoList.ReadData(_lpData, _pos)
+            self.FamilyBillboardInfoList.append(temFamilyBillboardInfoList)
         return _pos
 
     def Clear(self):
@@ -31429,13 +31573,18 @@
         self.ActNum = 0
         self.StartDate = ""
         self.EndtDate = ""
+        self.JoinStartTime = ""
+        self.JoinEndTime = ""
         self.IsDayReset = 0
         self.ResetType = 0
         self.LimitLV = 0
+        self.SubResetType = 0
         self.SubmitCount = 0
         self.SubmitInfoList = list()
-        self.BillardCount = 0
-        self.BillboardInfoList = list()
+        self.PersonalBillCount = 0
+        self.PersonalBillboardInfoList = list()
+        self.FamilyBillCount = 0
+        self.FamilyBillboardInfoList = list()
         return
 
     def GetLength(self):
@@ -31444,15 +31593,21 @@
         length += 1
         length += 10
         length += 10
+        length += 5
+        length += 5
         length += 1
         length += 1
         length += 2
         length += 1
+        length += 1
         for i in range(self.SubmitCount):
             length += self.SubmitInfoList[i].GetLength()
         length += 1
-        for i in range(self.BillardCount):
-            length += self.BillboardInfoList[i].GetLength()
+        for i in range(self.PersonalBillCount):
+            length += self.PersonalBillboardInfoList[i].GetLength()
+        length += 1
+        for i in range(self.FamilyBillCount):
+            length += self.FamilyBillboardInfoList[i].GetLength()
 
         return length
 
@@ -31462,15 +31617,21 @@
         data = CommFunc.WriteBYTE(data, self.ActNum)
         data = CommFunc.WriteString(data, 10, self.StartDate)
         data = CommFunc.WriteString(data, 10, self.EndtDate)
+        data = CommFunc.WriteString(data, 5, self.JoinStartTime)
+        data = CommFunc.WriteString(data, 5, self.JoinEndTime)
         data = CommFunc.WriteBYTE(data, self.IsDayReset)
         data = CommFunc.WriteBYTE(data, self.ResetType)
         data = CommFunc.WriteWORD(data, self.LimitLV)
+        data = CommFunc.WriteBYTE(data, self.SubResetType)
         data = CommFunc.WriteBYTE(data, self.SubmitCount)
         for i in range(self.SubmitCount):
             data = CommFunc.WriteString(data, self.SubmitInfoList[i].GetLength(), self.SubmitInfoList[i].GetBuffer())
-        data = CommFunc.WriteBYTE(data, self.BillardCount)
-        for i in range(self.BillardCount):
-            data = CommFunc.WriteString(data, self.BillboardInfoList[i].GetLength(), self.BillboardInfoList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.PersonalBillCount)
+        for i in range(self.PersonalBillCount):
+            data = CommFunc.WriteString(data, self.PersonalBillboardInfoList[i].GetLength(), self.PersonalBillboardInfoList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.FamilyBillCount)
+        for i in range(self.FamilyBillCount):
+            data = CommFunc.WriteString(data, self.FamilyBillboardInfoList[i].GetLength(), self.FamilyBillboardInfoList[i].GetBuffer())
         return data
 
     def OutputString(self):
@@ -31479,25 +31640,35 @@
                                 ActNum:%d,
                                 StartDate:%s,
                                 EndtDate:%s,
+                                JoinStartTime:%s,
+                                JoinEndTime:%s,
                                 IsDayReset:%d,
                                 ResetType:%d,
                                 LimitLV:%d,
+                                SubResetType:%d,
                                 SubmitCount:%d,
                                 SubmitInfoList:%s,
-                                BillardCount:%d,
-                                BillboardInfoList:%s
+                                PersonalBillCount:%d,
+                                PersonalBillboardInfoList:%s,
+                                FamilyBillCount:%d,
+                                FamilyBillboardInfoList:%s
                                 '''\
                                 %(
                                 self.Head.OutputString(),
                                 self.ActNum,
                                 self.StartDate,
                                 self.EndtDate,
+                                self.JoinStartTime,
+                                self.JoinEndTime,
                                 self.IsDayReset,
                                 self.ResetType,
                                 self.LimitLV,
+                                self.SubResetType,
                                 self.SubmitCount,
                                 "...",
-                                self.BillardCount,
+                                self.PersonalBillCount,
+                                "...",
+                                self.FamilyBillCount,
                                 "..."
                                 )
         return DumpString
@@ -31516,8 +31687,9 @@
                   ("Cmd", c_ubyte),
                   ("SubCmd", c_ubyte),
                   ("ActNum", c_ubyte),    # 活动编号
-                  ("SubmitCount", c_ushort),    # 已提交凭证个数
-                  ("SubmitCountAward", c_int),    # 提交凭证奖励领奖状态
+                  ("SubmitCount", c_int),    # 已提交凭证个数,总个数
+                  ("SubmitAwardCount", c_int),    # 已提交凭证个数,关联提交奖励的个数,领奖使用该个数判断
+                  ("SubmitAwardState", c_int),    # 提交凭证奖励领奖状态
                   ]
 
     def __init__(self):
@@ -31536,7 +31708,8 @@
         self.SubCmd = 0x68
         self.ActNum = 0
         self.SubmitCount = 0
-        self.SubmitCountAward = 0
+        self.SubmitAwardCount = 0
+        self.SubmitAwardState = 0
         return
 
     def GetLength(self):
@@ -31551,14 +31724,16 @@
                                 SubCmd:%s,
                                 ActNum:%d,
                                 SubmitCount:%d,
-                                SubmitCountAward:%d
+                                SubmitAwardCount:%d,
+                                SubmitAwardState:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
                                 self.ActNum,
                                 self.SubmitCount,
-                                self.SubmitCountAward
+                                self.SubmitAwardCount,
+                                self.SubmitAwardState
                                 )
         return DumpString
 
@@ -38327,6 +38502,290 @@
 
 
 #------------------------------------------------------
+# AA 76 Boss历练跨服活动信息 #tagMCCrossActBossTrialInfo
+
+class  tagMCCrossActBossTrialItem(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("ItemID", c_int),    
+                  ("ItemCount", c_ushort),    
+                  ("IsBind", c_ubyte),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        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.ItemID = 0
+        self.ItemCount = 0
+        self.IsBind = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCCrossActBossTrialItem)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// AA 76 Boss历练跨服活动信息 //tagMCCrossActBossTrialInfo:
+                                ItemID:%d,
+                                ItemCount:%d,
+                                IsBind:%d
+                                '''\
+                                %(
+                                self.ItemID,
+                                self.ItemCount,
+                                self.IsBind
+                                )
+        return DumpString
+
+
+class  tagMCCrossActBossTrialBillard(Structure):
+    Rank = 0    #(DWORD Rank)// 名次,1-代表第一名;支持夸段,如1,3 代表第1名,第2~3名
+    Count = 0    #(BYTE Count)// 奖励物品数
+    AwardItemList = list()    #(vector<tagMCCrossActBossTrialItem> AwardItemList)// 奖励物品列表,当仙盟榜时,如果有该奖励则代表盟主奖励,否则默认均为成员奖励
+    MemCount = 0    #(BYTE MemCount)// 成员奖励物品数
+    MemAwardItemList = list()    #(vector<tagMCCrossActBossTrialItem> MemAwardItemList)// 成员奖励物品列表,仅仙盟榜时有效
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.Rank,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.Count):
+            temAwardItemList = tagMCCrossActBossTrialItem()
+            _pos = temAwardItemList.ReadData(_lpData, _pos)
+            self.AwardItemList.append(temAwardItemList)
+        self.MemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemCount):
+            temMemAwardItemList = tagMCCrossActBossTrialItem()
+            _pos = temMemAwardItemList.ReadData(_lpData, _pos)
+            self.MemAwardItemList.append(temMemAwardItemList)
+        return _pos
+
+    def Clear(self):
+        self.Rank = 0
+        self.Count = 0
+        self.AwardItemList = list()
+        self.MemCount = 0
+        self.MemAwardItemList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 1
+        for i in range(self.Count):
+            length += self.AwardItemList[i].GetLength()
+        length += 1
+        for i in range(self.MemCount):
+            length += self.MemAwardItemList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.Rank)
+        data = CommFunc.WriteBYTE(data, self.Count)
+        for i in range(self.Count):
+            data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.MemCount)
+        for i in range(self.MemCount):
+            data = CommFunc.WriteString(data, self.MemAwardItemList[i].GetLength(), self.MemAwardItemList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Rank:%d,
+                                Count:%d,
+                                AwardItemList:%s,
+                                MemCount:%d,
+                                MemAwardItemList:%s
+                                '''\
+                                %(
+                                self.Rank,
+                                self.Count,
+                                "...",
+                                self.MemCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagMCCrossActBossTrialInfo(Structure):
+    Head = tagHead()
+    ServerInfoLen = 0    #(BYTE ServerInfoLen)
+    ServerIDRangeInfo = ""    #(String ServerIDRangeInfo)//开放该活动的服务器ID范围列表,json格式 [[IDA, IDB], ...], [] 为全服
+    GroupValue1 = 0    #(BYTE GroupValue1)// 活动榜单分组值1,用于查询对应榜单
+    StartDate = ""    #(char StartDate[10])// 开始日期 y-m-d
+    EndtDate = ""    #(char EndtDate[10])// 结束日期 y-m-d
+    JoinStartTime = ""    #(char JoinStartTime[5])// 参与开始时间点 mm:ss
+    JoinEndTime = ""    #(char JoinEndTime[5])// 参与结束时间点 mm:ss
+    IsDayReset = 0    #(BYTE IsDayReset)// 是否每天重置
+    ResetType = 0    #(BYTE ResetType)// 重置类型,0-0点重置;1-5点重置
+    RankLimitPersonal = 0    #(WORD RankLimitPersonal)// 个人榜上榜个数保底限制;
+    RankLimitFamily = 0    #(WORD RankLimitFamily)// 仙盟榜上榜个数保底限制;
+    PersonalBillCount = 0    #(BYTE PersonalBillCount)
+    PersonalBillboardInfoList = list()    #(vector<tagMCCrossActBossTrialBillard> PersonalBillboardInfoList)// 个人榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
+    FamilyBillCount = 0    #(BYTE FamilyBillCount)
+    FamilyBillboardInfoList = list()    #(vector<tagMCCrossActBossTrialBillard> FamilyBillboardInfoList)// 仙盟榜单奖励信息列表,如果没有代表本次活动没有该榜奖励
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x76
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.ServerInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.ServerIDRangeInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ServerInfoLen)
+        self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.JoinStartTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.JoinEndTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.IsDayReset,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.ResetType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RankLimitPersonal,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.RankLimitFamily,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.PersonalBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.PersonalBillCount):
+            temPersonalBillboardInfoList = tagMCCrossActBossTrialBillard()
+            _pos = temPersonalBillboardInfoList.ReadData(_lpData, _pos)
+            self.PersonalBillboardInfoList.append(temPersonalBillboardInfoList)
+        self.FamilyBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.FamilyBillCount):
+            temFamilyBillboardInfoList = tagMCCrossActBossTrialBillard()
+            _pos = temFamilyBillboardInfoList.ReadData(_lpData, _pos)
+            self.FamilyBillboardInfoList.append(temFamilyBillboardInfoList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x76
+        self.ServerInfoLen = 0
+        self.ServerIDRangeInfo = ""
+        self.GroupValue1 = 0
+        self.StartDate = ""
+        self.EndtDate = ""
+        self.JoinStartTime = ""
+        self.JoinEndTime = ""
+        self.IsDayReset = 0
+        self.ResetType = 0
+        self.RankLimitPersonal = 0
+        self.RankLimitFamily = 0
+        self.PersonalBillCount = 0
+        self.PersonalBillboardInfoList = list()
+        self.FamilyBillCount = 0
+        self.FamilyBillboardInfoList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += len(self.ServerIDRangeInfo)
+        length += 1
+        length += 10
+        length += 10
+        length += 5
+        length += 5
+        length += 1
+        length += 1
+        length += 2
+        length += 2
+        length += 1
+        for i in range(self.PersonalBillCount):
+            length += self.PersonalBillboardInfoList[i].GetLength()
+        length += 1
+        for i in range(self.FamilyBillCount):
+            length += self.FamilyBillboardInfoList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.ServerInfoLen)
+        data = CommFunc.WriteString(data, self.ServerInfoLen, self.ServerIDRangeInfo)
+        data = CommFunc.WriteBYTE(data, self.GroupValue1)
+        data = CommFunc.WriteString(data, 10, self.StartDate)
+        data = CommFunc.WriteString(data, 10, self.EndtDate)
+        data = CommFunc.WriteString(data, 5, self.JoinStartTime)
+        data = CommFunc.WriteString(data, 5, self.JoinEndTime)
+        data = CommFunc.WriteBYTE(data, self.IsDayReset)
+        data = CommFunc.WriteBYTE(data, self.ResetType)
+        data = CommFunc.WriteWORD(data, self.RankLimitPersonal)
+        data = CommFunc.WriteWORD(data, self.RankLimitFamily)
+        data = CommFunc.WriteBYTE(data, self.PersonalBillCount)
+        for i in range(self.PersonalBillCount):
+            data = CommFunc.WriteString(data, self.PersonalBillboardInfoList[i].GetLength(), self.PersonalBillboardInfoList[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.FamilyBillCount)
+        for i in range(self.FamilyBillCount):
+            data = CommFunc.WriteString(data, self.FamilyBillboardInfoList[i].GetLength(), self.FamilyBillboardInfoList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                ServerInfoLen:%d,
+                                ServerIDRangeInfo:%s,
+                                GroupValue1:%d,
+                                StartDate:%s,
+                                EndtDate:%s,
+                                JoinStartTime:%s,
+                                JoinEndTime:%s,
+                                IsDayReset:%d,
+                                ResetType:%d,
+                                RankLimitPersonal:%d,
+                                RankLimitFamily:%d,
+                                PersonalBillCount:%d,
+                                PersonalBillboardInfoList:%s,
+                                FamilyBillCount:%d,
+                                FamilyBillboardInfoList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.ServerInfoLen,
+                                self.ServerIDRangeInfo,
+                                self.GroupValue1,
+                                self.StartDate,
+                                self.EndtDate,
+                                self.JoinStartTime,
+                                self.JoinEndTime,
+                                self.IsDayReset,
+                                self.ResetType,
+                                self.RankLimitPersonal,
+                                self.RankLimitFamily,
+                                self.PersonalBillCount,
+                                "...",
+                                self.FamilyBillCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCCrossActBossTrialInfo=tagMCCrossActBossTrialInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCrossActBossTrialInfo.Head.Cmd,m_NAtagMCCrossActBossTrialInfo.Head.SubCmd))] = m_NAtagMCCrossActBossTrialInfo
+
+
+#------------------------------------------------------
 # AA 25 每日礼包活动信息 #tagMCDailyGiftbagInfo
 
 class  tagMCDailyGiftbagItem(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index 0f0ba57..f93743b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -615,6 +615,16 @@
     if cfgID == None or dayIndex == None or not ipyData:
         return 0
     templateIDList = ipyData.GetTemplateIDList()
+    if not templateIDList:
+        return 0
+    templateID = templateIDList[-1] if dayIndex >= len(templateIDList) else templateIDList[dayIndex]
+    return templateID
+
+def GetTemplateIDByList(templateIDList, dayIndex):
+    if dayIndex == None:
+        return 0
+    if not templateIDList:
+        return 0
     templateID = templateIDList[-1] if dayIndex >= len(templateIDList) else templateIDList[dayIndex]
     return templateID
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index e877b78..f766652 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -1412,17 +1412,22 @@
                         ("DWORD", "CfgID", 1),
                         ("char", "StartDate", 0),
                         ("char", "EndDate", 0),
+                        ("char", "JoinStartTime", 0),
+                        ("char", "JoinEndTime", 0),
                         ("WORD", "LVLimit", 0),
                         ("BYTE", "IsDayReset", 0),
                         ("BYTE", "ResetType", 0),
                         ("dict", "SubmitItemAwardInfo", 0),
+                        ("BYTE", "SubmitAwardResetType", 0),
                         ("list", "TemplateIDList", 0),
+                        ("list", "FamilyTemplateIDList", 0),
                         ),
 
                 "ActBossTrialTemplate":(
                         ("DWORD", "TemplateID", 1),
                         ("BYTE", "Rank", 0),
                         ("list", "AwardItemList", 0),
+                        ("list", "MemAwardItemList", 0),
                         ),
 
                 "ActXianXiaMJ":(
@@ -4302,11 +4307,15 @@
     def GetCfgID(self): return self.attrTuple[0] # 配置ID DWORD
     def GetStartDate(self): return self.attrTuple[1] # 开启日期 char
     def GetEndDate(self): return self.attrTuple[2] # 结束日期 char
-    def GetLVLimit(self): return self.attrTuple[3] # 限制等级 WORD
-    def GetIsDayReset(self): return self.attrTuple[4] # 是否每天重置 BYTE
-    def GetResetType(self): return self.attrTuple[5] # 重置类型,0-0点重置;1-5点重置 BYTE
-    def GetSubmitItemAwardInfo(self): return self.attrTuple[6] # 提交凭证个数对应奖励 dict
-    def GetTemplateIDList(self): return self.attrTuple[7] # 榜单模板编号列表 list
+    def GetJoinStartTime(self): return self.attrTuple[3] # 参与开始时间点 char
+    def GetJoinEndTime(self): return self.attrTuple[4] # 参与结束时间点 char
+    def GetLVLimit(self): return self.attrTuple[5] # 限制等级 WORD
+    def GetIsDayReset(self): return self.attrTuple[6] # 是否每天重置 BYTE
+    def GetResetType(self): return self.attrTuple[7] # 重置类型,0-0点重置;1-5点重置 BYTE
+    def GetSubmitItemAwardInfo(self): return self.attrTuple[8] # 提交凭证个数对应奖励 dict
+    def GetSubmitAwardResetType(self): return self.attrTuple[9] # 提交凭证每日重置类型,0-跟随活动; 1-0点重置;2-5点重置 BYTE
+    def GetTemplateIDList(self): return self.attrTuple[10] # 榜单模板编号列表 list
+    def GetFamilyTemplateIDList(self): return self.attrTuple[11] # 仙盟榜单模板编号列表 list
 
 # Boss历练榜单模版表
 class IPY_ActBossTrialTemplate():
@@ -4317,7 +4326,8 @@
         
     def GetTemplateID(self): return self.attrTuple[0] # 模板编号 DWORD
     def GetRank(self): return self.attrTuple[1] # 名次 BYTE
-    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品信息列表 [[物品ID,个数,是否拍品], ...] list
+    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] 仙盟榜时为盟主奖励,如果没有配置,则统一取成员奖励 list
+    def GetMemAwardItemList(self): return self.attrTuple[3] # 仙盟榜成员奖励物品信息列表[[物品ID,个数,是否拍品], ...] list
 
 # 仙匣秘境活动时间表
 class IPY_ActXianXiaMJ():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActBossTrial.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActBossTrial.py
index d6fd2ae..ad83198 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActBossTrial.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActBossTrial.py
@@ -21,6 +21,7 @@
 import PlayerControl
 import IpyGameDataPY
 import ChPyNetSendPack
+import CrossRealmPlayer
 import PlayerBillboard
 import ItemControler
 import NetPackCommon
@@ -53,6 +54,34 @@
             Sync_BossTrialActionInfo(curPlayer, actNum)
             Sync_BossTrialPlayerInfo(curPlayer, actNum)
             
+    if not __CheckPlayerCrossActBossTrial(curPlayer):
+        Sync_CrossActBossTrialActionInfo(curPlayer)
+        
+    return
+
+def PlayerOnDay(curPlayer, onEventType):
+    for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_BossTrial, {}).values():
+        if not actInfo.get(ShareDefine.ActKey_State):
+            continue
+                
+        actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0)
+        cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
+        ipyData = IpyGameDataPY.GetIpyGameData("ActBossTrial", cfgID)
+        if not ipyData:
+            continue
+        submitAwardResetType = ipyData.GetSubmitAwardResetType()
+        if not submitAwardResetType:
+            continue
+        
+        if onEventType != submitAwardResetType:
+            continue
+        
+        GameWorld.DebugLog("boss历练活动重置提交奖励: actNum=%s,cfgID=%s,submitAwardResetType=%s" 
+                           % (actNum, cfgID, submitAwardResetType), curPlayer.GetPlayerID())
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialSubmitAwardCount % actNum, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialSubmitAward % actNum, 0)
+        Sync_BossTrialPlayerInfo(curPlayer, actNum)
+        
     return
 
 def RefreshBossTrialActionInfo(actNum):
@@ -84,6 +113,7 @@
     
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialID % actNum, actID)
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialSubmitCount % actNum, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialSubmitAwardCount % actNum, 0)
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialSubmitAward % actNum, 0)
     
     if state:
@@ -91,6 +121,50 @@
         Sync_BossTrialPlayerInfo(curPlayer, actNum)
         
     return True
+
+def RefreshCrossActBossTrialInfo():
+    ## 收到GameServer同步的活动信息,刷新活动信息
+    playerManager = GameWorld.GetPlayerManager()
+    for index in xrange(playerManager.GetPlayerCount()):
+        curPlayer = playerManager.GetPlayerByIndex(index)
+        if curPlayer.GetID() == 0:
+            continue
+        __CheckPlayerCrossActBossTrial(curPlayer)
+        
+    return
+
+def __CheckPlayerCrossActBossTrial(curPlayer):
+    
+    playerID = curPlayer.GetPlayerID()
+    
+    actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_BossTrial)
+    cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
+    actID = actInfo.get(ShareDefine.ActKey_ID, 0)
+    state = actInfo.get(ShareDefine.ActKey_State, 0)
+    dayIndex = actInfo.get(ShareDefine.ActKey_DayIndex, 0)
+    
+    playerActID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_BossTrialID) # 玩家身上的活动ID
+    
+    # 活动ID 相同的话不处理
+    if actID == playerActID:
+        GameWorld.DebugLog("跨服Boss历练活动ID不变,不处理!cfgID=%s,dayIndex=%s,actID=%s" % (cfgID, dayIndex, actID), playerID)   
+        return
+    GameWorld.DebugLog("跨服Boss历练活动重置! cfgID=%s,actID=%s,playerActID=%s,state=%s" % (cfgID, actID, playerActID, state), playerID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_BossTrialID, actID)
+    
+    if not state:
+        CrossRealmPlayer.NotifyCrossActEnd(curPlayer, ShareDefine.CrossActName_BossTrial)
+        
+    Sync_CrossActBossTrialActionInfo(curPlayer)
+    return True
+
+
+def SendToGameServer_BossTrial(curPlayer, msgType, dataMsg=""):
+    playerID = curPlayer.GetPlayerID()
+    msgList = str([msgType, dataMsg])
+    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "BossTrial", msgList, len(msgList))
+    GameWorld.Log("Boss历练发送GameServer: %s, %s" % (msgType, dataMsg), playerID)
+    return
 
 #// AA 23 Boss历练提交凭证 #tagCMActBossTrialSubmit
 #
@@ -110,6 +184,9 @@
     if not actInfo.get(ShareDefine.ActKey_State):
         GameWorld.DebugLog("Boss历练非活动中: actNum=%s" % actNum, playerID)
         return
+    if not actInfo.get(ShareDefine.ActKey_StateJoin):
+        GameWorld.Log("Boss历练非参与活动中: actNum=%s" % actNum, playerID)
+        return
     
     itemID = IpyGameDataPY.GetFuncCfg("BossTrial", 1)
     itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
@@ -119,14 +196,21 @@
         return
     ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "BossTrialSubmit")
     
+    submitAwardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitAwardCount % actNum)
+    updSubmitAwardCount = submitAwardCount + submitCount    
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialSubmitAwardCount % actNum, updSubmitAwardCount)
+    
     nowSubmitCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitCount % actNum)
     updSubmitCount = nowSubmitCount + submitCount    
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BossTrialSubmitCount % actNum, updSubmitCount)
-    GameWorld.DebugLog("Boss历练提交凭证: actNum=%s,itemID=%s,submitCount=%s,updSubmitCount=%s" % (actNum, itemID, submitCount, updSubmitCount), playerID)
+    GameWorld.DebugLog("Boss历练提交凭证: actNum=%s,itemID=%s,submitCount=%s,updSubmitCount=%s,updSubmitAwardCount=%s" 
+                       % (actNum, itemID, submitCount, updSubmitCount, updSubmitAwardCount), playerID)
     
     PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_BossTrialSubmit, updSubmitCount, autoSort=True)
     
     Sync_BossTrialPlayerInfo(curPlayer, actNum)
+    
+    SendToGameServer_BossTrial(curPlayer, "BossTrialSubmit", [submitCount, updSubmitCount])
     return
 
 #// AA 24 Boss历练领奖 #tagCMActBossTrialGetAward
@@ -158,7 +242,7 @@
         return
     recordIndex, awardItemList = submitItemAwardInfo[submitCount]
     
-    nowSubmitCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitCount % actNum)
+    nowSubmitCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitAwardCount % actNum)
     if nowSubmitCount < submitCount:
         GameWorld.DebugLog("Boss历练提交凭证个数不足,无法领奖: actNum=%s,nowSubmitCount=%s < %s" % (actNum, nowSubmitCount, submitCount), playerID)
         return
@@ -185,16 +269,26 @@
     dropCountTotal = 0
     itemID = IpyGameDataPY.GetFuncCfg("BossTrial", 1)
     
-    for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_BossTrial, {}).values():
-        actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0)
-        if not actInfo.get(ShareDefine.ActKey_State):
-            GameWorld.DebugLog("Boss历练非活动中,不掉落! actNum=%s" % actNum)
-            continue
-        dropCount = GameWorld.GetResultByRandomList(dropCountRateList)
-        if not dropCount:
-            continue
-        dropCountTotal += dropCount
-        
+    if not GameWorld.IsCrossServer():
+        for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_BossTrial, {}).values():
+            actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0)
+            if not actInfo.get(ShareDefine.ActKey_State):
+                GameWorld.DebugLog("Boss历练非活动中,不掉落! actNum=%s" % actNum)
+                continue
+            dropCount = GameWorld.GetResultByRandomList(dropCountRateList)
+            GameWorld.DebugLog("本服Boss历练掉落! bossIndex=%s,actNum=%s,dropCount=%s" % (limitIndex, actNum, dropCount))
+            if not dropCount:
+                continue
+            dropCountTotal += dropCount
+            
+    else:
+        crossActInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_BossTrial)
+        if crossActInfo.get(ShareDefine.ActKey_State):
+            dropCount = GameWorld.GetResultByRandomList(dropCountRateList)
+            GameWorld.DebugLog("跨服Boss历练掉落! bossIndex=%s,dropCount=%s" % (limitIndex, dropCount))
+            if dropCount:
+                dropCountTotal += dropCount
+                
     return itemID, dropCountTotal
 
 def Sync_BossTrialPlayerInfo(curPlayer, actNum):
@@ -205,13 +299,13 @@
     clientPack = ChPyNetSendPack.tagMCActBossTrialPlayerInfo()
     clientPack.ActNum = actNum
     clientPack.SubmitCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitCount % actNum)
-    clientPack.SubmitCountAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitAward % actNum)
+    clientPack.SubmitAwardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitAwardCount % actNum)
+    clientPack.SubmitAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BossTrialSubmitAward % actNum)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
 
 def Sync_BossTrialActionInfo(curPlayer, actNum):
     ## 通知活动信息
-    
     actInfo = GameWorld.GetActInfo(ShareDefine.OperationActionName_BossTrial, actNum)
     if not actInfo.get(ShareDefine.ActKey_State):
         return
@@ -221,22 +315,29 @@
     ipyData = IpyGameDataPY.GetIpyGameData("ActBossTrial", cfgID)
     if not ipyData:
         return
-    templateID = GameWorld.GetTemplateID(ipyData, cfgID, dayIndex)
-    if not templateID:
-        return
-    tempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
-    if not tempIpyDataList:
-        return
     
+    personalTempIpyDataList = []
+    personalTempID = GameWorld.GetTemplateIDByList(ipyData.GetTemplateIDList(), dayIndex)
+    if personalTempID:
+        personalTempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", personalTempID)
+        
+    familyTempIpyDataList = []
+    familyTempID = GameWorld.GetTemplateIDByList(ipyData.GetFamilyTemplateIDList(), dayIndex)
+    if familyTempID:
+        familyTempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", familyTempID)
+        
     startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
     startDateSync = actInfo.get(ShareDefine.ActKey_StartDateSync, startDateStr)
     actInfo = ChPyNetSendPack.tagMCActBossTrialInfo()
     actInfo.ActNum = actNum
     actInfo.StartDate = startDateSync
     actInfo.EndtDate = endDateStr
+    actInfo.JoinStartTime = ipyData.GetJoinStartTime()
+    actInfo.JoinEndTime = ipyData.GetJoinEndTime()
     actInfo.IsDayReset = ipyData.GetIsDayReset()
     actInfo.ResetType = ipyData.GetResetType()
     actInfo.LimitLV = ipyData.GetLVLimit()
+    actInfo.SubResetType = ipyData.GetSubmitAwardResetType()
     
     actInfo.SubmitInfoList = []
     submitItemAwardInfo = ipyData.GetSubmitItemAwardInfo()
@@ -260,12 +361,24 @@
         actInfo.SubmitInfoList.append(subInfo)
     actInfo.SubmitCount = len(actInfo.SubmitInfoList)
     
-    actInfo.BillboardInfoList = []
-    for tempIpyData in tempIpyDataList:
+    actInfo.PersonalBillboardInfoList = __GetTempRankBillPackList(personalTempIpyDataList)
+    actInfo.PersonalBillCount = len(actInfo.PersonalBillboardInfoList)
+    
+    actInfo.FamilyBillboardInfoList = __GetTempRankBillPackList(familyTempIpyDataList)
+    actInfo.FamilyBillCount = len(actInfo.FamilyBillboardInfoList)
+    
+    NetPackCommon.SendFakePack(curPlayer, actInfo)
+    return
+
+def __GetTempRankBillPackList(ipyDataList):
+    packBillList = []
+    if not ipyDataList:
+        return packBillList
+    for tempIpyData in ipyDataList:
         rankInfo = ChPyNetSendPack.tagMCActBossTrialBillard()
         rankInfo.Rank = tempIpyData.GetRank()
+        
         rankInfo.AwardItemList = []
-                
         awardItemList = tempIpyData.GetAwardItemList()
         for itemID, itemCount, isAuctionItem in awardItemList:
             item = ChPyNetSendPack.tagMCActBossTrialItem()
@@ -275,8 +388,63 @@
             item.IsBind = isAuctionItem
             rankInfo.AwardItemList.append(item)
         rankInfo.Count = len(rankInfo.AwardItemList)
-        actInfo.BillboardInfoList.append(rankInfo)
-    actInfo.BillardCount = len(actInfo.BillboardInfoList)
+        
+        rankInfo.MemAwardItemList = []
+        memAwardItemList = tempIpyData.GetMemAwardItemList()
+        for itemID, itemCount, isAuctionItem in memAwardItemList:
+            item = ChPyNetSendPack.tagMCActBossTrialItem()
+            item.Clear()
+            item.ItemID = itemID
+            item.ItemCount = itemCount
+            item.IsBind = isAuctionItem
+            rankInfo.MemAwardItemList.append(item)
+        rankInfo.MemCount = len(rankInfo.MemAwardItemList)
+        
+        packBillList.append(rankInfo)
+    return packBillList
+
+def Sync_CrossActBossTrialActionInfo(curPlayer):
+    ## 通知活动信息
+    actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_BossTrial)
+    if not actInfo:
+        return
     
-    NetPackCommon.SendFakePack(curPlayer, actInfo)
+    if not actInfo.get(ShareDefine.ActKey_State):
+        return
+    
+    ipyDataDict = actInfo.get(ShareDefine.ActKey_IpyDataInfo, {})
+    if not ipyDataDict:
+        return
+    
+    personalTempIpyDataList = []
+    personalTempID = ipyDataDict.get("PersonalTemplateID", 0)
+    if personalTempID:
+        personalTempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", personalTempID)
+        
+    familyTempIpyDataList = []
+    familyTempID = ipyDataDict.get("FamilyTemplateID", 0)
+    if familyTempID:
+        familyTempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", familyTempID)
+        
+    actPack = ChPyNetSendPack.tagMCCrossActBossTrialInfo()
+    actPack.ServerIDRangeInfo = str(actInfo.get(ShareDefine.ActKey_ServerIDRangeList, []))
+    actPack.ServerInfoLen = len(actPack.ServerIDRangeInfo)
+    actPack.GroupValue1 = ipyDataDict.get("ZoneID", 0)
+    actPack.StartDate = ipyDataDict.get("StartDate", "")
+    actPack.EndtDate = ipyDataDict.get("EndDate", "")
+    actPack.JoinStartTime = ipyDataDict.get("JoinStartTime", "")
+    actPack.JoinEndTime = ipyDataDict.get("JoinEndTime", "")
+    actPack.IsDayReset = ipyDataDict.get("IsDayReset", 0)
+    actPack.ResetType = ipyDataDict.get("ResetType", 0)
+    RankLimitList = ipyDataDict.get("RankLimitList", [0, 0])
+    actPack.RankLimitPersonal = RankLimitList[0]
+    actPack.RankLimitFamily = RankLimitList[1]
+    
+    actPack.PersonalBillboardInfoList = __GetTempRankBillPackList(personalTempIpyDataList)
+    actPack.PersonalBillCount = len(actPack.PersonalBillboardInfoList)
+    
+    actPack.FamilyBillboardInfoList = __GetTempRankBillPackList(familyTempIpyDataList)
+    actPack.FamilyBillCount = len(actPack.FamilyBillboardInfoList)
+    
+    NetPackCommon.SendFakePack(curPlayer, actPack)
     return
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 1c8a3c6..36ed795 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
@@ -65,7 +65,7 @@
     
     return True
 
-def UpdatePlayerBillboard(curPlayer, bType, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0, exInfo=[], autoSort=False):
+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:
@@ -81,18 +81,33 @@
     if bType in ShareDefine.BTValue1_OfficialRankList:
         value1 = curPlayer.GetOfficialRank()
     GameServer_UpdateBillboard(bType, playerJob, playerID, playerName, playerOpInfo,
-                               value1, value2, cmpValue, cmpValue2, cmpValue3, 0, exInfo, autoSort)
+                               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):
-    sendMsg = "%s" % ({"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}) 
+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, %s" % (bType, cmpValue, sendMsg), bID)
     return
 
 def UpdatePlayerCrossBillboard(curPlayer, bType, groupValue1, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0, 
-                               groupValue2=0):
+                               groupValue2=0, **kwargs):
     ## 更新玩家跨服排行榜
     
     #if not cmpValue and not cmpValue2 and not cmpValue3:
@@ -109,14 +124,28 @@
         value1 = curPlayer.GetOfficialRank()
     id2 = 0
     GameServer_UpdateCrossBillboard(bType, groupValue1, playerID, playerName, playerOpInfo, playerJob, value1, value2, 
-                                    cmpValue, cmpValue2, cmpValue3, groupValue2, id2)
+                                    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):
-    sendMsg = "%s" % ({"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}) 
+                                    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)
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 35f6a31..c3a687a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -624,6 +624,8 @@
     PlayerWishingWell.OnDay(curPlayer)
     #通天令
     PlayerTongTianLing.OnDay(curPlayer, onEventType)
+    #boss凭证
+    PlayerActBossTrial.PlayerOnDay(curPlayer, onEventType)
     return
 
 
@@ -1513,12 +1515,19 @@
             actInfoDict = PyGameData.g_crossActInfoDict[actionName]
             actInfoDict.update(eval(msgValue))
             
+            if GameWorld.IsCrossServer():
+                #GameWorld.DebugLog("跨服服务器地图,不处理")
+                return
+            
             if actionName == ShareDefine.CrossActName_CTGBillboard:
                 CrossActCTGBillboard.RefreshCrossActCTGBillboardInfo()
                 
             elif actionName == ShareDefine.CrossActName_AllRecharge:
                 CrossActAllRecharge.RefreshCrossActAllRechargeInfo()
                 
+            elif actionName == ShareDefine.CrossActName_BossTrial:
+                PlayerActBossTrial.RefreshCrossActBossTrialInfo()
+                
             return
         
         if key == ShareDefine.Def_Notify_WorldKey_CrossZoneName:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 6f8cbb3..2cd0f53 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -344,15 +344,17 @@
 CrossActName_CTGBillboard = "CrossActCTGBillboard" # 充值排行榜
 CrossActName_AllRecharge = "CrossActAllRecharge" # 全民充值
 CrossActName_LuckyCloudBuy = "CrossActLuckyCloudBuy" # 幸运云购
+CrossActName_BossTrial = "CrossActBossTrial" # Boss历练 - 跨服
 
 #跨服运营活动列表
-CrossActNameList = [CrossActName_CTGBillboard, CrossActName_AllRecharge, CrossActName_LuckyCloudBuy]
+CrossActNameList = [CrossActName_CTGBillboard, CrossActName_AllRecharge, CrossActName_LuckyCloudBuy, CrossActName_BossTrial]
 #需要锁定活动分区分配直到活动结束的跨服运营活动,即使热更分区配置,也不会改变正在活动中的分区设定,直到活动结束
 CrossActLockServerGroupIDList = [CrossActName_CTGBillboard, CrossActName_AllRecharge]
 
 #活动信息字典key定义
 ActKey_ID = "ID" # 活动ID,唯一标识的ID,一般是活动开启的time值
 ActKey_State = "State" # 活动状态 0-未开启, >0开启中,也代表当日的第几个时间段
+ActKey_StateJoin = "StateJoin" # 活动某些功能可参与状态 0-还不可参与, >0可参与,一般可参与时该状态等于state
 ActKey_CfgID = "CfgID" # 活动表配置ID
 ActKey_ActNum = "ActNum" # 活动分组编号
 ActKey_DayIndex = "DayIndex" # 当前活动天索引,0开始,代表第1天
@@ -806,9 +808,11 @@
     Def_BT_BossTrialSubmit,                   #提交boss凭证榜 (boss历练活动)
     Def_BT_AlineInvade,                       #异兽入侵
     Def_BT_BossTrialSubmitBak,                #提交boss凭证榜 (boss历练活动 - 上一期) 35
+    Def_BT_BossTrialSubmitFamily,             #提交boss凭证仙盟榜 (boss历练活动)
+    Def_BT_BossTrialSubmitFamilyBak,          #提交boss凭证仙盟榜 (boss历练活动 - 上一期)
     
     Def_BT_Max, #排行榜最大类型
-) = range(0, 35 + 2) 
+) = range(0, 37 + 2) 
 
 ''' 跨服排行榜类型, 从 150 开始
 与本服榜单存储的是不一样的数据库表格,理论上类型可以和本服榜单类型重复,为了做下区分防误导,跨服榜单从 150 开始
@@ -824,7 +828,11 @@
 Def_CBT_YaomoBossHurt, # 跨服妖魔boss最新一次伤血排名  155
 Def_CBT_FamilyFlagwar, # 逐鹿万界 - 单场榜  156
 Def_CBT_FamilyFlagwarWeek, # 逐鹿万界 - 周总榜  157
-) = range(150, 157 + 1)
+Def_CBT_BossTrialSubmit, # boss凭证 - 个人榜  158
+Def_CBT_BossTrialSubmitBak, # boss凭证 - 个人榜 上一期  159
+Def_CBT_BossTrialSubmitFamily, # boss凭证 - 仙盟榜  160
+Def_CBT_BossTrialSubmitFamilyBak, # boss凭证 - 仙盟榜 上一期  161
+) = range(150, 161 + 1)
 
 #职业对应战力排行榜类型
 JobFightPowerBillboardDict = {
@@ -1366,7 +1374,8 @@
                       Def_ActionType_XXX10,    #10
                       Def_ActionType_OfficerModelEquip,    #记录家族有职位的成员模型装备信息11
                       Def_ActionType_FamilyEvent,    #记录家族事件12
-                      ) = range(0, 13)
+                      Def_ActionType_BossTrialSubmit,    #boss凭证提交 13
+                      ) = range(0, 14)
 
 # 家族行为事件类型定义; Def_ActionType_FamilyEvent; 存与事件记录Value1
 # 通用:time-时间;name-玩家;value1-事件类型
@@ -1506,6 +1515,7 @@
 CrossServerMsg_CrossDailyActionState = "CrossDailyActionState" # 跨服日常任务状态信息
 CrossServerMsg_CrossYaomoBossHurtInfo = "CrossYaomoBossHurtInfo" # 跨服妖魔boss玩家伤害信息
 CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
+CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
 
 # 子服发送跨服信息定义
 ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
@@ -1542,6 +1552,7 @@
 ClientServerMsg_ChampionshipWorship = "ChampionshipWorship" # 跨服排位膜拜
 ClientServerMsg_ActAllRechargeValue = "ActAllRechargeValue" # 跨服全民充值额度
 ClientServerMsg_CrossYaomoBossHurtAward = "CrossYaomoBossHurtAward" # 跨服妖魔boss玩家伤害领奖
+ClientServerMsg_BossTrialSubmit = "BossTrialSubmit" # boss凭证提交
 
 #跨服广播类型定义
 CrossNotify_CrossAct = "CrossAct"

--
Gitblit v1.8.0