hxp
2019-02-13 215a4edca77b43f1a60cf43c07049eb0a133d43a
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
@@ -25,30 +25,29 @@
import ShareDefine
#import PlayerExam
import PlayerDBGSEvent
import MergeBroadcast
#import PlayerManorWar
#import GameWorldShopItem
#import GameWorldActionTeHui
import GameWorldAverageLv
#import GameWorldMergeBoss
#import GameWorldMergeKing
#import GameWorldMergePK
import CrossRealmPK
import GameWorldFamilyWar
import PlayerFamilyParty
import IpyGameDataPY
import PlayerXMZZ
import PlayerFamilySWRH
import GameWorldBoss
import PlayerFamilyRedPacket
import PlayerFairyCeremony
import PlayerNewFairyCeremony
import PlayerUniversalGameRec
import GameWorldProcess
import ChPyNetSendPack
import NetPackCommon
import PlayerStore
from types import IntType
import time
#---------------------------------------------------------------------
MaxCustomServerDay = 14 # 最大定制开服天数
#年月日时间格式
Time_YmdFormat = ChConfig.TYPE_Time_YmdFormat
@@ -80,12 +79,24 @@
        ipyData = operationActionDict[ShareDefine.OperationActionName_FairyCeremony][0]
        if ipyData:
            PlayerFairyCeremony.Sync_OperationAction_FairyCeremony(ipyData, curPlayer)
    # 新仙界盛典活动进行中
    if ShareDefine.OperationActionName_NewFairyCeremony in operationActionDict:
        ipyData = operationActionDict[ShareDefine.OperationActionName_NewFairyCeremony][0]
        if ipyData:
            PlayerNewFairyCeremony.Sync_OperationAction_NewFairyCeremony(ipyData, curPlayer)
    # 多倍修行点活动进行中
    if ShareDefine.OperationActionName_RealmPoint in operationActionDict:
        ipyData = operationActionDict[ShareDefine.OperationActionName_RealmPoint][0]
        if ipyData:
            Sync_OperationAction_RealmPoint(ipyData, curPlayer)
    # 节日红包活动进行中
    if ShareDefine.OperationActionName_FeastRedPacket in operationActionDict:
        ipyData = operationActionDict[ShareDefine.OperationActionName_FeastRedPacket][0]
        if ipyData:
            PlayerFamilyRedPacket.Sync_FeastRedPacket(ipyData, curPlayer)
    # 幸运鉴宝活动进行中
    if ShareDefine.OperationActionName_LuckyTreasure in operationActionDict:
        PlayerUniversalGameRec.SendUniversalGameRecInfo(curPlayer, ShareDefine.Def_UniversalGameRecType_LuckyTreasure)
    return
def SendMapServerOperationActionState():
@@ -127,7 +138,7 @@
    curDateTimeStr = "%d-%d-%d %02d:%02d:00" % (serverTime.year, serverTime.month, serverTime.day, serverTime.hour, serverTime.minute)
    curDateTime = datetime.datetime.strptime(curDateTimeStr, ChConfig.TYPE_Time_Format)
    
    customMaxServerDay = MaxCustomServerDay # 定制运营活动最大开服天
    customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) # 定制运营活动最大开服天
    operationActionDict = {}
    mapServerOperationActionDict = {}
    serverID = GameWorld.GetServerID()
@@ -165,11 +176,17 @@
                startDateStr = "%d-%d-%d" % (openServerDateTime.year, openServerDateTime.month, openServerDateTime.day)
                endDateStr = "%d-%d-%d" % (endServerDateTime.year, endServerDateTime.month, endServerDateTime.day)
                GameWorld.Log("        开服天转化为日期: %s ~ %s" % (startDateStr, endDateStr))
            elif actName not in ShareDefine.FeastOperationActionNameList:
                if openServerDay <= customMaxServerDay:
                    GameWorld.Log("        按日期开的在开服定制限制天内,不处理! cfgID=%s,%s ~ %s,openServerDay=%s" % (cfgID, startDateStr, endDateStr, openServerDay))
                    continue
                customMaxServerDateTime = curDateTime + datetime.timedelta(days=(customMaxServerDay-openServerDay))
                curStartDateTime = datetime.datetime.strptime("%s %02d:%02d:%02d" % (startDateStr, customMaxServerDateTime.hour, customMaxServerDateTime.minute,
                                                                                     customMaxServerDateTime.second), ChConfig.TYPE_Time_Format)
                if curStartDateTime <= customMaxServerDateTime:
                    GameWorld.Log("        按日期开的开始日期在开服定制限制天内,不处理! cfgID=%s,curStartDateTime=%s,customMaxServerDateTime=%s" % (cfgID, curStartDateTime, customMaxServerDateTime))
                    continue
                
            elif openServerDay <= customMaxServerDay:
                GameWorld.Log("        按日期开的在开服定制限制天内,不处理! cfgID=%s,%s ~ %s,openServerDay=%s" % (cfgID, startDateStr, endDateStr, openServerDay))
                continue
            if hasattr(ipyData, "GetStartTimeList") and hasattr(ipyData, "GetEndTimeList"):
                startHMStrList = ipyData.GetStartTimeList()
                endHMStrList = ipyData.GetEndTimeList()
@@ -179,7 +196,7 @@
                
            notifyInfoDictStart = ipyData.GetNotifyInfoStart() if hasattr(ipyData, "GetNotifyInfoStart") else {}
            notifyInfoDictEnd = ipyData.GetNotifyInfoEnd() if hasattr(ipyData, "GetNotifyInfoEnd") else {}
            notifyInfoLoopInfo = ipyData.GetNotifyInfoLoop() if hasattr(ipyData, "GetNotifyInfoLoop") else {} # [循环分钟, 广播key]
            notifyInfoLoopInfo = ipyData.GetNotifyInfoLoop() if hasattr(ipyData, "GetNotifyInfoLoop") else {} # [循环分钟, 广播key, [广播参数列表可选]]
            
            if len(startHMStrList) != len(endHMStrList):
                GameWorld.ErrLog("        活动配置开始及结束时间个数不匹配! actName=%s,cfgID=%s,startHMStrList=%s,endHMStrList=%s" 
@@ -190,6 +207,9 @@
            if resetType == 1:
                startDayDate = datetime.datetime.strptime("%s 05:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
                endDayDate = datetime.datetime.strptime("%s 05:00:00" % (endDateStr), ChConfig.TYPE_Time_Format) # 结束日期5点
            elif resetType == 2:
                startDayDate = datetime.datetime.strptime("%s 05:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
                endDayDate = datetime.datetime.strptime("%s 00:00:00" % (endDateStr), ChConfig.TYPE_Time_Format) + datetime.timedelta(days=1) # 结束日期隔天0点
            else:
                startDayDate = datetime.datetime.strptime("%s 00:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
                endDayDate = datetime.datetime.strptime("%s 00:00:00" % (endDateStr), ChConfig.TYPE_Time_Format) + datetime.timedelta(days=1) # 结束日期隔天0点
@@ -206,6 +226,7 @@
            isActivity = False # 有需要处理开关时间的(开始、结束)
            isNotify = False
            isAdvanceNotice = False
            isEnd = False
            # 没配置时分的代表全天, 只要开始或结束时分没配都算
            if not startHMStrList or not endHMStrList:
                startDateTime = startDayDate
@@ -218,10 +239,12 @@
                    needStartList.append(startDateTime)
                    needEndList.append(endDateTime)
                    isActivity = True
                    isEnd = (curDateTime == endDayDate)
                    
            # 每天按时段开启的,支持多时段
            else:
                if startDayDate <= curDateTime <= endDayDate:
                    isEnd = (curDateTime == endDayDate)
                    for hmIndex, startHMStr in enumerate(startHMStrList):
                        endHMStr = endHMStrList[hmIndex]
                        # 每天开的, 实际开关时间只取今天的日期; 这里有个问题,全服广播的时间不是今天的, 暂不做支持,之后真有这种需求再说
@@ -264,9 +287,10 @@
                        isNotify = True
                        
                # 广播 - 循环广播
                if notifyInfoLoopInfo and len(notifyInfoLoopInfo) == 2:
                    loopMinutes, loopNotifyKey = notifyInfoLoopInfo
                    notifyInfo = [loopNotifyKey, []] # 循环广播的默认无参数,不做支持
                if notifyInfoLoopInfo and len(notifyInfoLoopInfo) >= 2:
                    loopMinutes, loopNotifyKey = notifyInfoLoopInfo[:2]
                    loopNotifyParamList = notifyInfoLoopInfo[2] if len(notifyInfoLoopInfo) > 2 else []
                    notifyInfo = [loopNotifyKey, loopNotifyParamList] # 循环广播的默认无参数
                    loopCount, loopMaxCount = 0, 100
                    while loopMinutes and loopNotifyKey and loopCount < loopMaxCount:
                        loopCount += 1
@@ -288,10 +312,10 @@
            if not isActivity and not isNotify and not isAdvanceNotice:
                continue
            
            GameWorld.Log("        需要处理的运营活动信息: cfgID=%s,isAdvanceNotice=%s,isActivity=%s,isNotify=%s" % (cfgID, isAdvanceNotice, isActivity, isNotify))
            # 当天有需要激活活动或者提前预告活动的取开始时间较早的为准
            GameWorld.Log("        需要处理的运营活动信息: cfgID=%s,isAdvanceNotice=%s,isActivity=%s,isEnd=%s,isNotify=%s" % (cfgID, isAdvanceNotice, isActivity, isEnd, isNotify))
            # 当天有需要激活活动或者提前预告活动的取非结束的为准,如果有多个非结束的一般就是策划在活动时间上配置交叉,这种是不允许的
            if isActivity or isAdvanceNotice:
                if not activityIpyData or ipyData.GetStartDate() < activityIpyData.GetStartDate():
                if not activityIpyData or (isActivity and not isEnd):
                    activityIpyData = ipyData
                    activityInfoDict = {ShareDefine.ActKey_CfgID:cfgID}
                    
@@ -332,12 +356,21 @@
def __GetOperationActionServerIpyDataList(ipyDataMgr, serverID, actName):
    ## 获取运营活动本服务器对应的配置数据列表
    
    if not hasattr(ipyDataMgr, "Get%sCount" % actName):
        GameWorld.ErrLog("没有该运营活动类型对应活动时间表! actName=%s" % actName)
        return []
    # 所有配置先按活动标识归组
    platform = GameWorld.GetPlatform()
    actGroupDict = {} # {ActMark:{ServerIDTuple:[ipyData, ...], ...}, ...}
    actCfgCount = getattr(ipyDataMgr, "Get%sCount" % actName)()
    for cfgIndex in xrange(actCfgCount):
        ipyData = getattr(ipyDataMgr, "Get%sByIndex" % actName)(cfgIndex)
        actMark = ipyData.GetActMark()
        platformList = [] if not hasattr(ipyData, "GetPlatformList") else ipyData.GetPlatformList()
        if platformList and platform not in platformList:
            GameWorld.Log("非本平台活动,不取!platform=%s,platformList=%s,actName=%s,cfgID=%s" % (platform, platformList, actName, ipyData.GetCfgID()))
            continue
        serverIDTuple = tuple(ipyData.GetServerIDList())
        
        serverIpyDataDict = actGroupDict.get(actMark, {})
@@ -423,7 +456,8 @@
        
        dbOperationActIDKey = PlayerDBGSEvent.Def_OperationActID % actName
        curActID = sendMapServerMsgDict.get(ShareDefine.ActKey_ID)
        if state >= 1 and curActID and PlayerDBGSEvent.GetDBGSTrig_ByKey(dbOperationActIDKey) != curActID:
        dayIndex = sendMapServerMsgDict.get(ShareDefine.ActKey_DayIndex, 0)
        if curActID and PlayerDBGSEvent.GetDBGSTrig_ByKey(dbOperationActIDKey) != curActID:
            PlayerDBGSEvent.SetDBGSTrig_ByKey(dbOperationActIDKey, curActID)
            if actName in ShareDefine.NeedWorldLVOperationActNameList:
                #记录开启时世界等级
@@ -437,10 +471,19 @@
            elif actName == ShareDefine.OperationActionName_FairyCeremony:
                #重置仙界盛典
                PlayerFairyCeremony.ResetFairyCeremony()
            elif actName == ShareDefine.OperationActionName_NewFairyCeremony:
                #重置仙界盛典
                PlayerNewFairyCeremony.ResetNewFairyCeremony()
            elif actName == ShareDefine.OperationActionName_FeastRedPacket:
                #重置节日红包
                if ipyData:
                    PlayerFamilyRedPacket.OnResetFeastRedPacket(ipyData, dayIndex)
            elif actName == ShareDefine.OperationActionName_FlashSale:
                #限时抢购重置购买次数 本次活动每场不能重复
                #dayIndex = sendMapServerMsgDict.get(ShareDefine.ActKey_DayIndex, 0)
                PlayerStore.ResetFlashSaleBuyCnt(ipyData)
                
        if state == 1 and actName in ShareDefine.NeedWorldLVOperationActNameList:
        if actName in ShareDefine.NeedWorldLVOperationActNameList:
            actWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_OActWorldLV % actName)
            sendMapServerMsgDict[ShareDefine.ActKey_WorldLV] = actWorldLV
        
@@ -460,9 +503,19 @@
                PlayerFairyCeremony.Sync_OperationAction_FairyCeremony(ipyData)
            if preState != state and state == 0:
                PlayerFairyCeremony.OnFairyCeremonyEnd()
        elif actName == ShareDefine.OperationActionName_NewFairyCeremony:
            if isReload and ipyData:
                PlayerNewFairyCeremony.Sync_OperationAction_NewFairyCeremony(ipyData)
            if preState != state and state == 0:
                PlayerNewFairyCeremony.OnNewFairyCeremonyEnd()
        elif actName == ShareDefine.OperationActionName_RealmPoint:
            if isReload and ipyData:
                Sync_OperationAction_RealmPoint(ipyData)
        elif actName == ShareDefine.OperationActionName_FeastRedPacket:
            if isReload and ipyData:
                PlayerFamilyRedPacket.Sync_FeastRedPacket(ipyData)
        #通知Mapserver,设置字典
        #GameWorld.SendMapServerMsgEx(dictName, state) # 运营活动不单独通知活动状态,需与活动信息整合后一起通知
        
@@ -517,6 +570,7 @@
    multiRealmPointInfo.EndtDate = GameWorld.GetOperationActionDateStr(ipyData.GetEndDate(), openServerDay)
    multiRealmPointInfo.Multiple = ipyData.GetMultiple()
    multiRealmPointInfo.LimitLV = ipyData.GetLVLimit()
    multiRealmPointInfo.LimitPoint = ipyData.GetPointLimit()
    if not curPlayer:
        # 全服广播在线玩家
        playerManager = GameWorld.GetPlayerManager()
@@ -549,7 +603,7 @@
    curDateStr = GameWorld.ChangeTimeNumToStr(curTime, ChConfig.TYPE_Time_YmdFormat) # 当天日期
    
    openServerWeekday = GameWorldProcess.GetOpenServerWeekday() # 服务器开服时是星期几
    curMaxCustomServerDay = MaxCustomServerDay - openServerWeekday + 1 # 最大有效定制开服天
    curMaxCustomServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) - openServerWeekday + 1 # 最大有效定制开服天
    GameWorld.Log("===== 加载今天日常活动信息 =====")
    GameWorld.Log("    开服是星期%s, 开服第%s天, 当前星期%s" % (openServerWeekday, openServerDay, weekDay))
    GameWorld.Log("    最大有效定制开服天: %s" % (curMaxCustomServerDay))
@@ -801,7 +855,7 @@
        GameWorld.ErrLog("获取开服是星期几数据错误!openServerWeekday=%s" % openServerWeekday)
        return []
    
    curMaxCustomServerDay = MaxCustomServerDay - openServerWeekday + 1 # 最大有效定制开服天
    curMaxCustomServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) - openServerWeekday + 1 # 最大有效定制开服天
    GameWorld.Log("===== 加载今天副本状态时间表 =====")
    GameWorld.Log("    开服是星期%s, 开服第%s天, 当前星期%s,%s点%s分 !" % (openServerWeekday, openServerDay, curWeekDay, curHour, curMinute))
    GameWorld.Log("    最大有效定制开服天: %s" % (curMaxCustomServerDay))
@@ -1037,87 +1091,6 @@
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FBOpenRecord, fbOpenRecord)
    return
## 处理重开服务器后, 活动继续开启逻辑根据天数
#  @param tick 当前时间
#  @return None
def Dispose_Action_GoOn_ByDay(tick):
    #已固定在每整分钟触发,故暂不需要时间间隔控制
    #if not GameWorld.SetWorldDictKey(ChConfig.TYPE_ActionOpenAndCloseByDayCountGoOn, tick):
    #    #间隔未到
    #    return
    if GameWorld.IsMergeServer():
        return
    Dispose_ActionGoOnByDayKey()
    return
## 设定上次开启活动时间距离现在天数事件
#  @param None:
#  @return: None
def DoLogic_ServerLastOpenActionDay():
    #是跨服服务器
    if GameWorld.IsMergeServer():
        if not PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MergeServerOpenActionDay):
            return
        PlayerDBGSEvent.SetDBGSTrig_ServerTime(PlayerDBGSEvent.Def_MergeServerOpenActionDay)
        #通知子服务器天数
        SendBroadcastMergeOpenActionDay()
        return
    DoLogic_ActionByDayKeyOnDay()
    #上次开启活动时间距离现在天数
    lastOpenActionDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerLastOpenActionDay)
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)
    initDayList = ReadChConfig.GetEvalChConfig('ActionControlByDayInitOpenServerDay')
    if openServerDay < initDayList[0]:
        #开服时间未超过30天
        return
    #新一轮活动从头开始
    if lastOpenActionDay >= initDayList[1] or openServerDay == initDayList[2]:
        NewRingOpenActionDay()
        return
    PlayerDBGSEvent.SetDBGSTrig_ServerTime(PlayerDBGSEvent.Def_ServerLastOpenActionDay)
    return
## 新一轮活动开始
#  @param None:
#  @return:
def NewRingOpenActionDay():
    #设置字典值从1开始, 跟SetDBGSTrig_ServerTime接口同步
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerLastOpenActionDay, 1)
    # 活动天数重设
    OpenActionDay_Reset()
    return
#------------------------------------------------------------------------------
## 活动天数重设
#  @param None
#  @return None
def OpenActionDay_Reset():
    # 设置国王战开始
    #PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MergeWarStart, 1)
    return
### 检查key是否处理
#def __CheckIsProcessDictName(dictName):
#
#    # 非跨服服务器不处理某些key
#    if dictName in [ShareDefine.Def_Notify_WorldKey_Merge_King] and not GameWorld.IsMergeServer():
#        return False
#
#    return True
## 当前时间与指定时间比较
#  @param curTime 当前服务器时间 
#  @param timeInfo 指定时间 [[3,4(星期几)], 年,月,日,时,分] 
@@ -1182,15 +1155,6 @@
    # #领地争夺战
    # if dictName == ShareDefine.Def_Notify_WorldKey_ManorWar:
    #    PlayerManorWar.ManorWar_ChangeState(isOpen)
    # #跨服boss
    # elif dictName == ShareDefine.Def_Notify_WorldKey_MergeBoss:
    #    GameWorldMergeBoss.MergeBoss_ChangeState(isOpen)
    # #跨服PK
    # elif dictName == ShareDefine.Def_Notify_WorldKey_Merge_PK:
    #    GameWorldMergePK.OnMergePKMatchStateChange(isOpen)
    # #跨服王者争霸
    # elif dictName == ShareDefine.Def_Notify_WorldKey_Merge_King:
    #    GameWorldMergeKing.OnMergeKingStateChange(isOpen)
    # #答题活动
    # elif dictName == ShareDefine.Def_Notify_WorldKey_Game_EXAM:
    #    PlayerExam.Exam_ChangeState(isOpen)
@@ -1217,215 +1181,9 @@
    #骑宠争夺
    elif dictName == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss:
        GameWorldBoss.OnHorsePetRobBossActionChange(isOpen)
    return
#------------------------------------------------------------------------------
## 通知子服务器天数
#  @param param: None
#  @return: None
def SendBroadcastMergeOpenActionDay():
    mergeServerOpenActionDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MergeServerOpenActionDay)
    MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergeServerOpenActionDay, 0, {"Day":mergeServerOpenActionDay})
    #跨服PK
    elif dictName == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossReamPK:
        CrossRealmPK.OnCrossRealmPKDailyActionStateChange(isOpen)
    return
#-------------------------------------------------------------------------------
## 根据活动开启的活动事件OnDay
#  @param None:
#  @return: None
def DoLogic_ActionByDayKeyOnDay():
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)
    isMixServer = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServer)
    mixServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MixServerDay)
    repeatDayInfo = ReadChConfig.GetEvalChConfig('ActionControlByDayKeyRepeat')
    startRepeatOpenDay, startRepeatMixDay, repeatList = repeatDayInfo
    # 不是循环阶段
    if openServerDay < startRepeatOpenDay or (isMixServer and mixServerDay < startRepeatMixDay):
        GameWorld.Log("没有正式进入周期循环,不处理!")
        return
    Def_RepeatOrderKey = PlayerDBGSEvent.Def_TeHuiRepeatOrderKey
    Def_RepeatNumKey = PlayerDBGSEvent.Def_TeHuiRepeatNumKey
    # 强制更新一次世界等级
    GameWorldAverageLv.OpenWorldAverageLv()
    repeatOrder = PlayerDBGSEvent.GetDBGSTrig_ByKey(Def_RepeatOrderKey)
    repeatOrder = "" if not repeatOrder else str(repeatOrder)
    preRepeatNum = PlayerDBGSEvent.GetDBGSTrig_ByKey(Def_RepeatNumKey)
    preRepeatNum = "" if not preRepeatNum else str(preRepeatNum)
    worldAverageLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
    GameWorld.Log("处理周期循环: openServerDay=%s,isMixServer=%s,mixServerDay=%s" % (openServerDay, isMixServer, mixServerDay))
    GameWorld.Log("    startRepeatOpenDay=%s,startRepeatMixDay=%s,repeatOrder=%s,preRepeatNum=%s,worldAverageLV=%s"
                  % (startRepeatOpenDay, startRepeatMixDay, repeatOrder, preRepeatNum, worldAverageLV))
    # 开始循环
    if openServerDay == startRepeatOpenDay or (isMixServer and mixServerDay == startRepeatMixDay):
        repeatOrder = ""
        for i, repeatInfo in enumerate(repeatList, 1):
            if i > 9:
                break
            needWorldAverageLV = repeatInfo[0]
            if worldAverageLV < needWorldAverageLV:
                continue
            repeatOrder = "%s%s" % (repeatOrder, i)
        PlayerDBGSEvent.SetDBGSTrig_ByKey(Def_RepeatOrderKey, GameWorld.ToIntDef(repeatOrder))
        GameWorld.Log("    开始循环, 生成循环编号顺序: %s" % repeatOrder)
    # 还没全部开始循环,则判断是否有动态新插入的循环
    elif len(repeatOrder) < len(repeatList):
        GameWorld.Log("    还没全部开始循环,判断是否有动态新插入的循环..")
        for i, repeatInfo in enumerate(repeatList, 1):
            if i > 9:
                break
            if str(i) in repeatOrder: # 已经在循环里的不处理
                continue
            needWorldAverageLV = repeatInfo[0]
            if worldAverageLV < needWorldAverageLV:
                continue
            # 插入新循环
            if preRepeatNum in repeatOrder:
                insertIndex = repeatOrder.index(preRepeatNum)
                repeatOrder = repeatOrder[:insertIndex + 1] + str(i) + repeatOrder[insertIndex + 1:]
            else:
                repeatOrder = str(i)
            PlayerDBGSEvent.SetDBGSTrig_ByKey(Def_RepeatOrderKey, GameWorld.ToIntDef(repeatOrder))
            GameWorld.Log("        编号%s, needWorldAverageLV=%s,插入循环,更新循环编号顺序: %s" % (i, needWorldAverageLV, repeatOrder))
            break
    if not repeatOrder:
        GameWorld.Log("    没有可循环的活动!")
        return
    # 进入下一天循环编号
    if preRepeatNum and preRepeatNum in repeatOrder:
        nextRepeatIndex = repeatOrder.index(preRepeatNum) + 1
        nextRepeatIndex = 0 if nextRepeatIndex >= len(repeatOrder) else nextRepeatIndex
    else:
        nextRepeatIndex = 0
    nextRepeatNum = GameWorld.ToIntDef(repeatOrder[nextRepeatIndex])
    PlayerDBGSEvent.SetDBGSTrig_ByKey(Def_RepeatNumKey, nextRepeatNum)
    if nextRepeatNum <= 0 or nextRepeatNum > len(repeatList):
        GameWorld.Log("    下一个循环编号错误!nextRepeatNum=%s" % nextRepeatNum)
        return
    GameWorld.Log("    过天变更循环活动状态, nextRepeatNum=%s" % nextRepeatNum)
    gameWorld = GameWorld.GetGameWorld()
    nextRepeatDict = repeatList[nextRepeatNum - 1][1]
    for dictName, signID in nextRepeatDict.items():
        # 已经是这个值不处理
        if gameWorld.GetDictByKey(dictName) == signID:
            #GameWorld.DebugLog("    已经是这个值不处理dictName=%s,signID=%s"  % (dictName,signID))
            continue
        # 默认当前的0点开始到当天的23点59分
        curDay, beginDay, beginH, beginM, endDay, endH, endM = 0, 0, 0, 0, 0, 23, 59
        __ChangeDA_ActionSign(gameWorld, dictName, signID, curDay, beginDay, beginH, beginM, endDay, endH, endM)
    return
## 处理重开服务器后, 活动继续开启逻辑根据天数key
#  @param None
#  @return None
def Dispose_ActionGoOnByDayKey():
    if GameWorld.IsMergeServer():
        return
    GameWorld.DebugLog("处理特惠状态信息...")
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)
    isMixServer = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServer)
    mixServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MixServerDay)
    allActionGoOnInfo = ReadChConfig.GetEvalChConfig("ActionControlByDayKeyGoOn")
    if not isMixServer:
        __DoActionGoOnByDayKeyCheck(allActionGoOnInfo[0], openServerDay)
    else:
        __DoActionGoOnByDayKeyCheck(allActionGoOnInfo[1], mixServerDay)
    return
## 按天开启可循环活动检查
#  @param controlList:
#  @return: None
def __DoActionGoOnByDayKeyCheck(goOnList, curDay):
    curTime = GameWorld.GetServerTime()
    gameWorld = GameWorld.GetGameWorld()
    for goOnControl in goOnList:
        beginDay, beginH, beginM = goOnControl[0]
        endDay, endH, endM = goOnControl[1]
        if curDay < beginDay or curDay > endDay:
            #活动不在这一时间段
            #GameWorld.DebugLog("活动不在这一时间段curDay=%s < beginDay=%s or curDay > endDay=%s"
            #                   % (curDay,beginDay,endDay))
            continue
        dictName = goOnControl[2]  # 字典名
        signID = goOnControl[3]  # 标记
        # 已经是这个值不处理
        if gameWorld.GetDictByKey(dictName) == signID:
            #GameWorld.DebugLog("已经是这个值不处理dictName=%s,signID=%s"  % (dictName,signID))
            continue
        beginTime = ['-', '-', '-', '-', beginH, beginM]
        endTime = ['-', '-', '-', '-', endH, endM]
        #还没开始
        if curDay == beginDay and CompareActTime(curTime, beginTime) == ChConfig.Def_Cmp_Lower:
            #GameWorld.DebugLog("还没开始...")
            continue
        #已经结束
        if curDay == endDay and CompareActTime(curTime, endTime) == ChConfig.Def_Cmp_Greater:
            #GameWorld.DebugLog("已经结束...")
            continue
        __ChangeDA_ActionSign(gameWorld, dictName, signID, curDay, beginDay, beginH, beginM, endDay, endH, endM)
    return
def __ChangeDA_ActionSign(gameWorld, dictName, signID, curDay, beginDay, beginH, beginM, endDay, endH, endM):
    # 计算开始及结束日期
    beginTime, endTime = GetBeginEndTimeByDay(dictName, curDay, beginDay, beginH, beginM, endDay, endH, endM)
    actionID = int(time.time())
    GameWorld.Log('活动状态变更: dictName=%s,signID=%s,beginTime=%s,endTime=%s,actionID=%s'
                  % (dictName, signID, beginTime, endTime, actionID))
    #潜规则:在ChConfig活动相关设置中,提取了字典名
    gameWorld.SetDict(dictName, signID)
    gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_DayAction_BeginTime % dictName, beginTime)
    gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_DayAction_EndTime % dictName, endTime)
    # 标记活动唯一id
    actionIDKey = ShareDefine.Def_Notify_WorldKey_DayAction_ID % dictName
    gameWorld.SetDict(actionIDKey, actionID)
    #通知Mapserver,设置字典
    GameWorld.SendMapServerMsgEx(actionIDKey, actionID)
    GameWorld.SendMapServerMsgEx(dictName, signID)
    #处理GameServer活动逻辑
    __DoLogic_GameServer_ActionState(dictName, signID)
    return
## 获取开启结束时间
#  @param tick
#  @return None
def GetBeginEndTimeByDay(dictName, curDay, beginDay, beginH, beginM, endDay, endH, endM):
    beginDiffDays = max(0, curDay - beginDay)
    beginDateTime = GameWorld.GetDatetimeBySubDays(beginDiffDays)
    beginDateTimeStr = str(beginDateTime).split(".")[0]
    beginDateTimeStr = "%s %02d:%02d:00" % (beginDateTimeStr[:10], beginH, beginM)
    beginTimeNum = GameWorld.ChangeTimeStrToNum(beginDateTimeStr, ChConfig.TYPE_Time_Format)
    endDiffDays = max(0, endDay - curDay)
    endDateTime = GameWorld.GetDatetimeByDiffDays(endDiffDays)
    endDateTimeStr = str(endDateTime).split(".")[0]
    endDateTimeStr = "%s %02d:%02d:59" % (endDateTimeStr[:10], endH, endM)
    endTimeNum = GameWorld.ChangeTimeStrToNum(endDateTimeStr, ChConfig.TYPE_Time_Format)
    return beginTimeNum, endTimeNum