ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -120,9 +120,11 @@
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
@@ -136,6 +138,10 @@
import PlayerMingge
import TurnAttack
import PlayerHJG
import DBFamily
import CrossPlayer
import CrossMsg
import CrossMgr
import ChEquip
import datetime
@@ -409,6 +415,7 @@
def DoPlayerLogin(curPlayer, tick):
    #这里只做初始化逻辑
    curPlayer.SetDict(ChConfig.Def_PlayerKey_LoadMapIsLogin, 1)
    CrossPlayer.GetCrossPlayerMgr().RegistPlayer(curPlayer.GetPlayerID())
    
    #通知时间
    Sync_PyServerDataTimeToClient(curPlayer)
@@ -472,8 +479,6 @@
    
    #上线检查一次装备属性
    ItemControler.OnPlayerLogin(curPlayer)  
    #更新服务器组ID
    PlayerControl.UpdPlayerServerGroupID(curPlayer)
    
    #上线学习技能
    #SkillCommon.PlayerLoginCheckLearnSkill(curPlayer)
@@ -737,16 +742,27 @@
        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):
    ''' 修正线上玩家数据内容
@@ -781,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
## 玩家扩展信息同步
@@ -1062,9 +1235,6 @@
    
    #检查更新总战斗力
    #PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer, True)
    #清除在本地图离线记录信息
    PlayerControl.RemoveLeaveServerPlayerInfo(curPlayer.GetPlayerID())
    
    PyGameData.g_needRefreshMapServerState = True # 有玩家登录地图时设置需要刷新
    return
@@ -2135,6 +2305,8 @@
    #离线session
    EventReport.WriteEvent_session(curPlayer)
    
    #最后同步跨服服务器
    SyncOnlineStateToCross(curPlayer, 0)
    #需放最后
    PlayerOnline.OnPlayerLogoff(curPlayer)
    return
@@ -3740,7 +3912,7 @@
#  @param curPlayer 
#  @param tick 时间戳
#  @return None
def Sync_PyServerDataTimeToClient(curPlayer):
def Sync_PyServerDataTimeToClient(curPlayer=None):
    # 服务器时间
    serverTime = GameWorld.GetCurrentTime()
    if not serverTime:
@@ -3755,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())
    
    # 通知客户端同步时间
    if curPlayer:
    NetPackCommon.SendFakePack(curPlayer, serverDateTime)
    else:
        NetPackCommon.SendFackPackOnline(serverDateTime)
    return
## 通知开服天数