ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -25,7 +25,6 @@
# @change: "2014-02-27 12:00" hxp 增加世界boss逻辑
# @change: "2014-04-26 19:30" hxp 增加领地战活动
# @change: "2014-06-21 15:20" hxp 增加特惠活动
# @change: "2014-08-04 17:30" xmnathan 天梯每日更新
# @change: "2014-08-15 17:00" xmnathan 修改OnDay函数内的执行顺序
# @change: "2014-10-08 10:30" xmnathan add 定时清理过期补偿
# @change: "2014-10-29 22:00" hxp MapServerInitOK增加扩展key状态通知
@@ -83,27 +82,38 @@
import GameWorldAverageLv
import PlayerDBOper
import PlayerGeTui
#import PlayerManorWar
import GameWorldBoss
#import GameWorldActionTeHui
#import HighLadder
import PlayerCompensation
#import GameWorldShopItem
import ReadChConfig
import EventReport
#import ReloadModule
import CrossRealmPK
import CrossRealmMsg
import CrossRealmPlayer
import CrossBattlefield
import CrossActionControl
import PlayerFBHelpBattle
import PlayerFamilyRedPacket
import PlayerFairyDomain
import IpyGameDataPY
import PlayerFamilyParty
import PlayerFamilyZhenfa
import GameWorldFamilyWar
import GameWorldArena
import CrossLuckyCloudBuy
import AuctionHouse
import PlayerXMZZ
import PlayerLove
import PlayerTeam
import PyGameData
import CrossBoss
import ChPlayer
import PyDataManager
import GameWorldOpenServerCampaign
import CrossBillboard
import CrossChampionship
import GameWorldMineArea
import GameWorship
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -119,8 +129,6 @@
    GameWorld.Log("GameServer -> OnHour!")
    PlayerEventCounter.DoLogic_GameServer_OnHour(tick)
    GameWorld.GetGameWorld().OnHour(curTimeStr)
    #每小时更新天梯
    #HighLadder.OnHour()
    #设置存取数据库Key
    __SetWorldKey_SavePlayer(curTimeStr)
    #每小时清空宝物掉落
@@ -129,6 +137,7 @@
    GameLogInfo.Set_Server_Hour()
    
    PlayerFamily.FamilyOnHour()
    ChPlayer.CheckOnedayJobPlayerLoginoffTimeout()
    return
## 触发每日事件(参数 -> 当前时间)
@@ -138,10 +147,9 @@
#  @remarks 函数详细说明.
def OnDay(curTimeStr, tick):
    GameWorld.Log("GameServer -> OnDay!")
    #天梯竞技场,放在排行榜更新之前处理
    #HighLadder.OnDay()
    #排行榜拷贝昨日榜单
    PlayerBillboard.CopyBillboardOnDay()
    CrossBillboard.CopyBillboardOnDay()
    #开服活动,放在排行榜拷贝昨日榜更新后处理
    PlayerEventCounter.DoLogic_GameServer_OnDay(tick)
    # 通知开服天数, 放在地图OnDay之前处理, 不然地图在OnDay时需要用到开服天时会取到昨天的值
@@ -167,13 +175,20 @@
    # 通知开服天数
    #openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)
    #GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ServerDay, openServerDay)
    GameWorldOpenServerCampaign.DoOnDay()
    #清理过期补偿
    PlayerCompensation.ClearUpTimeOutCompensation()
    PlayerGeTui.ClearFMTGeTuiLimit()
    #PlayerGeTui.ClearFMTGeTuiLimit()
    import PlayerBourse
    PlayerBourse.OverTimeItemsDeal()
    # 仙盟联赛
    GameWorldFamilyWar.DoOnDay()
    # 情缘
    PlayerLove.DoOnDay()
    # 云购
    CrossLuckyCloudBuy.DoOnDay()
    # 膜拜
    GameWorship.DoOnDay()
    return
def OnDayEx(tick):
@@ -184,6 +199,8 @@
    
    #仙魔之争
    PlayerXMZZ.XMZZOndayEx()
    #boss复活
    GameWorldBoss.BossRebornOnDayEx()
    return
## 触发每周事件(参数 -> 当前时间)
@@ -287,6 +304,8 @@
def __Func_HighPrecisionProcess(tick):
    if not GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_IsGameWorldInit):
        return
    curTime = int(time.time())
    #仙盟宴会答题定时器
    PlayerFamilyParty.FamilyParty_Process(tick)
    # 帮主弹劾时钟调用
@@ -297,13 +316,22 @@
    CrossRealmPK.OnPKMatchProcess(tick)
    
    GameWorldBoss.DoCheckWorldBossReborn(tick)
    GameWorldBoss.ProcessBossGeTui(tick)
    PlayerGeTui.ProcessNewGuyCallBackGeTui(tick)
    #GameWorldBoss.ProcessBossGeTui(tick)
    #PlayerGeTui.ProcessNewGuyCallBackGeTui(tick)
    #组队副本版本
    PlayerTeam.DoTeamProcess(tick)
    
    #操作Python表
    PlayerDBOper.PyDBProccess(tick)
    #拍卖行
    AuctionHouse.OnAuctionItemTimeProcess(curTime, tick)
    #情缘
    PlayerLove.OnTimeProcess(curTime, tick)
    #福地
    GameWorldMineArea.OnMineItemTimeProcess(curTime, tick)
    
    #每整分钟处理一次
    curDateTime = datetime.datetime.today()
@@ -338,9 +366,11 @@
def GameWorldProcessOnMinute(curMinute, tick):
    # 每整分钟触发一次
    CheckServerHasPlayerLoginAfterInitOK()
    #检查服务器正式开服
    DoCheckNewServerOpen(tick)
    #回报数据库当前在线玩家数
    DisposeGameActivePlayer(tick)
    #处理游戏世界中的时间事件
    DisposeGameWorldEvenByTime(tick)
    GameWorldActionControl.Dispose_OperationActionState()
@@ -348,19 +378,47 @@
    GameWorldActionControl.Dispose_FBStateTime()
    #跨服PK
    CrossRealmPK.OnMinuteProcess()
    #跨服排位
    CrossChampionship.OnMinuteProcess(curMinute)
    CrossBattlefield.OnMinuteProcess()
    #处理重开服务器后, 活动继续开启逻辑根据天数
    #GameWorldActionControl.Dispose_Action_GoOn_ByDay(tick)
    #触发世界等级
    GameWorldAverageLv.OpenWorldAverageLv()
    #倒计时离队处理
    PlayerTeam.DoCountdownLeaveTeamLogic(tick)
    #副本助战
    PlayerFBHelpBattle.OnMinuteProcess()
    #红包
    PlayerFamilyRedPacket.OnRedPacketMinuteProcess()
    #拍卖行
    AuctionHouse.OnAuctionItemMinuteProcess(tick)
    #福地
    GameWorldMineArea.OnProcessOnMinute()
    #每5分钟触发一次仙盟总战力更新
    if curMinute % 5 == 0:
        PlayerFamily.UpdFamilyTotalFightPower()
        PlayerFamilyRedPacket.CheckDelRedpacketData()
    return
def CheckServerHasPlayerLoginAfterInitOK():
    ## 检查服务器启动成功后是否有玩家正常登录
    initGameWorldTime = GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_IsGameWorldInit)
    if not initGameWorldTime:
        return
    if PyGameData.g_noPlayerLoginWarningMailState:
        return
    curTime = int(time.time())
    noPlayerLoginWarningTimes = IpyGameDataPY.GetFuncCfg("ServerEvent", 1) * 60 # x分钟没有玩家登录则预警
    if curTime - initGameWorldTime < noPlayerLoginWarningTimes:
        return
    GameWorld.SendGameError("NoPlayerLogin")
    PyGameData.g_noPlayerLoginWarningMailState = 1
    return
def OnReloadConfig():
    return
#---------------------------------------------------------------------
@@ -386,7 +444,7 @@
    #处理世界活动
    DisposeGameWorldGame(tick)
    #回报数据库当前在线玩家数
    DisposeGameActivePlayer(tick)
    #DisposeGameActivePlayer(tick)
    #同步地图服务器时间
    Dispose_MapServer_Time(tick)
    #保存玩家数据
@@ -399,8 +457,6 @@
    Dispose_DataBase_GMShell(tick)
    ##处理重开服务器后, 活动继续开启逻辑根据天数
    #GameWorldActionControl.Dispose_Action_GoOn_ByDay(tick)
    #定时神秘商店刷新
    #GameWorldShopItem.Dispose_ShopItemRefresh(tick)
    
    #定时向RouteServer发送消息
    Dispose_SendMsg_RouteServer(tick)
@@ -588,15 +644,18 @@
    #activePlayerCount = GameWorld.GetPlayerManager().GetActivePlayerCount()
    #DataRecordPack.DR_OnLinePlayerCount(activePlayerCount, platformOLDict, tjgOnlineCnt)
    #===========================================================================
    for platform, playerCnt in platformOLDict.items():
        DataRecordPack.DR_OnLinePlayerCount(playerCnt, platform, tjgOnlineCnt) # 单平台
        EventReport.WriteEvent_concurrency(playerCnt, 0, platform) # 单平台  此处不能传脱机挂玩家总数
    isMixture = False #是否混服
    if isMixture:
        for platform, playerCnt in platformOLDict.items():
            DataRecordPack.DR_OnLinePlayerCount(playerCnt, platform, tjgOnlineCnt) # 单平台
            EventReport.WriteEvent_concurrency(playerCnt, 0, platform) # 单平台  此处不能传脱机挂玩家总数
        DataRecordPack.DR_OnLinePlayerCount(activePlayerCount, {}, tjgOnlineCnt)    # 总在线
        #EventReport.WriteEvent_concurrency(activePlayerCount, tjgOnlineCnt)
    else:
        serverPlatform = GameWorld.GetPlatform()
        DataRecordPack.DR_OnLinePlayerCount(activePlayerCount, {}, tjgOnlineCnt)    # 总在线
        EventReport.WriteEvent_concurrency(activePlayerCount, tjgOnlineCnt, serverPlatform)
    #===========================================================================
    DataRecordPack.DR_OnLinePlayerCount(activePlayerCount, {}, tjgOnlineCnt)    # 总在线
    #EventReport.WriteEvent_concurrency(activePlayerCount, tjgOnlineCnt)
    #刷新当前地图服务器
    #===========================================================================
    # custom_concurrencyMapList = ReadChConfig.GetEvalChConfig("EventReportMapID")
@@ -1201,6 +1260,7 @@
def InitGameWorld(tick):
    #标记GameWorld初始化完成
    GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_IsGameWorldInit, int(time.time()))
    LoadDBPlayer()
    #初始化游戏时钟
    GameWorld.GetGameWorld().SetTickTypeCount(ChConfig.TYPE_Tick_Count)
    #初始话开服时间、星期几
@@ -1216,8 +1276,8 @@
    GameWorld.GetGameWorld().GetDBGoldOrderFormMgr().Sort()
    #排序排行榜
    PlayerBillboard.SortServerBillboard()
    #排序仙盟
    PlayerFamily.DoFamilySort()
    #仙盟
    PlayerFamily.OnGameServerInitOK()
    GameWorldActionControl.Dispose_FBStateTime()
    #仙盟联赛
    GameWorldFamilyWar.OnGameServerInitOK()
@@ -1235,11 +1295,20 @@
    ChPlayer.LoadPlayerLVData()
    #加载助战信息
    PlayerFBHelpBattle.OnServerStart()
    #本服竞技场
    GameWorldArena.OnServerStart()
    #跨服PK
    CrossRealmPK.OnGameServerInitOK()
    #跨服排位
    CrossChampionship.OnServerStart()
    #跨服战场
    CrossBattlefield.OnServerStart()
    #红包
    PlayerFamilyRedPacket.OnServerStart()
    #云购
    CrossLuckyCloudBuy.OnServerStart()
    #世界boss被杀次数重置
    #GameWorldBoss.CheckResetBossKilledCntOnServerInit()
    #GameWorldActionTeHui.OnGameServerInitOK() # 特惠活动初始化
    
    __Func_HighPrecisionProcess(tick) # 主动触发一次高精度的调用,确保服务器启动后一些功能活动等的数据会被加载
    
@@ -1255,8 +1324,28 @@
        GameWorld.Log("服务器启动成功: ServerGroupID=%s" % serverGroupID)
    GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_GameWorldInitOK, 1)
    
    AuctionHouse.OnGameServerInitOK()
    # 注意:跨服相关信息的调用需放在最后,不然可能导致服务器未启动功能或者功能未加载成功导致跨服服务器与子服之间的数据同步可能出现异常的情况
    CrossRealmMsg.OnGameServerInitOK()
    if PyGameData.g_allMapServerInitOK:
        GameWorld.Log("InitGameWorld时AllMapServerInitOK已触发则补触发一次!")
        GameWorld.SendGameError("GameWarning", "InitGameWorld later than AllMapServerInitOK")
        AllMapServerInitOK(tick)
    return
def LoadDBPlayer():
    if GameWorld.IsCrossServer():
        return
    PlayerDBOper.FindDBOper(PlayerDBOper.Table_DBPlayer, {}, {"PlayerID":1, "AccID":1, "_id":0}, LoadDBPlayerRet)
    return
def LoadDBPlayerRet(resultSetList, extendValueList):
    for resultDict in resultSetList:
        PyGameData.g_dbPlayerIDMap[resultDict["PlayerID"]] = resultDict["AccID"]
    GameWorld.Log("启动服务器加载DBPlayer玩家账号ID对应关系! %s, %s" % (len(PyGameData.g_dbPlayerIDMap), PyGameData.g_dbPlayerIDMap))
    PlayerFamily.OnLoadDBPlayerOK()
    return
def DoCheckNewServerOpen(tick):
@@ -1313,7 +1402,8 @@
        universalRecMgr.Delete(recType)
        if recordCount:
            GameWorld.Log("DeleteRecData recType=%s, count=%s" % (recType, recordCount))
    CrossBoss.g_bossRecDataDict = {} # 需要清除,不然会导致跨服boss通用记录缓存对象错误
    #清 家族
    familyList = []
    familyMgr = GameWorld.GetFamilyManager()
@@ -1328,11 +1418,18 @@
    
    PyGameData.g_sortBOSSRefreshList = [] # boss刷新信息记录缓存重置, 不重置会导致通知前端的boss信息为空
    
    GameWorldArena.OnServerStart()
    CrossBattlefield.OnServerStart()
    PlayerDBGSEvent.SetInitOpenServerTime(setOpenServerTime)
    
    ReadChConfig.ReloadConfig()
    
    AllMapServerInitOK(tick)
    GameWorld.GetGameWorld().SaveGameServerData()
    GameWorld.SendGameError("ClearOpenServerOK")
    return
## 服务器开服时是星期几
@@ -1343,6 +1440,10 @@
#  @return None
#  @remarks 当一个mapServer开启时,
def AllMapServerInitOK(tick):
    PyGameData.g_allMapServerInitOK = True
    if not GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_IsGameWorldInit):
        GameWorld.Log("AllMapServerInitOK时GameServer还未启动好!")
        return
    #通知所有地图服务器初始化成功, 同步时间
    GameWorld.GetGameWorld().Notify_AllMapServerInitOK(GameWorld.GetCurrentDataTimeStr())
    
@@ -1404,28 +1505,36 @@
    
    # 仙盟联赛
    GameWorldFamilyWar.OnMapServerInitOK()
    # 领地争夺战
    #PlayerManorWar.OnMapServerInitOK()
    # 特惠活动
    #GameWorldActionTeHui.OnMapServerInitOK()
    # 商店信息
    #GameWorldShopItem.OnMapServerInitOK()
    
    # 跨服服务器状态
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossServerTime, PyGameData.g_crossServerTimeInfo)
    isCrossServerOpen = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen)
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isCrossServerOpen)
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossZoneName, PyGameData.g_crossZoneName)
    
    # 跨服PK
    CrossRealmPK.OnMapServerInitOK()
    #跨服战场
    CrossBattlefield.OnMapServerInitOK()
    # 本服竞技场
    GameWorldArena.SendMapServerArenaInfo()
    # 幸运云购
    CrossLuckyCloudBuy.OnMapServerInitOK()
    
    SendAllMapGlobalDropInfo() # 全局掉落控制
    
    SendMapCommMapLinePlayerCount(True) # 同步一次普通地图线路人数信息
    #随机假仙盟
    PlayerFamily.RandomFakeFamily()
    #仙盟阵法
    PlayerFamilyZhenfa.OnMapServerInitOK()
    #缥缈仙域
    PlayerFairyDomain.OnMapServerInitOK()
    #情侣信息
    PyDataManager.GetDBPyCoupleManager().SendMapServerCoupleInfo()
    # 记录服务器是否正常开启完毕
    getUrl = ReadChConfig.GetPyMongoConfig("EventReport", "OpenStateUrl") + "?Type=MapInit&MapCount=%s"%GameWorld.GetGameWorld().GetGameMapManager().GetCount()
    GameWorld.GetGameWorld().EventReport_EventReport("", "", "", "", 0, getUrl)
    return
## 服务器合服首次启动数据加载处理
@@ -1454,8 +1563,8 @@
    # 删除过期的通用数据
    __DelOutofdayRecData(universalRecMgr)
    
    # 仙盟联赛重置
    GameWorldFamilyWar.DoFamilyWarReset()
    # 仙盟
    PlayerFamily.OnMixServerInit()
    
    # 设置合服首次启动加载成功
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServerInitOK, 1)
@@ -1826,14 +1935,19 @@
    gameMapManager = GameWorld.GetGameWorld().GetGameMapManager()
    
    curMap = gameMapManager.Find(mapServerPack.GetRouteServerIndex(), mapServerPack.GetMapID())
    if curMap == None:
        return
    
    if mapServerPack.GetState() not in [0,1,2,3] and curMap.GetState() != mapServerPack.GetState():
        # 记录服务器是否正常开启完毕, 避免重复发送
        GameWorld.DebugLog("MapServer_RunningStateRefresh--_%s"%([mapServerPack.GetState(), curMap.GetState(), mapServerPack.GetMapID(), curMap.GetID()]))
        GameWorld.SendGameError("MapError")
    curMap.SetState(mapServerPack.GetState())
    curMap.SetRefreshTick(tick)
    return
## 刷新地图服务器状态, 如果1分钟没有状态回报, 刷新为消失状态
#  @param tick 当前时间
#  @return None
@@ -1845,6 +1959,7 @@
    gameMapManager = GameWorld.GetGameWorld().GetGameMapManager()
    
    isSendMapClose = False
    for i in range(0, gameMapManager.GetCount()):
        curMap = gameMapManager.GetAt(i)
@@ -1855,8 +1970,12 @@
        if tick - curMap.GetRefreshTick() < ChConfig.Def_Tick_MapServer_MssNone:
            #间隔未到
            continue
        curMap.SetState(IPY_GameServer.mssNone)
        if not isSendMapClose:
            # 避免多地图发送过多邮件, 如关服的时候
            GameWorld.SendGameError("MapDisconnect")   # 状态报告
            isSendMapClose = True
    return
#---------------------------------------------------------------------
@@ -1905,6 +2024,20 @@
    PlayerTeam.OnServerClose(tick)
    ChPlayer.SavePlayerLVData()
    PlayerFBHelpBattle.OnServerClose()
    CrossActionControl.OnServerClose()
    CrossChampionship.OnServerClose()
    CrossBattlefield.OnServerClose()
    PlayerFamilyRedPacket.OnServerClose()
    CrossLuckyCloudBuy.OnServerClose()
    GameWorldArena.OnServerClose()
    PlayerLove.OnServerClose()
    GameWorld.Log("通知C++关服!")
    GameWorld.GetGameWorld().OnServerClose()
    
def ChangeGameServerState(state):
    # 只接收大于等于mssPyError
    GameWorld.DebugLog("ChangeGameServerState:%s"%state)
    GameWorld.SendGameError("GameServerError")