From c77f9ab6cebf625b07075bf6242ab86fff94a5db Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 02 八月 2024 17:17:51 +0800
Subject: [PATCH] 10229 【越南】【主干】【港台】【砍树】古神战场修改(增加功能组队系统;古神支持组队进入,组队参与可增加原当被召集人成就146;)

---
 ServerPython/CoreServerGroup/GameServer/PyNetPack.ini                                                                      |   28 
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/FuncTeam.py                                                     |  249 ++
 ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py                                                            |   35 
 ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py                                                         |  248 ++
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py                                          |   16 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py                                         |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                                         |    9 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py                                                          |   23 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                                         |  411 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                                     |  904 ++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                                          |    2 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                                              |  411 ++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                                          |  904 ++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py                                                            |   17 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py                                             |   22 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py                       |    6 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py                                          |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py |   17 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFuncTeam.py                                                    | 1569 ++++++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py                                                   |   76 
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                                              |    9 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py                           |    6 
 PySysDB/PySysDBG.h                                                                                                         |   14 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFuncTeam.py                               |   56 
 24 files changed, 5,025 insertions(+), 15 deletions(-)

diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h
index ff93107..f755866 100644
--- a/PySysDB/PySysDBG.h
+++ b/PySysDB/PySysDBG.h
@@ -238,6 +238,20 @@
 	list		DayFreeHelpCount;	//每日免费助战次数,[每日免费助战次数, 是否所有层通用]
 };
 
+//功能队伍设定表
+
+struct tagFuncTeamSet
+{
+	DWORD		_FuncMapID;	//功能地图ID
+	BYTE		NeedName;	//需要队伍名
+	BYTE		MemberMax;	//最大人员数
+	BYTE		ApplyMax;	//最大接受申请数
+	BYTE		ReqApplyMax;	//最大申请数
+	BYTE		SortType;	//队伍列表排序方案
+	BYTE		SortReverse;	//是否倒序
+	BYTE		OPLimitInAct;	//活动期间限制队伍操作
+};
+
 //地图表
 
 struct tagChinMap
diff --git a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
index e67bdf0..6d9ca8c 100644
--- a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
+++ b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -263,6 +263,34 @@
 PacketSubCMD_1=0x02
 PacketCallFunc_1=OnDujieFBHelp
 
+;功能组队
+[PlayerFuncTeam]
+ScriptName = Player\PlayerFuncTeam.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 5
+
+PacketCMD_1=0xB9
+PacketSubCMD_1=0x20
+PacketCallFunc_1=OnCreateFuncTeam
+
+PacketCMD_2=0xB9
+PacketSubCMD_2=0x21
+PacketCallFunc_2=OnChangeFuncTeam
+
+PacketCMD_3=0xB9
+PacketSubCMD_3=0x22
+PacketCallFunc_3=OnFuncTeamMemOP
+
+PacketCMD_4=0xB9
+PacketSubCMD_4=0x23
+PacketCallFunc_4=OnQueryFuncTeam
+
+PacketCMD_5=0xB9
+PacketSubCMD_5=0x24
+PacketCallFunc_5=OnQueryPlayerFuncTeam
+
 ;组队
 [PlayerTeam]
 ScriptName = Player\PlayerTeam.py
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 89efac0..331497e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -3595,6 +3595,82 @@
 
 
 #------------------------------------------------------
+# B9 21 修改功能队伍 #tagCGChangeFuncTeam
+
+class  tagCGChangeFuncTeam(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("TeamID", c_int),    
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ("MinLV", c_ushort),    #最低等级限制
+                  ("MinFightPower", c_int),    #最低战力限制,求余亿
+                  ("MinFightPowerEx", c_int),    #最低战力限制,整除亿
+                  ("ServerOnly", c_ubyte),    #是否仅本服玩家可加入,0-否,1-是
+                  ("NeedCheck", c_ubyte),    #是否需要审核
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        self.TeamID = 0
+        self.FuncMapID = 0
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGChangeFuncTeam)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 21 修改功能队伍 //tagCGChangeFuncTeam:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                TeamID:%d,
+                                FuncMapID:%d,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.TeamID,
+                                self.FuncMapID,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck
+                                )
+        return DumpString
+
+
+m_NAtagCGChangeFuncTeam=tagCGChangeFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGChangeFuncTeam.Cmd,m_NAtagCGChangeFuncTeam.SubCmd))] = m_NAtagCGChangeFuncTeam
+
+
+#------------------------------------------------------
 # B9 03 修改队伍信息 #tagCGChangeTeamInfo
 
 class  tagCGChangeTeamInfo(Structure):
@@ -3659,6 +3735,119 @@
 
 
 #------------------------------------------------------
+# B9 20 创建功能队伍 #tagCGCreateFuncTeam
+
+class  tagCGCreateFuncTeam(Structure):
+    Head = tagHead()
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级
+    NameLen = 0    #(BYTE NameLen)
+    TeamName = ""    #(String TeamName)// 队伍名称,可为空
+    MinLV = 0    #(WORD MinLV)//最低等级限制
+    MinFightPower = 0    #(DWORD MinFightPower)//最低战力限制,求余亿
+    MinFightPowerEx = 0    #(DWORD MinFightPowerEx)//最低战力限制,整除亿
+    ServerOnly = 0    #(BYTE ServerOnly)//是否仅本服玩家可加入,0-否,1-是
+    NeedCheck = 0    #(BYTE NeedCheck)//是否需要审核
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TeamName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.MinLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MinFightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinFightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ServerOnly,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.NeedCheck,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.NameLen = 0
+        self.TeamName = ""
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.TeamName)
+        length += 2
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.TeamName)
+        data = CommFunc.WriteWORD(data, self.MinLV)
+        data = CommFunc.WriteDWORD(data, self.MinFightPower)
+        data = CommFunc.WriteDWORD(data, self.MinFightPowerEx)
+        data = CommFunc.WriteBYTE(data, self.ServerOnly)
+        data = CommFunc.WriteBYTE(data, self.NeedCheck)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                NameLen:%d,
+                                TeamName:%s,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.NameLen,
+                                self.TeamName,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck
+                                )
+        return DumpString
+
+
+m_NAtagCGCreateFuncTeam=tagCGCreateFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCreateFuncTeam.Head.Cmd,m_NAtagCGCreateFuncTeam.Head.SubCmd))] = m_NAtagCGCreateFuncTeam
+
+
+#------------------------------------------------------
 # B9 01 创建队伍 #tagCGCreateTeam
 
 class  tagCGCreateTeam(Structure):
@@ -3720,6 +3909,70 @@
 
 m_NAtagCGCreateTeam=tagCGCreateTeam()
 ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCreateTeam.Cmd,m_NAtagCGCreateTeam.SubCmd))] = m_NAtagCGCreateTeam
+
+
+#------------------------------------------------------
+# B9 22 功能队伍成员操作 #tagCGFuncTeamMemOP
+
+class  tagCGFuncTeamMemOP(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("TeamID", c_int),    
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ("OPType", c_ubyte),    # 1-申请加入;2-申请取消;3-同意入队;4-拒绝入队;5-退出队伍;6-踢出队伍;7-转让队长;8-解散队伍;
+                  ("OPData", c_int),    # 可选
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x22
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x22
+        self.TeamID = 0
+        self.FuncMapID = 0
+        self.OPType = 0
+        self.OPData = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGFuncTeamMemOP)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 22 功能队伍成员操作 //tagCGFuncTeamMemOP:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                TeamID:%d,
+                                FuncMapID:%d,
+                                OPType:%d,
+                                OPData:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.TeamID,
+                                self.FuncMapID,
+                                self.OPType,
+                                self.OPData
+                                )
+        return DumpString
+
+
+m_NAtagCGFuncTeamMemOP=tagCGFuncTeamMemOP()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGFuncTeamMemOP.Cmd,m_NAtagCGFuncTeamMemOP.SubCmd))] = m_NAtagCGFuncTeamMemOP
 
 
 #------------------------------------------------------
@@ -3831,6 +4084,164 @@
 
 
 #------------------------------------------------------
+# B9 23 查找功能队伍列表 #tagCGQueryFuncTeam
+
+class  tagCGQueryFuncTeam(Structure):
+    Head = tagHead()
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级,0代表所有
+    StartIndex = 0    #(DWORD StartIndex)// 查看的起始索引, 默认0
+    QueryCnt = 0    #(BYTE QueryCnt)// 查看条数,默认20,最大不超过100
+    HaveSpace = 0    #(BYTE HaveSpace)// 是否只查看有空位置的队伍
+    IDLimitType = 0    #(BYTE IDLimitType)// ID限制类型:1-同仙盟队长;2-同ServerGroupID队长;3-同ServerID队长
+    SearchLen = 0    #(BYTE SearchLen)
+    SearchMsg = ""    #(String SearchMsg)// 指定搜索时有用,可搜索指定队伍ID或模糊搜索队伍名称,搜索时返回最多QueryCnt个数的队伍
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x23
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.StartIndex,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.QueryCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.HaveSpace,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.IDLimitType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchMsg,_pos = CommFunc.ReadString(_lpData, _pos,self.SearchLen)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x23
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.StartIndex = 0
+        self.QueryCnt = 0
+        self.HaveSpace = 0
+        self.IDLimitType = 0
+        self.SearchLen = 0
+        self.SearchMsg = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 1
+        length += 1
+        length += len(self.SearchMsg)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteDWORD(data, self.StartIndex)
+        data = CommFunc.WriteBYTE(data, self.QueryCnt)
+        data = CommFunc.WriteBYTE(data, self.HaveSpace)
+        data = CommFunc.WriteBYTE(data, self.IDLimitType)
+        data = CommFunc.WriteBYTE(data, self.SearchLen)
+        data = CommFunc.WriteString(data, self.SearchLen, self.SearchMsg)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                StartIndex:%d,
+                                QueryCnt:%d,
+                                HaveSpace:%d,
+                                IDLimitType:%d,
+                                SearchLen:%d,
+                                SearchMsg:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.StartIndex,
+                                self.QueryCnt,
+                                self.HaveSpace,
+                                self.IDLimitType,
+                                self.SearchLen,
+                                self.SearchMsg
+                                )
+        return DumpString
+
+
+m_NAtagCGQueryFuncTeam=tagCGQueryFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryFuncTeam.Head.Cmd,m_NAtagCGQueryFuncTeam.Head.SubCmd))] = m_NAtagCGQueryFuncTeam
+
+
+#------------------------------------------------------
+# B9 24 查找玩家功能队伍 #tagCGQueryPlayerFuncTeam
+
+class  tagCGQueryPlayerFuncTeam(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x24
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x24
+        self.FuncMapID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGQueryPlayerFuncTeam)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 24 查找玩家功能队伍 //tagCGQueryPlayerFuncTeam:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                FuncMapID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.FuncMapID
+                                )
+        return DumpString
+
+
+m_NAtagCGQueryPlayerFuncTeam=tagCGQueryPlayerFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryPlayerFuncTeam.Cmd,m_NAtagCGQueryPlayerFuncTeam.SubCmd))] = m_NAtagCGQueryPlayerFuncTeam
+
+
+#------------------------------------------------------
 # B9 05 查询推荐组队的附近玩家 #tagCGQueryRecommendNearbyPlayer
 
 class  tagCGQueryRecommendNearbyPlayer(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index c3fa85f..0aceafa 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -12634,6 +12634,854 @@
 
 
 #------------------------------------------------------
+# B9 23 功能队伍解散 #tagGCFuncTeamDissolve
+
+class  tagGCFuncTeamDissolve(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("TeamID", c_int),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x23
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x23
+        self.TeamID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCFuncTeamDissolve)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 23 功能队伍解散 //tagGCFuncTeamDissolve:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                TeamID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.TeamID
+                                )
+        return DumpString
+
+
+m_NAtagGCFuncTeamDissolve=tagGCFuncTeamDissolve()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFuncTeamDissolve.Cmd,m_NAtagGCFuncTeamDissolve.SubCmd))] = m_NAtagGCFuncTeamDissolve
+
+
+#------------------------------------------------------
+# B9 22 功能队伍列表 #tagGCFuncTeamList
+
+class  tagGCFuncTeamMem(Structure):
+    ServerID = 0    #(DWORD ServerID)
+    PlayerID = 0    #(DWORD PlayerID)
+    NameLen = 0    #(BYTE NameLen)
+    Name = ""    #(String Name)// 玩家名,size = NameLen
+    LV = 0    #(WORD LV)// 玩家等级
+    Job = 0    #(BYTE Job)// 玩家职业
+    RealmLV = 0    #(WORD RealmLV)// 玩家境界
+    FightPower = 0    #(DWORD FightPower)// 战力,求余亿
+    FightPowerEx = 0    #(DWORD FightPowerEx)// 战力,整除亿
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.ServerID = 0
+        self.PlayerID = 0
+        self.NameLen = 0
+        self.Name = ""
+        self.LV = 0
+        self.Job = 0
+        self.RealmLV = 0
+        self.FightPower = 0
+        self.FightPowerEx = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.Name)
+        length += 2
+        length += 1
+        length += 2
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.ServerID)
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.Name)
+        data = CommFunc.WriteWORD(data, self.LV)
+        data = CommFunc.WriteBYTE(data, self.Job)
+        data = CommFunc.WriteWORD(data, self.RealmLV)
+        data = CommFunc.WriteDWORD(data, self.FightPower)
+        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                ServerID:%d,
+                                PlayerID:%d,
+                                NameLen:%d,
+                                Name:%s,
+                                LV:%d,
+                                Job:%d,
+                                RealmLV:%d,
+                                FightPower:%d,
+                                FightPowerEx:%d,
+                                Value1:%d,
+                                Value2:%d
+                                '''\
+                                %(
+                                self.ServerID,
+                                self.PlayerID,
+                                self.NameLen,
+                                self.Name,
+                                self.LV,
+                                self.Job,
+                                self.RealmLV,
+                                self.FightPower,
+                                self.FightPowerEx,
+                                self.Value1,
+                                self.Value2
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeam(Structure):
+    TeamID = 0    #(DWORD TeamID)
+    CreateTime = 0    #(DWORD CreateTime)//创建队伍时间戳
+    FuncMapEx = 0    #(DWORD FuncMapEx)//功能地图扩展,如不同的层级
+    NameLen = 0    #(BYTE NameLen)
+    TeamName = ""    #(String TeamName)//队伍名称
+    CaptainID = 0    #(DWORD CaptainID)//队长ID,队伍ServerID直接取队长的ServerID
+    MinLV = 0    #(WORD MinLV)//最低等级限制
+    MinFightPower = 0    #(DWORD MinFightPower)//最低战力限制,求余亿
+    MinFightPowerEx = 0    #(DWORD MinFightPowerEx)//最低战力限制,整除亿
+    ServerOnly = 0    #(BYTE ServerOnly)//是否仅本服玩家可加入,0-否,1-是
+    NeedCheck = 0    #(BYTE NeedCheck)//是否需要审核
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    MemberCount = 0    #(BYTE MemberCount)
+    MemberList = list()    #(vector<tagGCFuncTeamMem> MemberList)// 成员列表
+    ApplyCount = 0    #(WORD ApplyCount)
+    ApplyIDList = list()    #(vector<DWORD> ApplyIDList)// 申请玩家ID列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.TeamID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CreateTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TeamName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.CaptainID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MinFightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinFightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ServerOnly,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.NeedCheck,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MemberCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemberCount):
+            temMemberList = tagGCFuncTeamMem()
+            _pos = temMemberList.ReadData(_lpData, _pos)
+            self.MemberList.append(temMemberList)
+        self.ApplyCount,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.ApplyCount):
+            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
+            self.ApplyIDList.append(value)
+        return _pos
+
+    def Clear(self):
+        self.TeamID = 0
+        self.CreateTime = 0
+        self.FuncMapEx = 0
+        self.NameLen = 0
+        self.TeamName = ""
+        self.CaptainID = 0
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.MemberCount = 0
+        self.MemberList = list()
+        self.ApplyCount = 0
+        self.ApplyIDList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.TeamName)
+        length += 4
+        length += 2
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 4
+        length += 4
+        length += 1
+        for i in range(self.MemberCount):
+            length += self.MemberList[i].GetLength()
+        length += 2
+        length += 4 * self.ApplyCount
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.TeamID)
+        data = CommFunc.WriteDWORD(data, self.CreateTime)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.TeamName)
+        data = CommFunc.WriteDWORD(data, self.CaptainID)
+        data = CommFunc.WriteWORD(data, self.MinLV)
+        data = CommFunc.WriteDWORD(data, self.MinFightPower)
+        data = CommFunc.WriteDWORD(data, self.MinFightPowerEx)
+        data = CommFunc.WriteBYTE(data, self.ServerOnly)
+        data = CommFunc.WriteBYTE(data, self.NeedCheck)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        data = CommFunc.WriteBYTE(data, self.MemberCount)
+        for i in range(self.MemberCount):
+            data = CommFunc.WriteString(data, self.MemberList[i].GetLength(), self.MemberList[i].GetBuffer())
+        data = CommFunc.WriteWORD(data, self.ApplyCount)
+        for i in range(self.ApplyCount):
+            data = CommFunc.WriteDWORD(data, self.ApplyIDList[i])
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                TeamID:%d,
+                                CreateTime:%d,
+                                FuncMapEx:%d,
+                                NameLen:%d,
+                                TeamName:%s,
+                                CaptainID:%d,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d,
+                                Value1:%d,
+                                Value2:%d,
+                                MemberCount:%d,
+                                MemberList:%s,
+                                ApplyCount:%d,
+                                ApplyIDList:%s
+                                '''\
+                                %(
+                                self.TeamID,
+                                self.CreateTime,
+                                self.FuncMapEx,
+                                self.NameLen,
+                                self.TeamName,
+                                self.CaptainID,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck,
+                                self.Value1,
+                                self.Value2,
+                                self.MemberCount,
+                                "...",
+                                self.ApplyCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeamList(Structure):
+    Head = tagHead()
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级,0代表所有
+    StartIndex = 0    #(DWORD StartIndex)// 查看的起始索引, 默认0
+    QueryCnt = 0    #(BYTE QueryCnt)// 查看条数,默认20,最大不超过100
+    HaveSpace = 0    #(BYTE HaveSpace)// 是否只查看有空位置的队伍
+    IDLimitType = 0    #(BYTE IDLimitType)// ID限制类型:1-同仙盟队长;2-同ServerGroupID队长;3-同ServerID队长
+    SearchLen = 0    #(BYTE SearchLen)
+    SearchMsg = ""    #(String SearchMsg)// 指定搜索时有用,可搜索指定队伍ID或模糊搜索队伍名称,搜索时返回最多QueryCnt个数的队伍
+    LoopIndex = 0    #(DWORD LoopIndex)// 服务器检索到的索引,列表下拉时下一个查询包的StartIndex从这个LoopIndex开始
+    TeamCount = 0    #(BYTE TeamCount)// 如果返回的队伍数小于QueryCnt,代表服务器已经没有满足条件的队伍了,列表再下拉时不再发查询包
+    TeamList = list()    #(vector<tagGCFuncTeam> TeamList)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x22
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.StartIndex,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.QueryCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.HaveSpace,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.IDLimitType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchMsg,_pos = CommFunc.ReadString(_lpData, _pos,self.SearchLen)
+        self.LoopIndex,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.TeamCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.TeamCount):
+            temTeamList = tagGCFuncTeam()
+            _pos = temTeamList.ReadData(_lpData, _pos)
+            self.TeamList.append(temTeamList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x22
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.StartIndex = 0
+        self.QueryCnt = 0
+        self.HaveSpace = 0
+        self.IDLimitType = 0
+        self.SearchLen = 0
+        self.SearchMsg = ""
+        self.LoopIndex = 0
+        self.TeamCount = 0
+        self.TeamList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 1
+        length += 1
+        length += len(self.SearchMsg)
+        length += 4
+        length += 1
+        for i in range(self.TeamCount):
+            length += self.TeamList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteDWORD(data, self.StartIndex)
+        data = CommFunc.WriteBYTE(data, self.QueryCnt)
+        data = CommFunc.WriteBYTE(data, self.HaveSpace)
+        data = CommFunc.WriteBYTE(data, self.IDLimitType)
+        data = CommFunc.WriteBYTE(data, self.SearchLen)
+        data = CommFunc.WriteString(data, self.SearchLen, self.SearchMsg)
+        data = CommFunc.WriteDWORD(data, self.LoopIndex)
+        data = CommFunc.WriteBYTE(data, self.TeamCount)
+        for i in range(self.TeamCount):
+            data = CommFunc.WriteString(data, self.TeamList[i].GetLength(), self.TeamList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                StartIndex:%d,
+                                QueryCnt:%d,
+                                HaveSpace:%d,
+                                IDLimitType:%d,
+                                SearchLen:%d,
+                                SearchMsg:%s,
+                                LoopIndex:%d,
+                                TeamCount:%d,
+                                TeamList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.StartIndex,
+                                self.QueryCnt,
+                                self.HaveSpace,
+                                self.IDLimitType,
+                                self.SearchLen,
+                                self.SearchMsg,
+                                self.LoopIndex,
+                                self.TeamCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCFuncTeamList=tagGCFuncTeamList()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFuncTeamList.Head.Cmd,m_NAtagGCFuncTeamList.Head.SubCmd))] = m_NAtagGCFuncTeamList
+
+
+#------------------------------------------------------
+# B9 20 功能队伍刷新 #tagGCFuncTeamRefresh
+
+class  tagGCFuncTeamRefreshApply(Structure):
+    ServerID = 0    #(DWORD ServerID)
+    PlayerID = 0    #(DWORD PlayerID)
+    NameLen = 0    #(BYTE NameLen)
+    Name = ""    #(String Name)// 玩家名,size = NameLen
+    LV = 0    #(WORD LV)// 玩家等级
+    Job = 0    #(BYTE Job)// 玩家职业
+    RealmLV = 0    #(WORD RealmLV)// 玩家境界
+    FightPower = 0    #(DWORD FightPower)// 战力,求余亿
+    FightPowerEx = 0    #(DWORD FightPowerEx)// 战力,整除亿
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.ServerID = 0
+        self.PlayerID = 0
+        self.NameLen = 0
+        self.Name = ""
+        self.LV = 0
+        self.Job = 0
+        self.RealmLV = 0
+        self.FightPower = 0
+        self.FightPowerEx = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.Name)
+        length += 2
+        length += 1
+        length += 2
+        length += 4
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.ServerID)
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.Name)
+        data = CommFunc.WriteWORD(data, self.LV)
+        data = CommFunc.WriteBYTE(data, self.Job)
+        data = CommFunc.WriteWORD(data, self.RealmLV)
+        data = CommFunc.WriteDWORD(data, self.FightPower)
+        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                ServerID:%d,
+                                PlayerID:%d,
+                                NameLen:%d,
+                                Name:%s,
+                                LV:%d,
+                                Job:%d,
+                                RealmLV:%d,
+                                FightPower:%d,
+                                FightPowerEx:%d
+                                '''\
+                                %(
+                                self.ServerID,
+                                self.PlayerID,
+                                self.NameLen,
+                                self.Name,
+                                self.LV,
+                                self.Job,
+                                self.RealmLV,
+                                self.FightPower,
+                                self.FightPowerEx
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeamRefreshMem(Structure):
+    ServerID = 0    #(DWORD ServerID)
+    PlayerID = 0    #(DWORD PlayerID)
+    NameLen = 0    #(BYTE NameLen)
+    Name = ""    #(String Name)// 玩家名,size = NameLen
+    LV = 0    #(WORD LV)// 玩家等级
+    Job = 0    #(BYTE Job)// 玩家职业
+    RealmLV = 0    #(WORD RealmLV)// 玩家境界
+    FightPower = 0    #(DWORD FightPower)// 战力,求余亿
+    FightPowerEx = 0    #(DWORD FightPowerEx)// 战力,整除亿
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.ServerID = 0
+        self.PlayerID = 0
+        self.NameLen = 0
+        self.Name = ""
+        self.LV = 0
+        self.Job = 0
+        self.RealmLV = 0
+        self.FightPower = 0
+        self.FightPowerEx = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.Name)
+        length += 2
+        length += 1
+        length += 2
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.ServerID)
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.Name)
+        data = CommFunc.WriteWORD(data, self.LV)
+        data = CommFunc.WriteBYTE(data, self.Job)
+        data = CommFunc.WriteWORD(data, self.RealmLV)
+        data = CommFunc.WriteDWORD(data, self.FightPower)
+        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                ServerID:%d,
+                                PlayerID:%d,
+                                NameLen:%d,
+                                Name:%s,
+                                LV:%d,
+                                Job:%d,
+                                RealmLV:%d,
+                                FightPower:%d,
+                                FightPowerEx:%d,
+                                Value1:%d,
+                                Value2:%d
+                                '''\
+                                %(
+                                self.ServerID,
+                                self.PlayerID,
+                                self.NameLen,
+                                self.Name,
+                                self.LV,
+                                self.Job,
+                                self.RealmLV,
+                                self.FightPower,
+                                self.FightPowerEx,
+                                self.Value1,
+                                self.Value2
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeamRefresh(Structure):
+    Head = tagHead()
+    TeamID = 0    #(DWORD TeamID)
+    CreateTime = 0    #(DWORD CreateTime)//创建队伍时间戳
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级
+    NameLen = 0    #(BYTE NameLen)
+    TeamName = ""    #(String TeamName)// 队伍名称
+    CaptainID = 0    #(DWORD CaptainID)//队长ID,队伍ServerID直接取队长的ServerID
+    MinLV = 0    #(WORD MinLV)//最低等级限制
+    MinFightPower = 0    #(DWORD MinFightPower)//最低战力限制,求余亿
+    MinFightPowerEx = 0    #(DWORD MinFightPowerEx)//最低战力限制,整除亿
+    ServerOnly = 0    #(BYTE ServerOnly)//是否仅本服玩家可加入,0-否,1-是
+    NeedCheck = 0    #(BYTE NeedCheck)//是否需要审核
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    MemberCount = 0    #(BYTE MemberCount)
+    MemberList = list()    #(vector<tagGCFuncTeamRefreshMem> MemberList)// 成员列表
+    ApplyCount = 0    #(WORD ApplyCount)
+    ApplyIDList = list()    #(vector<DWORD> ApplyIDList)// 申请玩家ID列表
+    ApplyInfoList = list()    #(vector<tagGCFuncTeamRefreshApply> ApplyInfoList)// 申请玩家明细列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.TeamID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CreateTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TeamName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.CaptainID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MinFightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinFightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ServerOnly,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.NeedCheck,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MemberCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemberCount):
+            temMemberList = tagGCFuncTeamRefreshMem()
+            _pos = temMemberList.ReadData(_lpData, _pos)
+            self.MemberList.append(temMemberList)
+        self.ApplyCount,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.ApplyCount):
+            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
+            self.ApplyIDList.append(value)
+        for i in range(self.ApplyCount):
+            temApplyInfoList = tagGCFuncTeamRefreshApply()
+            _pos = temApplyInfoList.ReadData(_lpData, _pos)
+            self.ApplyInfoList.append(temApplyInfoList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        self.TeamID = 0
+        self.CreateTime = 0
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.NameLen = 0
+        self.TeamName = ""
+        self.CaptainID = 0
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.MemberCount = 0
+        self.MemberList = list()
+        self.ApplyCount = 0
+        self.ApplyIDList = list()
+        self.ApplyInfoList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.TeamName)
+        length += 4
+        length += 2
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 4
+        length += 4
+        length += 1
+        for i in range(self.MemberCount):
+            length += self.MemberList[i].GetLength()
+        length += 2
+        length += 4 * self.ApplyCount
+        for i in range(self.ApplyCount):
+            length += self.ApplyInfoList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.TeamID)
+        data = CommFunc.WriteDWORD(data, self.CreateTime)
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.TeamName)
+        data = CommFunc.WriteDWORD(data, self.CaptainID)
+        data = CommFunc.WriteWORD(data, self.MinLV)
+        data = CommFunc.WriteDWORD(data, self.MinFightPower)
+        data = CommFunc.WriteDWORD(data, self.MinFightPowerEx)
+        data = CommFunc.WriteBYTE(data, self.ServerOnly)
+        data = CommFunc.WriteBYTE(data, self.NeedCheck)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        data = CommFunc.WriteBYTE(data, self.MemberCount)
+        for i in range(self.MemberCount):
+            data = CommFunc.WriteString(data, self.MemberList[i].GetLength(), self.MemberList[i].GetBuffer())
+        data = CommFunc.WriteWORD(data, self.ApplyCount)
+        for i in range(self.ApplyCount):
+            data = CommFunc.WriteDWORD(data, self.ApplyIDList[i])
+        for i in range(self.ApplyCount):
+            data = CommFunc.WriteString(data, self.ApplyInfoList[i].GetLength(), self.ApplyInfoList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                TeamID:%d,
+                                CreateTime:%d,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                NameLen:%d,
+                                TeamName:%s,
+                                CaptainID:%d,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d,
+                                Value1:%d,
+                                Value2:%d,
+                                MemberCount:%d,
+                                MemberList:%s,
+                                ApplyCount:%d,
+                                ApplyIDList:%s,
+                                ApplyInfoList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.TeamID,
+                                self.CreateTime,
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.NameLen,
+                                self.TeamName,
+                                self.CaptainID,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck,
+                                self.Value1,
+                                self.Value2,
+                                self.MemberCount,
+                                "...",
+                                self.ApplyCount,
+                                "...",
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCFuncTeamRefresh=tagGCFuncTeamRefresh()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFuncTeamRefresh.Head.Cmd,m_NAtagGCFuncTeamRefresh.Head.SubCmd))] = m_NAtagGCFuncTeamRefresh
+
+
+#------------------------------------------------------
 # B9 01 收到邀请加入队伍信息 #tagGCInviteJoinTeamInfo
 
 class  tagGCInviteJoinTeamInfo(Structure):
@@ -12945,6 +13793,62 @@
 
 
 #------------------------------------------------------
+# B9 21 查找玩家功能队伍结果 #tagGCQueryPlayerFuncTeamRet
+
+class  tagGCQueryPlayerFuncTeamRet(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ("TeamID", c_int),    # 玩家所属队伍ID,目前只同步0的情况,如果玩家有队伍统一B920封包同步处理
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        self.FuncMapID = 0
+        self.TeamID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCQueryPlayerFuncTeamRet)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 21 查找玩家功能队伍结果 //tagGCQueryPlayerFuncTeamRet:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                FuncMapID:%d,
+                                TeamID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.FuncMapID,
+                                self.TeamID
+                                )
+        return DumpString
+
+
+m_NAtagGCQueryPlayerFuncTeamRet=tagGCQueryPlayerFuncTeamRet()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCQueryPlayerFuncTeamRet.Cmd,m_NAtagGCQueryPlayerFuncTeamRet.SubCmd))] = m_NAtagGCQueryPlayerFuncTeamRet
+
+
+#------------------------------------------------------
 # B9 08 推荐组队的附近玩家信息 #tagGCRecommendNearbyPlayerList
 
 class  tagGCRecommendNearbyPlayer(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/FuncTeam.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/FuncTeam.py
new file mode 100644
index 0000000..a948482
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/FuncTeam.py
@@ -0,0 +1,249 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.FuncTeam
+#
+# @todo:功能队伍
+# @author hxp
+# @date 2024-08-02
+# @version 1.0
+#
+# 详细描述: 功能队伍
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-08-02 16:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyDataManager
+import PlayerFuncTeam
+import IpyGameDataPY
+import ShareDefine
+import ChConfig
+import random
+
+#---------------------------------------------------------------------
+#逻辑实现
+## 执行逻辑
+#  @param curPlayer 当前玩家
+#  @param gmList [cmdIndex gmAccID msg]
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(curPlayer, gmList):
+    ## 本服处理
+    GameWorld.DebugAnswer(curPlayer, "----------------------------")
+    if not gmList:
+        GameWorld.DebugAnswer(curPlayer, "清空队伍: FuncTeam 0")
+        GameWorld.DebugAnswer(curPlayer, "删除队伍: FuncTeam d teamID")
+        GameWorld.DebugAnswer(curPlayer, "创建队伍: FuncTeam c mapID 个数 [最低等级 最低战力 仅本服 需要审核 mapEx zoneID]")
+        GameWorld.DebugAnswer(curPlayer, "添加申请: FuncTeam a teamID 人数 [指定ID ...]")
+        GameWorld.DebugAnswer(curPlayer, "输出队伍: FuncTeam p [teamID]")
+        GameWorld.DebugAnswer(curPlayer, "输出玩家队伍: FuncTeam pt [playerID]")
+        GameWorld.DebugAnswer(curPlayer, "设置队伍ID上限: FuncTeam idMax 最大队伍ID")
+    return
+
+def OnGetMergeParam(curPlayer):
+    playerID = curPlayer.GetPlayerID()
+    serverGroupID = GameWorld.GetServerGroupID()
+    return [serverGroupID, playerID]
+
+def OnMergeServerExec(gmList, tick):
+    ## 跨服处理
+    
+    serverGroupID = gmList[-2]
+    playerID = gmList[-1]
+    
+    gmList = gmList[:-2]
+    if not gmList:
+        return
+    
+    value1 = gmList[0]
+    if value1 == 0:
+        delCount = PlayerFuncTeam.DelTealAll()
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "功能队伍已清空! delCount=%s" % delCount)
+        
+    elif value1 == "d":
+        teamID = gmList[1] if len(gmList) > 1 else 0
+        isOK = PlayerFuncTeam.DelTeam(teamID)
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "删除队伍[%s], isOK=%s" % (teamID, isOK))
+        
+    elif value1 == "c":
+        __CreateFuncTeam(playerID, serverGroupID, gmList)
+        
+    elif value1 == "a":
+        __AddApplyPlayer(playerID, serverGroupID, gmList)
+                
+    elif value1 == "p":
+        __PrintFuncTeamInfo(playerID, serverGroupID, gmList)
+        
+    elif value1 == "pt":
+        __PrintPlayerFuncTeamInfo(playerID, serverGroupID, gmList)
+        
+    elif value1 == "idMax":
+        teamIDMax = gmList[1] if len(gmList) > 1 else 99999
+        funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+        funcTeamMgr.teamIDMax = teamIDMax
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "设置队伍ID上限:%s" % teamIDMax)
+    return
+
+def __CreateFuncTeam(playerID, serverGroupID, gmList):
+    ## 创建虚拟队伍
+    funcMapID = gmList[1] if len(gmList) > 1 else 0
+    createCount = gmList[2] if len(gmList) > 2 else 1
+    minLV = gmList[3] if len(gmList) > 3 else 0
+    minFightPower = gmList[4] if len(gmList) > 4 else 0
+    serverOnly = gmList[5] if len(gmList) > 5 else 0
+    needCheck = gmList[6] if len(gmList) > 6 else 0
+    funcMapEx = gmList[7] if len(gmList) > 7 else 0
+    zoneID = gmList[8] if len(gmList) > 8 else 0
+    if not zoneID:
+        zoneInfo = PlayerFuncTeam.GetFuncTeamMapIDZoneInfo(funcMapID, serverGroupID)
+        if not zoneInfo:
+            return
+        zoneID, _ = zoneInfo
+        
+    captainID = 0
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    captainIDList = funcTeamMgr.playerFuncTeamIDDict.keys()
+    if captainIDList:
+        captainID = min(captainIDList)
+        
+    if not captainID or captainID > 10000:
+        captainID = 10000 # 假队长ID从9999倒序
+        
+    FakeName = "队伍名".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
+    teamInfo = {"funcMapID":funcMapID, "funcMapEx":funcMapEx, "teamName":"", "minLV":minLV, 
+               "minFightPower":minFightPower % ChConfig.Def_PerPointValue, 
+               "minFightPowerEx":minFightPower / ChConfig.Def_PerPointValue, 
+               "serverOnly":serverOnly, "needCheck":needCheck}
+    
+    funcTeamMgr.LockBatch()
+    createTeamIDList = []
+    for _ in xrange(createCount):
+        captainID -= 1
+        if captainID <= 0:
+            break
+        teamInfo.update({
+                         "teamName":"%s%s" % (FakeName, captainID), 
+                         })
+        newTeam = funcTeamMgr.CreateFuncTeam(captainID, teamInfo, zoneID)
+        if not newTeam:
+            break
+        createTeamIDList.append(newTeam.GetTeamID())
+        
+    funcTeamMgr.UnLockBatch()
+    funcTeamMgr.SortTeam(zoneID, funcMapID)
+    funcTeamMgr.SyncMapFuncTeamMemIDInfo(createTeamIDList)
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "成功创建队伍数:%s, 总队伍数:%s" % (len(createTeamIDList), len(funcTeamMgr.funcTeamDict)))
+    return
+
+def __AddApplyPlayer(playerID, serverGroupID, gmList):
+    ## 添加申请人数
+    teamID = gmList[1] if len(gmList) > 1 else 0
+    applyCount = gmList[2] if len(gmList) > 2 else 1
+    applyPlayerIDList = gmList[3:] if len(gmList) > 3 else []
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "队伍不存在! teamID=%s" % teamID)
+        return
+    funcMapID = funcTeam.GetFuncMapID()
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
+    if not ipyData:
+        return
+    applyMax = ipyData.GetApplyMax()
+    if not applyMax:
+        applyMax = 50
+    applyMax = min(applyMax, 100)
+    
+    addCount = 0
+    while applyCount > 0:
+        if applyPlayerIDList:
+            applyID = applyPlayerIDList.pop(0)
+        else:
+            applyID = random.randint(100, 1000)
+        applyIDList = funcTeam.GetApplyIDList()
+        if len(applyIDList) >= applyMax:
+            break
+        if applyID in applyIDList:
+            continue
+        if applyID in funcTeam.GetMemberIDList():
+            continue
+        funcTeam.AddApplyID(applyID)
+        addCount += 1
+        applyCount -= 1
+        
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "队伍申请入队数:%s,teamID:%s,新增:%s" % (len(funcTeam.GetApplyIDList()), teamID, addCount))
+    
+    PlayerFuncTeam.SendFuncTeamToClientServer(teamID)
+    return
+
+def __PrintPlayerFuncTeamInfo(playerID, serverGroupID, gmList):
+    ## 输出玩家队伍
+    tagPlayerID = gmList[1] if len(gmList) > 1 else playerID
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    if tagPlayerID not in funcTeamMgr.playerFuncTeamIDDict:
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "玩家没有队伍! %s" % tagPlayerID)
+        return
+    funcTeamIDDict = funcTeamMgr.playerFuncTeamIDDict[tagPlayerID]
+    for teamID in funcTeamIDDict.values():
+        __PrintFuncTeamDetail(playerID, serverGroupID, teamID)
+    return
+
+def __PrintFuncTeamDetail(playerID, serverGroupID, teamID):
+    ## 输出队伍明细
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "队伍不存在! teamID=%s" % teamID)
+        return
+    captainID = funcTeam.GetCaptainID()
+    memberIDList = funcTeam.GetMemberIDList()
+    applyIDList = funcTeam.GetApplyIDList()
+    fpTotal = funcTeam.GetMemFightPowerTotal()
+    needCheck = funcTeam.GetNeedCheck()
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "队伍ID=%s,队长=%s,队员=%s,申请=%s" 
+                               % (teamID, captainID, len(memberIDList), len(applyIDList)))
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "    zoneID=%s,mapID=%s-%s,审:%s" 
+                               % (funcTeam.GetZoneID(), funcTeam.GetFuncMapID(), funcTeam.GetFuncMapEx(), needCheck))
+    #GameWorld.DebugAnswerCross(playerID, serverGroupID, "    队名=%s" % (funcTeam.GetTeamName()))
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "    总战力=%s" % (fpTotal))
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "    队员ID=%s" % (memberIDList))
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "    申请ID=%s %s" % (applyIDList, len(applyIDList)))
+    return
+
+def __PrintFuncTeamInfo(playerID, serverGroupID, gmList):
+    ## 输出队伍
+    
+    teamID = gmList[1] if len(gmList) > 1 else 0
+    
+    if teamID:
+        __PrintFuncTeamDetail(playerID, serverGroupID, teamID)
+        return
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    if not funcTeamMgr.funcTeamDict:
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "没有功能队伍!")
+        return
+    GameWorld.DebugAnswerCross(playerID, serverGroupID, "总队伍数:%s,最小ID:%s,最大ID:%s" 
+                               % (len(funcTeamMgr.funcTeamDict), min(funcTeamMgr.funcTeamDict), max(funcTeamMgr.funcTeamDict)))
+    
+    for key, funcTeamList in funcTeamMgr.funcTeamListDict.items():
+        zoneID, funcMapID = key
+        if not funcTeamList:
+            continue
+        GameWorld.DebugAnswerCross(playerID, serverGroupID, "zoneID=%s,funcMapID=%s,队伍数=%s" % (zoneID, funcMapID, len(funcTeamList)))
+        for num, funcTeam in enumerate(funcTeamList[:20], 1):
+            teamID = funcTeam.GetTeamID()
+            captainID = funcTeam.GetCaptainID()
+            memberIDList = funcTeam.GetMemberIDList()
+            applyIDList = funcTeam.GetApplyIDList()
+            fpTotal = funcTeam.GetMemFightPowerTotal()
+            needCheck = funcTeam.GetNeedCheck()
+            GameWorld.DebugAnswerCross(playerID, serverGroupID, "%s,ID%s,队长%s,员%s-%s,审%s,战%s" 
+                                       % (num, teamID, captainID, len(memberIDList), len(applyIDList), needCheck, fpTotal))
+    return
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
index 9ac8890..5ed2757 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
@@ -24,6 +24,7 @@
 import CrossRealmPlayer
 import PlayerCompensation
 import PlayerViewCache
+import PlayerFuncTeam
 import CrossBillboard
 import IpyGameDataPY
 import NetPackCommon
@@ -469,7 +470,12 @@
                     PlayerFB.OpenCrossDynamicLineBySys(zoneID, ChConfig.Def_FBMapID_CrossBattlefield, funcLineIDList, True)
                 else:
                     GameWorld.Log("    无召集的场次不开分区战场! zoneID=%s" % (zoneID))
-                    
+                 
+    # 关闭
+    if not battlefieldState and beforeState != battlefieldState:
+        # 活动结束清空队伍
+        PlayerFuncTeam.DelTeamByFunc(ChConfig.Def_FBMapID_CrossBattlefield)
+        
     # 同步子服务器
     dataMsg = {"battlefieldState":battlefieldState}
     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldState, dataMsg)
@@ -897,7 +903,7 @@
     winnerPlayerIDList, loserPlayerIDList = [], []
     for playerInfo in battlePlayerList:
         playerID, job, realmLV, name, \
-            isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, \
+            isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID, \
             isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \
             factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt \
                 = playerInfo
@@ -935,10 +941,10 @@
             cmpValue = highScoreWeekTotal
             CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWScore, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue)
             
-        GameWorld.Log("    战场阵营玩家: faction=%s,isWinner=%s,rank=%s,playerID=%s,score=%s,highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,isCallOpen=%s,isCalled=%s" 
-                      % (faction, isWinner, rank, playerID, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallOpen, isCalled), fbPropertyID)
+        GameWorld.Log("    战场阵营玩家: faction=%s,isWinner=%s,rank=%s,playerID=%s,score=%s,highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,teamID=%s,isCallOpen=%s,isCalled=%s" 
+                      % (faction, isWinner, rank, playerID, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID, isCallOpen, isCalled), fbPropertyID)
         
-        syncPlayerDataInfo[playerID] = [isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek,
+        syncPlayerDataInfo[playerID] = [isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID,
                                         isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, 
                                         factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt]
         
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
index 9ac2e00..0dcbbdd 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
@@ -1395,7 +1395,7 @@
             
             # 添加开启分线数据
             realMapID = mapID
-            copyMapObj = PlayerFB.CrossCopyMapInfo(zoneID, 0)
+            copyMapObj = PlayerFB.CrossCopyMapInfo(zoneID, ChConfig.Def_FBMapID_CrossChampionship, 0)
             copyMapObj.realMapID = realMapID
             copyMapObj.copyMapID = copyMapID
             key = (realMapID, copyMapID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
index 029cf23..ef5a07d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -19,6 +19,7 @@
 import ShareDefine
 import PlayerAssist
 import PlayerControl
+import PlayerFuncTeam
 import CrossLuckyCloudBuy
 import IPY_GameServer
 import CrossRealmPlayer
@@ -175,6 +176,18 @@
             
         elif msgType == ShareDefine.ClientServerMsg_XianXiaMJScore:
             PlayerActXianXiaMJ.ClientServerMsg_XianXiaMJScore(serverGroupID, msgData)
+            
+        elif msgType == ShareDefine.ClientServerMsg_CreateFuncTeam:
+            PlayerFuncTeam.ClientServerMsg_CreateFuncTeam(serverGroupID, msgData)
+            
+        elif msgType == ShareDefine.ClientServerMsg_ChangeFuncTeam:
+            PlayerFuncTeam.ClientServerMsg_ChangeFuncTeam(serverGroupID, msgData)
+            
+        elif msgType == ShareDefine.ClientServerMsg_FuncTeamMemOP:
+            PlayerFuncTeam.ClientServerMsg_FuncTeamMemOP(serverGroupID, msgData)
+            
+        elif msgType == ShareDefine.ClientServerMsg_QueryFuncTeam:
+            PlayerFuncTeam.ClientServerMsg_QueryFuncTeam(serverGroupID, msgData)
             
         # 需要发送到地图服务器处理的
         elif msgType in [ShareDefine.ClientServerMsg_Reborn, ShareDefine.ClientServerMsg_CollectNPC]:
@@ -364,6 +377,15 @@
         elif msgType == ShareDefine.CrossServerMsg_CrossBossTrialFamilyAward:
             PlayerActBossTrial.CrossServerMsg_CrossBossTrialFamilyAward(msgData)
             
+        elif msgType == ShareDefine.CrossServerMsg_FuncTeamInfo:
+            PlayerFuncTeam.CrossServerMsg_FuncTeamInfo(msgData)
+            
+        elif msgType == ShareDefine.CrossServerMsg_FuncTeamDel:
+            PlayerFuncTeam.CrossServerMsg_FuncTeamDel(msgData)
+            
+        elif msgType == ShareDefine.CrossServerMsg_FuncTeamList:
+            PlayerFuncTeam.CrossServerMsg_FuncTeamList(msgData)
+            
         elif msgType == ShareDefine.CrossServerMsg_Worship:
             GameWorship.CrossServerMsg_Worship(msgData)
             
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
index 1cb6eee..2803a32 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -112,6 +112,7 @@
 import CrossBillboard
 import CrossChampionship
 import GameWorldMineArea
+import PlayerFuncTeam
 import GameWorship
 import GameWorldAlineInvade
 import os
@@ -1284,6 +1285,8 @@
     GameWorld.GetGameWorld().GetDBGoldOrderFormMgr().Sort()
     #排序排行榜
     PlayerBillboard.SortServerBillboard()
+    #功能队伍
+    PlayerFuncTeam.OnGameServerInitOK()
     #仙盟
     PlayerFamily.OnGameServerInitOK()
     GameWorldActionControl.Dispose_FBStateTime()
@@ -1498,6 +1501,9 @@
     lastMixServerWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_LastMixServerWorldLV)
     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_LastMixServerWorldLV, lastMixServerWorldLV)
     
+    # 功能队伍
+    PlayerFuncTeam.OnMapServerInitOK()
+    
     # 通知战盟相关活动开启状态
     fadState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_FamilyActivityDayState)
     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyActivityDayState, fadState) 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
index bce27d5..1161e8c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -213,6 +213,17 @@
                         ("list", "DayFreeHelpCount", 0),
                         ),
 
+                "FuncTeamSet":(
+                        ("DWORD", "FuncMapID", 1),
+                        ("BYTE", "NeedName", 0),
+                        ("BYTE", "MemberMax", 0),
+                        ("BYTE", "ApplyMax", 0),
+                        ("BYTE", "ReqApplyMax", 0),
+                        ("BYTE", "SortType", 0),
+                        ("BYTE", "SortReverse", 0),
+                        ("BYTE", "OPLimitInAct", 0),
+                        ),
+
                 "ChinMap":(
                         ("DWORD", "MapID", 1),
                         ("char", "MapName", 0),
@@ -1352,6 +1363,22 @@
     def GetFightPowerMax(self): return self.attrTuple[3] # 助战最高战力,0为不限制 DWORD
     def GetLVLimit(self): return self.attrTuple[4] # 助战等级限制, 0为不限制 WORD
     def GetDayFreeHelpCount(self): return self.attrTuple[5] # 每日免费助战次数,[每日免费助战次数, 是否所有层通用] list
+
+# 功能队伍设定表
+class IPY_FuncTeamSet():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetFuncMapID(self): return self.attrTuple[0] # 功能地图ID DWORD
+    def GetNeedName(self): return self.attrTuple[1] # 需要队伍名 BYTE
+    def GetMemberMax(self): return self.attrTuple[2] # 最大人员数 BYTE
+    def GetApplyMax(self): return self.attrTuple[3] # 最大接受申请数 BYTE
+    def GetReqApplyMax(self): return self.attrTuple[4] # 最大申请数 BYTE
+    def GetSortType(self): return self.attrTuple[5] # 队伍列表排序方案 BYTE
+    def GetSortReverse(self): return self.attrTuple[6] # 是否倒序 BYTE
+    def GetOPLimitInAct(self): return self.attrTuple[7] # 活动期间限制队伍操作 BYTE
 
 # 地图表
 class IPY_ChinMap():
@@ -2676,6 +2703,7 @@
         self.__LoadFileData("FBFunc", onlyCheck)
         self.__LoadFileData("FBLine", onlyCheck)
         self.__LoadFileData("FBHelpBattle", onlyCheck)
+        self.__LoadFileData("FuncTeamSet", onlyCheck)
         self.__LoadFileData("ChinMap", onlyCheck)
         self.__LoadFileData("BOSSInfo", onlyCheck)
         self.__LoadFileData("BOSSFirstKill", onlyCheck)
@@ -3099,6 +3127,13 @@
         self.CheckLoadData("FBHelpBattle")
         return self.ipyFBHelpBattleCache[index]
 
+    def GetFuncTeamSetCount(self):
+        self.CheckLoadData("FuncTeamSet")
+        return self.ipyFuncTeamSetLen
+    def GetFuncTeamSetByIndex(self, index):
+        self.CheckLoadData("FuncTeamSet")
+        return self.ipyFuncTeamSetCache[index]
+
     def GetChinMapCount(self):
         self.CheckLoadData("ChinMap")
         return self.ipyChinMapLen
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
index 10bcd77..3ff9a9a 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -36,6 +36,7 @@
 import CrossChampionship
 import DataRecordPack
 import CrossRealmMsg
+import PyDataManager
 import ShareDefine
 import CrossBoss
 import time
@@ -64,8 +65,9 @@
 ## 跨服地图动态分配的虚拟线路信息 {(mapID, copyMapID):CrossCopyMapInfo, ...}
 class CrossCopyMapInfo():
     
-    def __init__(self, zoneID, funcLineID):
+    def __init__(self, zoneID, funcMapID, funcLineID):
         self.zoneID = zoneID
+        self.funcMapID = funcMapID
         self.funcLineID = funcLineID
         self.newFuncLineNum = 0
         self.realMapID = 0
@@ -97,7 +99,22 @@
     
     def IsMustCopyMapPlayer(self, playerID):
         ## 是否必定在此分线的玩家, 在请求队列里 或 曾经进入到该分线的,都强制认为属于该分线的玩家
-        return playerID in self.waitPlayerDict or playerID in self.enterPlayerIDList
+        if playerID in self.waitPlayerDict or playerID in self.enterPlayerIDList:
+            return True
+        # 队友强制在一起
+        funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+        teamID = funcTeamMgr.GetPlayerTeamID(playerID, self.funcMapID)
+        if not teamID:
+            return False
+        funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+        if not funcTeam:
+            return False
+        for memID in funcTeam.GetMemberIDList():
+            if memID in self.waitPlayerDict or memID in self.enterPlayerIDList:
+                GameWorld.DebugLog("强制和队友在一条线路!  funcMapID=%s,memID=%s,realMapID=%s,copyMapID=%s" 
+                                   % (self.funcMapID, memID, self.realMapID, self.copyMapID), playerID)
+                return True
+        return False
         
     def OnRequestEnterCrossCopyMap(self, playerID, tick, copyMapPlayerMax, includeOffline):
         if not copyMapPlayerMax or self.IsMustCopyMapPlayer(playerID):
@@ -456,7 +473,7 @@
     newFuncLineObj.copyMapID = copyMapID
     newFuncLineObj.newFuncLineNum = newFuncLineNum
     
-    copyMapObj = CrossCopyMapInfo(zoneID, funcLineID)
+    copyMapObj = CrossCopyMapInfo(zoneID, mapID, funcLineID)
     copyMapObj.realMapID = realMapID
     copyMapObj.copyMapID = copyMapID
     copyMapObj.newFuncLineNum = newFuncLineNum
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFuncTeam.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFuncTeam.py
new file mode 100644
index 0000000..5022816
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFuncTeam.py
@@ -0,0 +1,1569 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package PlayerFuncTeam
+#
+# @todo:功能队伍表
+# @author hxp
+# @date 2024-08-02
+# @version 1.0
+#
+# 详细描述: 功能队伍表,支持跨服
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-08-02 16:30"""
+#-------------------------------------------------------------------------------
+
+import CommFunc
+import GameWorld
+import ShareDefine
+import IpyGameDataPY
+import PyDataManager
+import PyGameDataStruct
+import CrossBattlefield
+import CrossRealmPlayer
+import PlayerViewCache
+import ChPyNetSendPack
+import CrossRealmMsg
+import PlayerControl
+import NetPackCommon
+import DirtyList
+import ChConfig
+
+import time
+
+# 队伍操作
+Def_FuncTeamOPList = (
+Def_FuncTeamOP_JoinApply, # 申请加入 1
+Def_FuncTeamOP_JoinCancel, # 申请取消 2
+Def_FuncTeamOP_JoinAgree, # 同意入队 3
+Def_FuncTeamOP_JoinRefuse, # 拒绝入队 4
+Def_FuncTeamOP_Exit, # 退出队伍 5
+Def_FuncTeamOP_Kick, # 踢出队伍 6
+Def_FuncTeamOP_Transfer, # 转让队长 7
+Def_FuncTeamOP_Dissolve, # 解散队伍 8
+) = range(1, 1 + 8)
+
+class PyFuncTeamMem():
+    
+    def __init__(self, dbMemData=None):
+        self.dbMemData = dbMemData
+        return
+    def GetTeamID(self): return self.dbMemData.TeamID
+    def GetPlayerID(self): return self.dbMemData.PlayerID
+    def GetValue1(self): return self.dbMemData.Value1
+    def SetValue1(self, value1): self.dbMemData.Value1 = value1
+    def GetValue2(self): return self.dbMemData.Value2
+    def SetValue2(self, value2): self.dbMemData.Value2 = value2
+    def GetValue3(self): return self.dbMemData.Value3
+    def SetValue3(self, value3): self.dbMemData.Value3 = value3
+    def GetValue4(self): return self.dbMemData.Value4
+    def SetValue4(self, value4): self.dbMemData.Value4 = value4
+    def GetValue5(self): return self.dbMemData.Value5
+    def SetValue5(self, value5): self.dbMemData.Value5 = value5
+    
+    def GetFightPower(self):
+        cacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(self.GetPlayerID()))
+        return cacheDict.get("FightPower", 0)
+    
+    def GetSyncDict(self):
+        # Value 暂时只同步1~2
+        syncDict = {"PlayerID":self.GetPlayerID(), "Value1":self.GetValue1(), "Value2":self.GetValue2()}
+        syncDict.update(PlayerViewCache.GetShotCahceDict(self.GetPlayerID(), False))
+        return syncDict
+    
+class PyFuncTeam():
+    
+    def __init__(self, dbTeamData=None):
+        self.dbTeamData = dbTeamData
+        self.memberList = []
+        self.applyIDList = []
+        try:
+            self.applyIDList = eval(self.dbTeamData.ApplyIDList)
+        except:
+            self.applyIDList = []
+        return
+    
+    def getBuffer(self):
+        self.dbTeamData.ApplyIDList = str(self.applyIDList).replace(" ", "")
+        self.dbTeamData.ApplyIDLen = len(self.dbTeamData.ApplyIDList)
+        return self.dbTeamData.getBuffer()
+    
+    def GetTeamID(self): return self.dbTeamData.TeamID
+    def GetTeamName(self): return self.dbTeamData.TeamName
+    def GetZoneID(self): return self.dbTeamData.ZoneID
+    def GetFuncMapID(self): return self.dbTeamData.FuncMapID
+    def GetFuncMapEx(self): return self.dbTeamData.FuncMapEx
+    def GetCreateTime(self): return self.dbTeamData.CreateTime
+    def GetCaptainID(self): return self.dbTeamData.CaptainID
+    def SetCaptainID(self, captainID): self.dbTeamData.CaptainID = captainID
+    def GetMinLV(self): return self.dbTeamData.MinLV
+    def SetMinLV(self, minLV): self.dbTeamData.MinLV = minLV
+    def GetMinFightPower(self):
+        return self.dbTeamData.MinFightPower + self.dbTeamData.MinFightPowerEx * ChConfig.Def_PerPointValue
+    def SetMinFightPower(self, minFightPower):
+        self.dbTeamData.MinFightPower = minFightPower % ChConfig.Def_PerPointValue
+        self.dbTeamData.MinFightPowerEx = minFightPower / ChConfig.Def_PerPointValue
+        return
+    def GetServerOnly(self): return self.dbTeamData.ServerOnly
+    def SetServerOnly(self, serverOnly): self.dbTeamData.ServerOnly = serverOnly
+    def GetNeedCheck(self): return self.dbTeamData.NeedCheck
+    def SetNeedCheck(self, needCheck): self.dbTeamData.NeedCheck = needCheck
+    def GetValue1(self): return self.dbTeamData.Value1
+    def SetValue1(self, value1): self.dbTeamData.Value1 = value1
+    def GetValue2(self): return self.dbTeamData.Value2
+    def SetValue2(self, value2): self.dbTeamData.Value2 = value2
+    def GetValue3(self): return self.dbTeamData.Value3
+    def SetValue3(self, value3): self.dbTeamData.Value3 = value3
+    def GetValue4(self): return self.dbTeamData.Value4
+    def SetValue4(self, value4): self.dbTeamData.Value4 = value4
+    def GetValue5(self): return self.dbTeamData.Value5
+    def SetValue5(self, value5): self.dbTeamData.Value5 = value5
+    
+    def GetSyncDict(self, applyDetail=False):
+        MemberList = [mem.GetSyncDict() for mem in self.memberList]
+        ApplyIDList = self.applyIDList
+        ApplyList = []
+        if applyDetail:
+            for applyID in ApplyIDList[::-1]:
+                applyPlayerDict = PlayerViewCache.GetShotCahceDict(applyID, False)
+                if not applyPlayerDict:
+                    ApplyIDList.remove(applyID)
+                else:
+                    ApplyList.insert(0, applyPlayerDict)
+        # Value 暂时只同步1~2
+        syncDict = {"TeamID":self.GetTeamID(), "TeamName":self.GetTeamName(), "ZoneID":self.GetZoneID(), "FuncMapID":self.GetFuncMapID(), "FuncMapEx":self.GetFuncMapEx(), 
+                    "CreateTime":self.GetCreateTime(), "CaptainID":self.GetCaptainID(), "MinLV":self.GetMinLV(), "MinFightPower":self.GetMinFightPower(), 
+                    "ServerOnly":self.GetServerOnly(), "NeedCheck":self.GetNeedCheck(), "MemberList":MemberList, "ApplyIDList":ApplyIDList, "ApplyList":ApplyList,
+                    "Value1":self.GetValue1(), "Value2":self.GetValue2()}
+        return syncDict
+    
+    def GetSyncPlayerIDList(self):
+        ## 获取队伍信息需要同步的玩家ID列表  队员 + 申请玩家
+        syncPlayerIDList = []
+        syncPlayerIDList += self.GetMemberIDList()
+        syncPlayerIDList += self.GetApplyIDList()
+        return syncPlayerIDList
+    
+    def AddTeamMember(self, playerID):
+        teamMem = None
+        self.DelApplyID(playerID) # 加入的同时从申请列表中移除
+        mem = self.GetMemberByID(playerID)
+        if mem:
+            teamMem = mem
+            return teamMem
+        dbTeamMemData = PyGameDataStruct.tagDBPyFuncTeamMem()
+        dbTeamMemData.clear()
+        dbTeamMemData.TeamID = self.GetTeamID()
+        dbTeamMemData.PlayerID = playerID
+        teamMem = PyFuncTeamMem(dbTeamMemData)
+        self.AddTeamMemToList(teamMem)
+        return teamMem
+    
+    def AddTeamMemToList(self, teamMem):
+        if teamMem not in self.memberList:
+            self.memberList.append(teamMem)
+            
+        zoneID = self.GetZoneID()
+        teamID = self.GetTeamID()
+        funcMapID = self.GetFuncMapID()
+        teamMgr = PyDataManager.GetDBPyFuncTeamManager()
+        teamMgr.OnTeamMemTeamIDChange(zoneID, funcMapID, teamID, teamMem.GetPlayerID(), teamID)
+        return
+    
+    def GetMemberList(self): return self.memberList    
+    def GetMemberIDList(self): return [mem.GetPlayerID() for mem in self.memberList]
+    def GetMemberByID(self, playerID):
+        for mem in self.memberList:
+            if mem.GetPlayerID() == playerID:
+                return mem
+        return
+    
+    def GetMemFightPowerTotal(self):
+        ## 队员总战力
+        totalFightPower = 0
+        for mem in self.memberList:
+            totalFightPower += mem.GetFightPower()
+        return totalFightPower
+    
+    def DelTeamMember(self, playerID):
+        for mem in self.memberList[::-1]:
+            if mem.GetPlayerID() == playerID:
+                self.memberList.remove(mem)
+                
+                zoneID = self.GetZoneID()
+                teamID = self.GetTeamID()
+                funcMapID = self.GetFuncMapID()
+                teamMgr = PyDataManager.GetDBPyFuncTeamManager()
+                teamMgr.OnTeamMemTeamIDChange(zoneID, funcMapID, teamID, playerID, 0)
+                break
+        return
+    
+    def OnDel(self):
+        self.memberList = []
+        self.applyIDList = []
+        return
+    
+    def GetApplyIDList(self): return self.applyIDList
+    
+    def AddApplyID(self, playerID):
+        if playerID not in self.applyIDList:
+            self.applyIDList.append(playerID)
+        return
+    
+    def DelApplyID(self, playerID):
+        if playerID in self.applyIDList:
+            self.applyIDList.remove(playerID)
+        return
+    
+    def DelApplyIDAll(self):
+        self.applyIDList = []
+        return
+    
+class DBPyFuncTeamMemManager():
+    ## 功能队伍成员管理
+    
+    def __init__(self):
+        return
+    
+    # 保存数据 存数据库和realtimebackup
+    def GetSaveData(self):
+        savaData = ""
+        cntData = ""
+        cnt = 0
+        
+        teamMgr = PyDataManager.GetDBPyFuncTeamManager()
+        for teamList in teamMgr.funcTeamListDict.values():
+            for funcTeam in teamList:
+                for mem in funcTeam.GetMemberList():
+                    cnt += 1
+                    savaData += mem.dbMemData.getBuffer()
+                    
+        GameWorld.Log("Save DBPyFuncTeamMem count :%s len=%s" % (cnt, len(savaData)))
+        return CommFunc.WriteDWORD(cntData, cnt) + savaData
+    
+    # 从数据库载入数据
+    def LoadPyGameData(self, datas, pos, dataslen):
+        cnt, pos = CommFunc.ReadDWORD(datas, pos)
+        GameWorld.Log("Load DBPyFuncTeamMem count :%s" % cnt)
+        
+        teamMgr = PyDataManager.GetDBPyFuncTeamManager()
+        for _ in xrange(cnt):
+            memData = PyGameDataStruct.tagDBPyFuncTeamMem()
+            memData.clear()
+            pos += memData.readData(datas, pos, dataslen)
+            
+            teamID = memData.TeamID
+            funcTeam = teamMgr.GetFuncTeam(teamID)
+            if not funcTeam:
+                continue
+            funcTeam.AddTeamMemToList(PyFuncTeamMem(memData))
+            
+        return pos
+
+class DBPyFuncTeamManager():
+    ## 功能队伍管理
+    
+    def __init__(self):
+        self.Clear()
+        self.teamIDMax = 99999
+        return
+    
+    def Clear(self):
+        self.funcTeamDict = {} # {teamID:PyFuncTeam, ...}
+        self.playerFuncTeamIDDict = {} # {playerID:{funcMapID:teamID, ...}, ...}
+        self.funcTeamListDict = {} # {(zoneID, funcMapID):[PyFuncTeam, ...], ...}
+        self.loopTeamID = 0 # 递增,直到超过上限后,再从头开始
+        self.__loadOK = False # 队伍分多张表加载,队伍表、成员表等,由最后一张表加载完毕后设置为True
+        self.__lockBatch = False # 锁定排序,即暂时不排序,由强制排序后解锁
+        return
+    
+    def __GetNewTeamID(self):
+        ## 获取新队伍ID
+        idMin, idMax = 100, 9999 # 非跨服队伍ID范围,存储本服,合服清空
+        if GameWorld.IsCrossServer():
+            idMin, idMax = 10000, self.teamIDMax # 跨服队伍ID范围,存储跨服,合服不影响
+            
+        teamMax = idMax - idMin + 1
+        if len(self.funcTeamDict) >= teamMax:
+            GameWorld.ErrLog("功能队伍ID已满!")
+            return
+        
+        if not self.loopTeamID and self.funcTeamDict:
+            self.loopTeamID = max(self.funcTeamDict)
+            
+        newTeamID = 0
+        doCount = 0
+        while doCount < teamMax:
+            doCount += 1
+            if not self.loopTeamID or self.loopTeamID >= idMax or self.loopTeamID < idMin:
+                self.loopTeamID = idMin - 1
+            self.loopTeamID += 1
+            if self.loopTeamID not in self.funcTeamDict:
+                newTeamID = self.loopTeamID
+                break
+        return newTeamID
+    
+    def CreateFuncTeam(self, playerID, teamInfo, zoneID=0):
+        funcTeam = None
+        teamID = self.__GetNewTeamID()
+        if not teamID:
+            return funcTeam
+        
+        funcMapID = teamInfo["funcMapID"]
+        funcMapEx = teamInfo["funcMapEx"]
+        dbTeamData = PyGameDataStruct.tagDBPyFuncTeam()
+        dbTeamData.clear()
+        dbTeamData.TeamID = teamID
+        dbTeamData.TeamName = teamInfo["teamName"]
+        dbTeamData.ZoneID = zoneID
+        dbTeamData.FuncMapID = funcMapID
+        dbTeamData.FuncMapEx = funcMapEx
+        dbTeamData.CreateTime = int(time.time())
+        dbTeamData.CaptainID = playerID
+        dbTeamData.MinLV = teamInfo["minLV"]
+        dbTeamData.MinFightPower = teamInfo["minFightPower"]
+        dbTeamData.MinFightPowerEx = teamInfo["minFightPowerEx"]
+        dbTeamData.ServerOnly = teamInfo["serverOnly"]
+        dbTeamData.NeedCheck = teamInfo["needCheck"]
+        dbTeamData.Value1 = teamInfo.get("Value1", 0)
+        dbTeamData.Value2 = teamInfo.get("Value2", 0)
+        dbTeamData.Value3 = teamInfo.get("Value3", 0)
+        dbTeamData.Value4 = teamInfo.get("Value4", 0)
+        dbTeamData.Value5 = teamInfo.get("Value5", 0)
+        
+        funcTeam = PyFuncTeam(dbTeamData)
+        self.__AddFuncTeam(funcTeam)
+        funcTeam.AddTeamMember(playerID)
+        return funcTeam
+    
+    def __AddFuncTeam(self, funcTeam):
+        teamID = funcTeam.GetTeamID()
+        zoneID = funcTeam.GetZoneID()
+        funcMapID = funcTeam.GetFuncMapID()
+        #funcMapEx = teafuncTeammData.GetFuncMapEx()
+        
+        key = (zoneID, funcMapID)
+        if key not in self.funcTeamListDict:
+            self.funcTeamListDict[key] = []
+        funcTeamList = self.funcTeamListDict[key]
+        if funcTeam not in funcTeamList:
+            funcTeamList.append(funcTeam)
+            
+        self.funcTeamDict[teamID] = funcTeam
+        self.SortTeam(zoneID, funcMapID, "create")
+        return
+    
+    def SortTeam(self, zoneID, funcMapID, sortReason=""):
+        if not self.__loadOK:
+            #GameWorld.DebugLog("队伍未加载完毕,不排序")
+            return
+        if self.__lockBatch:
+            #GameWorld.DebugLog("队伍排序锁定中")
+            return
+        
+        teamList = self.GetFuncTeamList(zoneID, funcMapID)
+        if not teamList:
+            return
+        ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
+        if not ipyData:
+            return
+        sortType = ipyData.GetSortType()
+        sortReverse = ipyData.GetSortReverse()
+        # 按创建时间
+        if sortType == 0:
+            if not sortReason or sortReason == "create":
+                teamList.sort(key=lambda t: (t.GetCreateTime()), reverse=sortReverse)
+                #GameWorld.DebugLog("按时间排序: zoneID=%s,funcMapID=%s,sortReason=%s" % (zoneID, funcMapID, sortReason))
+        # 按队员总战力
+        elif sortType == 1:
+            if not sortReason or sortReason == "member":
+                teamList.sort(key=lambda t: (t.GetMemFightPowerTotal()), reverse=sortReverse)
+                #GameWorld.DebugLog("按战力排序: zoneID=%s,funcMapID=%s,sortReason=%s" % (zoneID, funcMapID, sortReason))
+        return
+    
+    def SyncMapFuncTeamMemIDInfo(self, teamIDList=None):
+        ## 同步地图队伍成员信息
+        if not self.__loadOK:
+            return
+        
+        if self.__lockBatch:
+            return
+        
+        teamMemIDInfoDict = {}
+        delTeamIDList = []
+        if not teamIDList:
+            for teamList in self.funcTeamListDict.values():
+                for funcTeam in teamList:
+                    self.__updSyncMapInfo(funcTeam, teamMemIDInfoDict)
+        else:
+            for teamID in teamIDList:
+                funcTeam = self.GetFuncTeam(teamID)
+                if not funcTeam:
+                    delTeamIDList.append(teamID)
+                    continue
+                self.__updSyncMapInfo(funcTeam, teamMemIDInfoDict)
+        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FuncTeamMemIDInfo, [teamIDList, delTeamIDList, teamMemIDInfoDict])
+        return
+    
+    def __updSyncMapInfo(self, funcTeam, teamMemIDInfoDict):
+        if not funcTeam:
+            return
+        zoneID = funcTeam.GetZoneID()
+        teamID = funcTeam.GetTeamID()
+        funcMapID = funcTeam.GetFuncMapID()
+        key = (zoneID, funcMapID)
+        if key not in teamMemIDInfoDict:
+            teamMemIDInfoDict[key] = {}
+        infoDict = teamMemIDInfoDict[key]
+        infoDict[teamID] = funcTeam.GetMemberIDList()
+        return
+    
+    def LockBatch(self): self.__lockBatch = True
+    def UnLockBatch(self): self.__lockBatch = False
+    def IsLockBatch(self): return self.__lockBatch
+    
+    def GetFuncTeam(self, teamID):
+        funcTeam = None
+        if teamID in self.funcTeamDict:
+            funcTeam = self.funcTeamDict[teamID]
+        if not funcTeam and False:
+            # 不会执行,仅为了.提示代码用
+            funcTeam = PyFuncTeam()
+        return funcTeam
+    
+    def GetFuncTeamList(self, zoneID, funcMapID):
+        key = (zoneID, funcMapID)
+        if key not in self.funcTeamListDict:
+            return []
+        return self.funcTeamListDict[key]
+    
+    def DelTeam(self, teamID):
+        ## 删除队伍
+        funcTeam = self.GetFuncTeam(teamID)
+        if not funcTeam:
+            return
+        
+        zoneID = funcTeam.GetZoneID()
+        funcMapID = funcTeam.GetFuncMapID()
+        for mem in funcTeam.GetMemberList():
+            self.__UpdPlayerTeamID(mem.GetPlayerID(), funcMapID, 0)
+        funcTeam.OnDel()
+        self.SyncMapFuncTeamMemIDInfo([teamID])
+        
+        # 移除实例
+        key = (zoneID, funcMapID)
+        if key in self.funcTeamListDict:
+            funcTeamList = self.funcTeamListDict[key]
+            if funcTeam in funcTeamList:
+                funcTeamList.remove(funcTeam)
+                
+        self.funcTeamDict.pop(teamID, None)
+        return
+    
+    def OnTeamMemTeamIDChange(self, zoneID, funcMapID, teamID, playerID, updTeamID):
+        self.__UpdPlayerTeamID(playerID, funcMapID, updTeamID)
+        self.SyncMapFuncTeamMemIDInfo([teamID])
+        self.SortTeam(zoneID, funcMapID, "member")
+        return
+    
+    def __UpdPlayerTeamID(self, playerID, funcMapID, teamID):
+        if playerID not in self.playerFuncTeamIDDict:
+            self.playerFuncTeamIDDict[playerID] = {}
+        teamIDDict = self.playerFuncTeamIDDict[playerID]
+        if not teamID:
+            teamIDDict.pop(funcMapID, 0)
+            if not teamIDDict:
+                self.playerFuncTeamIDDict.pop(playerID, None)
+        else:
+            teamIDDict[funcMapID] = teamID
+        return
+    
+    def GetPlayerTeamID(self, playerID, funcMapID):
+        if playerID not in self.playerFuncTeamIDDict:
+            return 0
+        teamIDDict = self.playerFuncTeamIDDict[playerID]
+        return teamIDDict.get(funcMapID, 0)
+    
+    def IsTeamPlayer(self, playerID):
+        if playerID in self.playerFuncTeamIDDict:
+            return True
+        for teamList in self.funcTeamListDict.values():
+            for funcTeam in teamList:
+                if playerID in funcTeam.GetApplyIDList():
+                    return True
+        return False
+    
+    # 保存数据 存数据库和realtimebackup
+    def GetSaveData(self):
+        savaData = ""
+        cntData = ""
+        cnt = 0
+        
+        for teamList in self.funcTeamListDict.values():
+            for funcTeam in teamList: # 按排好的队伍顺序保存
+                cnt += 1
+                savaData += funcTeam.getBuffer()
+                
+        GameWorld.Log("Save DBPyFuncTeam count :%s len=%s" % (cnt, len(savaData)))
+        return CommFunc.WriteDWORD(cntData, cnt) + savaData
+    
+    # 从数据库载入数据
+    def LoadPyGameData(self, datas, pos, dataslen):
+        cnt, pos = CommFunc.ReadDWORD(datas, pos)
+        GameWorld.Log("Load DBPyFuncTeam count :%s" % cnt)
+        
+        self.Clear()
+        
+        for _ in xrange(cnt):
+            dbTeamData = PyGameDataStruct.tagDBPyFuncTeam()
+            dbTeamData.clear()
+            pos += dbTeamData.readData(datas, pos, dataslen)
+            
+            self.__AddFuncTeam(PyFuncTeam(dbTeamData))
+            
+        return pos
+    
+    def OnTeamLoadOK(self):
+        GameWorld.DebugLog("功能队伍加载完毕")
+        self.__loadOK = True
+        for key in self.funcTeamListDict.keys():
+            zoneID, funcMapID = key
+            self.SortTeam(zoneID, funcMapID)
+        return
+    
+def OnGameServerInitOK():
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeamMgr.OnTeamLoadOK()
+    return
+
+def OnMapServerInitOK():
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeamMgr.SyncMapFuncTeamMemIDInfo()
+    return
+
+def IsOPLimitInAct(curPlayer, funcMapID):
+    ## 活动期间是否限制队伍操作
+    ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
+    if not ipyData:
+        return
+    if not ipyData.GetOPLimitInAct():
+        return
+    isInAct = False
+    if funcMapID == ChConfig.Def_FBMapID_CrossBattlefield:
+        isInAct = CrossBattlefield.GetCrossBattlefieldState()
+    if isInAct:
+        GameWorld.ErrLog("活动期间无法操作队伍! funcMapID=%s" % funcMapID, curPlayer.GetPlayerID())
+    return isInAct
+
+def GetFuncTeamZoneID(funcMapID):
+    zoneID = 0
+    if funcMapID == ChConfig.Def_FBMapID_CrossBattlefield:
+        zoneID = CrossBattlefield.GetCrossBattlefieldZoneID(GameWorld.GetServerGroupID())
+    return zoneID
+
+#// B9 20 创建功能队伍 #tagCGCreateFuncTeam
+#
+#struct    tagCGCreateFuncTeam
+#{
+#    tagHead        Head;
+#    DWORD        FuncMapID;    // 功能地图ID或自定义的活动功能ID
+#    DWORD        FuncMapEx;    // 功能地图扩展,如不同的层级
+#    BYTE        NameLen;
+#    char        TeamName[NameLen];    // 队伍名称,可为空
+#    WORD        MinLV;        //最低等级限制
+#    DWORD        MinFightPower;    //最低战力限制,求余亿
+#    DWORD        MinFightPowerEx;    //最低战力限制,整除亿
+#    BYTE        ServerOnly;    //是否仅本服玩家可加入,0-否,1-是
+#    BYTE        NeedCheck;     //是否需要审核
+#};
+def OnCreateFuncTeam(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    funcMapID = clientData.FuncMapID
+    funcMapEx = clientData.FuncMapEx
+    teamName = clientData.TeamName
+    minLV = clientData.MinLV
+    minFightPower = clientData.MinFightPower
+    minFightPowerEx = clientData.MinFightPowerEx
+    serverOnly = clientData.ServerOnly
+    needCheck = clientData.NeedCheck
+    
+    if IsOPLimitInAct(curPlayer, funcMapID):
+        return
+    
+    zoneID = GetFuncTeamZoneID(funcMapID)
+    if not zoneID:
+        return
+    
+    teamInfo = {"funcMapID":funcMapID, "funcMapEx":funcMapEx, "teamName":teamName, "minLV":minLV, 
+               "minFightPower":minFightPower, "minFightPowerEx":minFightPowerEx, 
+               "serverOnly":serverOnly, "needCheck":needCheck}
+    dataMsg = {"zoneID":zoneID, "playerID":playerID, "teamInfo":teamInfo, "cacheBase":PlayerViewCache.GetSyncCrossCacheBase(curPlayer)}
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_CreateFuncTeam, dataMsg)
+    return
+
+#// B9 21 修改功能队伍 #tagCGChangeFuncTeam
+#
+#struct    tagCGChangeFuncTeam
+#{
+#    tagHead        Head;
+#    DWORD        TeamID;
+#    DWORD        FuncMapID;    // 功能地图ID或自定义的活动功能ID
+#    WORD        MinLV;        //最低等级限制
+#    DWORD        MinFightPower;    //最低战力限制,求余亿
+#    DWORD        MinFightPowerEx;    //最低战力限制,整除亿
+#    BYTE        ServerOnly;    //是否仅本服玩家可加入,0-否,1-是
+#    BYTE        NeedCheck;     //是否需要审核
+#};
+def OnChangeFuncTeam(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    teamID = clientData.TeamID
+    funcMapID = clientData.FuncMapID
+    minLV = clientData.MinLV
+    minFightPower = clientData.MinFightPower
+    minFightPowerEx = clientData.MinFightPowerEx
+    serverOnly = clientData.ServerOnly
+    needCheck = clientData.NeedCheck
+    
+    if IsOPLimitInAct(curPlayer, funcMapID):
+        return
+    
+    zoneID = GetFuncTeamZoneID(funcMapID)
+    if not zoneID:
+        return
+    
+    teamInfo = {"teamID":teamID, "funcMapID":funcMapID, "minLV":minLV, 
+               "minFightPower":minFightPower, "minFightPowerEx":minFightPowerEx, 
+               "serverOnly":serverOnly, "needCheck":needCheck}
+    dataMsg = {"zoneID":zoneID, "playerID":playerID, "teamInfo":teamInfo, "cacheBase":PlayerViewCache.GetSyncCrossCacheBase(curPlayer)}
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_ChangeFuncTeam, dataMsg)
+    return
+
+#// B9 22 功能队伍成员操作 #tagCGFuncTeamMemOP
+#
+#struct    tagCGFuncTeamMemOP
+#{
+#    tagHead        Head;
+#    DWORD        TeamID;
+#    DWORD        FuncMapID;    // 功能地图ID或自定义的活动功能ID
+#    BYTE        OPType;        // 1-申请加入;2-申请取消;3-同意入队;4-拒绝入队;5-退出队伍;6-踢出队伍;7-转让队长;8-解散队伍;
+#    DWORD        OPData;        // 可选
+#};
+def OnFuncTeamMemOP(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    teamID = clientData.TeamID
+    funcMapID = clientData.FuncMapID
+    opType = clientData.OPType
+    opData = clientData.OPData
+    
+    if opType not in Def_FuncTeamOPList:
+        return
+    
+    if IsOPLimitInAct(curPlayer, funcMapID):
+        return
+    
+    zoneID = GetFuncTeamZoneID(funcMapID)
+    if not zoneID:
+        return
+    
+    dataMsg = {"zoneID":zoneID, "playerID":playerID, "teamID":teamID, "funcMapID":funcMapID, 
+               "opType":opType, "opData":opData}
+    dataMsg["cacheBase"] = PlayerViewCache.GetSyncCrossCacheBase(curPlayer)
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_FuncTeamMemOP, dataMsg)
+    return
+
+#// B9 23 查找功能队伍列表 #tagCGQueryFuncTeam
+#
+#struct    tagCGQueryFuncTeam
+#{
+#    tagHead        Head;
+#    DWORD        FuncMapID;    // 功能地图ID或自定义的活动功能ID
+#    DWORD        FuncMapEx;    // 功能地图扩展,如不同的层级,0代表所有
+#    DWORD        StartIndex;    // 查看的起始索引, 默认0
+#    BYTE        QueryCnt;    // 查看条数,默认20,最大不超过100
+#    BYTE        HaveSpace;    // 是否只查看有空位置的队伍
+#    BYTE        IDLimitType;    // ID限制类型:1-同仙盟队长;2-同ServerGroupID队长;3-同ServerID队长
+#    BYTE        SearchLen;
+#    char        SearchMsg[SearchLen];    // 指定搜索时有用,可搜索指定队伍ID或模糊搜索队伍名称,搜索时返回最多QueryCnt个数的队伍
+#};
+def OnQueryFuncTeam(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    funcMapID = clientData.FuncMapID
+    funcMapEx = clientData.FuncMapEx
+    startIndex = clientData.StartIndex
+    queryCnt = clientData.QueryCnt
+    haveSpace = clientData.HaveSpace
+    idLimitType = clientData.IDLimitType
+    searchMsg = clientData.SearchMsg
+    
+    zoneID = GetFuncTeamZoneID(funcMapID)
+    if not zoneID:
+        return
+    
+    dataMsg = {"zoneID":zoneID, "playerID":playerID, "funcMapID":funcMapID, "funcMapEx":funcMapEx, 
+               "startIndex":startIndex, "queryCnt":queryCnt, "haveSpace":haveSpace, "idLimitType":idLimitType, 
+               "searchMsg":searchMsg}
+    dataMsg["cacheBase"] = PlayerViewCache.GetSyncCrossCacheBase(curPlayer)
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryFuncTeam, dataMsg)
+    return
+
+#// B9 24 查找玩家功能队伍 #tagCGQueryPlayerFuncTeam
+#
+#struct    tagCGQueryPlayerFuncTeam
+#{
+#    tagHead        Head;
+#    DWORD        FuncMapID;    // 功能地图ID或自定义的活动功能ID
+#};
+def OnQueryPlayerFuncTeam(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    funcMapID = clientData.FuncMapID
+    
+    zoneID = GetFuncTeamZoneID(funcMapID)
+    if not zoneID:
+        return
+    
+    dataMsg = {"zoneID":zoneID, "playerID":playerID, "funcMapID":funcMapID}
+    dataMsg["cacheBase"] = PlayerViewCache.GetSyncCrossCacheBase(curPlayer)
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryFuncTeam, dataMsg)
+    return
+
+def CrossServerMsg_FuncTeamInfo(msgData):
+    ## 子服收到跨服信息 - 队伍刷新信息
+    infoType = msgData["infoType"]
+    playerID = msgData["playerID"]
+    funcMapID = msgData["funcMapID"]
+    teamInfo = msgData["teamInfo"]
+    teamID = msgData.get("teamID", 0)
+    syncPlayerIDList = msgData.get("syncPlayerIDList", [])
+    notifyMark = msgData.get("notifyMark", "")
+    
+    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+    if curPlayer:
+        if notifyMark:
+            PlayerControl.NotifyCode(curPlayer, notifyMark)
+            
+    if infoType == "QueryPlayerFuncTeam":
+        if curPlayer:
+            if teamInfo:
+                Sync_FuncTeamRefresh(teamInfo, [playerID])
+            else:
+                clientPack = ChPyNetSendPack.tagGCQueryPlayerFuncTeamRet()
+                clientPack.FuncMapID = funcMapID
+                clientPack.TeamID = 0
+                NetPackCommon.SendFakePack(curPlayer, clientPack)
+        return
+    
+    if not teamInfo:
+        # 操作后没有队伍信息了,解散
+        if infoType == "FuncTeamMemOP":
+            Sync_FuncTeamDissolve(teamID, syncPlayerIDList)
+        return
+    
+    Sync_FuncTeamRefresh(teamInfo, syncPlayerIDList)
+    return
+
+def CrossServerMsg_FuncTeamDel(msgData):
+    ## 子服收到跨服信息 - 队伍删除
+    #"zoneID":zoneID, "funcMapID":funcMapID, "delTeamDict":delTeamDict
+    #zoneID = msgData["zoneID"]
+    #funcMapID = msgData["funcMapID"]
+    delTeamDict = msgData["delTeamDict"]
+    for teamID, syncPlayerIDList in delTeamDict.items():
+        Sync_FuncTeamDissolve(teamID, syncPlayerIDList)
+    return
+
+def CrossServerMsg_FuncTeamList(msgData):
+    ## 子服收到跨服信息 - 队伍列表
+    queryInfo = msgData["queryInfo"]
+    loopIndex = msgData["loopIndex"]
+    teamInfoList = msgData["teamInfoList"]
+    
+    playerID = queryInfo["playerID"]
+    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+    if not curPlayer:
+        return
+    
+    clientPack = ChPyNetSendPack.tagGCFuncTeamList()
+    clientPack.FuncMapID = queryInfo["funcMapID"]
+    clientPack.FuncMapEx = queryInfo["funcMapEx"]
+    clientPack.StartIndex = queryInfo["startIndex"]
+    clientPack.QueryCnt = queryInfo["queryCnt"]
+    clientPack.HaveSpace = queryInfo["haveSpace"]
+    clientPack.IDLimitType = queryInfo["idLimitType"]
+    clientPack.SearchMsg = queryInfo["searchMsg"]
+    clientPack.SearchLen = len(clientPack.SearchMsg)
+    clientPack.LoopIndex = loopIndex
+    
+    for teamInfo in teamInfoList:
+        team = ChPyNetSendPack.tagGCFuncTeam()
+        team.TeamID = teamInfo["TeamID"]
+        team.CreateTime = teamInfo["CreateTime"]
+        team.FuncMapEx = teamInfo["FuncMapEx"]
+        team.TeamName = teamInfo["TeamName"]
+        team.NameLen = len(team.TeamName)
+        team.CaptainID = teamInfo["CaptainID"]
+        team.MinLV = teamInfo["MinLV"]
+        team.MinFightPower = teamInfo["MinFightPower"] % ChConfig.Def_PerPointValue
+        team.MinFightPowerEx = teamInfo["MinFightPower"] / ChConfig.Def_PerPointValue
+        team.ServerOnly = teamInfo["ServerOnly"]
+        team.NeedCheck = teamInfo["NeedCheck"]
+        team.Value1 = teamInfo["Value1"]
+        team.Value2 = teamInfo["Value2"]
+        
+        memberList = []
+        for memberInfo in teamInfo["MemberList"]:
+            mem = ChPyNetSendPack.tagGCFuncTeamMem()
+            mem.ServerID = memberInfo["ServerID"]
+            mem.PlayerID = memberInfo["PlayerID"]
+            mem.Name = memberInfo["Name"]
+            mem.NameLen = len(mem.Name)
+            mem.LV = memberInfo["LV"]
+            mem.Job = memberInfo["Job"]
+            mem.RealmLV = memberInfo["RealmLV"]
+            mem.FightPower = memberInfo["FightPower"] % ChConfig.Def_PerPointValue
+            mem.FightPowerEx = memberInfo["FightPower"] / ChConfig.Def_PerPointValue
+            mem.Value1 = memberInfo["Value1"]
+            mem.Value2 = memberInfo["Value2"]
+            memberList.append(mem)
+            
+        team.MemberList = memberList
+        team.MemberCount = len(team.MemberList)
+        team.ApplyIDList = teamInfo["ApplyIDList"]
+        team.ApplyCount = len(team.ApplyIDList)
+        
+        clientPack.TeamList.append(team)
+    clientPack.TeamCount = len(clientPack.TeamList)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
+
+def Sync_FuncTeamRefresh(teamInfo, syncPlayerIDList):
+    ## 功能队伍刷新
+    if not teamInfo or not syncPlayerIDList:
+        return
+    
+    syncPlayerList = []
+    playerManager = GameWorld.GetPlayerManager()
+    for playerID in syncPlayerIDList:
+        player = playerManager.FindPlayerByID(playerID)
+        if player == None or not player.GetInitOK():
+            continue
+        syncPlayerList.append(player)
+        
+    if not syncPlayerList:
+        return
+    
+    clientPack = ChPyNetSendPack.tagGCFuncTeamRefresh()
+    clientPack.TeamID = teamInfo["TeamID"]
+    clientPack.CreateTime = teamInfo["CreateTime"]
+    clientPack.FuncMapID = teamInfo["FuncMapID"]
+    clientPack.FuncMapEx = teamInfo["FuncMapEx"]
+    clientPack.TeamName = teamInfo["TeamName"]
+    clientPack.NameLen = len(clientPack.TeamName)
+    clientPack.CaptainID = teamInfo["CaptainID"]
+    clientPack.MinLV = teamInfo["MinLV"]
+    clientPack.MinFightPower = teamInfo["MinFightPower"] % ChConfig.Def_PerPointValue
+    clientPack.MinFightPowerEx = teamInfo["MinFightPower"] / ChConfig.Def_PerPointValue
+    clientPack.ServerOnly = teamInfo["ServerOnly"]
+    clientPack.NeedCheck = teamInfo["NeedCheck"]
+    clientPack.Value1 = teamInfo["Value1"]
+    clientPack.Value2 = teamInfo["Value2"]
+    
+    memberInfoList = teamInfo["MemberList"]
+    applyInfoList = teamInfo["ApplyList"]
+    
+    memberList = []
+    for memberInfo in memberInfoList:
+        mem = ChPyNetSendPack.tagGCFuncTeamRefreshMem()
+        mem.ServerID = memberInfo["ServerID"]
+        mem.PlayerID = memberInfo["PlayerID"]
+        mem.Name = memberInfo["Name"]
+        mem.NameLen = len(mem.Name)
+        mem.LV = memberInfo["LV"]
+        mem.Job = memberInfo["Job"]
+        mem.RealmLV = memberInfo["RealmLV"]
+        mem.FightPower = memberInfo["FightPower"] % ChConfig.Def_PerPointValue
+        mem.FightPowerEx = memberInfo["FightPower"] / ChConfig.Def_PerPointValue
+        mem.Value1 = memberInfo["Value1"]
+        mem.Value2 = memberInfo["Value2"]
+        memberList.append(mem)
+        
+    applyList, applyIDList = [], []
+    for applyInfo in applyInfoList:
+        applyP = ChPyNetSendPack.tagGCFuncTeamRefreshApply()
+        applyP.ServerID = applyInfo["ServerID"]
+        applyP.PlayerID = applyInfo["PlayerID"]
+        applyP.Name = applyInfo["Name"]
+        applyP.NameLen = len(applyP.Name)
+        applyP.LV = applyInfo["LV"]
+        applyP.Job = applyInfo["Job"]
+        applyP.RealmLV = applyInfo["RealmLV"]
+        applyP.FightPower = applyInfo["FightPower"] % ChConfig.Def_PerPointValue
+        applyP.FightPowerEx = applyInfo["FightPower"] / ChConfig.Def_PerPointValue
+        applyList.append(applyP)
+        applyIDList.append(applyInfo["PlayerID"])
+        
+    clientPack.MemberList = memberList
+    clientPack.MemberCount = len(clientPack.MemberList)
+    clientPack.ApplyIDList = applyIDList
+    clientPack.ApplyInfoList = applyList
+    clientPack.ApplyCount = len(clientPack.ApplyInfoList)
+    
+    for player in syncPlayerList:
+        NetPackCommon.SendFakePack(player, clientPack)
+    return
+
+def Sync_FuncTeamDissolve(teamID, syncPlayerIDList):
+    ## 功能队伍解散
+    if not teamID or not syncPlayerIDList:
+        return
+    
+    syncPlayerList = []
+    playerManager = GameWorld.GetPlayerManager()
+    for playerID in syncPlayerIDList:
+        player = playerManager.FindPlayerByID(playerID)
+        if player == None or not player.GetInitOK():
+            continue
+        syncPlayerList.append(player)
+        
+    if not syncPlayerList:
+        return
+    
+    clientPack = ChPyNetSendPack.tagGCFuncTeamDissolve()
+    clientPack.TeamID = teamID
+    for player in syncPlayerList:
+        NetPackCommon.SendFakePack(player, clientPack)
+    return
+
+##--------------------------------------------------------------------------------------------------
+
+def GetFuncTeamMapIDZoneInfo(funcMapID, serverGroupID):
+    ## 获取功能队伍分区信息
+    
+    funcZoneID = 0
+    serverGroupList = []
+    
+    if funcMapID == ChConfig.Def_FBMapID_CrossBattlefield:
+        zoneIpyData = CrossBattlefield.GetCrossBattlefieldZoneIpyData(serverGroupID)
+        if not zoneIpyData:
+            return
+        funcZoneID = zoneIpyData.GetZoneID()
+        serverGroupList = zoneIpyData.GetServerGroupIDList() # 只通知该分区服务器
+        
+    return funcZoneID, serverGroupList
+
+def ClientServerMsg_CreateFuncTeam(serverGroupID, msgData):
+    ## 收到子服 - 功能队伍创建
+    
+    zoneID = msgData["zoneID"]
+    playerID = msgData["playerID"]
+    teamInfo = msgData["teamInfo"]
+    cacheBase = msgData["cacheBase"]
+    
+    funcMapID = teamInfo["funcMapID"]
+    
+    zoneInfo = GetFuncTeamMapIDZoneInfo(funcMapID, serverGroupID)
+    if not zoneInfo:
+        return
+    funcZoneID, _ = zoneInfo
+    
+    if zoneID != funcZoneID:
+        GameWorld.ErrLog("功能队伍分区不一致,无法创建! funcMapID=%s,zoneID=%s != %s" % (funcMapID, zoneID, funcZoneID), playerID)
+        return
+    
+    canCreate, notifyMark = CheckCanCreateFuncTeam(playerID, teamInfo, zoneID)
+    
+    # 某些功能创建前检查
+    if funcMapID == ChConfig.Def_FBMapID_CrossBattlefield:
+        pass
+    
+    newTeam = None
+    teamID = 0
+    newTeamInfo = {}
+    if canCreate:
+        PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase)
+        funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+        newTeam = funcTeamMgr.CreateFuncTeam(playerID, teamInfo, zoneID)
+        
+    if newTeam:
+        teamID = newTeam.GetTeamID()
+        newTeamInfo = newTeam.GetSyncDict(True)
+        
+        # 某些功能创建后处理
+        if funcMapID == ChConfig.Def_FBMapID_CrossBattlefield:
+            pass
+        
+    else:
+        if not notifyMark:
+            notifyMark = "CreatTeamFail"
+            
+    serverGroupList = [serverGroupID] # 创建仅通知指定服即可
+    syncPlayerIDList = [playerID]
+    sendMsg = {"infoType":"CreateFuncTeam", "zoneID":zoneID, "playerID":playerID, "funcMapID":funcMapID, 
+               "teamInfo":newTeamInfo, "teamID":teamID, "syncPlayerIDList":syncPlayerIDList, "notifyMark":notifyMark}
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamInfo, sendMsg, serverGroupList)
+    return
+
+def CheckCanCreateFuncTeam(playerID, teamInfo, zoneID=0, checkInTeam=True):
+    ## 检查可否创建功能队伍 - 本服跨服通用
+    # @param checkInTeam: 是否检查已经在队伍中,如果功能只允许单个队伍,则需要检查,反之可设置为不检查
+    # @return: 是否可创建, 不可创建提示信息
+    
+    funcMapID = teamInfo["funcMapID"]
+    ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
+    if not ipyData:
+        return False, ""
+    
+    needName = ipyData.GetNeedName()
+    if needName:
+        teamName = teamInfo["teamName"]
+        if not teamName or len(teamName) > 33:
+            # 队伍名不合法
+            return False, "TeamNameLenError"
+        
+        if DirtyList.IsWordForbidden(teamName):
+            return False, "TeamNameUnallow"
+        
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    teamList = funcTeamMgr.GetFuncTeamList(zoneID, funcMapID)
+    for funcTeam in teamList:
+        if needName:
+            if teamName == funcTeam.GetTeamName():
+                # 队伍名已存在
+                return False, "TeamNameExist"
+        
+        if checkInTeam:
+            if funcTeam.GetMemberByID(playerID):
+                # 已经在队伍中
+                return False, "AlreadyHaveTeam"
+            
+    return True, ""
+
+def ClientServerMsg_ChangeFuncTeam(serverGroupID, msgData):
+    ## 收到子服 - 功能队伍修改
+    
+    zoneID = msgData["zoneID"]
+    playerID = msgData["playerID"]
+    teamInfo = msgData["teamInfo"]
+    cacheBase = msgData.get("cacheBase", {})
+    
+    teamID = teamInfo["teamID"]
+    funcMapID = teamInfo["funcMapID"]
+    
+    zoneInfo = GetFuncTeamMapIDZoneInfo(funcMapID, serverGroupID)
+    if not zoneInfo:
+        return
+    funcZoneID, serverGroupList = zoneInfo
+    
+    if zoneID != funcZoneID:
+        GameWorld.ErrLog("功能队伍分区不一致,无法修改! funcMapID=%s,zoneID=%s != %s" % (funcMapID, zoneID, funcZoneID), playerID)
+        return
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        GameWorld.ErrLog("功能队伍不存在! funcMapID=%s,teamID=%s" % (funcMapID, teamID), playerID)
+        return
+    
+    if playerID != funcTeam.GetCaptainID():
+        GameWorld.DebugLog("非功能队伍队长,无法修改! funcMapID=%s,teamID=%s,CaptainID=%s" % (funcMapID, teamID, funcTeam.GetCaptainID()), playerID)
+        return
+    
+    if cacheBase:
+        PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase)
+        
+    funcTeam.SetMinFightPower(teamInfo["minFightPower"] + teamInfo["minFightPowerEx"] * ChConfig.Def_PerPointValue)
+    funcTeam.SetMinLV(teamInfo["minLV"])
+    funcTeam.SetServerOnly(teamInfo["serverOnly"])
+    funcTeam.SetNeedCheck(teamInfo["needCheck"])
+    
+    if not funcTeam.GetNeedCheck():
+        pass
+    
+    teamID = funcTeam.GetTeamID()
+    teamInfo = funcTeam.GetSyncDict(True)
+    syncPlayerIDList = funcTeam.GetSyncPlayerIDList()
+    sendMsg = {"infoType":"ChangeFuncTeam", "zoneID":zoneID, "playerID":playerID, "funcMapID":funcMapID, 
+               "teamInfo":teamInfo, "teamID":teamID, "syncPlayerIDList":syncPlayerIDList}
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamInfo, sendMsg, serverGroupList)
+    return
+
+def ClientServerMsg_FuncTeamMemOP(serverGroupID, msgData):
+    ## 收到子服 - 功能队伍操作
+    
+    zoneID = msgData["zoneID"]
+    playerID = msgData["playerID"] # 操作的玩家ID
+    teamID = msgData["teamID"]
+    funcMapID = msgData["funcMapID"]
+    opType = msgData["opType"]
+    opData = msgData["opData"]
+    cacheBase = msgData.get("cacheBase", {})
+    
+    zoneInfo = GetFuncTeamMapIDZoneInfo(funcMapID, serverGroupID)
+    if not zoneInfo:
+        return
+    funcZoneID, serverGroupList = zoneInfo
+    
+    if zoneID != funcZoneID:
+        GameWorld.ErrLog("功能队伍分区不一致,无法操作! funcMapID=%s,zoneID=%s != %s" % (funcMapID, zoneID, funcZoneID), playerID)
+        return
+    
+    if cacheBase:
+        PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase)
+        
+    isOK = False
+    syncDict = {}
+    teamInfo = {}
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        GameWorld.ErrLog("功能队伍不存在! funcMapID=%s,teamID=%s,opType=%s" % (funcMapID, teamID, opType), playerID)
+        syncDict["notifyMark"] = "TeamNotExist"
+        syncPlayerIDList = [playerID]
+    else:
+        # 仅队长可操作
+        if opType in [Def_FuncTeamOP_JoinAgree, Def_FuncTeamOP_JoinRefuse, Def_FuncTeamOP_Kick, 
+                      Def_FuncTeamOP_Transfer, Def_FuncTeamOP_Dissolve]:
+            if playerID != funcTeam.GetCaptainID():
+                GameWorld.ErrLog("仅队长可操作! funcMapID=%s,teamID=%s,opType=%s,CaptainID=%s" 
+                                 % (funcMapID, teamID, opType, funcTeam.GetCaptainID()), playerID)
+                return
+            
+        syncPlayerIDList = funcTeam.GetSyncPlayerIDList()
+        
+        # 申请加入
+        if opType == Def_FuncTeamOP_JoinApply:
+            isOK = __DoFuncTeamOP_JoinApply(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+            if playerID not in syncPlayerIDList:
+                syncPlayerIDList.append(playerID)
+                
+        # 申请取消
+        elif opType == Def_FuncTeamOP_JoinCancel:
+            isOK = __DoFuncTeamOP_JoinCancel(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+            if playerID not in syncPlayerIDList:
+                syncPlayerIDList.append(playerID)
+                
+        # 同意入队
+        elif opType == Def_FuncTeamOP_JoinAgree:
+            isOK = __DoFuncTeamOP_JoinAgree(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+            
+        # 拒绝入队
+        elif opType == Def_FuncTeamOP_JoinRefuse:
+            isOK = __DoFuncTeamOP_JoinRefuse(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+            
+        # 退出队伍
+        elif opType == Def_FuncTeamOP_Exit:
+            isOK = __DoFuncTeamOP_Exit(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+            
+        # 踢出队伍
+        elif opType == Def_FuncTeamOP_Kick:
+            isOK = __DoFuncTeamOP_Kick(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+            
+        # 转让队长
+        elif opType == Def_FuncTeamOP_Transfer:
+            isOK = __DoFuncTeamOP_Transfer(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+                
+        # 解散队伍
+        elif opType == Def_FuncTeamOP_Dissolve:
+            isOK = __DoFuncTeamOP_Dissolve(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+            
+    if not isOK and not syncDict:
+        # 没有执行成功 且 没有需要回复的信息,则不需要回发子服
+        return
+    
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if funcTeam:
+        teamInfo = funcTeam.GetSyncDict(True)
+        
+    sendMsg = {"infoType":"FuncTeamMemOP", "zoneID":zoneID, "playerID":playerID, "funcMapID":funcMapID, 
+               "teamInfo":teamInfo, "teamID":teamID, "syncPlayerIDList":syncPlayerIDList, "opType":opType}
+    sendMsg.update(syncDict)
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamInfo, sendMsg, serverGroupList)
+    return
+
+def DelTeam(teamID):
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        GameWorld.ErrLog("删除功能队伍时不存在! teamID=%s" % teamID)
+        return
+    zoneID = funcTeam.GetZoneID()
+    funcMapID = funcTeam.GetFuncMapID()
+    syncPlayerIDList = funcTeam.GetSyncPlayerIDList()
+    
+    funcTeamMgr.DelTeam(teamID)
+    
+    if not funcTeamMgr.IsLockBatch():
+        sendMsg = {"zoneID":zoneID, "funcMapID":funcMapID, "delTeamDict":{teamID:syncPlayerIDList}}
+        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamDel, sendMsg)
+        
+    return syncPlayerIDList
+
+def DelTeamByFunc(delFuncMapID):
+    GameWorld.Log("清空功能队伍! delFuncMapID=%s" % delFuncMapID)
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeamMgr.LockBatch()
+    delTeamIDList = []
+    for key, teamList in funcTeamMgr.funcTeamListDict.items():
+        zoneID, funcMapID = key
+        if funcMapID != delFuncMapID:
+            continue
+        delTeamDict = {}
+        for funcTeam in teamList[::-1]:
+            teamID = funcTeam.GetTeamID()
+            syncPlayerIDList = DelTeam(teamID)
+            if syncPlayerIDList:
+                delTeamDict[teamID] = syncPlayerIDList
+            delTeamIDList.append(teamID)
+             
+        # 按分区处理后一次性同步子服
+        zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(funcMapID, zoneID)
+        serverGroupIDList = zoneIpyData.GetServerGroupIDList() if zoneIpyData else []
+        sendMsg = {"zoneID":zoneID, "funcMapID":funcMapID, "delTeamDict":delTeamDict}
+        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamDel, sendMsg, serverGroupIDList)
+    funcTeamMgr.UnLockBatch()
+    
+    delCount = len(delTeamIDList)
+    funcTeamMgr.SyncMapFuncTeamMemIDInfo(delTeamIDList)
+    return delCount
+
+def DelTealAll():
+    delCount = 0
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in range(ipyDataMgr.GetFuncTeamSetCount()):
+        ipyData = ipyDataMgr.GetFuncTeamSetByIndex(index)
+        delCount += DelTeamByFunc(ipyData.GetFuncMapID())
+    return delCount
+
+def SendFuncTeamToClientServer(teamID):
+    ## 同步队伍明细到子服
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    funcMapID = funcTeam.GetFuncMapID()
+    teamInfo = funcTeam.GetSyncDict(True)
+    syncPlayerIDList = funcTeam.GetSyncPlayerIDList()
+    
+    sendMsg = {"infoType":"", "playerID":0, "funcMapID":funcMapID, 
+               "teamInfo":teamInfo, "teamID":teamID, "syncPlayerIDList":syncPlayerIDList}
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamInfo, sendMsg)
+    return
+
+def __DoFuncTeamOP_JoinApply(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 申请加入
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    playerTeamID = funcTeamMgr.GetPlayerTeamID(playerID, funcMapID)
+    if playerTeamID:
+        GameWorld.Log("已经有功能队伍了,不能再申请! funcMapID=%s,playerTeamID=%s" % (funcMapID, playerTeamID), playerID)
+        return
+    
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    
+    if funcTeam.GetMemberByID(playerID):
+        GameWorld.Log("已在功能队伍中! funcMapID=%s,teamID=%s" % (funcMapID, teamID), playerID)
+        return
+    
+    if playerID in funcTeam.GetApplyIDList():
+        GameWorld.Log("已在功能队伍申请列表中! funcMapID=%s,teamID=%s" % (funcMapID, teamID), playerID)
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
+    if not ipyData:
+        return
+    
+    memberMax = ipyData.GetMemberMax()
+    applyMax = ipyData.GetApplyMax()
+    reqApplyMax = ipyData.GetReqApplyMax()
+    
+    if len(funcTeam.GetMemberList()) >= memberMax:
+        GameWorld.DebugLog("功能队伍成员已满! funcMapID=%s,teamID=%s,memberMax=%s" % (funcMapID, teamID, memberMax), playerID)
+        syncDict["notifyMark"] = "TeamMemFull"
+        return
+    
+    if applyMax and len(funcTeam.GetApplyIDList()) >= applyMax:
+        GameWorld.DebugLog("功能队伍申请队列已满! funcMapID=%s,teamID=%s,applyMax=%s" % (funcMapID, teamID, applyMax), playerID)
+        syncDict["notifyMark"] = "TeamApplyFull"
+        return
+    
+    minLV = funcTeam.GetMinLV()
+    if minLV and minLV > cacheBase.get("LV", 0):
+        GameWorld.DebugLog("功能队伍最低等级限制,无法申请! funcMapID=%s,teamID=%s,minLV=%s" % (funcMapID, teamID, minLV), playerID)
+        syncDict["notifyMark"] = "TeamLVLimit"
+        return
+    
+    minFightPower = funcTeam.GetMinFightPower()
+    if minFightPower and minFightPower > cacheBase.get("FightPower", 0):
+        GameWorld.DebugLog("功能队伍最低战力限制,无法申请! funcMapID=%s,teamID=%s,minFightPower=%s" % (funcMapID, teamID, minFightPower), playerID)
+        syncDict["notifyMark"] = "TeamFightPowerLimit"
+        return
+    
+    minServerOnly = funcTeam.GetServerOnly()
+    if minServerOnly:
+        # 待扩展,看是取ServerID,还是 ServerGroupID,需注意GroupID合服后可能不一致的问题
+        pass
+    
+    if reqApplyMax:
+        applyTeamIDList = []
+        teamList = funcTeamMgr.GetFuncTeamList(zoneID, funcMapID)
+        for fTeam in teamList:
+            if playerID in fTeam.GetApplyIDList():
+                applyTeamIDList.append(fTeam.GetTeamID())
+        if len(applyTeamIDList) >= reqApplyMax:
+            GameWorld.DebugLog("玩家申请加入队伍数已满,无法申请! funcMapID=%s,applyTeamCount=%s, %s" 
+                               % (funcMapID, len(applyTeamIDList), applyTeamIDList), playerID)
+            syncDict["notifyMark"] = "TeamReqJoinApplyFull"
+            return
+        
+    if funcTeam.GetNeedCheck():
+        syncDict["notifyMark"] = "TeamReqJoinApplyOK"
+        funcTeam.AddApplyID(playerID)
+    else:
+        funcTeam.AddTeamMember(playerID)
+        
+    return True
+
+def __DoFuncTeamOP_JoinCancel(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 申请取消
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    
+    funcTeam.DelApplyID(playerID)
+    
+    return True
+
+def __DoFuncTeamOP_JoinAgree(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 同意入队
+    # @param opData: 目标玩家ID,为0时一键同意
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
+    if not ipyData:
+        return
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    
+    applyIDList = funcTeam.GetApplyIDList()
+    if not applyIDList:
+        return
+        
+    memberMax = ipyData.GetMemberMax()
+    joinPlayerIDList = []
+    tagPlayerID = opData
+    if tagPlayerID:
+        if tagPlayerID not in applyIDList:
+            GameWorld.Log("目标玩家不在功能队伍申请列表中! funcMapID=%s,teamID=%s,tagPlayerID=%s not in applyIDList=%s" 
+                          % (funcMapID, teamID, tagPlayerID, applyIDList), playerID)
+            return
+        
+        tagPlayerTeamID = funcTeamMgr.GetPlayerTeamID(tagPlayerID, funcMapID)
+        if tagPlayerTeamID:
+            GameWorld.DebugLog("目标玩家已加入其他功能队伍! funcMapID=%s,tagPlayerID=%s,tagPlayerTeamID=%s" 
+                               % (funcMapID, tagPlayerID, tagPlayerTeamID), playerID)
+            syncDict["notifyMark"] = "PlayerInOtherTeam"
+        else:
+            joinPlayerIDList = [tagPlayerID]
+    else:
+        joinPlayerIDList = [] + applyIDList # 一键同意按申请顺序,如需按战力再做优化
+        
+    for joinPlayerID in joinPlayerIDList:
+        if len(funcTeam.GetMemberList()) >= memberMax:
+            GameWorld.DebugLog("功能队伍成员已满! funcMapID=%s,teamID=%s,memberMax=%s" % (funcMapID, teamID, memberMax), playerID)
+            break
+        tagPlayerTeamID = funcTeamMgr.GetPlayerTeamID(joinPlayerID, funcMapID)
+        if tagPlayerTeamID:
+            GameWorld.DebugLog("目标玩家已加入其他功能队伍! funcMapID=%s,joinPlayerID=%s,tagPlayerTeamID=%s" 
+                               % (funcMapID, joinPlayerID, tagPlayerTeamID), playerID)
+            continue
+        funcTeam.AddTeamMember(joinPlayerID)
+        
+    return True
+
+def __DoFuncTeamOP_JoinRefuse(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 拒绝入队
+    # @param opData: 目标玩家ID,为0时一键拒绝
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    
+    tagPlayerID = opData
+    if tagPlayerID:
+        funcTeam.DelApplyID(tagPlayerID)
+    else:
+        funcTeam.DelApplyIDAll() # 一键拒绝
+        
+    return True
+
+def __DoFuncTeamOP_Exit(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 退出队伍
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    
+    # 队长退出,直接解散
+    if playerID == funcTeam.GetCaptainID():
+        return __DoFuncTeamOP_Dissolve(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict)
+    
+    funcTeam.DelTeamMember(playerID)
+    
+    return True
+
+def __DoFuncTeamOP_Kick(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 踢出队伍
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    
+    tagPlayerID = opData
+    if not tagPlayerID:
+        GameWorld.DebugLog("需指定踢出队伍目标队员! opData=%s" % opData, playerID)
+        return
+    
+    if tagPlayerID == funcTeam.GetCaptainID():
+        GameWorld.DebugLog("不能踢队长! opData=%s" % opData, playerID)
+        return
+    
+    funcTeam.DelTeamMember(tagPlayerID)
+    
+    return True
+
+def __DoFuncTeamOP_Transfer(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 转让队长
+    
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+    if not funcTeam:
+        return
+    
+    memberIDList = funcTeam.GetMemberIDList()
+    tagPlayerID = opData
+    if tagPlayerID not in memberIDList:
+        GameWorld.Log("目标玩家不是队员,无法转让队长! funcMapID=%s,teamID=%s,tagPlayerID=%s not in %s" 
+                      % (funcMapID, teamID, tagPlayerID, memberIDList), playerID)
+        return
+    
+    funcTeam.SetCaptainID(tagPlayerID)
+    
+    return True
+
+def __DoFuncTeamOP_Dissolve(zoneID, funcMapID, teamID, playerID, opType, opData, cacheBase, syncDict):
+    ## 解散队伍
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    funcTeamMgr.DelTeam(teamID)
+    return True
+
+def ClientServerMsg_QueryFuncTeam(serverGroupID, msgData):
+    ## 收到子服 - 查找队伍列表
+    
+    zoneID = msgData["zoneID"]
+    playerID = msgData["playerID"]
+    funcMapID = msgData["funcMapID"]
+    cacheBase = msgData.get("cacheBase", {})
+    
+    zoneInfo = GetFuncTeamMapIDZoneInfo(funcMapID, serverGroupID)
+    if not zoneInfo:
+        return
+    funcZoneID, _ = zoneInfo
+    
+    if zoneID != funcZoneID:
+        GameWorld.ErrLog("功能队伍分区不一致,无法查询! funcMapID=%s,zoneID=%s != %s" % (funcMapID, zoneID, funcZoneID), playerID)
+        return
+    
+    if cacheBase:
+        PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase)
+        
+    # 非列表查询,返回玩家相关队伍
+    if "startIndex" not in msgData:
+        funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+        teamID = funcTeamMgr.GetPlayerTeamID(playerID, funcMapID)
+        funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+        teamInfo = funcTeam.GetSyncDict(True) if funcTeam else {}
+        syncPlayerIDList = [playerID]
+        serverGroupList = [serverGroupID]
+        sendMsg = {"infoType":"QueryPlayerFuncTeam", "zoneID":zoneID, "playerID":playerID, "funcMapID":funcMapID, 
+                   "teamInfo":teamInfo, "teamID":teamID, "syncPlayerIDList":syncPlayerIDList}
+        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamInfo, sendMsg, serverGroupList)
+        return
+    
+    # 列表查询
+    funcMapEx = msgData["funcMapEx"]
+    startIndex = msgData["startIndex"]
+    queryCnt = msgData["queryCnt"]
+    haveSpace = msgData["haveSpace"]
+    idLimitType = msgData["idLimitType"]
+    searchMsg = msgData["searchMsg"]
+    if queryCnt <= 0:
+        queryCnt = 20
+    queryCnt = min(100, queryCnt) # 默认20,最大100
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
+    if not ipyData:
+        return
+    memberMax = ipyData.GetMemberMax()
+    
+    idLimitTypeDict = {1:"FamilyID", 2:"ServerGroupID", 3:"AccID"}
+    loopIndex = startIndex
+    teamInfoList = []
+    funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+    teamList = funcTeamMgr.GetFuncTeamList(zoneID, funcMapID)
+    for index in xrange(startIndex, len(teamList)):
+        loopIndex = index + 1
+        funcTeam = teamList[index]
+        if searchMsg:
+            # 精确匹配队伍名、队伍ID的插入在最前面
+            if searchMsg == funcTeam.GetTeamName() or searchMsg == str(funcTeam.GetTeamID()):
+                teamInfoList.insert(0, funcTeam.GetSyncDict(False))
+            elif searchMsg in funcTeam.GetTeamName():
+                teamInfoList.append(funcTeam.GetSyncDict(False))
+            else:
+                continue
+        else:
+            if funcMapEx != 0 and funcMapEx != funcTeam.GetFuncMapEx():
+                continue
+            if haveSpace and len(funcTeam.GetMemberList()) >= memberMax:
+                #GameWorld.DebugLog("已满员,不加入列表查看 teamID=%s" % funcTeam.GetTeamID())
+                continue
+            if idLimitType in idLimitTypeDict:
+                limitAttrName = idLimitTypeDict[idLimitType]
+                curIDValue = cacheBase.get(limitAttrName, 0)
+                captainID = funcTeam.GetCaptainID()
+                cacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(captainID))
+                teamIDValue = cacheDict.get(limitAttrName, 0)
+                if limitAttrName == "AccID":
+                    curIDValue = GameWorld.GetAccIDServerID(str(curIDValue))
+                    teamIDValue = GameWorld.GetAccIDServerID(str(teamIDValue))
+                    
+                if not curIDValue or curIDValue != teamIDValue:
+                    #GameWorld.DebugLog("没有或不同ID限制,不加入列表查看! idLimitType=%s,curIDValue=%s != %s, teamID=%s, captainID=%s" 
+                    #                   % (idLimitType, curIDValue, teamIDValue, funcTeam.GetTeamID(), captainID))
+                    continue
+            teamInfoList.append(funcTeam.GetSyncDict(False))
+            
+        if len(teamInfoList) >= queryCnt:
+            break
+        
+    serverGroupList = [serverGroupID] # 仅通知查询服即可
+    sendMsg = {"teamInfoList":teamInfoList, "loopIndex":loopIndex, "queryInfo":msgData}
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FuncTeamList, sendMsg, serverGroupList)
+    return
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
index 5d8626c..07cf830 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -29,6 +29,7 @@
 import GameWorldSkyTower
 import CrossChampionship
 import CrossBattlefield
+import CrossRealmPlayer
 import PyGameDataStruct
 import IpyGameDataPY
 import PyDataManager
@@ -37,6 +38,7 @@
 
 import json
 import time
+import random
 
 def DoOnDayEx():
     DelOutofTimeViewCacheData()
@@ -57,6 +59,9 @@
         return True
     
     if GameWorship.IsWorshipPlayer(playerID):
+        return True
+    
+    if PyDataManager.GetDBPyFuncTeamManager().IsTeamPlayer(playerID):
         return True
     
     if GameWorldSkyTower.IsSkyTowerPassPlayer(playerID):
@@ -141,7 +146,24 @@
     playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
     if playerID in playerViewCachePyDict:
         curCache = playerViewCachePyDict[playerID]
-    elif isAddNew:
+    elif isAddNew or playerID < 10000:
+        # 内网测试假玩家
+        if playerID < 10000 and not newPropData:
+            openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1)
+            fakeName = "匿名玩家".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
+            fakeName = "%s%s" % (fakeName, playerID)
+            serverID = random.randint(9900, 9950)
+            accID = "fake%s@test@s%s" % (playerID, serverID)
+            newPropData = {
+                           "AccID":accID, 
+                           "PlayerID":playerID, 
+                           "Name":fakeName, 
+                           "Job":random.choice(openJobList) if openJobList else 1, 
+                           "LV":random.randint(100, 200), 
+                           "RealmLV":random.randint(5, 15),
+                           "FightPower":random.randint(1000000, 100000000), 
+                           "ServerGroupID":serverID,
+                           }
         curCache = PyGameDataStruct.tagPlayerViewCachePy()
         curCache.PlayerID = playerID
         if newPropData:
@@ -160,6 +182,58 @@
         curCache.PropDataDict = eval(curCache.PropData)
     return curCache.PropDataDict
 
+def GetShotCahceDict(playerID, withEquip=False):
+    ## 获取玩家简短的缓存信息字典
+    cacheDict = GetCachePropDataDict(FindViewCache(playerID))
+    if not cacheDict:
+        return {}
+    shotCacheDict = {
+                     "PlayerID":playerID, 
+                     "Name":cacheDict["Name"], 
+                     "Job":cacheDict["Job"], 
+                     "LV":cacheDict["LV"], 
+                     "RealmLV":cacheDict["RealmLV"], 
+                     "FightPower":cacheDict["FightPower"],
+                     "ServerID":GameWorld.GetAccIDServerID(cacheDict["AccID"]),
+                     }
+    if withEquip:
+        shotCacheDict.update({
+                              "TitleID":cacheDict.get("TitleID", 0),
+                              "EquipShowSwitch":cacheDict.get("EquipShowSwitch", 0),
+                              "EquipShowID":cacheDict.get("EquipShowID", 0),
+                              })
+    return shotCacheDict
+
+def GetSyncCrossCacheBase(curPlayer):
+    ## 获取同步跨服基础查看缓存,主要用于个别功能需要提前先同步玩家基础缓存到跨服,因为跨服不一定有玩家缓存,需要提前同步
+    playerID = curPlayer.GetPlayerID()
+    cacheDict = GetCachePropDataDict(FindViewCache(playerID))
+    cacheBase = {
+                 "AccID":curPlayer.GetAccID(),
+                 "LV":curPlayer.GetLV(),
+                 "RealmLV":curPlayer.GetOfficialRank(),
+                 "Job":curPlayer.GetJob(),
+                 "VIPLV":curPlayer.GetVIPLv(),
+                 "Name":CrossRealmPlayer.GetCrossPlayerName(curPlayer),
+                 "FamilyID":curPlayer.GetFamilyID(),
+                 "FamilyName":cacheDict.get("FamilyName", ""),
+                 "TitleID":cacheDict.get("TitleID", 0),
+                 "FightPower":PlayerControl.GetFightPower(curPlayer),
+                 "EquipShowSwitch":cacheDict.get("EquipShowSwitch", 0),
+                 "EquipShowID":cacheDict.get("EquipShowID", 0),
+                 "ServerGroupID":PlayerControl.GetPlayerServerGroupID(curPlayer),
+                 }
+    return cacheBase
+
+def UpdCrossCacheBase(playerID, cacheBase):
+    ## 更新同步跨服基础查看缓存
+    cacheDict = GetCachePropDataDict(FindViewCache(playerID, True))
+    if not cacheBase:
+        return cacheDict
+    for k, v in cacheBase.items():
+        cacheDict[k] = v
+    return cacheDict
+
 #//04 01 地图同步玩家缓存数据到GameServer#tagMGUpdatePlayerCache
 #
 #struct    tagMGUpdatePlayerCache
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
index 67c88dd..291784f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -29,6 +29,7 @@
 import PlayerRecData
 import GameWorldMineArea
 import PyGameDataStruct
+import PlayerFuncTeam
 import IpyGameDataPY
 import PlayerCharm
 import PlayerLove
@@ -311,6 +312,8 @@
 
 class PyGameDataManager(object):
     def __init__(self):
+        self.DBPyFuncTeamManager = PlayerFuncTeam.DBPyFuncTeamManager()
+        self.DBPyFuncTeamMemManager = PlayerFuncTeam.DBPyFuncTeamMemManager()
         self.DBPlayerRecDataManager = PlayerRecData.DBPlayerRecDataManager()
         self.DBPyMineAreaAwardManager = GameWorldMineArea.DBPyMineAreaAwardManager()
         self.DBPyMineAreaRecordManager = GameWorldMineArea.DBPyMineAreaRecordManager()
@@ -344,6 +347,8 @@
 
     def GetSaveData(self):
         buff = ""
+        buff += self.DBPyFuncTeamManager.GetSaveData()
+        buff += self.DBPyFuncTeamMemManager.GetSaveData()
         buff += self.DBPlayerRecDataManager.GetSaveData()
         buff += self.DBPyMineAreaAwardManager.GetSaveData()
         buff += self.DBPyMineAreaRecordManager.GetSaveData()
@@ -376,6 +381,8 @@
         return buff
     
     def LoadGameData(self, gameBuffer, pos):
+        pos = self.DBPyFuncTeamManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
+        pos = self.DBPyFuncTeamMemManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.DBPlayerRecDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.DBPyMineAreaAwardManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.DBPyMineAreaRecordManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
@@ -495,6 +502,16 @@
     pyGameDataMgr = GetPyGameDataManager()
     return pyGameDataMgr.familyStoreItemManager
 
+def GetDBPyFuncTeamManager():
+    # 功能队伍管理
+    pyGameDataMgr = GetPyGameDataManager()
+    return pyGameDataMgr.DBPyFuncTeamManager
+
+#def GetDBPyFuncTeamMemManager():
+#    # 功能队伍成员管理
+#    pyGameDataMgr = GetPyGameDataManager()
+#    return pyGameDataMgr.DBPyFuncTeamMemManager
+
 def GetDBPlayerRecDataManager():
     # 玩家记录管理
     pyGameDataMgr = GetPyGameDataManager()
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
index 67dbe48..9b43f57 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
@@ -3148,3 +3148,251 @@
             )
         return output
 
+
+# 功能队伍成员表 #tagDBPyFuncTeamMem
+class tagDBPyFuncTeamMem(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('TeamID', ctypes.c_ulong),
+        ('PlayerID', ctypes.c_ulong),
+        ('Value1', ctypes.c_ulong),
+        ('Value2', ctypes.c_ulong),
+        ('Value3', ctypes.c_ulong),
+        ('Value4', ctypes.c_ulong),
+        ('Value5', ctypes.c_ulong),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+
+    def clear(self):
+        memset(addressof(self), 0, self.getLength())
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        self.TeamID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value3, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value4, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value5, pos = CommFunc.ReadDWORD(buf, pos)
+        return self.getLength()
+
+
+    def getBuffer(self):
+        buf = create_string_buffer(self.getLength())
+        memmove(addressof(buf), addressof(self), self.getLength())
+        return string_at(addressof(buf), self.getLength())
+
+    def getLength(self):
+        return sizeof(tagDBPyFuncTeamMem)
+
+    def outputString(self):
+        output = '''// 功能队伍成员表 #tagDBPyFuncTeamMem:
+            TeamID = %s,
+            PlayerID = %s,
+            Value1 = %s,
+            Value2 = %s,
+            Value3 = %s,
+            Value4 = %s,
+            Value5 = %s,
+            ADOResult = %s,
+            '''%(
+                self.TeamID,
+                self.PlayerID,
+                self.Value1,
+                self.Value2,
+                self.Value3,
+                self.Value4,
+                self.Value5,
+                self.ADOResult,
+            )
+        return output
+
+
+# 功能队伍表 #tagDBPyFuncTeam
+class tagDBPyFuncTeam(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('TeamID', ctypes.c_ulong),
+        ('TeamName', ctypes.c_char * 33),
+        ('ZoneID', ctypes.c_ubyte),
+        ('FuncMapID', ctypes.c_ulong),
+        ('FuncMapEx', ctypes.c_ulong),
+        ('CreateTime', ctypes.c_ulong),
+        ('CaptainID', ctypes.c_ulong),
+        ('MinLV', ctypes.c_ushort),
+        ('MinFightPower', ctypes.c_ulong),
+        ('MinFightPowerEx', ctypes.c_ulong),
+        ('ServerOnly', ctypes.c_ubyte),
+        ('NeedCheck', ctypes.c_ubyte),
+        ('ApplyIDLen', ctypes.c_ushort),
+        ('ApplyIDList', ctypes.c_char_p),
+        ('Value1', ctypes.c_ulong),
+        ('Value2', ctypes.c_ulong),
+        ('Value3', ctypes.c_ulong),
+        ('Value4', ctypes.c_ulong),
+        ('Value5', ctypes.c_ulong),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+    def clear(self):
+        self.TeamID = 0
+        self.TeamName = ''
+        self.ZoneID = 0
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.CreateTime = 0
+        self.CaptainID = 0
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        self.ApplyIDLen = 0
+        self.ApplyIDList = ''
+        self.Value1 = 0
+        self.Value2 = 0
+        self.Value3 = 0
+        self.Value4 = 0
+        self.Value5 = 0
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        self.TeamID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.TeamName, pos = CommFunc.ReadString(buf, pos, 33)
+        self.ZoneID, pos = CommFunc.ReadBYTE(buf, pos)
+        self.FuncMapID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.FuncMapEx, pos = CommFunc.ReadDWORD(buf, pos)
+        self.CreateTime, pos = CommFunc.ReadDWORD(buf, pos)
+        self.CaptainID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.MinLV, pos = CommFunc.ReadWORD(buf, pos)
+        self.MinFightPower, pos = CommFunc.ReadDWORD(buf, pos)
+        self.MinFightPowerEx, pos = CommFunc.ReadDWORD(buf, pos)
+        self.ServerOnly, pos = CommFunc.ReadBYTE(buf, pos)
+        self.NeedCheck, pos = CommFunc.ReadBYTE(buf, pos)
+        self.ApplyIDLen, pos = CommFunc.ReadWORD(buf, pos)
+        tmp, pos = CommFunc.ReadString(buf, pos, self.ApplyIDLen)
+        self.ApplyIDList = ctypes.c_char_p(tmp)
+        self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value3, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value4, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Value5, pos = CommFunc.ReadDWORD(buf, pos)
+        return self.getLength()
+
+    def getBuffer(self):
+        buf = ''
+        buf = CommFunc.WriteDWORD(buf, self.TeamID)
+        buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 33, self.TeamName)
+        buf = CommFunc.WriteBYTE(buf, self.ZoneID)
+        buf = CommFunc.WriteDWORD(buf, self.FuncMapID)
+        buf = CommFunc.WriteDWORD(buf, self.FuncMapEx)
+        buf = CommFunc.WriteDWORD(buf, self.CreateTime)
+        buf = CommFunc.WriteDWORD(buf, self.CaptainID)
+        buf = CommFunc.WriteWORD(buf, self.MinLV)
+        buf = CommFunc.WriteDWORD(buf, self.MinFightPower)
+        buf = CommFunc.WriteDWORD(buf, self.MinFightPowerEx)
+        buf = CommFunc.WriteBYTE(buf, self.ServerOnly)
+        buf = CommFunc.WriteBYTE(buf, self.NeedCheck)
+        buf = CommFunc.WriteWORD(buf, self.ApplyIDLen)
+        buf = CommFunc.WriteString(buf, self.ApplyIDLen, self.ApplyIDList)
+        buf = CommFunc.WriteDWORD(buf, self.Value1)
+        buf = CommFunc.WriteDWORD(buf, self.Value2)
+        buf = CommFunc.WriteDWORD(buf, self.Value3)
+        buf = CommFunc.WriteDWORD(buf, self.Value4)
+        buf = CommFunc.WriteDWORD(buf, self.Value5)
+        return buf
+
+    def getLength(self):
+        length = 0
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_char) * 33
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ushort)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ushort)
+        length += self.ApplyIDLen
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        return length
+
+    def outputString(self):
+        output = '''// 功能队伍表 #tagDBPyFuncTeam:
+            TeamID = %s,
+            TeamName = %s,
+            ZoneID = %s,
+            FuncMapID = %s,
+            FuncMapEx = %s,
+            CreateTime = %s,
+            CaptainID = %s,
+            MinLV = %s,
+            MinFightPower = %s,
+            MinFightPowerEx = %s,
+            ServerOnly = %s,
+            NeedCheck = %s,
+            ApplyIDLen = %s,
+            ApplyIDList = %s,
+            Value1 = %s,
+            Value2 = %s,
+            Value3 = %s,
+            Value4 = %s,
+            Value5 = %s,
+            ADOResult = %s,
+            '''%(
+                self.TeamID,
+                self.TeamName,
+                self.ZoneID,
+                self.FuncMapID,
+                self.FuncMapEx,
+                self.CreateTime,
+                self.CaptainID,
+                self.MinLV,
+                self.MinFightPower,
+                self.MinFightPowerEx,
+                self.ServerOnly,
+                self.NeedCheck,
+                self.ApplyIDLen,
+                self.ApplyIDList,
+                self.Value1,
+                self.Value2,
+                self.Value3,
+                self.Value4,
+                self.Value5,
+                self.ADOResult,
+            )
+        return output
+
+    #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
+    def SetTeamName(self,Str):
+        if len(Str)<=33:
+            self.TeamName = Str
+        else:
+            self.TeamName = Str[:33]
+            
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index c3e36dd..c5b9ab0 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -187,6 +187,8 @@
 Def_Notify_WorldKey_CrossBattlefieldCallTeamInfo = "CrossBattlefieldCallTeamInfo" # 跨服战场召集队伍信息
 Def_Notify_WorldKey_CrossBattlefieldSysCallBuyInfo = "CrossBattlefieldSysCallBuyInfo" # 跨服战场系统场次购买召集信息
 
+Def_Notify_WorldKey_FuncTeamMemIDInfo = "FuncTeamMemIDInfo" # 功能队伍成员ID信息
+
 CrossChampionshipState_Guess8 = 80 #8强竞猜
 CrossChampionshipState_Group64 = 641 #64强分组
 CrossChampionshipState_Enter64 = 642 #64强进场
@@ -1594,6 +1596,9 @@
 CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
 CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
 CrossServerMsg_Worship = "Worship"  # 膜拜信息
+CrossServerMsg_FuncTeamInfo = "FuncTeamInfo"  # 功能队伍信息同步
+CrossServerMsg_FuncTeamDel = "FuncTeamDel"  # 功能队伍删除同步
+CrossServerMsg_FuncTeamList = "FuncTeamList"  # 功能队伍列表同步
 
 # 子服发送跨服信息定义
 ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
@@ -1632,6 +1637,10 @@
 ClientServerMsg_CrossYaomoBossHurtAward = "CrossYaomoBossHurtAward" # 跨服妖魔boss玩家伤害领奖
 ClientServerMsg_BossTrialSubmit = "BossTrialSubmit" # boss凭证提交
 ClientServerMsg_XianXiaMJScore = "XianXiaMJScore" # 仙匣秘境积分
+ClientServerMsg_CreateFuncTeam = "CreateFuncTeam"   # 创建功能队伍
+ClientServerMsg_ChangeFuncTeam = "ChangeFuncTeam"   # 修改功能队伍
+ClientServerMsg_FuncTeamMemOP = "FuncTeamMemOP"   # 功能队伍成员操作
+ClientServerMsg_QueryFuncTeam = "QueryFuncTeam"   # 查询功能队伍
 
 #跨服广播类型定义
 CrossNotify_CrossAct = "CrossAct"
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 89efac0..331497e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -3595,6 +3595,82 @@
 
 
 #------------------------------------------------------
+# B9 21 修改功能队伍 #tagCGChangeFuncTeam
+
+class  tagCGChangeFuncTeam(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("TeamID", c_int),    
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ("MinLV", c_ushort),    #最低等级限制
+                  ("MinFightPower", c_int),    #最低战力限制,求余亿
+                  ("MinFightPowerEx", c_int),    #最低战力限制,整除亿
+                  ("ServerOnly", c_ubyte),    #是否仅本服玩家可加入,0-否,1-是
+                  ("NeedCheck", c_ubyte),    #是否需要审核
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        self.TeamID = 0
+        self.FuncMapID = 0
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGChangeFuncTeam)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 21 修改功能队伍 //tagCGChangeFuncTeam:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                TeamID:%d,
+                                FuncMapID:%d,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.TeamID,
+                                self.FuncMapID,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck
+                                )
+        return DumpString
+
+
+m_NAtagCGChangeFuncTeam=tagCGChangeFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGChangeFuncTeam.Cmd,m_NAtagCGChangeFuncTeam.SubCmd))] = m_NAtagCGChangeFuncTeam
+
+
+#------------------------------------------------------
 # B9 03 修改队伍信息 #tagCGChangeTeamInfo
 
 class  tagCGChangeTeamInfo(Structure):
@@ -3659,6 +3735,119 @@
 
 
 #------------------------------------------------------
+# B9 20 创建功能队伍 #tagCGCreateFuncTeam
+
+class  tagCGCreateFuncTeam(Structure):
+    Head = tagHead()
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级
+    NameLen = 0    #(BYTE NameLen)
+    TeamName = ""    #(String TeamName)// 队伍名称,可为空
+    MinLV = 0    #(WORD MinLV)//最低等级限制
+    MinFightPower = 0    #(DWORD MinFightPower)//最低战力限制,求余亿
+    MinFightPowerEx = 0    #(DWORD MinFightPowerEx)//最低战力限制,整除亿
+    ServerOnly = 0    #(BYTE ServerOnly)//是否仅本服玩家可加入,0-否,1-是
+    NeedCheck = 0    #(BYTE NeedCheck)//是否需要审核
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TeamName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.MinLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MinFightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinFightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ServerOnly,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.NeedCheck,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.NameLen = 0
+        self.TeamName = ""
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.TeamName)
+        length += 2
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.TeamName)
+        data = CommFunc.WriteWORD(data, self.MinLV)
+        data = CommFunc.WriteDWORD(data, self.MinFightPower)
+        data = CommFunc.WriteDWORD(data, self.MinFightPowerEx)
+        data = CommFunc.WriteBYTE(data, self.ServerOnly)
+        data = CommFunc.WriteBYTE(data, self.NeedCheck)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                NameLen:%d,
+                                TeamName:%s,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.NameLen,
+                                self.TeamName,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck
+                                )
+        return DumpString
+
+
+m_NAtagCGCreateFuncTeam=tagCGCreateFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCreateFuncTeam.Head.Cmd,m_NAtagCGCreateFuncTeam.Head.SubCmd))] = m_NAtagCGCreateFuncTeam
+
+
+#------------------------------------------------------
 # B9 01 创建队伍 #tagCGCreateTeam
 
 class  tagCGCreateTeam(Structure):
@@ -3720,6 +3909,70 @@
 
 m_NAtagCGCreateTeam=tagCGCreateTeam()
 ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCreateTeam.Cmd,m_NAtagCGCreateTeam.SubCmd))] = m_NAtagCGCreateTeam
+
+
+#------------------------------------------------------
+# B9 22 功能队伍成员操作 #tagCGFuncTeamMemOP
+
+class  tagCGFuncTeamMemOP(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("TeamID", c_int),    
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ("OPType", c_ubyte),    # 1-申请加入;2-申请取消;3-同意入队;4-拒绝入队;5-退出队伍;6-踢出队伍;7-转让队长;8-解散队伍;
+                  ("OPData", c_int),    # 可选
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x22
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x22
+        self.TeamID = 0
+        self.FuncMapID = 0
+        self.OPType = 0
+        self.OPData = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGFuncTeamMemOP)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 22 功能队伍成员操作 //tagCGFuncTeamMemOP:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                TeamID:%d,
+                                FuncMapID:%d,
+                                OPType:%d,
+                                OPData:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.TeamID,
+                                self.FuncMapID,
+                                self.OPType,
+                                self.OPData
+                                )
+        return DumpString
+
+
+m_NAtagCGFuncTeamMemOP=tagCGFuncTeamMemOP()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGFuncTeamMemOP.Cmd,m_NAtagCGFuncTeamMemOP.SubCmd))] = m_NAtagCGFuncTeamMemOP
 
 
 #------------------------------------------------------
@@ -3831,6 +4084,164 @@
 
 
 #------------------------------------------------------
+# B9 23 查找功能队伍列表 #tagCGQueryFuncTeam
+
+class  tagCGQueryFuncTeam(Structure):
+    Head = tagHead()
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级,0代表所有
+    StartIndex = 0    #(DWORD StartIndex)// 查看的起始索引, 默认0
+    QueryCnt = 0    #(BYTE QueryCnt)// 查看条数,默认20,最大不超过100
+    HaveSpace = 0    #(BYTE HaveSpace)// 是否只查看有空位置的队伍
+    IDLimitType = 0    #(BYTE IDLimitType)// ID限制类型:1-同仙盟队长;2-同ServerGroupID队长;3-同ServerID队长
+    SearchLen = 0    #(BYTE SearchLen)
+    SearchMsg = ""    #(String SearchMsg)// 指定搜索时有用,可搜索指定队伍ID或模糊搜索队伍名称,搜索时返回最多QueryCnt个数的队伍
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x23
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.StartIndex,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.QueryCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.HaveSpace,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.IDLimitType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchMsg,_pos = CommFunc.ReadString(_lpData, _pos,self.SearchLen)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x23
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.StartIndex = 0
+        self.QueryCnt = 0
+        self.HaveSpace = 0
+        self.IDLimitType = 0
+        self.SearchLen = 0
+        self.SearchMsg = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 1
+        length += 1
+        length += len(self.SearchMsg)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteDWORD(data, self.StartIndex)
+        data = CommFunc.WriteBYTE(data, self.QueryCnt)
+        data = CommFunc.WriteBYTE(data, self.HaveSpace)
+        data = CommFunc.WriteBYTE(data, self.IDLimitType)
+        data = CommFunc.WriteBYTE(data, self.SearchLen)
+        data = CommFunc.WriteString(data, self.SearchLen, self.SearchMsg)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                StartIndex:%d,
+                                QueryCnt:%d,
+                                HaveSpace:%d,
+                                IDLimitType:%d,
+                                SearchLen:%d,
+                                SearchMsg:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.StartIndex,
+                                self.QueryCnt,
+                                self.HaveSpace,
+                                self.IDLimitType,
+                                self.SearchLen,
+                                self.SearchMsg
+                                )
+        return DumpString
+
+
+m_NAtagCGQueryFuncTeam=tagCGQueryFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryFuncTeam.Head.Cmd,m_NAtagCGQueryFuncTeam.Head.SubCmd))] = m_NAtagCGQueryFuncTeam
+
+
+#------------------------------------------------------
+# B9 24 查找玩家功能队伍 #tagCGQueryPlayerFuncTeam
+
+class  tagCGQueryPlayerFuncTeam(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x24
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x24
+        self.FuncMapID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGQueryPlayerFuncTeam)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 24 查找玩家功能队伍 //tagCGQueryPlayerFuncTeam:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                FuncMapID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.FuncMapID
+                                )
+        return DumpString
+
+
+m_NAtagCGQueryPlayerFuncTeam=tagCGQueryPlayerFuncTeam()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryPlayerFuncTeam.Cmd,m_NAtagCGQueryPlayerFuncTeam.SubCmd))] = m_NAtagCGQueryPlayerFuncTeam
+
+
+#------------------------------------------------------
 # B9 05 查询推荐组队的附近玩家 #tagCGQueryRecommendNearbyPlayer
 
 class  tagCGQueryRecommendNearbyPlayer(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index c3fa85f..0aceafa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -12634,6 +12634,854 @@
 
 
 #------------------------------------------------------
+# B9 23 功能队伍解散 #tagGCFuncTeamDissolve
+
+class  tagGCFuncTeamDissolve(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("TeamID", c_int),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x23
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x23
+        self.TeamID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCFuncTeamDissolve)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 23 功能队伍解散 //tagGCFuncTeamDissolve:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                TeamID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.TeamID
+                                )
+        return DumpString
+
+
+m_NAtagGCFuncTeamDissolve=tagGCFuncTeamDissolve()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFuncTeamDissolve.Cmd,m_NAtagGCFuncTeamDissolve.SubCmd))] = m_NAtagGCFuncTeamDissolve
+
+
+#------------------------------------------------------
+# B9 22 功能队伍列表 #tagGCFuncTeamList
+
+class  tagGCFuncTeamMem(Structure):
+    ServerID = 0    #(DWORD ServerID)
+    PlayerID = 0    #(DWORD PlayerID)
+    NameLen = 0    #(BYTE NameLen)
+    Name = ""    #(String Name)// 玩家名,size = NameLen
+    LV = 0    #(WORD LV)// 玩家等级
+    Job = 0    #(BYTE Job)// 玩家职业
+    RealmLV = 0    #(WORD RealmLV)// 玩家境界
+    FightPower = 0    #(DWORD FightPower)// 战力,求余亿
+    FightPowerEx = 0    #(DWORD FightPowerEx)// 战力,整除亿
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.ServerID = 0
+        self.PlayerID = 0
+        self.NameLen = 0
+        self.Name = ""
+        self.LV = 0
+        self.Job = 0
+        self.RealmLV = 0
+        self.FightPower = 0
+        self.FightPowerEx = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.Name)
+        length += 2
+        length += 1
+        length += 2
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.ServerID)
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.Name)
+        data = CommFunc.WriteWORD(data, self.LV)
+        data = CommFunc.WriteBYTE(data, self.Job)
+        data = CommFunc.WriteWORD(data, self.RealmLV)
+        data = CommFunc.WriteDWORD(data, self.FightPower)
+        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                ServerID:%d,
+                                PlayerID:%d,
+                                NameLen:%d,
+                                Name:%s,
+                                LV:%d,
+                                Job:%d,
+                                RealmLV:%d,
+                                FightPower:%d,
+                                FightPowerEx:%d,
+                                Value1:%d,
+                                Value2:%d
+                                '''\
+                                %(
+                                self.ServerID,
+                                self.PlayerID,
+                                self.NameLen,
+                                self.Name,
+                                self.LV,
+                                self.Job,
+                                self.RealmLV,
+                                self.FightPower,
+                                self.FightPowerEx,
+                                self.Value1,
+                                self.Value2
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeam(Structure):
+    TeamID = 0    #(DWORD TeamID)
+    CreateTime = 0    #(DWORD CreateTime)//创建队伍时间戳
+    FuncMapEx = 0    #(DWORD FuncMapEx)//功能地图扩展,如不同的层级
+    NameLen = 0    #(BYTE NameLen)
+    TeamName = ""    #(String TeamName)//队伍名称
+    CaptainID = 0    #(DWORD CaptainID)//队长ID,队伍ServerID直接取队长的ServerID
+    MinLV = 0    #(WORD MinLV)//最低等级限制
+    MinFightPower = 0    #(DWORD MinFightPower)//最低战力限制,求余亿
+    MinFightPowerEx = 0    #(DWORD MinFightPowerEx)//最低战力限制,整除亿
+    ServerOnly = 0    #(BYTE ServerOnly)//是否仅本服玩家可加入,0-否,1-是
+    NeedCheck = 0    #(BYTE NeedCheck)//是否需要审核
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    MemberCount = 0    #(BYTE MemberCount)
+    MemberList = list()    #(vector<tagGCFuncTeamMem> MemberList)// 成员列表
+    ApplyCount = 0    #(WORD ApplyCount)
+    ApplyIDList = list()    #(vector<DWORD> ApplyIDList)// 申请玩家ID列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.TeamID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CreateTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TeamName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.CaptainID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MinFightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinFightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ServerOnly,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.NeedCheck,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MemberCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemberCount):
+            temMemberList = tagGCFuncTeamMem()
+            _pos = temMemberList.ReadData(_lpData, _pos)
+            self.MemberList.append(temMemberList)
+        self.ApplyCount,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.ApplyCount):
+            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
+            self.ApplyIDList.append(value)
+        return _pos
+
+    def Clear(self):
+        self.TeamID = 0
+        self.CreateTime = 0
+        self.FuncMapEx = 0
+        self.NameLen = 0
+        self.TeamName = ""
+        self.CaptainID = 0
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.MemberCount = 0
+        self.MemberList = list()
+        self.ApplyCount = 0
+        self.ApplyIDList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.TeamName)
+        length += 4
+        length += 2
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 4
+        length += 4
+        length += 1
+        for i in range(self.MemberCount):
+            length += self.MemberList[i].GetLength()
+        length += 2
+        length += 4 * self.ApplyCount
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.TeamID)
+        data = CommFunc.WriteDWORD(data, self.CreateTime)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.TeamName)
+        data = CommFunc.WriteDWORD(data, self.CaptainID)
+        data = CommFunc.WriteWORD(data, self.MinLV)
+        data = CommFunc.WriteDWORD(data, self.MinFightPower)
+        data = CommFunc.WriteDWORD(data, self.MinFightPowerEx)
+        data = CommFunc.WriteBYTE(data, self.ServerOnly)
+        data = CommFunc.WriteBYTE(data, self.NeedCheck)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        data = CommFunc.WriteBYTE(data, self.MemberCount)
+        for i in range(self.MemberCount):
+            data = CommFunc.WriteString(data, self.MemberList[i].GetLength(), self.MemberList[i].GetBuffer())
+        data = CommFunc.WriteWORD(data, self.ApplyCount)
+        for i in range(self.ApplyCount):
+            data = CommFunc.WriteDWORD(data, self.ApplyIDList[i])
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                TeamID:%d,
+                                CreateTime:%d,
+                                FuncMapEx:%d,
+                                NameLen:%d,
+                                TeamName:%s,
+                                CaptainID:%d,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d,
+                                Value1:%d,
+                                Value2:%d,
+                                MemberCount:%d,
+                                MemberList:%s,
+                                ApplyCount:%d,
+                                ApplyIDList:%s
+                                '''\
+                                %(
+                                self.TeamID,
+                                self.CreateTime,
+                                self.FuncMapEx,
+                                self.NameLen,
+                                self.TeamName,
+                                self.CaptainID,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck,
+                                self.Value1,
+                                self.Value2,
+                                self.MemberCount,
+                                "...",
+                                self.ApplyCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeamList(Structure):
+    Head = tagHead()
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级,0代表所有
+    StartIndex = 0    #(DWORD StartIndex)// 查看的起始索引, 默认0
+    QueryCnt = 0    #(BYTE QueryCnt)// 查看条数,默认20,最大不超过100
+    HaveSpace = 0    #(BYTE HaveSpace)// 是否只查看有空位置的队伍
+    IDLimitType = 0    #(BYTE IDLimitType)// ID限制类型:1-同仙盟队长;2-同ServerGroupID队长;3-同ServerID队长
+    SearchLen = 0    #(BYTE SearchLen)
+    SearchMsg = ""    #(String SearchMsg)// 指定搜索时有用,可搜索指定队伍ID或模糊搜索队伍名称,搜索时返回最多QueryCnt个数的队伍
+    LoopIndex = 0    #(DWORD LoopIndex)// 服务器检索到的索引,列表下拉时下一个查询包的StartIndex从这个LoopIndex开始
+    TeamCount = 0    #(BYTE TeamCount)// 如果返回的队伍数小于QueryCnt,代表服务器已经没有满足条件的队伍了,列表再下拉时不再发查询包
+    TeamList = list()    #(vector<tagGCFuncTeam> TeamList)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x22
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.StartIndex,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.QueryCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.HaveSpace,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.IDLimitType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SearchMsg,_pos = CommFunc.ReadString(_lpData, _pos,self.SearchLen)
+        self.LoopIndex,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.TeamCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.TeamCount):
+            temTeamList = tagGCFuncTeam()
+            _pos = temTeamList.ReadData(_lpData, _pos)
+            self.TeamList.append(temTeamList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x22
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.StartIndex = 0
+        self.QueryCnt = 0
+        self.HaveSpace = 0
+        self.IDLimitType = 0
+        self.SearchLen = 0
+        self.SearchMsg = ""
+        self.LoopIndex = 0
+        self.TeamCount = 0
+        self.TeamList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 1
+        length += 1
+        length += len(self.SearchMsg)
+        length += 4
+        length += 1
+        for i in range(self.TeamCount):
+            length += self.TeamList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteDWORD(data, self.StartIndex)
+        data = CommFunc.WriteBYTE(data, self.QueryCnt)
+        data = CommFunc.WriteBYTE(data, self.HaveSpace)
+        data = CommFunc.WriteBYTE(data, self.IDLimitType)
+        data = CommFunc.WriteBYTE(data, self.SearchLen)
+        data = CommFunc.WriteString(data, self.SearchLen, self.SearchMsg)
+        data = CommFunc.WriteDWORD(data, self.LoopIndex)
+        data = CommFunc.WriteBYTE(data, self.TeamCount)
+        for i in range(self.TeamCount):
+            data = CommFunc.WriteString(data, self.TeamList[i].GetLength(), self.TeamList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                StartIndex:%d,
+                                QueryCnt:%d,
+                                HaveSpace:%d,
+                                IDLimitType:%d,
+                                SearchLen:%d,
+                                SearchMsg:%s,
+                                LoopIndex:%d,
+                                TeamCount:%d,
+                                TeamList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.StartIndex,
+                                self.QueryCnt,
+                                self.HaveSpace,
+                                self.IDLimitType,
+                                self.SearchLen,
+                                self.SearchMsg,
+                                self.LoopIndex,
+                                self.TeamCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCFuncTeamList=tagGCFuncTeamList()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFuncTeamList.Head.Cmd,m_NAtagGCFuncTeamList.Head.SubCmd))] = m_NAtagGCFuncTeamList
+
+
+#------------------------------------------------------
+# B9 20 功能队伍刷新 #tagGCFuncTeamRefresh
+
+class  tagGCFuncTeamRefreshApply(Structure):
+    ServerID = 0    #(DWORD ServerID)
+    PlayerID = 0    #(DWORD PlayerID)
+    NameLen = 0    #(BYTE NameLen)
+    Name = ""    #(String Name)// 玩家名,size = NameLen
+    LV = 0    #(WORD LV)// 玩家等级
+    Job = 0    #(BYTE Job)// 玩家职业
+    RealmLV = 0    #(WORD RealmLV)// 玩家境界
+    FightPower = 0    #(DWORD FightPower)// 战力,求余亿
+    FightPowerEx = 0    #(DWORD FightPowerEx)// 战力,整除亿
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.ServerID = 0
+        self.PlayerID = 0
+        self.NameLen = 0
+        self.Name = ""
+        self.LV = 0
+        self.Job = 0
+        self.RealmLV = 0
+        self.FightPower = 0
+        self.FightPowerEx = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.Name)
+        length += 2
+        length += 1
+        length += 2
+        length += 4
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.ServerID)
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.Name)
+        data = CommFunc.WriteWORD(data, self.LV)
+        data = CommFunc.WriteBYTE(data, self.Job)
+        data = CommFunc.WriteWORD(data, self.RealmLV)
+        data = CommFunc.WriteDWORD(data, self.FightPower)
+        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                ServerID:%d,
+                                PlayerID:%d,
+                                NameLen:%d,
+                                Name:%s,
+                                LV:%d,
+                                Job:%d,
+                                RealmLV:%d,
+                                FightPower:%d,
+                                FightPowerEx:%d
+                                '''\
+                                %(
+                                self.ServerID,
+                                self.PlayerID,
+                                self.NameLen,
+                                self.Name,
+                                self.LV,
+                                self.Job,
+                                self.RealmLV,
+                                self.FightPower,
+                                self.FightPowerEx
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeamRefreshMem(Structure):
+    ServerID = 0    #(DWORD ServerID)
+    PlayerID = 0    #(DWORD PlayerID)
+    NameLen = 0    #(BYTE NameLen)
+    Name = ""    #(String Name)// 玩家名,size = NameLen
+    LV = 0    #(WORD LV)// 玩家等级
+    Job = 0    #(BYTE Job)// 玩家职业
+    RealmLV = 0    #(WORD RealmLV)// 玩家境界
+    FightPower = 0    #(DWORD FightPower)// 战力,求余亿
+    FightPowerEx = 0    #(DWORD FightPowerEx)// 战力,整除亿
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.ServerID = 0
+        self.PlayerID = 0
+        self.NameLen = 0
+        self.Name = ""
+        self.LV = 0
+        self.Job = 0
+        self.RealmLV = 0
+        self.FightPower = 0
+        self.FightPowerEx = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.Name)
+        length += 2
+        length += 1
+        length += 2
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.ServerID)
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.Name)
+        data = CommFunc.WriteWORD(data, self.LV)
+        data = CommFunc.WriteBYTE(data, self.Job)
+        data = CommFunc.WriteWORD(data, self.RealmLV)
+        data = CommFunc.WriteDWORD(data, self.FightPower)
+        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                ServerID:%d,
+                                PlayerID:%d,
+                                NameLen:%d,
+                                Name:%s,
+                                LV:%d,
+                                Job:%d,
+                                RealmLV:%d,
+                                FightPower:%d,
+                                FightPowerEx:%d,
+                                Value1:%d,
+                                Value2:%d
+                                '''\
+                                %(
+                                self.ServerID,
+                                self.PlayerID,
+                                self.NameLen,
+                                self.Name,
+                                self.LV,
+                                self.Job,
+                                self.RealmLV,
+                                self.FightPower,
+                                self.FightPowerEx,
+                                self.Value1,
+                                self.Value2
+                                )
+        return DumpString
+
+
+class  tagGCFuncTeamRefresh(Structure):
+    Head = tagHead()
+    TeamID = 0    #(DWORD TeamID)
+    CreateTime = 0    #(DWORD CreateTime)//创建队伍时间戳
+    FuncMapID = 0    #(DWORD FuncMapID)// 功能地图ID或自定义的活动功能ID
+    FuncMapEx = 0    #(DWORD FuncMapEx)// 功能地图扩展,如不同的层级
+    NameLen = 0    #(BYTE NameLen)
+    TeamName = ""    #(String TeamName)// 队伍名称
+    CaptainID = 0    #(DWORD CaptainID)//队长ID,队伍ServerID直接取队长的ServerID
+    MinLV = 0    #(WORD MinLV)//最低等级限制
+    MinFightPower = 0    #(DWORD MinFightPower)//最低战力限制,求余亿
+    MinFightPowerEx = 0    #(DWORD MinFightPowerEx)//最低战力限制,整除亿
+    ServerOnly = 0    #(BYTE ServerOnly)//是否仅本服玩家可加入,0-否,1-是
+    NeedCheck = 0    #(BYTE NeedCheck)//是否需要审核
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    MemberCount = 0    #(BYTE MemberCount)
+    MemberList = list()    #(vector<tagGCFuncTeamRefreshMem> MemberList)// 成员列表
+    ApplyCount = 0    #(WORD ApplyCount)
+    ApplyIDList = list()    #(vector<DWORD> ApplyIDList)// 申请玩家ID列表
+    ApplyInfoList = list()    #(vector<tagGCFuncTeamRefreshApply> ApplyInfoList)// 申请玩家明细列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.TeamID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CreateTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FuncMapEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TeamName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
+        self.CaptainID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MinFightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MinFightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.ServerOnly,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.NeedCheck,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MemberCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MemberCount):
+            temMemberList = tagGCFuncTeamRefreshMem()
+            _pos = temMemberList.ReadData(_lpData, _pos)
+            self.MemberList.append(temMemberList)
+        self.ApplyCount,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.ApplyCount):
+            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
+            self.ApplyIDList.append(value)
+        for i in range(self.ApplyCount):
+            temApplyInfoList = tagGCFuncTeamRefreshApply()
+            _pos = temApplyInfoList.ReadData(_lpData, _pos)
+            self.ApplyInfoList.append(temApplyInfoList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB9
+        self.Head.SubCmd = 0x20
+        self.TeamID = 0
+        self.CreateTime = 0
+        self.FuncMapID = 0
+        self.FuncMapEx = 0
+        self.NameLen = 0
+        self.TeamName = ""
+        self.CaptainID = 0
+        self.MinLV = 0
+        self.MinFightPower = 0
+        self.MinFightPowerEx = 0
+        self.ServerOnly = 0
+        self.NeedCheck = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.MemberCount = 0
+        self.MemberList = list()
+        self.ApplyCount = 0
+        self.ApplyIDList = list()
+        self.ApplyInfoList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        length += len(self.TeamName)
+        length += 4
+        length += 2
+        length += 4
+        length += 4
+        length += 1
+        length += 1
+        length += 4
+        length += 4
+        length += 1
+        for i in range(self.MemberCount):
+            length += self.MemberList[i].GetLength()
+        length += 2
+        length += 4 * self.ApplyCount
+        for i in range(self.ApplyCount):
+            length += self.ApplyInfoList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.TeamID)
+        data = CommFunc.WriteDWORD(data, self.CreateTime)
+        data = CommFunc.WriteDWORD(data, self.FuncMapID)
+        data = CommFunc.WriteDWORD(data, self.FuncMapEx)
+        data = CommFunc.WriteBYTE(data, self.NameLen)
+        data = CommFunc.WriteString(data, self.NameLen, self.TeamName)
+        data = CommFunc.WriteDWORD(data, self.CaptainID)
+        data = CommFunc.WriteWORD(data, self.MinLV)
+        data = CommFunc.WriteDWORD(data, self.MinFightPower)
+        data = CommFunc.WriteDWORD(data, self.MinFightPowerEx)
+        data = CommFunc.WriteBYTE(data, self.ServerOnly)
+        data = CommFunc.WriteBYTE(data, self.NeedCheck)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        data = CommFunc.WriteBYTE(data, self.MemberCount)
+        for i in range(self.MemberCount):
+            data = CommFunc.WriteString(data, self.MemberList[i].GetLength(), self.MemberList[i].GetBuffer())
+        data = CommFunc.WriteWORD(data, self.ApplyCount)
+        for i in range(self.ApplyCount):
+            data = CommFunc.WriteDWORD(data, self.ApplyIDList[i])
+        for i in range(self.ApplyCount):
+            data = CommFunc.WriteString(data, self.ApplyInfoList[i].GetLength(), self.ApplyInfoList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                TeamID:%d,
+                                CreateTime:%d,
+                                FuncMapID:%d,
+                                FuncMapEx:%d,
+                                NameLen:%d,
+                                TeamName:%s,
+                                CaptainID:%d,
+                                MinLV:%d,
+                                MinFightPower:%d,
+                                MinFightPowerEx:%d,
+                                ServerOnly:%d,
+                                NeedCheck:%d,
+                                Value1:%d,
+                                Value2:%d,
+                                MemberCount:%d,
+                                MemberList:%s,
+                                ApplyCount:%d,
+                                ApplyIDList:%s,
+                                ApplyInfoList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.TeamID,
+                                self.CreateTime,
+                                self.FuncMapID,
+                                self.FuncMapEx,
+                                self.NameLen,
+                                self.TeamName,
+                                self.CaptainID,
+                                self.MinLV,
+                                self.MinFightPower,
+                                self.MinFightPowerEx,
+                                self.ServerOnly,
+                                self.NeedCheck,
+                                self.Value1,
+                                self.Value2,
+                                self.MemberCount,
+                                "...",
+                                self.ApplyCount,
+                                "...",
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCFuncTeamRefresh=tagGCFuncTeamRefresh()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFuncTeamRefresh.Head.Cmd,m_NAtagGCFuncTeamRefresh.Head.SubCmd))] = m_NAtagGCFuncTeamRefresh
+
+
+#------------------------------------------------------
 # B9 01 收到邀请加入队伍信息 #tagGCInviteJoinTeamInfo
 
 class  tagGCInviteJoinTeamInfo(Structure):
@@ -12945,6 +13793,62 @@
 
 
 #------------------------------------------------------
+# B9 21 查找玩家功能队伍结果 #tagGCQueryPlayerFuncTeamRet
+
+class  tagGCQueryPlayerFuncTeamRet(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("FuncMapID", c_int),    # 功能地图ID或自定义的活动功能ID
+                  ("TeamID", c_int),    # 玩家所属队伍ID,目前只同步0的情况,如果玩家有队伍统一B920封包同步处理
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB9
+        self.SubCmd = 0x21
+        self.FuncMapID = 0
+        self.TeamID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCQueryPlayerFuncTeamRet)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B9 21 查找玩家功能队伍结果 //tagGCQueryPlayerFuncTeamRet:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                FuncMapID:%d,
+                                TeamID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.FuncMapID,
+                                self.TeamID
+                                )
+        return DumpString
+
+
+m_NAtagGCQueryPlayerFuncTeamRet=tagGCQueryPlayerFuncTeamRet()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCQueryPlayerFuncTeamRet.Cmd,m_NAtagGCQueryPlayerFuncTeamRet.SubCmd))] = m_NAtagGCQueryPlayerFuncTeamRet
+
+
+#------------------------------------------------------
 # B9 08 推荐组队的附近玩家信息 #tagGCRecommendNearbyPlayerList
 
 class  tagGCRecommendNearbyPlayer(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
index 34bcf6e..d901547 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
@@ -25,6 +25,7 @@
 import GameWorldProcess
 import NPCCustomRefresh
 import DataRecordPack
+import PlayerFuncTeam
 import PlayerControl
 import ShareDefine
 import SkillCommon
@@ -892,6 +893,17 @@
     if callFaction:
         faction = callFaction # 召集阵营为固定阵营
         
+    # 队伍同阵营
+    teamID = PlayerFuncTeam.GetPlayerTeamID(playerID, ChConfig.Def_FBMapID_CrossBattlefield)
+    if not faction and teamID:
+        memIDList = PlayerFuncTeam.GetMemberIDList(teamID)
+        for memID in memIDList:
+            memBattleObj = GetBattlePlayerObj(memID)
+            if memBattleObj.faction:
+                faction = memBattleObj.faction
+                GameWorld.Log("与队友同一阵营! playerID=%s,teamID=%s,faction=%s,memIDList=%s" % (playerID, teamID, faction, memIDList), fbPropertyID)
+                break
+            
     if not faction:
         jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
         eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
@@ -1762,6 +1774,7 @@
             
             isCallOpen = 1 if playerID in worldObj.callOpenPlayerInfo else 0 # 是否召集进入的
             isCalled = 1 if (playerID in allCallPlayerIDList and not isCallOpen) else 0 # 是否被召集的
+            teamID = PlayerFuncTeam.GetPlayerTeamID(playerID, ChConfig.Def_FBMapID_CrossBattlefield)
             killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \
                 factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt = \
                 battleObj.killCount, battleObj.ckillCntInfo, battleObj.killBossCnt, battleObj.killScoreKing, battleObj.killGuardCnt, \
@@ -1769,13 +1782,13 @@
                 battleObj.crystalCollCnt, battleObj.wallCollCnt
                 
             playerInfo = [playerID, job, realmLV, name,
-                          isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek,
+                          isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID,
                           isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt,
                           factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt]
             battlePlayerList.append(playerInfo)
             
             drPlayerList.append({"playerID":playerID, "accID":battleObj.accID, "fightPower":battleObj.fightPower,
-                                 "score":score, "auraScore":auraScore, "wallCollCnt":wallCollCnt,
+                                 "score":score, "auraScore":auraScore, "wallCollCnt":wallCollCnt, "teamID":teamID,
                                  "superItemAwardCnt":superItemAwardCnt, "superItemContribution":battleObj.superItemContribution})
             
             player = copyMapMgr.FindPlayerByID(playerID)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
index 0e32197..9a5b9b6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
@@ -220,7 +220,7 @@
     
     playerID = curPlayer.GetPlayerID()
     overTime, \
-        isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, \
+        isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID, \
         isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \
         factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt = dataMsg
         
@@ -228,7 +228,7 @@
     isSameWeek = GameWorld.CheckTimeIsSameWeek(overTime)
     GameWorld.Log("跨服战场结算玩家结果: highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,overTime=%s,isToday=%s,isSameWeek=%s" 
                   % (highScoreToday, highScoreWeekTotal, enterCountWeek, GameWorld.ChangeTimeNumToStr(overTime), isToday, isSameWeek), playerID)
-    GameWorld.Log("    isWinner=%s,faction=%s,rank=%s,score=%s,isCallOpen=%s,isCalled=%s" % (isWinner, faction, rank, score, isCallOpen, isCalled), playerID)
+    GameWorld.Log("    isWinner=%s,faction=%s,rank=%s,score=%s,teamID=%s,isCallOpen=%s,isCalled=%s" % (isWinner, faction, rank, score, teamID, isCallOpen, isCalled), playerID)
     GameWorld.Log("    killCnt=%s,ckillCntInfo=%s,killBossCnt=%s,killScoreKing=%s,killGuardCnt=%s,auraScore=%s,superItemAwardCnt=%s" 
                   % (killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt), playerID)
     GameWorld.Log("    factionBuffCollCnt=%s,personBuffCollCnt=%s,crystalCollCnt=%s,wallCollCnt=%s" 
@@ -254,7 +254,7 @@
     
     # 成就
     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_Join, 1)
-    if isCalled:
+    if isCalled or teamID:
         PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_Called, 1)
     if isWinner:
         if faction == ShareDefine.CampType_Justice:
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 9c9e317..017d7a7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -132,6 +132,7 @@
 import PyGameData
 import PlayerTJG
 import PlayerGuaji
+import PlayerFuncTeam
 import PlayerMineArea
 
 import datetime
@@ -1560,6 +1561,11 @@
             PlayerLuckyCloudBuy.OnLuckyCloudBuyChange()
             return
         
+        # 功能队伍
+        if key == ShareDefine.Def_Notify_WorldKey_FuncTeamMemIDInfo:
+            PlayerFuncTeam.OnFuncTeamMemIDRefresh(eval(msgValue))
+            return
+        
         if key == ShareDefine.Def_Notify_WorldKey_CrossBattlefieldCallTeamInfo:
             PyGameData.g_crossBattlefieldCallTeamInfo = eval(msgValue)
             return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFuncTeam.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFuncTeam.py
new file mode 100644
index 0000000..e1bc7c2
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFuncTeam.py
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerFuncTeam
+#
+# @todo:功能队伍表
+# @author hxp
+# @date 2024-08-02
+# @version 1.0
+#
+# 详细描述: 功能队伍表
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-08-02 16:30"""
+#-------------------------------------------------------------------------------
+
+import PyGameData
+
+def OnFuncTeamMemIDRefresh(msgList):
+    ## 功能队伍成员ID刷新
+    teamIDList, delTeamIDList, teamMemIDInfoDict = msgList
+    
+    # 没有指定时,全部刷新
+    if not teamIDList:
+        PyGameData.g_funcTeamPlayerDict = {}
+        
+    for key, refreshDict in teamMemIDInfoDict.items():
+        if key not in PyGameData.g_funcTeamPlayerDict:
+            PyGameData.g_funcTeamPlayerDict[key] = {}
+        infoDict = PyGameData.g_funcTeamPlayerDict[key]
+        infoDict.update(refreshDict)
+        
+    for teamInfoDict in PyGameData.g_funcTeamPlayerDict.values():
+        for delTeamID in delTeamIDList[::-1]:
+            if delTeamID not in teamInfoDict:
+                continue
+            teamInfoDict.pop(delTeamID, None)
+            delTeamIDList.remove(delTeamID)
+            
+    return
+
+def GetPlayerTeamID(playerID, funcMapID):
+    for key, infoDict in PyGameData.g_funcTeamPlayerDict.items():
+        if funcMapID != key[1]:
+            continue
+        for teamID, memIDList in infoDict.items():
+            if playerID in memIDList:
+                return teamID
+    return 0
+
+def GetMemberIDList(teamID):
+    for infoDict in PyGameData.g_funcTeamPlayerDict.values():
+        if teamID in infoDict:
+            return infoDict[teamID]
+    return []
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index 7ae4553..8b56353 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -46,6 +46,8 @@
 g_teamPlayerDict = {} # 地图队伍对应玩家ID列表,含离线玩家 {teamID:[playerID, ...], ...}
 g_teamPlayerInfoDict = {} # 地图队伍对应玩家ID信息 {teamID:{playerID:{k:v, ...}, ...}
 
+g_funcTeamPlayerDict = {} # 功能队伍玩家ID列表 {(zoneID, funcMapID): {teamID:[playerID, ...], ...}, ...}
+
 g_unLoginOKPlayerMailInfo = {} # GameServer 未登录成功前需要发送的邮件缓存,防止登录失败不存db导致重复发送邮件 {playerID:[[待发送邮件内容信息], ...], ...}
 g_disconnectPlayer = {} # 在本地图离线的玩家信息 {playerID:[tick, posX, posY], ...}
 g_lastExitFBType = {} # 最后一个离开副本信息 {fbIndex:[exitType, tick], ...} exitType: 1-掉线,2-主动退出
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index c3e36dd..c5b9ab0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -187,6 +187,8 @@
 Def_Notify_WorldKey_CrossBattlefieldCallTeamInfo = "CrossBattlefieldCallTeamInfo" # 跨服战场召集队伍信息
 Def_Notify_WorldKey_CrossBattlefieldSysCallBuyInfo = "CrossBattlefieldSysCallBuyInfo" # 跨服战场系统场次购买召集信息
 
+Def_Notify_WorldKey_FuncTeamMemIDInfo = "FuncTeamMemIDInfo" # 功能队伍成员ID信息
+
 CrossChampionshipState_Guess8 = 80 #8强竞猜
 CrossChampionshipState_Group64 = 641 #64强分组
 CrossChampionshipState_Enter64 = 642 #64强进场
@@ -1594,6 +1596,9 @@
 CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
 CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
 CrossServerMsg_Worship = "Worship"  # 膜拜信息
+CrossServerMsg_FuncTeamInfo = "FuncTeamInfo"  # 功能队伍信息同步
+CrossServerMsg_FuncTeamDel = "FuncTeamDel"  # 功能队伍删除同步
+CrossServerMsg_FuncTeamList = "FuncTeamList"  # 功能队伍列表同步
 
 # 子服发送跨服信息定义
 ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
@@ -1632,6 +1637,10 @@
 ClientServerMsg_CrossYaomoBossHurtAward = "CrossYaomoBossHurtAward" # 跨服妖魔boss玩家伤害领奖
 ClientServerMsg_BossTrialSubmit = "BossTrialSubmit" # boss凭证提交
 ClientServerMsg_XianXiaMJScore = "XianXiaMJScore" # 仙匣秘境积分
+ClientServerMsg_CreateFuncTeam = "CreateFuncTeam"   # 创建功能队伍
+ClientServerMsg_ChangeFuncTeam = "ChangeFuncTeam"   # 修改功能队伍
+ClientServerMsg_FuncTeamMemOP = "FuncTeamMemOP"   # 功能队伍成员操作
+ClientServerMsg_QueryFuncTeam = "QueryFuncTeam"   # 查询功能队伍
 
 #跨服广播类型定义
 CrossNotify_CrossAct = "CrossAct"

--
Gitblit v1.8.0