From 9d5ec7599f3abe0cebb76ce1df3c3b8c4e0aa51e Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 10 二月 2026 11:40:15 +0800
Subject: [PATCH] 66 【公会】基础主体-服务端(跨服聊天;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py |  258 ++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 201 insertions(+), 57 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
index e8e095a..9e5032a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
@@ -31,10 +31,12 @@
 import PlayerMail
 import PlayerTask
 import CrossPlayer
+import PlayerTalk
 import DirtyList
 import DBDataMgr
 import DBFamily
 import CrossMsg
+import CrossMgr
 
 import random
 import time
@@ -77,7 +79,7 @@
 
 def FamilyOnHour():
     if not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
-        # 非游戏服或本服已跨服互通了不处理
+        GameWorld.DebugLog("非游戏服或本服已跨服互通了不处理 FamilyOnHour")
         return
     __doFamilyOnHour()
     return
@@ -101,7 +103,7 @@
     ## 本服时间自己触发的onday逻辑
     
     if not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
-        # 非游戏服或本服已跨服互通了不处理
+        GameWorld.DebugLog("非游戏服或本服已跨服互通了不处理 FamilyOnDay")
         return
     
     __doFamilyOnDay()
@@ -125,7 +127,7 @@
                 member.SetContribDay(0)
                 member.SetDonateCntDay(0)
                 
-            Broadcast_FamilyInfo(familyID)
+            Broadcast_FamilyInfo(familyID) # onday
     return
 
 def PlayerCrossCenterOnDay(curPlayer):
@@ -147,13 +149,12 @@
 def __doPlayerOnDay(curPlayer):
     PlayerFamilyZhenbaoge.PlayerOnDay(curPlayer)
     PlayerFamilyTaofa.PlayerOnDay(curPlayer)
-    Do_MapServer_PlayerOnDay(curPlayer)
+    ResetDailyDonateCnt(curPlayer)
     return
 
 def OnPlayerLogin(curPlayer, tick):
-    Do_MapServer_PlayerLogin(curPlayer)
     if DBFamily.IsFamilyCross():
-        #公会已跨服不处理,由所属跨服服务器处理成员登录逻辑
+        GameWorld.DebugLog("公会已跨服不处理,由所属跨服服务器处理成员登录逻辑 OnPlayerLogin", curPlayer.GetPlayerID())
         return
     crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(curPlayer.GetPlayerID())
     OnCrossPlayerLogin(crossPlayer)
@@ -161,14 +162,17 @@
 
 def OnCrossPlayerLogin(crossPlayer):
     ## 玩家上线,游戏服跨服通用,流程上当做以前GameServer处理公会一样,处理后再通知地图(现在的游戏服)
-    PlayerLoginRefreshFamily(crossPlayer)
+    PlayerLoginRefreshFamily(crossPlayer) # 必须先刷新
     Sync_RequestAddFamilyInfo(crossPlayer, False)
-    #PlayerFamilyTaofa.OnPlayerLogin(curPlayer) 讨伐待修改
+    PlayerTalk.NotifyTalkCache(crossPlayer, [IPY_GameWorld.tcFamily]) # 公会聊天缓存
+    if GameWorld.IsCrossServer():
+        PlayerTalk.NotifyTalkCache(crossPlayer, [IPY_GameWorld.tcCountry]) # 跨服公会聊天缓存
+    PlayerFamilyTaofa.OnCrossPlayerLogin(crossPlayer)
     return
 
 def OnPlayerLogout(curPlayer):
     if DBFamily.IsFamilyCross():
-        #公会已跨服不处理,由所属跨服服务器处理成员登录逻辑
+        GameWorld.DebugLog("公会已跨服不处理,由所属跨服服务器处理成员离线逻辑 OnPlayerLogout", curPlayer.GetPlayerID())
         return
     crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(curPlayer.GetPlayerID())
     OnCrossPlayerLogout(crossPlayer)
@@ -190,7 +194,7 @@
     curMember.SetOffTime(int(time.time()))
     
     # 通知成员下线
-    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID])
+    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID]) # 成员下线
     return
 
 def SendToFamilyMapPlayer(crossPlayer, doType, doData):
@@ -202,12 +206,13 @@
         C2S_FamilyMapPlayer(dataMsg, playerID)
     return
 
-def MapServer_FamilyRefresh(crossPlayer, familyID, isVoluntarily=0):
+def MapServer_FamilyRefresh(crossPlayer, familyID, isVoluntarily=0, isLogin=False):
     ''' 相当于GameServer调用 curPlayer.MapServer_FamilyRefresh()
     '''
     playerID = crossPlayer.GetPlayerID()
     FmLV = 0 # 职位
     FamilyLV = 0 # 公会等级
+    JoinTime = 0
     FamilyName = ""
     EmblemID, EmblemWord = 0, ""
     if familyID:
@@ -221,16 +226,21 @@
             member = curFamily.FindMember(playerID)
             if member:
                 FmLV = member.GetFmLV()
+                JoinTime = member.GetJoinTime()
         else:
             familyID = 0
                     
     crossPlayer.SetFamilyID(familyID)
+    # 同步更新查看缓存
+    PlayerViewCache.UpdPlayerViewFamilyInfo(playerID, familyID, FamilyName, EmblemID, EmblemWord)
     
     doData = {"FamilyID":familyID}
     if familyID:
-        doData.update({"FmLV":FmLV, "FamilyLV":FamilyLV, "FamilyName":FamilyName, "EmblemID":EmblemID, "EmblemWord":EmblemWord})
+        doData.update({"FmLV":FmLV, "JoinTime":JoinTime, "FamilyLV":FamilyLV, "FamilyName":FamilyName, "EmblemID":EmblemID, "EmblemWord":EmblemWord})
     if isVoluntarily:
         doData["isVoluntarily"] = 1
+    if isLogin:
+        doData["isLogin"] = 1
     SendToFamilyMapPlayer(crossPlayer, "FamilyRefresh", doData)
     return
 
@@ -242,7 +252,7 @@
     refreshFamilyID = familyMgr.GetPlayerFamilyID(playerID)
     GameWorld.DebugLog("PlayerLoginRefreshFamily playerID=%s,refreshFamilyID=%s" % (playerID, refreshFamilyID))
     crossPlayer.SetFamilyID(refreshFamilyID)
-    MapServer_FamilyRefresh(crossPlayer, refreshFamilyID)
+    MapServer_FamilyRefresh(crossPlayer, refreshFamilyID, isLogin=True) # 登录
     familyID = refreshFamilyID
     if not familyID:
         return
@@ -258,7 +268,7 @@
     
     Sync_FamilyInfo(crossPlayer) # 给自己同步完整的
     # 广播成员在线
-    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID])
+    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员登录
     
     #通知招人
     if GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
@@ -287,6 +297,7 @@
     if not member:
         return
     member.RefreshMemberByID(playerID)
+    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员信息变更
     return
 
 def FamilyPyPackForwarding(curPlayer, clientData, tick, funcName, needResult=False, reqCD=0.5, reqDataEx=None):
@@ -312,13 +323,18 @@
             __doFamilyPyPackRet(curPlayer, clientData, funcName, isOK)
         return
     
+    ssServer = CrossMgr.GetSSServerMgr().GetSSServer(crossServerID)
+    if not ssServer or not ssServer.IsServerOpen():
+        PlayerControl.NotifyCode(curPlayer, "ServerNoOpen")
+        return
+    
     # 转发请求CD验证
     if reqCD:
-        reqTick = curPlayer.GetDictByKey("FamilyPyPackForwardingTick")
+        reqTick = curPlayer.GetDictByKey(funcName) # 根据函数名单独处理CD,防止相互影响
         if reqTick and (tick - reqTick) < reqCD * 1000:
             PlayerControl.NotifyCode(curPlayer, "RequestLater")
             return
-        curPlayer.SetDict("FamilyPyPackForwardingTick", tick)
+        curPlayer.SetDict(funcName, tick)
         
     # 剩下的就是大于0
     dataMsg = {"funcName":funcName}
@@ -352,10 +368,11 @@
     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
     if not curPlayer:
         return
-    curPlayer.SetDict("FamilyPyPackForwardingTick", 0)
-    
     funcName = dataMsg["funcName"]
     packBuff = dataMsg.get("packBuff")
+    
+    curPlayer.SetDict(funcName, 0) # 重置CD
+    
     clientData = None
     if packBuff:
         clientData = NetPackCommon.ReadRecPyPackData(packBuff)
@@ -470,11 +487,13 @@
         GameWorld.ErrLog("创建家族失败", playerID)
         return
     newFamilyID = curFamily.GetID()
+    zoneMgr = familyMgr.GetZoneFamilyMgrByFamilyID(newFamilyID)
+    zoneID = zoneMgr.GetZoneID() if zoneMgr else -1
     curFamily.SetLV(1)
     emblemIDList = PlayerFamilyEmblem.GetDefaultFamilyEmblemIDList()
     if not emblemID or emblemID not in emblemIDList:
         emblemID = random.choice(emblemIDList) # 从默认徽章中随机选择一个
-    GameWorld.Log("创建公会: familyID=%s,playerID=%s,emblemID=%s,serverID=%s" % (newFamilyID, playerID, emblemID, serverID))
+    GameWorld.Log("创建公会: familyID=%s,playerID=%s,emblemID=%s,serverID=%s,zoneID=%s" % (newFamilyID, playerID, emblemID, serverID, zoneID))
     curFamily.SetEmblemID(emblemID)
     curFamily.SetEmblemWord(emblemWord)
     
@@ -486,9 +505,9 @@
         
     #-设置家族成员属性
     DoPlayerJionFamily(curFamily, playerID, crossPlayer, IPY_PlayerDefine.fmlLeader)
-    zoneMgr = familyMgr.GetZoneFamilyMgrByFamilyID(newFamilyID)
-    zoneMgr and zoneMgr.Sort()
-    
+    if zoneMgr:
+        zoneMgr.Sort()
+        
     #XW_JZ_EstablishSud <n color="255,255,0">恭喜您,家族建立成功!</n>    25  -   -
     #CrossPlayer.NotifyCode(crossPlayer, "XW_JZ_EstablishSud")
     #PlayerControl.WorldNotify(0, "jiazu_liubo_671654", [curPlayer.GetName(), fullFamilyName, newFamilyID])
@@ -559,24 +578,25 @@
     member = curFamily.AddMember(playerID)
     member.SetFmLV(jionFamilySetLv)
     member.RefreshMemberByID(playerID)
-    curFamily.SetFightPowerTotal(curFamily.GetFightPowerTotal() + member.GetFightPowerTotal())
     
     if jionFamilySetLv == IPY_PlayerDefine.fmlLeader:
         curFamily.SetLeaderID(playerID)
         
     if broadcastFamilyChange:
-        Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID])
+        # 广播其他在线成员
+        Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员加入
         
     familyMgr.DelPlayerReqJoinFamilyIDAll(playerID)
     #设置玩家身上保存的家族信息
     if crossPlayer:
-        MapServer_FamilyRefresh(crossPlayer, familyID)
+        MapServer_FamilyRefresh(crossPlayer, familyID) # 加入
+        Sync_FamilyInfo(crossPlayer) # 给自己同步完整的
         Sync_RequestAddFamilyInfo(crossPlayer)
         PlayerFamilyTaofa.OnCrossPlayerEnterFamily(crossPlayer)
         
-    #if jionFamilySetLv != IPY_PlayerDefine.fmlLeader:
+    if jionFamilySetLv != IPY_PlayerDefine.fmlLeader:
         #通知所有家族成员, 这个人加入了家族
-        #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
+        CrossPlayer.FamilyNotify(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
         #if jionPlayer:
         #    PlayerControl.NotifyCode(jionPlayer, 'XW_JZ_EnterFamilyInfo', [family.GetName()])
             
@@ -1084,7 +1104,7 @@
     #    return
     SendFamilyReqJoinInfo(familyID)
     if joinOKPlayerIDList:
-        Broadcast_FamilyInfo(familyID, changeMemIDList=joinOKPlayerIDList)
+        Broadcast_FamilyInfo(familyID, changeMemIDList=joinOKPlayerIDList, excludeIDList=joinOKPlayerIDList) # 审核
     return
 
 #// A6 22 修改收人方式 #tagCMChangeFamilyJoin
@@ -1122,7 +1142,7 @@
     GameWorld.DebugLog("修改招人设置: familyID=%s,joinReview=%s,joinLVMin=%s" % (familyID, joinReview, joinLVMin), playerID)
     family.SetJoinReview(joinReview)
     family.SetJoinLVMin(joinLVMin)
-    Broadcast_FamilyInfo(familyID, isSyncMem=False)
+    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 修改招人
     return
 
 #// A6 23 修改家族公告 #tagCMChangeFamilyBroadcast
@@ -1156,7 +1176,7 @@
         return
     family.SetBroadcast(broadcast)
     GameWorld.DebugLog('更改公会公告: Family=%s,公告=%s' % (GameWorld.CodeToGbk(family.GetName()), GameWorld.CodeToGbk(broadcast)), playerID)
-    Broadcast_FamilyInfo(familyID, isSyncMem=False)
+    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 修改公告
     return
 
 #// A6 24 修改家族徽章 #tagCMChangeFamilyEmblem
@@ -1240,8 +1260,10 @@
                 GameWorld.DebugLog("修改的目标成员职位不能比自己高或平级! tagFmlv=%s" % tagMember.GetFmLV(), playerID)
                 return
             
+    changeMemIDList = [tagID]
     if changeFmlv == IPY_PlayerDefine.fmlLeader:
         ChangeFamilyLeader(family, tagMember)
+        changeMemIDList.append(playerID)
         
     else:
         fmLVMemCnt = 0
@@ -1261,7 +1283,7 @@
         
     if isGMOP:
         family.SetBroadcast("")
-    Broadcast_FamilyInfo(familyID, changeMemIDList=[tagID])
+    Broadcast_FamilyInfo(familyID, changeMemIDList=changeMemIDList) # 修改职位
     return True
 
 def ChangeFamilyLeader(family, newLeaderMem):
@@ -1294,7 +1316,7 @@
     
     tagCrossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagID)
     if tagCrossPlayer:
-        MapServer_FamilyRefresh(tagCrossPlayer, familyID)
+        MapServer_FamilyRefresh(tagCrossPlayer, familyID) # 修改职位
         if GetFamilyMemberHasPow(tagMember, FamilyPowerID_Call):
             CrossPlayer.SendFakePack(tagCrossPlayer, GetPack_FamilyReqJoinInfo(familyID))
         
@@ -1304,8 +1326,7 @@
                         [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_FMLV, changeFamilyLV, befFamilyLV], tick)
     
     #xx被任命为xx
-    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_AppointFamily", [memName, changeFamilyLV])
-    #GetFamilyMgr().SetSyncCrossFamilyUpd(familyMember.GetFamilyID(), familyMember.GetPlayerID(), syncNow=True) # 成员职位变更
+    CrossPlayer.FamilyNotify(familyID, "XW_JZ_AppointFamily", [memName, changeFamilyLV])
     return
 
 def __AutoChangeLeader(curFamily):
@@ -1372,7 +1393,7 @@
     GameWorld.Log("公会自动传位: familyID=%s,leaderID=%s,offTime=%s,passHours=%s,newLeaderID=%s" 
                   % (familyID, leaderID, GameWorld.ChangeTimeNumToStr(offTime), passHours, newLeaderID))
     ChangeFamilyLeader(curFamily, toMember)
-    Broadcast_FamilyInfo(familyID, changeMemIDList=[leaderID, newLeaderID])
+    Broadcast_FamilyInfo(familyID, changeMemIDList=[leaderID, newLeaderID]) # 自动传位
     
     # 邮件通知
     toServerID = toMember.GetServerID()
@@ -1433,12 +1454,11 @@
     AddFamilyActionNote(crossPlayer.GetPlayerName(), familyID, ShareDefine.Def_ActionType_FamilyEvent, 
                         [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_Leave], tick)
     
-    #XW_JZ_LeaveFamily   <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n>  25  -   -
-    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaveFamily", [curPlayer.GetName()])
-    
     __DoPlayerLeaveFamilyByID(family, playerID, crossPlayer)
-    MapServer_FamilyRefresh(crossPlayer, 0, 1)
+    MapServer_FamilyRefresh(crossPlayer, 0, 1) # 主动退出
     CrossPlayer.SendFakePackByFamily(familyID, GetPack_FamilyDel(playerID, crossPlayer.GetPlayerName(), 1))
+    CrossPlayer.FamilyNotify(familyID, "XW_JZ_LeaveFamily", [crossPlayer.GetPlayerName()])
+    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 退出
     
     if family.GetCount() == 0:
         #玩家离开后, 家族没有人了 , 删除这个家族
@@ -1504,15 +1524,17 @@
                         [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_KickOut], tick)
     
     #XW_JZ_LeaveFamily   <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n>  25  -   -
-    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaveFamily", [tagPlayerName])
+    CrossPlayer.FamilyNotify(familyID, "XW_JZ_LeaveFamily", [tagPlayerName])
     
     #删除玩家
-    crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagMemberID)
-    __DoPlayerLeaveFamilyByID(family, tagPlayerID, crossPlayer)
-    if crossPlayer:
-        MapServer_FamilyRefresh(crossPlayer, 0)
+    tagCrossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagMemberID)
+    __DoPlayerLeaveFamilyByID(family, tagPlayerID, tagCrossPlayer)
+    if tagCrossPlayer:
+        MapServer_FamilyRefresh(tagCrossPlayer, 0) # 被踢
+        CrossPlayer.NotifyCode(tagCrossPlayer, "XW_JZ_LeaveFamilyKick", [curMember.GetPlayerName()])
         
     CrossPlayer.SendFakePackByFamily(familyID, GetPack_FamilyDel(tagMemberID, tagPlayerName, 0))
+    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 踢人
     return
 
 def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID, crossPlayer=None):
@@ -1589,11 +1611,66 @@
         memCrossPlayer = crossPlayerMgr.FindCrossPlayer(memID)
         if not memCrossPlayer:
             continue
-        MapServer_FamilyRefresh(memCrossPlayer, familyID)
+        MapServer_FamilyRefresh(memCrossPlayer, familyID) # 改名
         #player.Notify_FamilyNameRefresh() #//04 36    周围玩家家族名刷新#tagPlayerFamilyNameRefresh
         
-    Broadcast_FamilyInfo(familyID, isSyncMem=False)
+    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 改名
     return True
+
+#// A6 19 查看目标公会 #tagCSViewTagFamily
+#
+#struct tagCSViewTagFamily
+#{
+#    tagHead        Head;
+#    DWORD        FamilyID;
+#    DWORD        DataServerID;    //数据所在服务器ID
+#};
+def OnViewTagFamily(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    tagFamilyID = clientData.FamilyID
+    dataServerID = clientData.DataServerID
+    
+    # 本服或主服是本服
+    if not dataServerID or dataServerID == GameWorld.GetGameWorld().GetServerID():
+        NetPackCommon.SendFakePack(curPlayer, GetTagFamilyInfoPack(tagFamilyID))
+        return
+    
+    CrossMsg.SendToServer(ShareDefine.S2S_ViewTagFamily, {"tagFamilyID":tagFamilyID}, [dataServerID], ShareDefine.dirType_All, playerID)
+    return
+
+def S2S_ViewTagFamily(dataMsg, fromServerID, playerID):
+    tagFamilyID = dataMsg["tagFamilyID"]
+    CrossPlayer.SendFakePackByID(playerID, GetTagFamilyInfoPack(tagFamilyID), fromServerID)
+    return
+
+def GetTagFamilyInfoPack(tagFamilyID):
+    familyMgr = DBDataMgr.GetFamilyMgr()
+    family = familyMgr.FindFamily(tagFamilyID)
+    if not family:
+        GameWorld.ErrLog("本服数据找不到目标公会! tagFamilyID=%s" % tagFamilyID)
+        return
+    clientPack = ChPyNetSendPack.tagSCTagFamilyInfo()
+    clientPack.FamilyID = family.GetID()
+    clientPack.FamilyName = family.GetName()
+    clientPack.FamilyNameLen = len(clientPack.FamilyName)
+    clientPack.LeaderID = family.GetLeaderID()
+    leaderMember = family.FindMember(clientPack.LeaderID)
+    if leaderMember:
+        clientPack.LeaderName = leaderMember.GetPlayerName()
+        clientPack.LeaderNameLen = len(clientPack.LeaderName)
+        clientPack.LeaderServerID = leaderMember.GetServerID()
+    clientPack.FamilyLV = family.GetLV()
+    clientPack.ServerID = family.GetServerID()
+    clientPack.EmblemID = family.GetEmblemID()
+    clientPack.EmblemWord = family.GetEmblemWord()
+    clientPack.FightPower = family.GetFightPower()
+    clientPack.FightPowerEx = family.GetFightPowerEx()
+    clientPack.Broadcast = family.GetBroadcast()
+    clientPack.BroadcastLen = len(clientPack.Broadcast)
+    clientPack.MemberCount = family.GetCount()
+    clientPack.DataServerID = GameWorld.GetGameWorld().GetServerID()
+    return clientPack
 
 #// A6 20 搜索家族列表 #tagCMViewFamilyPage
 #
@@ -1670,6 +1747,7 @@
         leaderMember = family.FindMember(familyView.LeaderID)
         familyView.LeaderName = leaderMember.GetPlayerName() if leaderMember else ""
         familyView.LeaderNameLen = len(familyView.LeaderName)
+        familyView.LeaderServerID = leaderMember.GetServerID() if leaderMember else family.GetServerID()
         familyView.FamilyLV = family.GetLV()
         familyView.JoinReview = family.GetJoinReview()
         familyView.JoinLVMin = family.GetJoinLVMin()
@@ -1811,7 +1889,7 @@
     curFamily.SetLV(updLV)
     curFamily.SetExp(updExp)
     
-    Broadcast_FamilyInfo(familyID, isSyncMem=False)
+    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 公会经验
     return True
 
 def AddFamilyContrib(curPlayer, addContribValue):
@@ -1843,7 +1921,7 @@
     curMember.SetContribTotal(contribTotal)
     GameWorld.DebugLog("增加成员贡献: familyID=%s,addContribValue=%s,contribDay=%s,contribTotal=%s" % (familyID, addContribValue, contribDay, contribTotal), playerID)
     
-    Broadcast_FamilyInfo(familyID, isSyncMem=False)
+    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 成员贡献
     return
 
 ## ------------------------------------------------------------------------------------------------
@@ -1944,6 +2022,67 @@
     CrossPlayer.SendFakePackByFamily(familyID, clientPack)
     return
 
+def OnFamilyTalk(curPlayer, familyID, talkPack, tick):
+    clientData, tick = None, 0
+    reqDataEx = {"talkBuffer":talkPack.GetBuffer()}
+    FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnFamilyTalk", reqDataEx=reqDataEx)
+    return
+def __OnFamilyTalk(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+    talkBuffer = reqDataEx["talkBuffer"]
+    playerID = crossPlayer.GetPlayerID()
+    familyID = crossPlayer.GetFamilyID()
+    if not familyID or not talkBuffer:
+        return
+    clientPack = ChPyNetSendPack.tagMCTalk()
+    clientPack.ReadData(talkBuffer)
+    
+    CrossPlayer.SendFakePackByFamily(familyID, clientPack)
+    
+    # 聊天缓存
+    channelType = clientPack.ChannelType
+    content = clientPack.Content
+    bubbleBox = clientPack.BubbleBox
+    PlayerTalk.DoTalkCache(channelType, playerID, content, bubbleBox, familyID)
+    return
+
+def OnCrossFamilyTalk(curPlayer, talkPack, tick):
+    ## 跨服公会聊天,与跨服公会互通范围一致
+    crossServerID = DBDataMgr.GetFamilyMgr().GetCurCrossServerID()
+    if crossServerID <= 0:
+        GameWorld.DebugLog("本服公会未互通,不允许跨服聊天")
+        return
+    clientData, tick = None, 0
+    reqDataEx = {"talkBuffer":talkPack.GetBuffer()}
+    FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnCrossTalk", reqDataEx=reqDataEx)
+    return
+def __OnCrossTalk(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+    talkBuffer = reqDataEx["talkBuffer"]
+    playerID = crossPlayer.GetPlayerID()
+    
+    if not talkBuffer:
+        return
+    
+    familyMgr = DBDataMgr.GetFamilyMgr()
+    zoneID = familyMgr.GetZoneIDInThisServer(fromServerID)
+    if zoneID < 0:
+        GameWorld.ErrLog("找不到服务器ID在跨服中的公会分区! fromServerID=%s" % fromServerID)
+        return
+    zoneMgr = familyMgr.GetZoneFamilyMgr(zoneID)
+    serverIDList = zoneMgr.GetZoneServerIDList()
+    if not serverIDList:
+        return
+    
+    clientPack = ChPyNetSendPack.tagMCTalk()
+    clientPack.ReadData(talkBuffer)
+    CrossPlayer.SendFackPackToServerList(clientPack, serverIDList)
+    
+    # 聊天缓存
+    channelType = clientPack.ChannelType
+    content = clientPack.Content
+    bubbleBox = clientPack.BubbleBox
+    PlayerTalk.DoTalkCache(channelType, playerID, content, bubbleBox)
+    return
+
 ## -------------------------------------- 游戏服本服处理 --------------------------------------------
 '''
 为方便本服、跨服互通公会逻辑统一,公会相关数据处理统一使用 CrossPlayer,视为以前的GameServer处理,这样本服跨服的公会管理通用
@@ -1961,26 +2100,20 @@
         Do_MapServer_FamilyRefresh(curPlayer, doData)
     return
 
-def Do_MapServer_PlayerOnDay(curPlayer):
-    ResetDailyDonateCnt(curPlayer)
-    return
-
-def Do_MapServer_PlayerLogin(curPlayer):
-    SyncDonateCntInfo(curPlayer)
-    PlayerFamilyZhenbaoge.OnPlayerLogin(curPlayer)
-    return
-
 def Do_MapServer_FamilyRefresh(curPlayer, doData):
     tick = GameWorld.GetGameWorld().GetTick()
     playerID = curPlayer.GetPlayerID()
     refreshFamilyID = doData["FamilyID"]
     refreshFmLV = doData.get("FmLV", 0)
+    refreshJoinTime = doData.get("JoinTime", 0)
     refreshFamilyLV = doData.get("FamilyLV", 0)
     refreshFamilyName = doData.get("FamilyName", "")
     refreshEmblemID = doData.get("EmblemID", 0)
     refreshEmblemWord = doData.get("EmblemWord", "")
+    isLogin = doData.get("isLogin", 0) # 是否登录刷新的
     
     PlayerViewCache.UpdPlayerViewFamilyInfo(playerID, refreshFamilyID, refreshFamilyName, refreshEmblemID, refreshEmblemWord)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyJoinTime, refreshJoinTime)
     
     lastFamilyID = curPlayer.GetFamilyID()
     lastFamilyLV = curPlayer.GetFamilyLV() # 公会等级,非职位等级
@@ -2022,6 +2155,17 @@
         
     #---通知客户端刷新属性---
     curPlayer.View_FamilyInfoRefresh() #//04 30 玩家家族名字职位等信息刷新#tagPlayerInFamilyInfoRefresh
+    
+    if isLogin:
+        Do_MapServer_PlayerLogin(curPlayer)
+    return
+
+def Do_MapServer_PlayerLogin(curPlayer):
+    ## 地图公会玩家的登录逻辑由最新所属公会刷新后处理
+    DBFamily.Sync_FamilyCrossInfo(curPlayer)
+    SyncDonateCntInfo(curPlayer)
+    PlayerFamilyZhenbaoge.OnPlayerLogin(curPlayer)
+    PlayerFamilyTaofa.OnPlayerLogin(curPlayer)
     return
 
 def __OnEnterFamily(curPlayer, tick):

--
Gitblit v1.8.0