ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
@@ -23,26 +23,111 @@
import PlayerControl
import PlayerViewCache
import ChPyNetSendPack
import PlayerDBGSEvent
import NetPackCommon
import PyGameData
# 获取玩家跨服服务器上的名字
#===============================================================================
# def GetCrossPlayerName(curPlayer):
#    # 通过游戏账号中的平台标志获取名称,目前为spid
#    playerName = curPlayer.GetPlayerName()
#    nameFormat = ReadChConfig.GetPyMongoConfig("Merge", "NameFormat", True)
#    if not nameFormat:
#        return playerName
#
#    opName = ReadChConfig.GetPyMongoConfig("Merge", "OpName_%s" % GameWorld.GetPlayerPlatform(curPlayer))
#
#    return (nameFormat%{"opname":opName, "sid":GameWorld.GetPlayerServerID(curPlayer)}).decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName
#===============================================================================
# 获取玩家跨服服务器上的名字
def GetCrossPlayerName(curPlayer):
    # 通过游戏账号中的平台标志获取名称,目前为spid
    playerName = curPlayer.GetPlayerName()
    nameFormat = ReadChConfig.GetPyMongoConfig("Merge", "NameFormat", True)
    if not nameFormat:
    opName = ReadChConfig.GetPyMongoConfig("Merge", "OpName_%s_%s" % (GameWorld.GetPlayerPlatform(curPlayer),
                                           GameWorld.GetPlayerServerSID(curPlayer)))
    if not opName:
        return playerName
    
    opName = ReadChConfig.GetPyMongoConfig("Merge", "OpName_%s" % GameWorld.GetPlayerPlatform(curPlayer))
    return opName.decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName
    return (nameFormat%{"opname":opName, "sid":GameWorld.GetPlayerServerID(curPlayer)}).decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName
def IsCrossServerOpen():
    ## 跨服服务器是否开放中
    return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen)
def ClientServerMsg_ServerInitOK(serverGroupID):
    ## 子服连接成功
    isOpen = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen)
    GameWorld.Log("子服连接成功,通知当前跨服服务器状态: isOpen=%s" % isOpen)
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossServerState, {"isOpen":isOpen}, [serverGroupID])
    return
def DoChangeCrossServerState(isOpen):
    ## 跨服服务器状态变更
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossServerClose, 0 if isOpen else 1) # 存DB的反着存
    GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isOpen)
    if not isOpen:
        # 踢掉所有玩家
        playerManager = GameWorld.GetPlayerManager()
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None:
                continue
            PlayerControl.SetCrossRealmState(curPlayer, 0)
            curPlayer.Kick(0)
    # 广播所有子服,本服务器进入维护
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossServerState, {"isOpen":isOpen})
    return
def CrossServerMsg_CrossServerState(msgData):
    ## 子服收到跨服服务器状态变更,子服不存DB,默认跨服维护中,连接跨服成功后由跨服同步状态直接更新到字典即可,没连上就默认维护中
    isOpen = msgData["isOpen"]
    isOpen = 1 if isOpen else 0
    GameWorld.Log("收到跨服服务器状态变更: 是否正常开放中=%s" % isOpen)
    GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isOpen)
    if not isOpen:
        playerManager = GameWorld.GetPlayerManager()
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None:
                continue
            PlayerControl.SetCrossRealmState(curPlayer, 0)
    # 通知地图
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isOpen)
    return
def PlayerExitCrossServer(curPlayer):
    ## 玩家退出跨服服务器
    if not GameWorld.IsCrossServer():
        return
    # 通知子服玩家退出跨服服务器
    playerID = curPlayer.GetPlayerID()
    serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_ExitCrossServer, playerID, [serverGroupID])
    # 设置非跨服状态,踢下线
    PlayerControl.SetCrossRealmState(curPlayer, 0)
    curPlayer.Kick(0)
    GameWorld.Log("PlayerExitCrossServer...serverGroupID=%s" % serverGroupID, playerID)
    return
def CrossServerMsg_ExitCrossServer(msgData):
    ## 收到跨服服务器同步的玩家退出跨服服务器
    playerID = msgData
    GameWorld.Log("收到跨服服务器同步的玩家退出跨服服务器: playerID=%s" % playerID)
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
        GameWorld.Log("    退出跨服时本服玩家不在线!", playerID)
        return
    PlayerControl.SetCrossRealmState(curPlayer, 0)
    return
@@ -63,6 +148,9 @@
    
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
        return
    if not IsCrossServerOpen():
        return
    
    #newAccount, newName = msgList
@@ -98,6 +186,21 @@
def NotifyCanEnterMergeServer(curPlayer, actionType):
    # 通用包,通知客户端可进入跨服服务器
    return
#// C0 03 强制退出跨服状态 #tagCGForceQuitCrossState
#
#struct    tagCGForceQuitCrossState
#{
#    tagHead        Head;
#};
def OnForceQuitCrossState(index, clientData, tick):
    ''' 约定该封包仅玩家当前处于跨服状态,但是一直连不上跨服服务器时才会发次包强制重置跨服状态
                一般是跨服服务器异常或其他错误导致无法登录跨服服务器
    '''
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    GameWorld.ErrLog("某些异常情况下,前端强制发包退出跨服状态! ", curPlayer.GetPlayerID())
    PlayerControl.SetCrossRealmState(curPlayer, 0)
    return
#// C0 02 查看跨服玩家信息 #tagCGViewCrossPlayerInfo
@@ -187,6 +290,7 @@
    sendPack.ItemDataSize = len(sendPack.ItemData)
    sendPack.PlusData = PlusData
    sendPack.PlusDataSize = len(sendPack.PlusData)
    sendPack.CrossPlayer = 1
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    return