From 01a0e539b786ae0f1c46646874502367f5410aca Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 04 二月 2026 18:18:51 +0800
Subject: [PATCH] 66 【公会】基础主体-服务端(优化游戏服及跨服启动、通讯逻辑;服务器类型增加跨服中心、跨服事件、时间管理;跨服玩家在线状态、基础信息、玩家资源增减管理、发送跨服个人邮件等;跨服公会初版,修复公会成员审核、成员战力刷新等bug,增加公会名次同步;跨服公会暂未测试;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py |  197 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 188 insertions(+), 9 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index c26452a..a523967 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -120,20 +120,28 @@
 import PlayerActTask
 import PlayerMail
 import DBDataMgr
+import PlayerViewCache
 import UpdatePlayerName
 import GameServerRefresh
 import IPY_ServerDefine
+import IPY_PlayerDefine
 import CommFunc
 from PyMongoDB import RecvPackToMapDB
+import GMT_BroadCast
 import PyMongoMain
 import PlayerTalk
 import PlayerHero
+import PlayerPreset
 import PlayerOnline
 import PlayerBeauty
 import PlayerTravel
 import PlayerMingge
 import TurnAttack
 import PlayerHJG
+import DBFamily
+import CrossPlayer
+import CrossMsg
+import CrossMgr
 import ChEquip
 
 import datetime
@@ -407,6 +415,7 @@
 def DoPlayerLogin(curPlayer, tick):
     #这里只做初始化逻辑
     curPlayer.SetDict(ChConfig.Def_PlayerKey_LoadMapIsLogin, 1)
+    CrossPlayer.GetCrossPlayerMgr().RegistPlayer(curPlayer.GetPlayerID())
     
     #通知时间
     Sync_PyServerDataTimeToClient(curPlayer)
@@ -469,9 +478,7 @@
     SyncGuideState(curPlayer)
     
     #上线检查一次装备属性
-    ItemControler.OnPlayerLogin(curPlayer)  
-    #更新服务器组ID
-    PlayerControl.UpdPlayerServerGroupID(curPlayer)
+    ItemControler.OnPlayerLogin(curPlayer)
     
     #上线学习技能
     #SkillCommon.PlayerLoginCheckLearnSkill(curPlayer)
@@ -714,6 +721,7 @@
     
     else:
         PyMongoMain.GetUserCtrlDB().OnPlayerLogin(curPlayer)
+        GMT_BroadCast.OnPlayerLogin(curPlayer)
         PlayerHero.OnPlayerLogin(curPlayer)
         PlayerMail.OnPlayerLogin(curPlayer)
         PlayerHJG.OnPlayerLogin(curPlayer)
@@ -733,16 +741,28 @@
         PlayerTravel.OnPlayerLogin(curPlayer)
         PlayerMingge.OnPlayerLogin(curPlayer)
         OpenServerActivity.OnPlayerLogin(curPlayer)
+        PlayerPreset.OnPlayerLogin(curPlayer)
+        CrossPlayer.OnPlayerLogin(curPlayer)
         
         __OnFixVersion(curPlayer) # 修正线上玩家数据用,暂时放最后
         # 上线查询一次充值订单
         # curPlayer.SendDBQueryRecharge() 不查了,由在线轮询触发即可
+        SyncOnlineStateToCross(curPlayer, 1)
         
     # 通知GameServer地图最终登录成功了
     isMixServerFirstLogin = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MixServerFirstLogin)
     msg = str([isMixServerFirstLogin])
     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "PlayerRealLoginOK", msg, len(msg))
     return
+
+#def C2S_PlayerLoginOK(playerID):
+#    ## 跨服登录成功后续处理
+#    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+#    if not curPlayer:
+#        return
+#    
+#    PlayerFamily.CrossServer_PlayerLogin(curPlayer)
+#    return
 
 def __OnFixVersion(curPlayer):
     ''' 修正线上玩家数据内容
@@ -777,6 +797,163 @@
     
     # 最终强制设置为最新版本号
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FixVersion, sysFixVersion)
+    return
+
+def GetSyncCrossServerIDAndFuncInfo():
+    ## 获取需要同步给的目标跨服服务器ID及相关额外的功能信息
+    dataEx = {}
+    serverIDList = []
+    
+    # 公会
+    if DBFamily.IsFamilyCross():
+        crossFamilyServerID = DBDataMgr.GetFamilyMgr().GetCurCrossServerID()
+        if crossFamilyServerID > 0:
+            dataEx["crossFamilyServerID"] = crossFamilyServerID
+            if crossFamilyServerID not in serverIDList:
+                serverIDList.append(crossFamilyServerID)
+                
+    # 其他跨服功能
+    
+    return serverIDList, dataEx
+
+def OnPlayerBaseInfoChange(curPlayer, refreshType=0):
+    '''玩家基础信息变更同步更新其他功能,可以视为同步到以前的GameServer
+    除了相关基础值变化同步外,上下线状态变更也会附带基础信息的同步
+    '''
+    
+    playerID = curPlayer.GetPlayerID()
+    crossPlayerMgr = CrossPlayer.GetCrossPlayerMgr()
+    crossPlayer = crossPlayerMgr.FindCrossPlayer(playerID)
+    if not crossPlayer:
+        return
+    
+    # 公会成员
+    PlayerFamily.RefreshFamilyMember(crossPlayer)
+    
+    # 相关排行榜
+    if refreshType == IPY_PlayerDefine.CDBPlayerRefresh_PlayerName:
+        PlayerBillboard.UpdatePlayerBillboardName(curPlayer)
+        
+    # 社交名待更新
+    
+    # --------------------------------------------------------------
+    
+    # 同步给相关跨服
+    tick = GameWorld.GetGameWorld().GetTick()
+    lastSyncTick = curPlayer.GetDictByKey("S2C_PlayerBaseInfo")
+    if lastSyncTick and (tick - lastSyncTick) <= 2000:
+        # 短时间内只同步一次
+        return
+    curPlayer.SetDict("S2C_PlayerBaseInfo", tick)
+    
+    if refreshType == IPY_PlayerDefine.CDBPlayerRefresh_LV:
+        if curPlayer.GetLV() < 20:
+            return
+        
+    serverIDList = GetSyncCrossServerIDAndFuncInfo()[0]
+    if not serverIDList:
+        return
+    
+    playerID = curPlayer.GetPlayerID()
+    baseInfo = PlayerViewCache.GetPlayerBaseViewInfo(playerID, curPlayer)
+    dataMsg = {"baseInfo":baseInfo}
+    CrossMsg.SendToCrossServer(ShareDefine.S2C_PlayerBaseInfo, dataMsg, serverIDList, playerID)
+    return
+
+def S2C_PlayerBaseInfo(dataMsg, fromServerID, playerID):
+    isOnline = True
+    baseInfo = dataMsg["baseInfo"]
+    UpdCrossPlayerFromMainServer(fromServerID, playerID, baseInfo, isOnline)
+    return
+
+def UpdCrossPlayerFromMainServer(fromServerID, playerID, baseInfo, isOnline):
+    ## 更新CrossPlayer根据游戏服同步的信息
+    # @return: crossPlayer
+    crossPlayerMgr = CrossPlayer.GetCrossPlayerMgr()
+    crossPlayer = crossPlayerMgr.FindCrossPlayer(playerID)
+    if not crossPlayer:
+        crossPlayer = crossPlayerMgr.RegistPlayer(playerID) # 跨服不存在该玩家信息,直接注册,不用管是否在线
+        
+    # 信息更新
+    curCache = PlayerViewCache.UpdPlayerBaseViewInfo(playerID, baseInfo, not isOnline)
+    crossPlayer.UpdByViewCache(curCache, fromServerID)
+    
+    # 公会成员更新
+    PlayerFamily.RefreshFamilyMember(crossPlayer)
+    
+    # 如果是离线的处理
+    if not isOnline:
+        PlayerViewCache.OnCrossPlayerLogout(crossPlayer)
+        crossPlayerMgr.DeletePlayer(playerID)
+        
+    return crossPlayer
+
+def SyncOnlinePlayerToCross(toCrossServerID):
+    ## 重新同步在线玩家,确保目标服务器有跨服玩家基础数据,一般用于重连跨服、或某些跨服功能开启时重新同步确保目标服务器有本服在线玩家基本数据信息
+    playerManager = GameWorld.GetPlayerManager()
+    for i in xrange(playerManager.OnlineCount()):
+        curPlayer = playerManager.OnlineAt(i)
+        if not GameWorld.IsNormalPlayer(curPlayer):
+            continue
+        SyncOnlineStateToCross(curPlayer, 1, False, toCrossServerID)
+    return
+
+def SyncOnlineStateToCross(curPlayer, isOnline, isLoginout=True, toCrossServerID=0):
+    ## 同步玩家在线状态给相关跨服
+    # @param isLoginout: 是否上下线的,重新连上跨服时也会重新同步
+    
+    playerID = curPlayer.GetPlayerID()
+    
+    # 游戏服、跨服通用,当做以前GameServer的Player处理
+    crossPlayerMgr = CrossPlayer.GetCrossPlayerMgr()
+    # 离线直接清除
+    if not isOnline:
+        crossPlayerMgr.DeletePlayer(playerID)
+        
+    serverIDList, dataEx = GetSyncCrossServerIDAndFuncInfo()
+    if not serverIDList:
+        # 没有需要同步的跨服不处理
+        return
+    
+    if toCrossServerID:
+        if toCrossServerID not in serverIDList:
+            return
+        serverIDList = [toCrossServerID] # 如果有指定,指同步给该服
+        
+    baseInfo = PlayerViewCache.GetPlayerBaseViewInfo(playerID, curPlayer)
+    dataMsg = {"isOnline":isOnline, "isLoginout":isLoginout, "baseInfo":baseInfo}
+    dataMsg.update(dataEx)
+    CrossMsg.SendToCrossServer(ShareDefine.S2C_OnlineState, dataMsg, serverIDList, playerID)
+    return
+
+def S2C_OnlineState(dataMsg, fromServerID, playerID):
+    ## 收到游戏服玩家在线状态同步
+    isOnline = dataMsg["isOnline"]
+    isLoginout = dataMsg["isLoginout"]
+    baseInfo = dataMsg["baseInfo"]
+    
+    crossPlayer = UpdCrossPlayerFromMainServer(fromServerID, playerID, baseInfo, isOnline)
+    
+    # 其他跨服功能处理,暂时仅上下线时处理
+    curServerID = GameWorld.GetGameWorld().GetServerID()
+    if isLoginout:
+        # 公会
+        if "crossFamilyServerID" in dataMsg:
+            crossFamilyServerID = dataMsg["crossFamilyServerID"]
+            if curServerID == crossFamilyServerID:
+                if isOnline:
+                    PlayerFamily.OnCrossPlayerLogin(crossPlayer)
+                else:
+                    PlayerFamily.OnCrossPlayerLogout(crossPlayer)
+                    
+        # 最后处理缓存,先放在更新中处理删除,有问题再放后面
+        #if not isOnline:
+        #    PlayerViewCache.OnCrossPlayerLogout(crossPlayer)
+        #    CrossPlayer.GetCrossPlayerMgr().DeletePlayer(playerID)
+            
+    # 最后同步处理跨服登录成功
+    #if isLoginout and isOnline:
+    #    CrossMsg.SendToClientServer(ShareDefine.C2S_PlayerLoginOK, {}, [fromServerID], playerID)
     return
 
 ## 玩家扩展信息同步
@@ -1058,9 +1235,6 @@
     
     #检查更新总战斗力
     #PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer, True)
-    
-    #清除在本地图离线记录信息
-    PlayerControl.RemoveLeaveServerPlayerInfo(curPlayer.GetPlayerID())
     
     PyGameData.g_needRefreshMapServerState = True # 有玩家登录地图时设置需要刷新
     return
@@ -2131,6 +2305,8 @@
     #离线session
     EventReport.WriteEvent_session(curPlayer)
     
+    #最后同步跨服服务器
+    SyncOnlineStateToCross(curPlayer, 0)
     #需放最后
     PlayerOnline.OnPlayerLogoff(curPlayer)
     return
@@ -3736,7 +3912,7 @@
 #  @param curPlayer 
 #  @param tick 时间戳
 #  @return None
-def Sync_PyServerDataTimeToClient(curPlayer):
+def Sync_PyServerDataTimeToClient(curPlayer=None):
     # 服务器时间
     serverTime = GameWorld.GetCurrentTime()
     if not serverTime:
@@ -3751,10 +3927,13 @@
     serverDateTime.Minute = serverTime.minute
     serverDateTime.Second = serverTime.second
     serverDateTime.MicSecond = serverTime.microsecond
-    serverDateTime.CrossServerTime = GameWorld.GetCrossServerTimeStr()
+    serverDateTime.CrossServerTime = GameWorld.ChangeTimeNumToStr(CrossMgr.GetSSServerMgr().GetCrossTime())
     
     # 通知客户端同步时间
-    NetPackCommon.SendFakePack(curPlayer, serverDateTime)
+    if curPlayer:
+        NetPackCommon.SendFakePack(curPlayer, serverDateTime)
+    else:
+        NetPackCommon.SendFackPackOnline(serverDateTime)
     return
 
 ## 通知开服天数

--
Gitblit v1.8.0