hxp
2021-11-17 ffa8a645ed6a92a3c723bbf5c7f1eb4d5425c826
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -27,35 +27,24 @@
import GMCommon
import ShareDefine
#import PlayerFamilyTech
import PlayerDataCollect
import time
import ChPyNetSendPack
import NetPackCommon
import GameDataRecord
import GameConfig
import ReadChConfig
import UpdatePlayerName
import GameWorldBoss
import PlayerFamilyBoss
#import PlayerManorWar
import PlayerBourse
import GameWorldActionTeHui
import PlayerZhuXianBoss
import PlayerXMZZ
import GameWorldMergePK
import GameWorldShopItem
import MergeChildMsg
import PlayerTruck
import PlayerMergeEvent
import HighLadder
import EventReport
import MergePlayer
import PlayerHorsePetBoss
import PlayerCompensation
import PlayerFamilyRedPacket
import PlayerFamilyStore
import PyDataManager
#import PlayerFamilyStore
import PlayerSocial
import PlayerFamilyParty
import PlayerSealDemon
#import PlayerSealDemon
import PlayerBillboard
import PlayerLVAward
import PlayerDuJie
@@ -65,13 +54,32 @@
import PlayerGeTui
import PlayerStore
import GameWorldActionControl
import GameWorldFamilyWar
import PlayerFBHelpBattle
import GameWorldSkyTower
import GMT_CTG
import PyGameData
import GMShell
import IPY_PlayerDefine
import GameWorldArena
import CrossRealmPK
import AuctionHouse
import PlayerAssist
import PlayerFB
import PlayerLove
import PlayerCharm
#---------------------------------------------------------------------
#---------------------------------------------------------------------
def DoRefreshMainServerRole(curPlayer):
    ## 刷新本服角色信息
    curTeam = curPlayer.GetTeam()
    if curTeam:
        PlayerTeam.Sync_TeamMemberInfo(curTeam)
    return
## 玩家登录初始化(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
@@ -84,9 +92,7 @@
    except:
        curPlayer.Kick(IPY_PlayerDefine.disWaitForPlayerLoinError)
        import traceback
        GameWorld.ErrLog("玩家上线逻辑错误~~~~~\r\n%s" % traceback.format_exc())
        if GameWorld.GetGameWorld().GetDebugLevel():
            raise Exception("玩家上线逻辑错误~~~~\r\n%s" % traceback.format_exc())
        GameWorld.RaiseException("玩家上线逻辑错误\r\n%s" % traceback.format_exc())
    return
#---------------------------------------------------------------------
@@ -97,18 +103,35 @@
#  @remarks 登陆顺序, PlayerLogin->PlayerLoadMapState(PlayerLoginLoadMapOK), 此处未设置初始化状态
def __Func_PlayerLogin(curPlayer, tick):
    
    GameWorld.Log("__Func_PlayerLogin mapID=%s" % curPlayer.GetMapID(), curPlayer.GetPlayerID())
    curPlayer.SetDict(ChConfig.Def_PDict_LoginMapID, curPlayer.GetMapID())
    #玩家在线时间初始化
    InitPlayerOnLineTime(curPlayer, tick)
    #玩家响应信息初始化
    InitPlayerOnLineReply(curPlayer, tick)
    # 统计登入人数
    GameDataRecord.PlayerLoginRecord(curPlayer, tick)
    __DoPlayerLoginServer(curPlayer, tick)
    #通知地图服务器自己初始化成功
    curPlayer.MapServer_InitOK()
    return
def __DoPlayerLoginServer(curPlayer, tick):
    ''' 玩家登录需要处理的内容,本服及跨服服务器分开
    '''
    if GameWorld.IsCrossServer():
        #跨服PK
        CrossRealmPK.OnPlayerLoginCrossServer(curPlayer)
        return
    #玩家家族刷新
    #家族任务需要刷新 FamilyLV, 地图服务器需要知道FamilyLV来通知玩家家族任务次数 
    PlayerFamily.PlayerLoginRefreshFamily(curPlayer, tick)
    #玩家队伍初始化
    PlayerTeam.OnPlayerLoginRefreshTeam(curPlayer, tick)
    PlayerCompensation.NotifyPlayerCompensation(curPlayer)
    __UpdOnedayJobPlayerLoginoffTime(curPlayer)
    
    if not PlayerControl.GetIsTJG(curPlayer):
        # 只有通知逻辑的应该放此处减少IO,如有逻辑处理存储等不可放在此处
@@ -123,30 +146,23 @@
        # 通知广播信息
        GMCommon.SendBroadCastToClient(curPlayer)
    
        # 在非跨服服务器上线时,在跨服PK赛期间如果roomID不为0则重置
        #if not GameWorld.IsMergeServer() and GameWorldMergePK.IsMergePKMatchOpen() \
        #    and curPlayer.GetVsRoomId() != 0:
        #    PlayerControl.SetVsRoomId(curPlayer, 0)
        PlayerTruck.SyncPlayerTruckStartTime(curPlayer)
        #通知玩家交易所挂单情况
        PlayerBourse.OnPlayerLogin(curPlayer)
        #拍卖行
        AuctionHouse.OnPlayerLogin(curPlayer)
        #上线广播
        __CheckWorldNotifyOnLogin(curPlayer, tick)
        #上线奖励处理
        #PlayerMergeEvent.MergeEventOnPlayerLogin(curPlayer)
        #MergePlayer.OnPlayerLogin(curPlayer)
        
        #仙盟红包
        PlayerFamilyRedPacket.OnPlayerLogin(curPlayer)
        #仙盟仓库
        PlayerFamilyStore.OnPlayerLogin(curPlayer)
        #PlayerFamilyStore.OnPlayerLogin(curPlayer)
        #仙盟宴会
        PlayerFamilyParty.OnPlayerLogin(curPlayer)
        #封魔坛
        PlayerSealDemon.OnPlayerLogin(curPlayer)
        #PlayerSealDemon.OnPlayerLogin(curPlayer)
        #仙魔之争
        PlayerXMZZ.OnXMZZOnLogin(curPlayer)
        #等级奖励
@@ -155,24 +171,83 @@
        PlayerStore.OnPlayerLogin(curPlayer)
        #通知世界boss信息
        GameWorldBoss.OnPlayerLogin(curPlayer)
        #家族副本boss状态通知
        PlayerFamilyBoss.OnLogin(curPlayer)
        #渡劫
        PlayerDuJie.OnPlayerLogin(curPlayer)
        #守卫人皇
        PlayerFamilySWRH.OnLogin(curPlayer)
        PlayerTalk.LoginChatMi(curPlayer)
        PlayerGeTui.CleanNewGuyCallBackGeTui(curPlayer.GetID())
        PlayerTalk.NotifyTalkCache(curPlayer)
        #PlayerGeTui.CleanNewGuyCallBackGeTui(curPlayer.GetID())
        #活动
        GameWorldActionControl.OnPlayerLogin(curPlayer)
        #玩家等级记录
        PyGameData.g_todayPlayerLVDict[curPlayer.GetID()] = curPlayer.GetLV()
        GMShell.OnPlayerLogin(curPlayer)
        #竞技场
        GameWorldArena.OnPlayerLogin(curPlayer)
        #跨服PK
        CrossRealmPK.OnPlayerLogin(curPlayer)
        #诛仙BOSS
        PlayerZhuXianBoss.OnPlayerLogin(curPlayer)
        #骑宠boss状态通知
        PlayerHorsePetBoss.OnLogin(curPlayer)
        #协助
        PlayerAssist.OnPlayerLogin(curPlayer, False)
        #天星塔
        GameWorldSkyTower.OnPlayerLogin(curPlayer)
        GMT_CTG.OnPlayerLogin(curPlayer)
        
    #通知地图服务器自己初始化成功
    curPlayer.MapServer_InitOK()
    else:
        #协助
        PlayerAssist.OnPlayerLogin(curPlayer, True)
    return
def DoPlayerRealLoginOK(curPlayer, tick):
    ''' 玩家最终登录成功处理, 由  MapServer  DoPlayerRealLoginOK  通知
        该函数为地图最终登录成功才会执行到,以后一些功能类的登录处理建议均写到这里
        旧的功能先不动( __DoPlayerLoginServer 函数中的功能),如果有登录相关的bug再考虑是否移动到此函数
    '''
    GameWorld.Log("GameServer->DoPlayerRealLoginOK", curPlayer.GetPlayerID())
    if not PlayerControl.GetIsTJG(curPlayer):
        #家族副本boss状态通知
        PlayerFamilyBoss.OnLogin(curPlayer)
        #魅力
        PlayerCharm.OnPlayerLogin(curPlayer)
        #情缘
        PlayerLove.OnPlayerLogin(curPlayer)
    return
def __UpdOnedayJobPlayerLoginoffTime(curPlayer):
    ## 更新一天内职业对应玩家登录、离线时间
    job = curPlayer.GetJob()
    playerID = curPlayer.GetPlayerID()
    if job not in PyGameData.g_onedayJobPlayerLoginoffTimeDict:
        PyGameData.g_onedayJobPlayerLoginoffTimeDict[job] = {}
    playerLoginoffTimeDict = PyGameData.g_onedayJobPlayerLoginoffTimeDict[job]
    playerLoginoffTimeDict[playerID] = int(time.time())
    #GameWorld.DebugLog("更新职业对应玩家登录离线时间: %s" % PyGameData.g_onedayJobPlayerLoginoffTimeDict)
    return
def CheckOnedayJobPlayerLoginoffTimeout():
    ## 检查一天内职业对应玩家登录、离线时间超时玩家,每小时检查一次
    maxTime = 24 * 3600 # 暂定24小时
    curTime = int(time.time())
    #GameWorld.DebugLog("处理24小时内在线的角色职业玩家: curTime=%s,maxTime=%s, %s" % (curTime, maxTime, PyGameData.g_onedayJobPlayerLoginoffTimeDict))
    playerManager = GameWorld.GetPlayerManager()
    for playerDict in PyGameData.g_onedayJobPlayerLoginoffTimeDict.values():
        for playerID, loginoffTime in playerDict.items():
            if playerManager.FindPlayerByID(playerID):
                #GameWorld.DebugLog("    在线不处理, playerID=%s" % playerID)
                continue
            if curTime - loginoffTime > maxTime:
                playerDict.pop(playerID)
                #GameWorld.DebugLog("    超时玩家,移除! playerID=%s,loginoffTime=%s" % (playerID, loginoffTime))
    #GameWorld.DebugLog("    处理完毕,剩余玩家! %s" % PyGameData.g_onedayJobPlayerLoginoffTimeDict)
    return
## 增加高手玩家上线广播
@@ -180,7 +255,7 @@
#  @return None
def __CheckWorldNotifyOnLogin(curPlayer, tick):
    # 跨服服务器不广播
    if GameWorld.IsMergeServer():
    if GameWorld.IsCrossServer():
        return
    
    limitLV = IpyGameDataPY.GetFuncCfg("BillBoardPlayerLoginNotify", 2) # 最低等级限制
@@ -203,9 +278,6 @@
            if checkMark not in ShareDefine.BillboardTypeList:
                continue
            
            if checkMark in [ShareDefine.Def_BT_HighLadder]:
                continue
            billboard = GameWorld.GetBillboard().FindBillboard(checkMark)
            if not billboard:
                continue
@@ -224,11 +296,7 @@
                objBillboard = billboard.At(index)
                if curPlayer.GetID() == objBillboard.GetID():
                    msgMark = notifyDict[order]
                    break
#        # 竞技场
#        elif checkMark == "HighLadder":
#            highLadderOrder = HighLadder.GetPlayerOrder(curPlayer.GetID()) + 1
#            msgMark = notifyDict.get(highLadderOrder, "")
                    break
        
        # 有可以广播的,马上广播,退出,不再检查
        if msgMark:
@@ -254,31 +322,6 @@
    diff_Time = loginTime - logoffTime
    #天数 * 24小时 * 60 分钟 + 秒
    return diff_Time.days * 24 * 60 * 60 + diff_Time.seconds
## 统计客户端跨服赛激活时间
#  @param index 玩家索引
#  @return None
def SendMergeWarOpen(curPlayer):
    # 发送跨服赛服务器信息
    mapConfig = GameConfig.GetConfig()
    mergeServerIP = mapConfig.get("MergeServerIP")
    mergeServerPort = mapConfig.get("MergeServerPort")
    if not mergeServerIP:
        return
    mergeServerInfo = ChPyNetSendPack.tagMergeServerInfo()
    mergeServerInfo.ServerIPLen = len(mergeServerIP)
    mergeServerInfo.ServerIP = mergeServerIP
    mergeServerInfo.Port = mergeServerPort
    mergeServerInfo.IsMergeServer = GameWorld.IsMergeServer()
    NetPackCommon.SendFakePack(curPlayer, mergeServerInfo)
    return
## 跨服赛通知奖励
#  @param curPlayer: 玩家实例
#  @return: None
def MSGetReward(curPlayer):
    #PlayerCanGetReward.SynClient_CanGetRewardList(curPlayer)
    return
## 运营登陆信息处理
#  @param curPlayer
@@ -495,9 +538,7 @@
        __Func_PlayerDisconnect(curPlayer, tick)
    except:
        import traceback
        GameWorld.ErrLog("玩家下线逻辑错误~~~~~\r\n%s" % traceback.format_exc())
        if GameWorld.GetGameWorld().GetDebugLevel():
            raise Exception("玩家下线逻辑错误~~~~\r\n%s" % traceback.format_exc())
        GameWorld.RaiseException("玩家下线逻辑错误\r\n%s" % traceback.format_exc())
    #调用底层下线
    curPlayer.DoDisconnect()
    return
@@ -509,8 +550,11 @@
#  @remarks 函数详细说明.
def __Func_PlayerDisconnect(curPlayer, tick):
    
    if GameWorld.IsCrossServer():
        PlayerFB.OnPlayerDisconnectCrossServer(curPlayer)
    #跨服匹配PK
    #GameWorldMergePK.OnLeaveServer(curPlayer)
    CrossRealmPK.OnLeaveServer(curPlayer)
    
    #组队玩家离线
    PlayerTeam.DoPlayerLogOffTeamLogic(curPlayer, tick)
@@ -518,13 +562,23 @@
    PlayerFamily.PlayerLogoffRefreshFamily(curPlayer, tick)
    PlayerFriend.OnPlayerDisconnect(curPlayer, tick)
    
    PlayerGeTui.NewGuyCallBackGeTui(curPlayer, tick)
    __UpdOnedayJobPlayerLoginoffTime(curPlayer)
    #PlayerGeTui.NewGuyCallBackGeTui(curPlayer, tick)
    # 设置家族成员离线时间
    SetPlayerOfflineTime(curPlayer)
    #MergePlayer.OnPlayerLeaveGotoMergeServer(curPlayer, tick)
    #拍卖行
    AuctionHouse.OnPlayerLeaveServer(curPlayer)
    #协助
    PlayerAssist.OnLeaveServer(curPlayer)
    #红包
    PlayerFamilyRedPacket.OnLeaveServer(curPlayer)
    #------------镖车逻辑
    #TruckPlayerDisconnectProcess(curPlayer, tick)
    if not PlayerControl.GetIsTJG(curPlayer):
        playerID = curPlayer.GetPlayerID()
        PyGameData.g_unTJLogoffTime[playerID] = int(time.time())
    return
## 设置玩家离线时间
@@ -532,8 +586,8 @@
#  @return None
#  @remarks 函数详细说明.
def SetPlayerOfflineTime(curPlayer):
    if PlayerControl.GetIsTJG(curPlayer):
        return
    #if PlayerControl.GetIsTJG(curPlayer):
    #    return
    
    curPlayerID = curPlayer.GetPlayerID()
    curFamily = curPlayer.GetFamily()
@@ -587,6 +641,7 @@
    
    playerStatePack = IPY_GameServer.IPY_GRefreshPlayerProperty()
    packValue = playerStatePack.GetValue()
    packValueEx = playerStatePack.GetValueEx()
    packType = playerStatePack.GetType()
    
    #---特殊逻辑处理---
@@ -594,6 +649,10 @@
        PlayerControl.SetGMForbidenTalk(curPlayer, packValue)
        return
    
    if packType == ShareDefine.CDBPlayerRefresh_ExAttr17:
        PlayerControl.SetPlayerAccState(curPlayer, packValue)
        return
    if packType == IPY_GameServer.CDBPlayerRefresh_State:
        # 脱机在线
        PlayerControl.SetIsTJG(curPlayer, packValue)
@@ -609,7 +668,7 @@
        return
    
    if packType == IPY_GameServer.CDBPlayerRefresh_FightPower:
        curPlayer.SetFightPower(packValue)
        curPlayer.SetFightPower(packValue, packValueEx)
        return
    if packType == IPY_GameServer.CDBPlayerRefresh_ExAttr2:
@@ -617,11 +676,19 @@
        PlayerTeam.SetTeamCheckState(curPlayer, packValue)
        return
    
    #if packType == IPY_GameServer.CDBPlayerRefresh_ExAttr1:
    #    PlayerControl.SetAssistTagPlayerID(curPlayer, packValue)
    #    return
    if packType == IPY_GameServer.CDBPlayerRefresh_ExAttr3:
        PlayerControl.SetFBFuncLineID(curPlayer, packValue)
        return
    #---常规逻辑处理---
        
    elif packType == IPY_GameServer.CDBPlayerRefresh_LV:
        curPlayer.SetLV(packValue)
        PlayerSocial.UpdateSocialInfo(curPlayer, packType, packValue)
        PlayerSocial.UpdateSocialInfo(curPlayer.GetID(), packType, packValue)
        #玩家等级记录
        playerID = curPlayer.GetID()
        if playerID in PyGameData.g_todayPlayerLVDict:
@@ -629,8 +696,6 @@
    elif packType == IPY_GameServer.CDBPlayerRefresh_Job:
        curPlayer.SetJob(packValue)
    elif packType == IPY_GameServer.CDBPlayerRefresh_ExAttr1:
        PlayerControl.SetJobRank(curPlayer, packValue)
        
#    elif packType == IPY_GameServer.CDBPlayerRefresh_CurrentPlayerType:
#        #这里应该通知组队那边刷新
@@ -652,15 +717,25 @@
    elif packType == IPY_GameServer.CDBPlayerRefresh_VIPLv:
        curPlayer.SetVIPLv(packValue);
#        __RefreshTeamState(curPlayer)
    elif packType == IPY_GameServer.CDBPlayerRefresh_ExAttr5:
        PlayerControl.SetCrossMapID(curPlayer, packValue, False)
    elif packType == IPY_GameServer.CDBPlayerRefresh_ExAttr9:
        PlayerControl.SetVIPExpireTime(curPlayer, packValue)
    elif packType == IPY_GameServer.CDBPlayerRefresh_ExAttr10:
        PlayerControl.SetChatBubbleBox(curPlayer, packValue)
    elif packType == IPY_GameServer.CDBPlayerRefresh_ExAttr13:
        PlayerControl.SetPlayerServerGroupID(curPlayer, packValue)
        
    elif packType == IPY_GameServer.CDBPlayerRefresh_OperateInfo:
        curPlayer.SetOperateInfo(packValue);
    
    elif packType == IPY_GameServer.CDBPlayerRefresh_OfficialRank:
        curPlayer.SetOfficialRank(packValue)
        PlayerSocial.UpdateSocialInfo(curPlayer, packType, packValue)
        PlayerSocial.UpdateSocialInfo(curPlayer.GetID(), packType, packValue)
        #更新排行榜的境界
        PlayerBillboard.UpdateBillboardRealm(curPlayer)
        
@@ -668,7 +743,8 @@
    PlayerTeam.PlayerTeamMemberRefresh(curPlayer, packType, packValue, tick)
    #家族刷新
    PlayerFamily.PlayerRefresh(curPlayer, tick)
    #副本助战
    PlayerFBHelpBattle.UpdateCheckInPlayerInfoByRefresh(curPlayer, packType, packValue)
    return
## 玩家切换地图的响应(参数 -> 当前玩家,当前时间)
@@ -687,6 +763,7 @@
    GameWorldBoss.OnPlayerChangeMap(curPlayer)
    PlayerFamily.OnPlayerChangeMap(curPlayer, tick)
    PlayerFamilyParty.OnPlayerChangeMap(curPlayer, tick)
    GameWorldFamilyWar.OnPlayerChangeMap(curPlayer)
    return 
## 玩家切换真实地图
@@ -764,7 +841,10 @@
    #改到mapServer登录成功通知
    #Sync_PyServerDataTimeToClient(curPlayer, tick)
    
    #PlayerTeam.OnPlayerReadMapOK(curPlayer, tick)
    if GameWorld.IsCrossServer():
        PlayerFB.PlayerLoginLoadCrossMapOK(curPlayer)
    PlayerTeam.OnPlayerReadMapOK(curPlayer, tick)
    
    #刷新人物日期状态
    PlayerEventCounter.UpdatePlayerLoginTime(curPlayer)
@@ -777,7 +857,7 @@
#===============================================================================
    #自己已经初始化成功
    curPlayer.SetInitOK(True)
    GMShell.OnPlayerLogin(curPlayer)
    #发送请求至目标地图(任务需要登陆家族长触发事件)
    __RefreshFamilyToMapServer(curPlayer)
    return
@@ -877,17 +957,29 @@
#{
#    tagHead        Head;
#    DWORD        MapID;
#    BYTE        FBLineID;
#    BYTE        IsAllLine;
#    BYTE        LineCount;
#    BYTE        LineIDList[LineCount];    //个数为0时代表查全部
#};
def ClinetQueryFBLinePlayerCnt(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    queryMapID = clientData.MapID
    fbLineID = clientData.FBLineID
    isAllLine = clientData.IsAllLine
    queryFBLineIDList = clientData.LineIDList
    playerManager = GameWorld.GetPlayerManager()
    
    sendCMD = str([queryMapID, fbLineID, isAllLine])
    if queryMapID in ChConfig.Def_CrossMapIDList:
        fbLinePlayerInfoDict = PyGameData.g_crossFBFuncLinePlayerCountInfo.get(queryMapID, {})
        if not queryFBLineIDList:
            resultInfo = [queryMapID, fbLinePlayerInfoDict]
        else:
            defaultInfo = [0] # 与本服结构相同,默认0人
            queryFBLineInfo = {}
            for lineID in queryFBLineIDList:
                queryFBLineInfo[lineID] = fbLinePlayerInfoDict.get(lineID, defaultInfo)
            resultInfo = [queryMapID, queryFBLineInfo]
        QueryFBLinePlayerCntResult(curPlayer, resultInfo)
        return
    sendCMD = str([queryMapID, queryFBLineIDList])
    playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), 0, 0, queryMapID,
                'FBLinePlayerCnt', sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex())
    return
@@ -903,11 +995,13 @@
    fblinePack = ChPyNetSendPack.tagGCFBLinePlayerCnt()
    fblinePack.MapID = tagMapID
    fblinePack.FBLineInfoList = []
    for lineID, playerCnt in fbLinePlayerCntDict.items():
    for lineID, infoList in fbLinePlayerCntDict.items():
        mapLineState = ChPyNetSendPack.tagGCFBLineInfo()
        mapLineState.Clear()
        mapLineState.FBLineID = lineID
        mapLineState.PlayerCnt = playerCnt
        mapLineState.PlayerCnt = infoList[0] if infoList else 0
        mapLineState.ExtraStr = infoList[1] if len(infoList) > 1 else ''
        mapLineState.ExtraStrLen = len(mapLineState.ExtraStr)
        fblinePack.FBLineInfoList.append(mapLineState)
    
    fblinePack.Count = len(fblinePack.FBLineInfoList)