From 540eced2499bf2814f3264c0d41eb0e9c52b9957 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期日, 08 二月 2026 15:33:04 +0800
Subject: [PATCH] 462 【付费活动】限时冲刺-服务端(轮回殿)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLunhuidian.py     |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py  |    5 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                    |   97 ++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldAction.py |  782 +++++++++++++++++++++++++++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                  |   20 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                |   11 
 PySysDB/PySysDBPY.h                                                                                   |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py                      |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py      |  107 -----
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                       |    1 
 10 files changed, 865 insertions(+), 179 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 311584f..9a713be 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -2121,9 +2121,12 @@
 
 //轮回殿活动时间表
 
-struct tagActLunhuidian
+struct ActLunhuidian
 {
 	DWORD		_CfgID;	//配置ID
+	list		PlatformList;	//活动平台列表["平台A", "平台A", ...],配[]代表所有
+	list		ServerIDList;	//服务器ID列表
+	BYTE		ActNum;	//活动分组编号, 活动类型 * 10 + 不同界面编号
 	char		StartDate;	//开启日期
 	char		EndDate;	//结束日期
 	WORD		LVLimit;	//限制等级
@@ -2135,7 +2138,7 @@
 
 //轮回殿活动奖励表
 
-struct tagActLunhuidianAward
+struct ActLunhuidianAward
 {
 	BYTE		_RoundType;	//轮回类型
 	DWORD		NeedValue;	//奖励所需值
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 31fb91f..c64bcaa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -2450,6 +2450,7 @@
 #玩家时间的记录格式
 TYPE_Time_Format = "%Y-%m-%d %H:%M:%S"
 TYPE_Time_Format_Day = "%Y-%m-%d"
+TYPE_Time_Format_Ymd = "%Y-%m-%d"
 TYPE_Time_Format_YmdHMS = "%Y%m%d%H%M%S"
 TYPE_Time_Format_YmdH = "%Y%m%d%H"
 #---------------------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index 1fb8f02..1262e72 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -700,20 +700,21 @@
         return startDateStr, endDateStr
     
     # 开服天
+    import DBDataMgr
     if startDateStr.isdigit():
-        diffDay = GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
+        diffDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
         startDateTime = curDateTime + datetime.timedelta(days=(int(startDateStr)-diffDay))
         endDateTime = curDateTime + datetime.timedelta(days=(int(endDateStr)-diffDay))
         
     # K开服天
     elif startDateStr.startswith("K"):
-        diffDay = GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
+        diffDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
         startDateTime = curDateTime + datetime.timedelta(days=(ToIntDef(startDateStr[1:])-diffDay))
         endDateTime = curDateTime + datetime.timedelta(days=(ToIntDef(endDateStr[1:])-diffDay))
         
     # 合服天
     elif startDateStr.startswith("Mix"):
-        diffDay = GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_MixServerDay) + 1
+        diffDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_MixServerDay) + 1
         startDateTime = curDateTime + datetime.timedelta(days=(int(startDateStr[3:])-diffDay))
         endDateTime = curDateTime + datetime.timedelta(days=(int(endDateStr[3:])-diffDay))
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldAction.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldAction.py
new file mode 100644
index 0000000..20d4750
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldAction.py
@@ -0,0 +1,782 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GameWorldLogic.GameWorldAction
+#
+# @todo:活动时间控制器
+# @author hxp
+# @date 2026-02-08
+# @version 1.0
+#
+# 详细描述: 活动时间控制器
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2026-02-08 16:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import DBDataMgr
+import ShareDefine
+import PlayerActLunhuidian
+import IpyGameDataPY
+import PlayerControl
+import PyGameData
+import ChConfig
+
+import datetime
+import time
+
+(
+OperationAction_ReloadSign, # 信息重载标记
+OperationAction_TodayInfo, # 当日的活动信息
+) = range(2)
+
+def GetOperationActType(actNum):
+    ## 运营活动类型
+    return actNum / 10
+
+def OnProcessGameAction(curTime):
+    ## 定时处理游戏的活动时间
+    Dispose_OperationActionState()
+    #Dispose_DailyActionState()
+    #Dispose_FBStateTime()
+    return
+
+def __GetOperationActionInfo():
+    # @return: isReload, OperationActionInfo
+    
+    key = "OperationActionInfo"
+    openServerDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
+    isMixServer = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_IsMixServer)
+    mixServerDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_MixServerDay) + 1
+    
+    OperationActionInfo = IpyGameDataPY.GetConfigEx(key)
+    serverTime = GameWorld.GetServerTime()
+    #curHour = serverTime.hour
+    reloadSignHour = 0 #0 if curHour < 5 else 5 废弃5点刷新逻辑
+    reloadSign = [openServerDay, isMixServer, mixServerDay, reloadSignHour]
+    if OperationActionInfo and OperationActionInfo[OperationAction_ReloadSign] == reloadSign:
+        #GameWorld.DebugLog("已经加载过本日运营活动处理信息!openServerDay=%s" % openServerDay)
+        return False, OperationActionInfo
+    
+    # 因为后面的时间判断都是精确到分的,而处理此逻辑的时候可能不是0秒,所以这里的datetime取当前时间精确到分的
+    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)
+    
+    startDateInCustomCanOpenList = IpyGameDataPY.GetFuncEvalCfg("OperationAction", 2) # 开始天在定制天内在定制天结束后可继续开启的活动列表
+    customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) # 定制运营活动最大开服天
+    #maxCustomServerDayMix = IpyGameDataPY.GetFuncCfg("MixServer", 1) # 定制运营活动最大合服天
+    operationTodayActionDict = {}
+    PyGameData.g_operationActionDict = {}
+    platform = GameWorld.GetPlatform()
+    serverID = GameWorld.GetGameWorld().GetServerID()
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    curWeekday = curDateTime.weekday() + 1 # 今天星期几, 1代表星期1
+    
+    GameWorld.Log("===== 加载本日运营活动信息: %s, serverID=%s,openServerDay=%s,customMaxServerDay=%s,isMixServer=%s,mixServerDay=%s,reloadSign=%s =====" 
+                  % (curDateTime, serverID, openServerDay, customMaxServerDay, isMixServer, mixServerDay, reloadSign))
+    GameWorld.Log("    今日周%s" % (curWeekday))
+    
+    for actName in ShareDefine.OperationActionNameList:
+        
+        if actName not in PyGameData.g_operationActionDict:
+            PyGameData.g_operationActionDict[actName] = {}
+            
+        # 取出本活动所属本服ID的所有配置
+        GameWorld.Log("加载运营活动: actName=%s,platform=%s,serverID=%s" % (actName, platform, serverID))
+        curServerActIpyDataList = __GetOperationActionServerIpyDataList(ipyDataMgr, platform, serverID, actName)
+        GameWorld.Log("    可处理条数=%s" % (len(curServerActIpyDataList)))
+        coverDisableLoopIpyDataInfo, disableLoopCfgIDDict, otherLoopCfgIDDict, coverDisableWeekIpyDataInfo, disableWeekCfgIDDict, kOpenServerActInfo = \
+            __GetOperationActionDisableIpyDataInfo(actName, curDateTime, curServerActIpyDataList)
+        GameWorld.Log("    kOpenServerActInfo=%s" % kOpenServerActInfo)
+            
+        for ipyData in curServerActIpyDataList:
+            
+            platformList = [] if not hasattr(ipyData, "GetPlatformList") else ipyData.GetPlatformList()
+            serverIDList = [] if not hasattr(ipyData, "GetServerIDList") else ipyData.GetServerIDList()
+            serverIDListExcept = [] if not hasattr(ipyData, "GetServerIDListExcept") else ipyData.GetServerIDListExcept()
+            cfgID = ipyData.GetCfgID()
+            startDateStr = ipyData.GetStartDate()
+            endDateStr = ipyData.GetEndDate()
+            actNum = ipyData.GetActNum()
+            actType = GetOperationActType(actNum)
+            if kOpenServerActInfo and actNum in kOpenServerActInfo:
+                kOpenServerCfgIDInfo = kOpenServerActInfo[actNum]
+                actCustomServerDayMax = max(max(kOpenServerCfgIDInfo.values()), customMaxServerDay)
+            else:
+                actCustomServerDayMax = customMaxServerDay
+            GameWorld.Log("    cfgID=%s,actNum=%s,startDateStr=%s,endDateStr=%s,openServerDay=%s,actCustomServerDayMax=%s,isMixServer=%s,mixServerDay=%s,curDateTime=%s,platformList=%s,serverIDList=%s,Except=%s" 
+                          % (cfgID, actNum, startDateStr, endDateStr, openServerDay, actCustomServerDayMax, isMixServer, mixServerDay, curDateTime, platformList, serverIDList, serverIDListExcept))
+            
+            actIDDateTimeSpec = None # 特殊指定的活动ID日期
+            startDateSync = None # 特殊同步前端显示用的开始日期,一般用于与开服前X天交叉的活动
+            
+            # 多活动分组编号支持
+            if actNum not in PyGameData.g_operationActionDict[actName]:
+                PyGameData.g_operationActionDict[actName][actNum] = {ShareDefine.ActKey_ActNum:actNum}
+                
+            curActTodayInfo = operationTodayActionDict.get(actName, {}).get(actNum)
+
+                
+            if not startDateStr:
+                startDateStr = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)
+                GameWorld.Log("        开始日期为空,默认每天,今日为: startDateStr=%s" % startDateStr)
+            if not endDateStr:
+                endDateStr = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)
+                GameWorld.Log("        结束日期为空,默认每天,今日为: endDateStr=%s" % endDateStr)
+                
+            actByLoopYmd = startDateStr.startswith("L") # 按日期循环
+            # 根据日期循环的通用
+            if actByLoopYmd:
+                if cfgID in coverDisableLoopIpyDataInfo:
+                    loopStartDate, loopEndDate, ymdCfgID, ymdStartDate, ymdEndDate = coverDisableLoopIpyDataInfo[cfgID]
+                    GameWorld.Log("        按日期循环的在按日期开启的时间内,不处理! cfgID=%s,%s(%s) ~ %s(%s) in ymdCfgID=%s,%s ~ %s" 
+                                  % (cfgID, loopStartDate, startDateStr, loopEndDate, endDateStr, ymdCfgID, ymdStartDate, ymdEndDate))
+                    continue
+                
+                if cfgID in disableLoopCfgIDDict:
+                    GameWorld.Log("        按日期循环的未到开启循环日期或已结束循环日期,不处理! cfgID=%s,startDateStr=%s,endDateStr=%s" % (cfgID, startDateStr, endDateStr))
+                    continue
+                
+                if cfgID in otherLoopCfgIDDict:
+                    loopCfgIDList, startDateStr, endDateStr, loopIndex, loopTimes = otherLoopCfgIDDict[cfgID]
+                    GameWorld.Log("        按日期循环的还未循环到当前配置,不处理! cfgID=%s,startDateStr=%s,endDateStr=%s,loopCfgIDList=%s,loopIndex=%s,loopTimes=%s" 
+                                  % (cfgID, startDateStr, endDateStr, loopCfgIDList, loopIndex, loopTimes))
+                    continue
+                startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
+                
+            # 开服常规:  开服天 > 日期 > 周x=日期循环   (不受合服天影响,合服活动新增一套独立的活动,还是走运营活动配置)
+            if actType == ShareDefine.ActType_OpenComm:
+                actByWeek = (startDateStr.startswith("W") and endDateStr.startswith("W")) # 按周x开
+                actByDate = (not actByLoopYmd and not actByWeek and startDateStr.count("-") == 2 and endDateStr.count("-") == 2) # 按日期开
+                
+                # 开服天的
+                if startDateStr.isdigit() and endDateStr.isdigit():
+                    startServerDay, endServerDay = int(startDateStr), int(endDateStr)
+                    #结束日可能还需要处理广播之类,所以这里需要+1
+                    if openServerDay > endServerDay + 1:
+                        GameWorld.Log("        当前开服天超过活动结束开服天,不处理! cfgID=%s,%s ~ %s < openServerDay(%s)" % (cfgID, startDateStr, endDateStr, openServerDay))
+                        continue
+                    openServerDateTime = curDateTime + datetime.timedelta(days=(startServerDay - openServerDay))
+                    endServerDateTime = curDateTime + datetime.timedelta(days=(endServerDay - openServerDay))
+                    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))
+                    
+                # K开头的
+                elif startDateStr.startswith("K"):
+                    startServerDay, endServerDay = GameWorld.ToIntDef(startDateStr[1:]), GameWorld.ToIntDef(endDateStr[1:])
+                    #结束日可能还需要处理广播之类,所以这里需要+1
+                    if openServerDay > endServerDay + 1:
+                        GameWorld.Log("        当前开服天超过活动结束K开服天,不处理! cfgID=%s,%s ~ %s < openServerDay(%s)" % (cfgID, startDateStr, endDateStr, openServerDay))
+                        continue
+                    openServerDateTime = curDateTime + datetime.timedelta(days=(startServerDay - openServerDay))
+                    endServerDateTime = curDateTime + datetime.timedelta(days=(endServerDay - openServerDay))
+                    startDateStr = "%d-%d-%d" % (openServerDateTime.year, openServerDateTime.month, openServerDateTime.day)
+                    endDateStr = "%d-%d-%d" % (endServerDateTime.year, endServerDateTime.month, endServerDateTime.day)
+                    GameWorld.Log("        K开服天转化为日期: %s ~ %s" % (startDateStr, endDateStr))
+                    
+                # 常规配置: 开服前X天不开,不受合服影响,功能配置表可配置 开服前X天后交叉可开,每日重置的活动默认可开
+                elif actByWeek or actByDate or actByLoopYmd:
+                    if openServerDay <= actCustomServerDayMax:
+                        GameWorld.Log("        按日期/周开的在开服定制限制天内,不处理! cfgID=%s,%s ~ %s,openServerDay=%s,actCustomServerDayMax=%s,K开服天信息=%s" 
+                                      % (cfgID, startDateStr, endDateStr, openServerDay, actCustomServerDayMax, kOpenServerActInfo))
+                        continue
+                    
+                    if cfgID in coverDisableWeekIpyDataInfo:
+                        startWeekDate, endWeekDate, ymdCfgID, ymdStartDate, ymdEndDate = coverDisableWeekIpyDataInfo[cfgID]
+                        GameWorld.Log("        常规活动,按星期开启的在按日期开启的时间内,不处理! cfgID=%s,%s(%s) ~ %s(%s) in ymdCfgID=%s,%s ~ %s" 
+                                      % (cfgID, startWeekDate, startDateStr, endWeekDate, endDateStr, ymdCfgID, ymdStartDate, ymdEndDate))
+                        continue
+                    
+                    if cfgID in disableWeekCfgIDDict:
+                        GameWorld.Log("        常规活动,按星期开启的未到开启循环日期或已结束循环日期,不处理! cfgID=%s,startDateStr=%s,endDateStr=%s, %s" 
+                                      % (cfgID, startDateStr, endDateStr, str(disableWeekCfgIDDict[cfgID])))
+                        continue
+                    
+                    if actByWeek:
+                        startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
+                        GameWorld.Log("        星期X转化为日期: %s ~ %s" % (startDateStr, endDateStr))
+                        
+                    curServerOpenDateTime = curDateTime + datetime.timedelta(days=(1 - openServerDay)) # 开服第一天的日期
+                    customMaxServerDateTime = curDateTime + datetime.timedelta(days=(actCustomServerDayMax - openServerDay))
+                    curStartDateTime = datetime.datetime.strptime("%s %02d:%02d:%02d" % (startDateStr, customMaxServerDateTime.hour, customMaxServerDateTime.minute,
+                                                                                         customMaxServerDateTime.second), ChConfig.TYPE_Time_Format)
+                    if curServerOpenDateTime <= curStartDateTime <= customMaxServerDateTime:
+                        # 每日重置的默认交叉后可开启
+                        isDayRest = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
+                        if not isDayRest and actName not in startDateInCustomCanOpenList:
+                            GameWorld.Log("        按日期/周开的开始日期在开服定制限制天内,不处理! cfgID=%s,curServerOpenDateTime=%s<=curStartDateTime=%s<=customMaxServerDateTime=%s" % (cfgID, curServerOpenDateTime, curStartDateTime, customMaxServerDateTime))
+                            continue
+                        
+                        # 非每日重置的 且 开始天在定制天内在定制天结束后可继续开启的活动
+                        # 注: 为防止开始日期与开服天内的活动开始天对应日期刚好同一天导致活动ID一样,所以这里默认将开始日期改为定制天后一天
+                        if not isDayRest and actName in startDateInCustomCanOpenList:
+                            actIDDateTimeSpec = datetime.datetime.strptime("%d-%d-%d 00:00:00" 
+                                                                           % (customMaxServerDateTime.year, customMaxServerDateTime.month, customMaxServerDateTime.day), 
+                                                                           ChConfig.TYPE_Time_Format) + datetime.timedelta(days=1)
+                            GameWorld.Log("        开服天后可开启的非每日重置活动! 活动ID日期特殊设置为开服定制天结束后一天! cfgID=%s,actIDDateTimeSpec=%s" % (cfgID, actIDDateTimeSpec))
+                            
+                        # 特殊同步的开始日期,无视是否每日重置
+                        if actName in startDateInCustomCanOpenList:
+                            startDateSync = datetime.datetime.strptime("%d-%d-%d 00:00:00" 
+                                                                       % (customMaxServerDateTime.year, customMaxServerDateTime.month, customMaxServerDateTime.day), 
+                                                                       ChConfig.TYPE_Time_Format) + datetime.timedelta(days=1)
+                            startDateSync = "%d-%d-%d" % (startDateSync.year, startDateSync.month, startDateSync.day)
+                            
+                else:
+                    GameWorld.Log("        开服常规活动,配置时间格式不支持,不处理! cfgID=%s,startDateStr=%s,endDateStr=%s" % (cfgID, startDateStr, endDateStr))
+                    continue
+                
+            # 合服活动: 只受合服天影响
+            elif actType == ShareDefine.ActType_MixServer:
+                if not startDateStr.startswith("Mix") or not endDateStr.startswith("Mix"):
+                    GameWorld.Log("        合服活动,配置非合服天,不处理! cfgID=%s,startDateStr=%s,endDateStr=%s" % (cfgID, startDateStr, endDateStr))
+                    continue
+                if not isMixServer:
+                    GameWorld.Log("        非合服服务器,不处理! cfgID=%s,%s ~ %s" % (cfgID, startDateStr, endDateStr))
+                    continue
+                startMixServerDay, endMixServerDay = int(startDateStr[3:]), int(endDateStr[3:])
+                #结束日可能还需要处理广播之类,所以这里需要+1
+                if mixServerDay > endMixServerDay + 1:
+                    GameWorld.Log("        当前合服天超过活动结束合服天,不处理! cfgID=%s,%s ~ %s < mixServerDay(%s)" % (cfgID, startDateStr, endDateStr, mixServerDay))
+                    continue
+                openServerDateTime = curDateTime + datetime.timedelta(days=(startMixServerDay - mixServerDay))
+                endServerDateTime = curDateTime + datetime.timedelta(days=(endMixServerDay - mixServerDay))
+                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 actType == ShareDefine.ActType_Feast:
+                if startDateStr.count("-") != 2 or endDateStr.count("-") != 2:
+                    GameWorld.Log("        节日活动,配置非日期,不处理! cfgID=%s,startDateStr=%s,endDateStr=%s" % (cfgID, startDateStr, endDateStr))
+                    continue
+                
+            else:
+                GameWorld.Log("        非法配置,未知活动类型,不处理! cfgID=%s,actNum=%s" % (cfgID, actNum))
+                continue
+            
+            if hasattr(ipyData, "GetJoinStartTime") and hasattr(ipyData, "GetJoinEndTime"):
+                joinStartTimeStr = ipyData.GetJoinStartTime()
+                joinEndTimeStr = ipyData.GetJoinEndTime()
+            else:
+                joinStartTimeStr = ""
+                joinEndTimeStr = ""
+                
+            if hasattr(ipyData, "GetStartTimeList") and hasattr(ipyData, "GetEndTimeList"):
+                startHMStrList = ipyData.GetStartTimeList()
+                endHMStrList = ipyData.GetEndTimeList()
+            else:
+                startHMStrList = []
+                endHMStrList = []
+                
+            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, [广播参数列表可选]]
+            
+            if len(startHMStrList) != len(endHMStrList):
+                GameWorld.ErrLog("        活动配置开始及结束时间个数不匹配! actName=%s,cfgID=%s,startHMStrList=%s,endHMStrList=%s" 
+                                 % (actName, cfgID, startHMStrList, endHMStrList))
+                continue
+            
+            isDayRest = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
+            resetType = 0 if not hasattr(ipyData, "GetResetType") else ipyData.GetResetType() # 重置类型,0-0点重置;1-5点重置
+            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点
+                
+            advanceMinutes = 0 if not hasattr(ipyData, "GetAdvanceMinutes") else ipyData.GetAdvanceMinutes() # 提前通知时间,分钟,暂只支持按天的
+            GameWorld.Log("        resetType=%s,startDayDate=%s,endDayDate=%s,startHMStrList=%s,endHMStrList=%s,advanceMinutes=%s" 
+                          % (resetType, startDayDate, endDayDate, startHMStrList, endHMStrList, advanceMinutes))
+                
+            advanceNoticeDateTime = None
+            startDayDateJudge = startDayDate # 用于判断是否需要处理的起始时间,一般是活动开始时间,如果有提前广播或预告则时间会提前
+            # 提前预告
+            if advanceMinutes:
+                advanceNoticeDateTime = startDayDate + datetime.timedelta(minutes= -advanceMinutes)
+                startDayDateJudge = advanceNoticeDateTime
+            # 提前广播
+            minNotifyStartMinute = 0 if not notifyInfoDictStart else min(notifyInfoDictStart.keys())
+            if minNotifyStartMinute < 0:
+                minNotifyStartDateTime = startDayDate + datetime.timedelta(minutes=minNotifyStartMinute)
+                if minNotifyStartDateTime < startDayDateJudge:
+                    startDayDateJudge = minNotifyStartDateTime
+            if curDateTime < startDayDateJudge or curDateTime > endDayDate: # 结束时间点的时候可能需要处理广播之类的
+                GameWorld.Log("        非活动时间!不处理!")
+                continue
+            
+            #注: 同个活动编号可配置多个时间不交叉的活动,如果多个时间配置同时满足条件,则只会以最后一个为准,提前预告、广播除外
+            if curActTodayInfo and curDateTime < startDayDate:
+                activityIpyData = curActTodayInfo[0]
+                ## 防止未真正开始的活动需要提前预告,而导致覆盖掉了实际正在进行中的活动,一般是活动时间配置连续的时候可能出现该情况
+                GameWorld.Log("        已经存在需要处理的配置ID(%s)! 当前需要提前通知或广播的活动未达到活动开始时间,不处理!cfgID=%s,advanceMinutes=%s,minNotifyStartMinute=%s,startDayDateJudge=%s" 
+                              % (activityIpyData.GetCfgID(), cfgID, advanceMinutes, minNotifyStartMinute, startDayDateJudge))
+                continue
+            
+            #注:刚好是结束的时间点,防范已经有需要处理的配置被覆盖
+            if curActTodayInfo and curDateTime == endDayDate:
+                activityIpyData = curActTodayInfo[0]
+                GameWorld.Log("        已经存在需要处理的配置ID(%s)! 当前刚好结束的时间点,不处理!cfgID=%s" % (activityIpyData.GetCfgID(), cfgID))
+                continue
+            
+            startList = [] # [startDateTime, ...]
+            endList = [] # [endDateTime, ...]
+            startNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
+            endNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
+            loopNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
+            notifyDict = {}
+            
+            isActTime = (startDayDate <= curDateTime < endDayDate)
+            isEnd = (curDateTime == endDayDate)
+            isNotify = False
+            isAdvanceNotice = False
+            
+            # 没配置时分的代表全天, 只要开始或结束时分没配都算
+            if not startHMStrList or not endHMStrList:
+                startDateTime = startDayDate
+                endDateTime = endDayDate
+                startList.append(startDateTime)
+                endList.append(endDateTime)
+                
+            # 每天按时段开启的,支持多时段
+            else:
+                for hmIndex, startHMStr in enumerate(startHMStrList):
+                    endHMStr = endHMStrList[hmIndex]
+                    # 每天开的, 实际开关时间只取今天的日期; 这里有个问题,全服广播的时间不是今天的, 暂不做支持,之后真有这种需求再说
+                    startTimeStr = "%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, startHMStr)
+                    endTimeStr = "%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, endHMStr)
+                    startDateTime = datetime.datetime.strptime(startTimeStr, ChConfig.TYPE_Time_Format)
+                    endDateTime = datetime.datetime.strptime(endTimeStr, ChConfig.TYPE_Time_Format)
+                    
+                    startList.append(startDateTime)
+                    endList.append(endDateTime)
+                    
+            if advanceNoticeDateTime:
+                if advanceNoticeDateTime.year == curDateTime.year and advanceNoticeDateTime.month == curDateTime.month and advanceNoticeDateTime.day == curDateTime.day:
+                    isAdvanceNotice = True
+                GameWorld.Log("        advanceNoticeDateTime=%s,isAdvanceNotice=%s" % (advanceNoticeDateTime, isAdvanceNotice))
+            GameWorld.Log("        startList=%s" % (startList))
+            GameWorld.Log("        end  List=%s" % (endList))
+            
+            joinStartTimeList, joinEndTimeList = [], [] # 可指定活动可参与的时间点,不影响活动状态,只影响活动某些功能的参与时机,如上榜类
+            if joinStartTimeStr:
+                if isDayRest:
+                    joinStartTimeList.append(datetime.datetime.strptime("%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, joinStartTimeStr), ChConfig.TYPE_Time_Format))
+                    joinEndTimeList.append(datetime.datetime.strptime("%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, joinEndTimeStr), ChConfig.TYPE_Time_Format))
+                else:
+                    joinStartTimeList.append(datetime.datetime.strptime("%s %s:00" % (startDateStr, joinStartTimeStr), ChConfig.TYPE_Time_Format))
+                    joinEndTimeList.append(datetime.datetime.strptime("%s %s:00" % (endDateStr, joinEndTimeStr), ChConfig.TYPE_Time_Format))                    
+            GameWorld.Log("        joinStartTimeList=%s" % (joinStartTimeList))
+            GameWorld.Log("        joinEndTime  List=%s" % (joinEndTimeList))
+            
+            for dtIndex, startDateTime in enumerate(startList):
+                endDateTime = endList[dtIndex]
+                # 广播 - 相对实际开始时间
+                for notifyMinute, notifyInfo in notifyInfoDictStart.items():
+                    notifyDateTime = startDateTime + datetime.timedelta(minutes=notifyMinute)
+                    if notifyDateTime.year == curDateTime.year and notifyDateTime.month == curDateTime.month and notifyDateTime.day == curDateTime.day:
+                        startNotifyDict[notifyDateTime] = notifyInfo
+                        isNotify = True
+                    
+                # 广播 - 相对实际结束时间
+                for notifyMinute, notifyInfo in notifyInfoDictEnd.items():
+                    notifyDateTime = endDateTime + datetime.timedelta(minutes=notifyMinute)
+                    if notifyDateTime.year == curDateTime.year and notifyDateTime.month == curDateTime.month and notifyDateTime.day == curDateTime.day:
+                        endNotifyDict[notifyDateTime] = notifyInfo
+                        isNotify = True
+                        
+                # 广播 - 循环广播
+                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
+                        notifyDateTime = startDateTime + datetime.timedelta(minutes=loopMinutes * loopCount)
+                        if notifyDateTime >= endDateTime:
+                            break
+                        if notifyDateTime.year == curDateTime.year and notifyDateTime.month == curDateTime.month and notifyDateTime.day == curDateTime.day:
+                            loopNotifyDict[notifyDateTime] = notifyInfo
+                            isNotify = True
+                            
+            if startNotifyDict or endNotifyDict or loopNotifyDict:
+                GameWorld.Log("        startNotifyDict: minutes=%s, %s" % (notifyInfoDictStart.keys(), startNotifyDict))
+                GameWorld.Log("        end  NotifyDict: minutes=%s, %s" % (notifyInfoDictEnd.keys(), endNotifyDict))
+                GameWorld.Log("        loop NotifyDict: lopInfo=%s, %s" % (notifyInfoLoopInfo, loopNotifyDict.keys()))
+                notifyDict.update(startNotifyDict)
+                notifyDict.update(endNotifyDict)
+                notifyDict.update(loopNotifyDict)
+                
+            GameWorld.Log("        需要处理的运营活动信息: cfgID=%s,isActTime=%s,isEnd=%s,isNotify=%s,isAdvanceNotice=%s" % (cfgID, isActTime, isEnd, isNotify, isAdvanceNotice))
+            
+            if actName not in operationTodayActionDict:
+                operationTodayActionDict[actName] = {} # 今日有需要处理的才初始化
+            operationTodayActionDict[actName][actNum] = [ipyData, startList, endList, notifyDict, joinStartTimeList, joinEndTimeList]
+            
+            if isActTime:
+                activityInfoDict = {ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ActNum:actNum}
+                #if actName == ShareDefine.OperationActionName_LoginAward:
+                #    #活动每天的世界等级
+                #    activityInfoDict[ShareDefine.ActKey_WorldLVList] = GameWorldAverageLv.GetWorldLVListByTime(startDayDate, (endDayDate - startDayDate).days)
+                if startDateSync:
+                    activityInfoDict[ShareDefine.ActKey_StartDateSync] = startDateSync
+                    GameWorld.Log("        startDateSync=%s" % (startDateSync))
+                    
+                dayIndex = (curDateTime - startDayDate).days
+                    
+                if ipyData.GetStartDate().startswith("K"):
+                    startServerDay = GameWorld.ToIntDef(ipyData.GetStartDate()[1:])
+                    # 按时段开的默认每天重置
+                    if isDayRest or (startHMStrList and endHMStrList):
+                        actID = startServerDay + dayIndex
+                    else:
+                        actID = startServerDay
+                    GameWorld.Log("        isDayRest=%s,startServerDay=%s,actID=%s" % (isDayRest, startServerDay, actID))
+                else:
+                    actIDDateTime = startDayDate
+                    # 按时段开的默认每天重置
+                    if isDayRest or (startHMStrList and endHMStrList):
+                        actIDDateTime += datetime.timedelta(days=dayIndex)
+                    if actIDDateTimeSpec:
+                        actIDDateTime = actIDDateTimeSpec
+                    actID = int(time.mktime(actIDDateTime.timetuple())) # 默认取开始时间点的time值作为活动ID
+                    GameWorld.Log("        isDayRest=%s,actIDDateTime=%s,actID=%s" % (isDayRest, actIDDateTime, actID))
+                activityInfoDict[ShareDefine.ActKey_DayIndex] = dayIndex
+                activityInfoDict[ShareDefine.ActKey_ID] = actID
+                GameWorld.Log("        activityInfoDict=%s" % (activityInfoDict))
+                
+                PyGameData.g_operationActionDict[actName][actNum] = activityInfoDict
+                
+    OperationActionInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, operationTodayActionDict])
+    
+    GameWorld.Log("本日运营活动信息加载完毕!reloadSign=%s" % (reloadSign))
+    #GameWorld.Log("    operationTodayActionDict=%s" % operationTodayActionDict)
+    GameWorld.Log("    PyGameData.g_operationActionDict=%s" % PyGameData.g_operationActionDict)
+    GameWorld.Log("=============================================================")
+    return True, OperationActionInfo
+
+def __GetOperationActionServerIpyDataList(ipyDataMgr, platform, serverID, actName):
+    ## 获取运营活动本服务器对应的配置数据列表
+    
+    if not hasattr(ipyDataMgr, "Get%sCount" % actName):
+        GameWorld.ErrLog("没有该运营活动类型对应活动时间表! actName=%s" % actName)
+        return []
+    
+    curServerActIpyDataList = []
+    actCfgCount = getattr(ipyDataMgr, "Get%sCount" % actName)()
+    for cfgIndex in xrange(actCfgCount):
+        ipyData = getattr(ipyDataMgr, "Get%sByIndex" % actName)(cfgIndex)            
+        platformList = [] if not hasattr(ipyData, "GetPlatformList") else ipyData.GetPlatformList()
+        serverIDList = [] if not hasattr(ipyData, "GetServerIDList") else ipyData.GetServerIDList()
+        serverIDListExcept = [] if not hasattr(ipyData, "GetServerIDListExcept") else ipyData.GetServerIDListExcept()
+        
+        if platformList and platform not in platformList:
+            continue
+        
+        # 排除的服务器组ID列表
+        if serverIDListExcept:
+            isExcept = False
+            for serverIDInfo in serverIDListExcept:
+                if GameWorld.CheckServerIDInList(serverID, serverIDInfo):
+                    isExcept = True
+                    break
+            if isExcept:
+                continue
+            
+        if not serverIDList:
+            curServerActIpyDataList.append(ipyData)
+        else:
+            for serverIDInfo in serverIDList:
+                if GameWorld.CheckServerIDInList(serverID, serverIDInfo):
+                    curServerActIpyDataList.append(ipyData)
+                    break
+                
+    return curServerActIpyDataList
+
+def __GetOperationActionDisableIpyDataInfo(actName, curDateTime, curServerActIpyDataList):
+    ## 获取不可用的按星期X开启的配置数据信息,按星期X开启的 活动优先级小于按日期的,当有重叠时以日期的为准
+    # 优先级 日期 > 按日期循环 > 按星期循环
+    
+    actNumYMDIpyDataInfo = {} # {actNum:ymdIpyDataList, ...} # 配置日期的
+    actNumLoopIpyDataInfo = {} # {actNum:{loopKey:[loopCfgIDList, loopDateInfo]}, ...} # 按日期循环的
+    actNumWeekIpyDataInfo = {} # {actNum:weekIpyDataList, ...} # 按星期循环的
+    
+    disableWeekCfgIDDict = {} # {cfgID:[startDateStr, endDateStr], ...} # 未开始循环的星期
+    disableLoopCfgIDDict = {} # {cfgID:[startDateStr, endDateStr], ...} # 未开始循环的日期
+    
+    kOpenServerActInfo = {} # 以K为开头的开服天活动中信息 {actNum:{cftID:endOpenServerDay, ...}, ...}
+    
+    curDateTimeYmdStr = "%d-%d-%d" % (curDateTime.year, curDateTime.month, curDateTime.day)
+    curDateTimeYmd = GameWorld.ChangeStrToDatetime(curDateTimeYmdStr, ChConfig.TYPE_Time_Format_Ymd)
+    
+    for ipyData in curServerActIpyDataList:
+        cfgID = ipyData.GetCfgID()
+        startDateStr = ipyData.GetStartDate()
+        endDateStr = ipyData.GetEndDate()
+        actNum = ipyData.GetActNum()
+        
+        # 按星期X的
+        if startDateStr.startswith("W"):
+            if actNum not in actNumWeekIpyDataInfo:
+                actNumWeekIpyDataInfo[actNum] = []
+            weekIpyDataList = actNumWeekIpyDataInfo[actNum]
+            startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
+            startWeekDate = GameWorld.ChangeStrToDatetime(startDateStr, ChConfig.TYPE_Time_Format_Ymd)
+            endWeekDate = GameWorld.ChangeStrToDatetime(endDateStr, ChConfig.TYPE_Time_Format_Ymd)
+            if startWeekDate > curDateTimeYmd or curDateTimeYmd > endWeekDate: # 还未开始的循环 or 已经强制结束的循环
+                disableWeekCfgIDDict[cfgID] = [startDateStr, endDateStr]
+            else:
+                weekIpyDataList.append([cfgID, startWeekDate, endWeekDate])
+            
+        # 指定开服天的,不受开服前7天配置影响
+        elif endDateStr.startswith("K"):
+            endKOpenServerDay = GameWorld.ToIntDef(endDateStr[1:])
+            if endKOpenServerDay:
+                if actNum not in kOpenServerActInfo:
+                    kOpenServerActInfo[actNum] = {}
+                kOpenServerCfgIDInfo = kOpenServerActInfo[actNum]
+                kOpenServerCfgIDInfo[cfgID] = endKOpenServerDay
+                
+        # 按日期循环
+        elif startDateStr.startswith("L"):
+            loopStartDate, loopEndDate, loopTimes = GameWorld.GetOperationActionLoopDate(startDateStr, endDateStr, curDateTime)
+            if loopStartDate > curDateTimeYmd or curDateTimeYmd > loopEndDate: # 还未开始的循环 or 已经强制结束的循环
+                disableLoopCfgIDDict[cfgID] = [startDateStr, endDateStr]
+            else:
+                loopKey = (startDateStr, endDateStr) # 同个循环周期的视为同一组
+                if actNum not in actNumLoopIpyDataInfo:
+                    actNumLoopIpyDataInfo[actNum] = {}
+                loopIpyDataDict = actNumLoopIpyDataInfo[actNum]
+                if loopKey not in loopIpyDataDict:
+                    loopCfgIDList, loopDateInfo = [], [loopStartDate, loopEndDate, loopTimes]
+                    loopIpyDataDict[loopKey] = [loopCfgIDList, loopDateInfo]
+                loopCfgIDList, loopDateInfo = loopIpyDataDict[loopKey]
+                loopCfgIDList.append(cfgID)
+                
+        # 按日期的
+        elif startDateStr.count("-") == 2:
+            if actNum not in actNumYMDIpyDataInfo:
+                actNumYMDIpyDataInfo[actNum] = []
+            ymdIpyDataList = actNumYMDIpyDataInfo[actNum]
+            ymdStartDate = GameWorld.ChangeStrToDatetime(startDateStr, ChConfig.TYPE_Time_Format_Ymd)
+            ymdEndDate = GameWorld.ChangeStrToDatetime(endDateStr, ChConfig.TYPE_Time_Format_Ymd)
+            ymdIpyDataList.append([cfgID, ymdStartDate, ymdEndDate])
+            
+        else:
+            # 其他的不处理
+            pass
+        
+    nowLoopYMDIpyDataInfo = {} # {actNum:loopIpyDataList, ...} # # 日期循环中当前在循环的
+    otherLoopCfgIDDict = {} # {cfgID:[info], ...} # 日期循环中不是当前循环的其他循环
+    coverDisableLoopIpyDataInfo = {} # {cfgID:[info], ...} # 被日期覆盖的日期循环
+    for actNum, loopIpyDataDict in actNumLoopIpyDataInfo.items():
+        ymdIpyDataList = actNumYMDIpyDataInfo.get(actNum, [])
+        if actNum not in nowLoopYMDIpyDataInfo:
+            nowLoopYMDIpyDataInfo[actNum] = []
+        loopIpyDataList = nowLoopYMDIpyDataInfo[actNum]
+        for loopKey, loopInfo in loopIpyDataDict.items():
+            startDateStr, endDateStr = loopKey
+            loopCfgIDList, loopDateInfo = loopInfo
+            loopStartDate, loopEndDate, loopTimes = loopDateInfo
+            loopIndex = (loopTimes - 1) % len(loopCfgIDList) # 当前循环次数对应的循环索引
+            curLoopCfgID = 0
+            for index, loopCfgID in enumerate(loopCfgIDList):
+                if index == loopIndex: # 当前循环的
+                    curLoopCfgID = loopCfgID
+                    loopIpyDataList.append([loopCfgID, loopStartDate, loopEndDate])
+                else:
+                    otherLoopCfgIDDict[loopCfgID] = [loopCfgIDList, startDateStr, endDateStr, loopIndex, loopTimes]
+                    
+            for ymdCfgID, ymdStartDate, ymdEndDate in ymdIpyDataList:
+                if ymdStartDate <= loopStartDate <= ymdEndDate or ymdStartDate <= loopEndDate <= ymdEndDate:
+                    coverDisableLoopIpyDataInfo[curLoopCfgID] = [loopStartDate, loopEndDate, ymdCfgID, ymdStartDate, ymdEndDate]
+                    
+    coverDisableWeekIpyDataInfo = {} # {cfgID:[info], ...} # 被日期覆盖的星期循环
+    for actNum, weekIpyDataList in actNumWeekIpyDataInfo.items():
+        ymdIpyDataList = actNumYMDIpyDataInfo.get(actNum, [])
+        loopIpyDatList = nowLoopYMDIpyDataInfo.get(actNum, [])
+        for weekCfgID, startWeekDate, endWeekDate in weekIpyDataList:
+            # 被常规日期覆盖的
+            for ymdCfgID, ymdStartDate, ymdEndDate in ymdIpyDataList:
+                if ymdStartDate <= startWeekDate <= ymdEndDate or ymdStartDate <= endWeekDate <= ymdEndDate:
+                    coverDisableWeekIpyDataInfo[weekCfgID] = [startWeekDate, endWeekDate, ymdCfgID, ymdStartDate, ymdEndDate]
+                    
+            # 被循环日期覆盖的
+            for loopCfgID, loopStartDate, loopEndDate in loopIpyDatList:
+                if loopStartDate <= startWeekDate <= loopEndDate or loopStartDate <= endWeekDate <= loopEndDate:
+                    coverDisableWeekIpyDataInfo[weekCfgID] = [startWeekDate, endWeekDate, loopCfgID, loopStartDate, loopEndDate]
+                    
+    return coverDisableLoopIpyDataInfo, disableLoopCfgIDDict, otherLoopCfgIDDict, coverDisableWeekIpyDataInfo, disableWeekCfgIDDict, kOpenServerActInfo
+
+def Dispose_OperationActionState():
+    # 运营活动状态处理
+    
+    if GameWorld.IsCrossCenter():
+        # 跨服活动管理,待扩展,由跨服中心统一管理
+        #CrossActionControl.Dispose_CrossActState(reloadRefresh)
+        return
+    
+    if not GameWorld.IsMainServer():
+        return
+    
+    isReload, OperationActionInfo = __GetOperationActionInfo()
+    operationTodayActionDict = OperationActionInfo[OperationAction_TodayInfo]
+    mapServerInfoDict = PyGameData.g_operationActionDict #OperationActionInfo[OperationAction_MapServerInfo]
+    
+    gameWorld = GameWorld.GetGameWorld()
+    dbEventMgr = DBDataMgr.GetEventTrigMgr()
+    
+    # 这里时间需精确到分钟,不然后面的比较会匹配不到
+    curDateTime = GameWorld.GetServerTime()
+    curDateTime = datetime.datetime.strptime("%d-%d-%d %d:%d:00" % (curDateTime.year, curDateTime.month, curDateTime.day,
+                                                                    curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)
+    
+    syncMapList = []
+    for actName in ShareDefine.OperationActionNameList:
+        
+        if actName not in mapServerInfoDict:
+            continue
+        
+        curActMapInfoDictList = mapServerInfoDict[actName].values()
+        for sendMapServerMsgDict in curActMapInfoDictList:
+            
+            state = 0 # 默认关闭
+            stateJoin = ShareDefine.ActStateJoin_None # 可参与状态,0-参与前;1-可参与;2-参与结束
+            ipyData = None
+            
+            actNum = sendMapServerMsgDict.get(ShareDefine.ActKey_ActNum, 0)
+            
+            if actName in operationTodayActionDict:
+                todayActInfoList = []
+                
+                if actNum in operationTodayActionDict[actName]:
+                    todayActInfoList = operationTodayActionDict[actName][actNum]
+                    
+                if isinstance(todayActInfoList, list) and len(todayActInfoList) == 6:
+                    #startList = [] # [startDateTime, ...]
+                    #endList = [] # [endDateTime, ...]
+                    #notifyDict = {} # {notifyDateTime:[notifyKey, [参数]], ...}
+                    #ipyData 可能为 None
+                    ipyData, startList, endList, notifyDict, joinStartTimeList, joinEndTimeList = todayActInfoList
+                    
+                    # 状态
+                    for dIndex, startDateTime in enumerate(startList):
+                        endDateTime = endList[dIndex]
+                        if startDateTime <= curDateTime < endDateTime:
+                            state = dIndex + 1 # 代表第几个时间段
+                            break
+                        
+                    if joinStartTimeList:
+                        for jIndex, joinStartDateTime in enumerate(joinStartTimeList):
+                            endJoinDateTime = joinEndTimeList[jIndex]
+                            if joinStartDateTime <= curDateTime < endJoinDateTime:
+                                stateJoin = ShareDefine.ActStateJoin_Start
+                                break
+                            elif curDateTime >= endJoinDateTime:
+                                stateJoin = ShareDefine.ActStateJoin_End
+                    else:
+                        stateJoin = ShareDefine.ActStateJoin_Start if state else ShareDefine.ActStateJoin_None
+                        
+                    # 全服广播提示信息
+                    if curDateTime in notifyDict:
+                        notifyKey, paramList = notifyDict[curDateTime]
+                        PlayerControl.WorldNotify(0, notifyKey, paramList)
+                        
+            dictName = ShareDefine.Def_WorldKey_OperationActionState % (actName, actNum)
+            dictNameJoin = ShareDefine.Def_WorldKey_OperationActionStateJoin % (actName, actNum)
+            
+            preState = gameWorld.GetGameWorldDictByKey(dictName)            
+            preStateJoin = gameWorld.GetGameWorldDictByKey(dictNameJoin)
+            if not isReload and preState == state and preStateJoin == stateJoin:
+                #GameWorld.DebugLog("运营活动已经是这个状态了: actName=%s,actNum=%s,preState=%s,state=%s,preStateJoin=%s,stateJoin=%s" % (actName, actNum, preState, state, preStateJoin, stateJoin))
+                continue
+            GameWorld.Log("运营活动变更: actName=%s,actNum=%s,preState=%s,state=%s,preStateJoin=%s,stateJoin=%s,isReload=%s" 
+                          % (actName, actNum, preState, state, preStateJoin, stateJoin, isReload))
+            #更新字典值
+            gameWorld.SetGameWorldDict(dictName, state)
+            gameWorld.SetGameWorldDict(dictNameJoin, stateJoin)
+            
+            dbOperationActIDKey = ShareDefine.Def_OperationActID % (actName, actNum)
+            dbActID = dbEventMgr.GetValue(dbOperationActIDKey)
+            
+            curActID = sendMapServerMsgDict.get(ShareDefine.ActKey_ID, 0)
+            #dayIndex = sendMapServerMsgDict.get(ShareDefine.ActKey_DayIndex, 0)
+            if dbActID != curActID:
+                GameWorld.Log("    dbActID变更: dbActID=%s,curActID=%s" % (dbActID, curActID))
+                dbEventMgr.SetValue(dbOperationActIDKey, curActID)
+                
+                # 结束旧的
+                if dbActID:
+                    pass
+                    #if actName == ShareDefine.OperationActionName_Gubao:
+                    #    PlayerActGubao.OnActEnd(actNum, ipyData, dayIndex)
+                    
+                if curActID:
+                    pass
+                    #此处为活动开启时
+                    #if actName == ShareDefine.OperationActionName_Gubao:
+                    #    PlayerActGubao.OnActStart(actNum, ipyData)
+                    
+                #else:
+                #    if actName == ShareDefine.OperationActionName_GarbageSorting:
+                #        PlayerActGarbageSorting.OnActEnd(actNum)
+                        
+            else:
+                GameWorld.Log("    dbActID不变: dbActID=%s,curActID=%s" % (dbActID, curActID))
+                
+            # 活动中刷新,每次都需要刷新的逻辑,包含重读配置等
+            if state:
+                pass
+                #if actName == ShareDefine.OperationActionName_Gubao:
+                #    PlayerActGubao.OnActInStateRefresh(actNum, ipyData)
+                    
+            # 仅活动有配置参与时间段的会触发
+            if curActID and dbActID == curActID and preStateJoin != stateJoin:
+                GameWorld.Log("    参与状态变更: preStateJoin=%s,stateJoin=%s" % (preStateJoin, stateJoin))
+                # 参与开始
+                if stateJoin == ShareDefine.ActStateJoin_Start:
+                    pass
+                # 参与结束
+                elif stateJoin == ShareDefine.ActStateJoin_End:
+                    pass
+                    #if actName == ShareDefine.OperationActionName_Gubao:
+                    #    PlayerActGubao.OnActJoinEnd(actNum, ipyData, dayIndex)
+                    
+            if ipyData:
+                pass      
+            #if actName == ShareDefine.OperationActionName_ExpRate:
+            #    if isReload and ipyData:
+            #        Sync_OperationAction_ExpRate(ipyData)
+                    
+            #通知Mapserver,设置字典
+            #GameWorld.SendMapServerMsgEx(dictName, state) # 运营活动不单独通知活动状态,需与活动信息整合后一起通知
+            sendMapServerMsgDict[ShareDefine.ActKey_State] = state
+            sendMapServerMsgDict[ShareDefine.ActKey_StateJoin] = stateJoin
+            mapServerInfoDict[actName][actNum] = sendMapServerMsgDict
+            syncMapList.append([actName, actNum, sendMapServerMsgDict])
+            
+    if syncMapList:
+        GameWorld.Log("=============================================================")
+        for actName, actNum, actInfo in syncMapList:
+            OnMapOperationActionRefresh(actName, actNum, actInfo) # 通知地图玩家刷新活动相关 
+            
+    return
+
+def OnMapOperationActionRefresh(actName, actNum, actInfo):
+    ## 处理类似之前由GameServer通知MapServer的运营活动刷新
+    GameWorld.Log("OperationActionRefresh: %s,actNum=%s,%s" % (actName, actNum, actInfo))
+    if actName == ShareDefine.OperationActionName_Lunhuidian:
+        PlayerActLunhuidian.RefreshActLunhuidianActionInfo(actNum)
+        
+    return
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
index 08e4dfb..cb47a5c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
@@ -25,6 +25,7 @@
 import IPY_GameWorld
 import DataRecordPack
 import PlayerEventCounter
+import GameWorldAction
 import PlayerViewCache
 import PlayerControl
 import NetPackCommon
@@ -335,15 +336,13 @@
     DoCheckNewServerOpen(tick)
     DBDataMgr.OnMinute(curTime)
     DoLogic_GameWorldEvenByTime(tick)
+    GameWorldAction.OnProcessGameAction(curTime)
     
     #每5分钟
     if curMinute % 5 == 0:
         OnMinute_5(curTime, tick)
         
     #其他功能逻辑
-    #GameWorldActionControl.Dispose_OperationActionState()
-    #GameWorldActionControl.Dispose_DailyActionState()
-    #GameWorldActionControl.Dispose_FBStateTime()
     PlayerControl.OnMinute(curTime)
     PlayerFamily.OnMinute()
     PlayerOnline.OnMinute()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 20a6e83..9e8588d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -1696,6 +1696,9 @@
 
                 "ActLunhuidian":(
                         ("DWORD", "CfgID", 1),
+                        ("list", "PlatformList", 0),
+                        ("list", "ServerIDList", 0),
+                        ("BYTE", "ActNum", 0),
                         ("char", "StartDate", 0),
                         ("char", "EndDate", 0),
                         ("WORD", "LVLimit", 0),
@@ -4571,13 +4574,16 @@
         return
         
     def GetCfgID(self): return self.attrTuple[0] # 配置ID DWORD
-    def GetStartDate(self): return self.attrTuple[1] # 开启日期 char
-    def GetEndDate(self): return self.attrTuple[2] # 结束日期 char
-    def GetLVLimit(self): return self.attrTuple[3] # 限制等级 WORD
-    def GetResetType(self): return self.attrTuple[4] # 重置类型,0-0点重置;1-5点重置 BYTE
-    def GetRoundSetInfo(self): return self.attrTuple[5] # 开放轮回设定 dict
-    def GetRoundCTGIDInfo(self): return self.attrTuple[6] # 轮回类型对应充值ID列表 dict
-    def GetRoundShopTypeInfo(self): return self.attrTuple[7] # 轮回类型对应商店类型 dict
+    def GetPlatformList(self): return self.attrTuple[1] # 活动平台列表["平台A", "平台A", ...],配[]代表所有 list
+    def GetServerIDList(self): return self.attrTuple[2] # 服务器ID列表 list
+    def GetActNum(self): return self.attrTuple[3] # 活动分组编号, 活动类型 * 10 + 不同界面编号 BYTE
+    def GetStartDate(self): return self.attrTuple[4] # 开启日期 char
+    def GetEndDate(self): return self.attrTuple[5] # 结束日期 char
+    def GetLVLimit(self): return self.attrTuple[6] # 限制等级 WORD
+    def GetResetType(self): return self.attrTuple[7] # 重置类型,0-0点重置;1-5点重置 BYTE
+    def GetRoundSetInfo(self): return self.attrTuple[8] # 开放轮回设定 dict
+    def GetRoundCTGIDInfo(self): return self.attrTuple[9] # 轮回类型对应充值ID列表 dict
+    def GetRoundShopTypeInfo(self): return self.attrTuple[10] # 轮回类型对应商店类型 dict
 
 # 轮回殿活动奖励表
 class IPY_ActLunhuidianAward():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index 2110b27..cf93f29 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -482,7 +482,7 @@
     EventReport.WriteEvent_login(curPlayer)
     
     # 合服首登处理
-    __DoMixServerFirstLogin(curPlayer)
+    #__DoMixServerFirstLogin(curPlayer)
     PlayerBillboard.BillboardOnLogin(curPlayer)
     
     #玩家扩展信息
@@ -580,8 +580,6 @@
     PlayerActTask.OnPlayerLogin(curPlayer)
     # 运势活动
     PlayerActYunshi.OnPlayerLogin(curPlayer)
-    # 轮回殿活动
-    PlayerActLunhuidian.OnPlayerLogin(curPlayer)
     # 登录活动
     PlayerActLoginNew.OnPlayerLogin(curPlayer)
     # 节日登录活动
@@ -687,6 +685,7 @@
         OpenServerActivity.OnPlayerLogin(curPlayer)
         PlayerPreset.OnPlayerLogin(curPlayer)
         CrossPlayer.OnPlayerLogin(curPlayer)
+        PlayerActLunhuidian.OnPlayerLogin(curPlayer)
         
         __OnFixVersion(curPlayer) # 修正线上玩家数据用,暂时放最后
         # 上线查询一次充值订单
@@ -3399,6 +3398,9 @@
     # 开服庆典积分阶段奖励 
     elif rewardType == ChConfig.Def_RewardType_OSACelebrationPointAward:
         OpenServerActivity.GetOSACelebrationPointAward(curPlayer, dataEx)
+    # 轮回殿奖励
+    elif rewardType == ChConfig.Def_RewardType_LunhuidianAward:
+        PlayerActLunhuidian.GetLunhuidianAward(curPlayer, dataEx, dataExStr)
         
         
     # 每日免费直购礼包
@@ -3455,9 +3457,6 @@
     # 寻宝累计次数奖励
     elif rewardType == ChConfig.Def_RewardType_TreasureCntAward:
         PlayerTreasure.GetTreasureCntAward(curPlayer, dataEx, dataExStr)
-    # 轮回殿奖励
-    elif rewardType == ChConfig.Def_RewardType_LunhuidianAward:
-        PlayerActLunhuidian.GetLunhuidianAward(curPlayer, dataEx, dataExStr)
     #历史累计充值领取
     elif rewardType == ChConfig.Def_RewardType_HistoryChargeAward:
         PlayerGoldGift.OnGetHistoryRechargeAward(curPlayer, dataEx)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLunhuidian.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLunhuidian.py
index 9bc3a02..60d3fdb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLunhuidian.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLunhuidian.py
@@ -24,6 +24,7 @@
 import NetPackCommon
 import ItemControler
 import PlayerCoin
+import PlayerMail
 import GameWorld
 import ChConfig
 
@@ -176,7 +177,7 @@
         return
     GameWorld.Log("处理补发轮回奖励完毕: actNum=%s,roundType=%s,roundMax=%s,curRound=%s,curValue=%s,awardState=%s,mailItemList=%s" 
                        % (actNum, roundType, roundMax, curRound, curValue, awardState, mailItemList), playerID)
-    PlayerControl.SendMailByKey("LunhuidianUnget", [playerID], mailItemList)
+    PlayerMail.SendMailByKey("LunhuidianUnget", playerID, mailItemList)
     return
 
 def GetRoundSetValue(roundSet, setIndex): return roundSet[setIndex] if len(roundSet) > setIndex else 0
@@ -338,7 +339,9 @@
                 award = ChPyNetSendPack.tagMCActLunhuidianAward()
                 award.AwardIndex = awardIpyData.GetAwardIndex()
                 award.NeedValue = awardIpyData.GetNeedValue()
-                for itemID, itemCount, isAuctionItem in awardIpyData.GetAwardItemList():
+                for itemInfo in awardIpyData.GetAwardItemList():
+                    itemID, itemCount = itemInfo[:2]
+                    isAuctionItem = itemInfo[2] if len(itemInfo) > 2 else 0
                     item = ChPyNetSendPack.tagMCActLunhuidianItem()
                     item.ItemID = itemID
                     item.ItemCount = itemCount
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 5ff46fc..2a84f19 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -37,29 +37,11 @@
 import ChItem
 import GameLogic_Tianzi
 import PlayerGoldInvest
-import PlayerActCollectWords
-import PlayerActTotalRecharge
-import PlayerActGodGift
-import PlayerActFamilyCTGAssist
-import PlayerActManyDayRecharge
-import PlayerActSingleRecharge
-import PlayerActGrowupBuy
 import PlayerActTurntable
-import PlayerActBuyOne
-import PlayerSpringSale
-import PlayerFeastLogin
-import PlayerFeastWish
 import PlayerActTask
-import PlayerActYunshi
-import PlayerActLunhuidian
 import PlayerActBuyCountGift
 import PlayerActLoginNew
-import PlayerActLogin
-import PlayerFlashGiftbag
-import PlayerDailyGiftbag
 import PlayerOfflineSupport
-import PlayerLuckyTreasure
-import PlayerFlashSale
 import PlayerWishingWell
 import PlayerTreasure
 import PlayerZhanling
@@ -904,93 +886,8 @@
                 PlayerControl.SetCoupleInfo(playerID, coupleInfo)
             return
         
-        if key.startswith(ShareDefine.Def_Notify_WorldKey_OperationActionInfo[:-2]): 
-            keyHead = ShareDefine.Def_Notify_WorldKey_OperationActionInfo[:-2]
-            actionName = key[len(keyHead):]
-            actInfo = eval(msgValue)
-            actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0)
-            if actionName in ShareDefine.MultiActNumOperationActNameList:
-                if not actNum:
-                    GameWorld.ErrLog('MultiActNumOperation can not found actNum. actionName=%s,msg = %s' % (actionName, msg))
-                    return
-                if actionName not in PyGameData.g_operationActionDict:
-                    PyGameData.g_operationActionDict[actionName] = {}
-                PyGameData.g_operationActionDict[actionName][actNum] = actInfo
-            else:
-                PyGameData.g_operationActionDict[actionName] = actInfo
-                
-            if actionName == ShareDefine.OperationActionName_ExpRate:
-                PlayerControl.RefreshOperationAction_ExpRate()
-                
-            elif actionName == ShareDefine.OperationActionName_TotalRecharge:
-                PlayerActTotalRecharge.RefreshTotalRechargeActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_GodGift:
-                PlayerActGodGift.RefreshGodGiftActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_ManyDayRecharge:
-                PlayerActManyDayRecharge.RefreshManyDayRechargeActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_SingleRecharge:
-                PlayerActSingleRecharge.RefreshSingleRechargeActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_Turntable:
-                PlayerActTurntable.RefreshTurntableActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_SpringSale:
-                PlayerSpringSale.RefreshSpringSaleActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_FlashGiftbag:
-                PlayerFlashGiftbag.RefreshFlashGiftbagActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_DailyGiftbag:
-                PlayerDailyGiftbag.RefreshDailyGiftbagActionInfo()
-                
-            elif actionName == ShareDefine.OperationActionName_BuyOne:
-                PlayerActBuyOne.RefreshBuyOneActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_FamilyCTGAssist:
-                PlayerActFamilyCTGAssist.RefreshFamilyCTGAssistActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_FlashSale:
-                PlayerFlashSale.RefreshflashSaleActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_WishingWell:
-                PlayerWishingWell.RefreshWishingWellAction()
-                
-            elif actionName == ShareDefine.OperationActionName_CollectWords:
-                PlayerActCollectWords.RefreshActCollectWordsInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_BuyCountGift:
-                PlayerActBuyCountGift.RefreshBuyCountGiftActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_ActTask:
-                PlayerActTask.RefreshActTaskActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_Yunshi:
-                PlayerActYunshi.RefreshActYunshiActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_Lunhuidian:
-                PlayerActLunhuidian.RefreshActLunhuidianActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_LoginAward:
-                PlayerActLogin.RefreshOperationAction_LoginAward()
-                
-            elif actionName == ShareDefine.OperationActionName_ActLoginNew:
-                PlayerActLoginNew.RefreshActLoginActionInfo(actNum)
-                
-            elif actionName == ShareDefine.OperationActionName_FeastLogin:
-                PlayerFeastLogin.RefreshFeastLoginActionInfo()
-                
-            elif actionName == ShareDefine.OperationActionName_FeastWish:
-                PlayerFeastWish.RefreshFeastWishActionInfo()
-                
-            elif actionName == ShareDefine.OperationActionName_LuckyTreasure:
-                PlayerLuckyTreasure.RefreshLuckyTreasureAction()
-                
-            elif actionName == ShareDefine.OperationActionName_GrowupBuy:
-                PlayerActGrowupBuy.RefreshGrowupBuyActionInfo()
-                
+        if key.startswith(ShareDefine.Def_Notify_WorldKey_OperationActionInfo[:-2]):
+            # 运营活动改为通过 GameWorldAction.OnMapOperationActionRefresh 触发刷新
             return
         
         if key.startswith(ShareDefine.Def_Notify_WorldKey_CrossActInfo[:-2]):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index c25a811..779b473 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -46,6 +46,7 @@
 Def_FamilyCrossState = 'FamilyCrossState' # 本服公会跨服状态, 0-未跨服;1-已跨服
 Def_FamilyTransDataTime = 'FamilyTransDataTime' # 本服公会首次跨服互通数据开始传输时间戳,不为0代表传输数据中
 Def_OSAAwardState = 'OSAAwardState' #开服冲榜活动结算状态
+Def_OperationActID = 'OperationActID_%s_%s' # 运营活动ID的标记,参数(运营活动名, actNum)
 
 #---奇迹, 职业枚举定义---
 (
@@ -198,6 +199,9 @@
 
 Def_Notify_WorldKey_CoupleInfo = "CoupleInfo"  # 伴侣信息
 
+Def_WorldKey_OperationActionState = "State_%s_%s"               #运营活动状态,参数为(运营活动名, actNum)
+Def_WorldKey_OperationActionStateJoin = "StateJoin_%s_%s"       #运营活动可参与状态,参数为(运营活动名, actNum)
+
 #活动类型定义
 ActTypeList = (
 ActType_OpenComm, # 开服及常规运营活动 1
@@ -206,6 +210,11 @@
 ) = range(1, 1 + 3)
 
 #运营活动表名定义
+OperationActionName_Lunhuidian = "ActLunhuidian" # 轮回殿活动
+
+#所有的运营活动列表,默认都支持多活动分组编号的活动名
+OperationActionNameList = [OperationActionName_Lunhuidian]
+
 OperationActionName_ExpRate = "ActExpRate" # 多倍经验活动
 OperationActionName_SpringSale = "ActSpringSale" # 限时特惠活动
 OperationActionName_FlashGiftbag = "ActFlashGiftbag" # 限时礼包活动
@@ -232,58 +241,44 @@
 OperationActionName_BuyCountGift = "ActBuyCountGift" # 购买次数礼包活动
 OperationActionName_FamilyCTGAssist = "ActFamilyCTGAssist" # 仙盟充值协助
 OperationActionName_Yunshi = "ActYunshi" # 运势活动
-OperationActionName_Lunhuidian = "ActLunhuidian" # 轮回殿活动
-#节日活动类型列表 - 该类型无视开服天,日期到了就开启
-FeastOperationActionNameList = [OperationActionName_GrowupBuy,
-                                OperationActionName_FeastLogin,
-                                OperationActionName_FeastWish,
-                                ]
-#所有的运营活动列表,含节日活动
-OperationActionNameList = [OperationActionName_ExpRate, 
-                           OperationActionName_SpringSale, 
-                           OperationActionName_FlashGiftbag, OperationActionName_FairyCeremony,
-                           OperationActionName_RealmPoint, OperationActionName_FlashSale,
-                           OperationActionName_WishingWell, OperationActionName_TotalRecharge,
-                           OperationActionName_LoginAward, 
-                           OperationActionName_NewFairyCeremony, OperationActionName_LuckyTreasure,
-                           OperationActionName_DailyGiftbag, OperationActionName_SingleRecharge,
-                           OperationActionName_CollectWords, OperationActionName_ManyDayRecharge,
-                           OperationActionName_Turntable,
-                           OperationActionName_GodGift,
-                           OperationActionName_BuyOne,
-                           OperationActionName_ActLoginNew, OperationActionName_ActTask,
-                           OperationActionName_BuyCountGift, OperationActionName_FamilyCTGAssist,
-                           OperationActionName_Yunshi,
-                           OperationActionName_Lunhuidian,
-                           ] + FeastOperationActionNameList
-#需要记录开启活动时的世界等级的运营活动
-NeedWorldLVOperationActNameList = [OperationActionName_FairyCeremony, OperationActionName_WishingWell, 
-                                   OperationActionName_NewFairyCeremony, OperationActionName_FlashSale,
-                                   OperationActionName_TotalRecharge,
-                                   OperationActionName_FlashGiftbag,
-                                   OperationActionName_SpringSale, OperationActionName_LuckyTreasure,
-                                   OperationActionName_DailyGiftbag, OperationActionName_GrowupBuy,
-                                   OperationActionName_Turntable,
-                                   OperationActionName_CollectWords,
-                                   OperationActionName_FeastLogin,
-                                   OperationActionName_FeastWish,
-                                   OperationActionName_ManyDayRecharge, OperationActionName_SingleRecharge,
-                                   OperationActionName_GodGift,
-                                   ]
 
-#支持多活动分组编号的活动名
-MultiActNumOperationActNameList = [OperationActionName_TotalRecharge, OperationActionName_CollectWords,
-                                   OperationActionName_FlashGiftbag,
-                                   OperationActionName_SpringSale, OperationActionName_FlashSale,
-                                   OperationActionName_ManyDayRecharge, OperationActionName_SingleRecharge,
-                                   OperationActionName_Turntable,
-                                   OperationActionName_GodGift,
-                                   OperationActionName_BuyOne,
-                                   OperationActionName_ActLoginNew, OperationActionName_ActTask,
-                                   OperationActionName_BuyCountGift, OperationActionName_FamilyCTGAssist,
-                                   OperationActionName_Yunshi,
-                                   OperationActionName_Lunhuidian,
-                                   ]
+##节日活动类型列表 - 该类型无视开服天,日期到了就开启
+#FeastOperationActionNameList = [OperationActionName_GrowupBuy,
+#                                OperationActionName_FeastLogin,
+#                                OperationActionName_FeastWish,
+#                                ]
+##所有的运营活动列表,含节日活动
+#OperationActionNameList = [OperationActionName_ExpRate, 
+#                           OperationActionName_SpringSale, 
+#                           OperationActionName_FlashGiftbag, OperationActionName_FairyCeremony,
+#                           OperationActionName_RealmPoint, OperationActionName_FlashSale,
+#                           OperationActionName_WishingWell, OperationActionName_TotalRecharge,
+#                           OperationActionName_LoginAward, 
+#                           OperationActionName_NewFairyCeremony, OperationActionName_LuckyTreasure,
+#                           OperationActionName_DailyGiftbag, OperationActionName_SingleRecharge,
+#                           OperationActionName_CollectWords, OperationActionName_ManyDayRecharge,
+#                           OperationActionName_Turntable,
+#                           OperationActionName_GodGift,
+#                           OperationActionName_BuyOne,
+#                           OperationActionName_ActLoginNew, OperationActionName_ActTask,
+#                           OperationActionName_BuyCountGift, OperationActionName_FamilyCTGAssist,
+#                           OperationActionName_Yunshi,
+#                           OperationActionName_Lunhuidian,
+#                           ] + FeastOperationActionNameList
+##需要记录开启活动时的世界等级的运营活动
+#NeedWorldLVOperationActNameList = [OperationActionName_FairyCeremony, OperationActionName_WishingWell, 
+#                                   OperationActionName_NewFairyCeremony, OperationActionName_FlashSale,
+#                                   OperationActionName_TotalRecharge,
+#                                   OperationActionName_FlashGiftbag,
+#                                   OperationActionName_SpringSale, OperationActionName_LuckyTreasure,
+#                                   OperationActionName_DailyGiftbag, OperationActionName_GrowupBuy,
+#                                   OperationActionName_Turntable,
+#                                   OperationActionName_CollectWords,
+#                                   OperationActionName_FeastLogin,
+#                                   OperationActionName_FeastWish,
+#                                   OperationActionName_ManyDayRecharge, OperationActionName_SingleRecharge,
+#                                   OperationActionName_GodGift,
+#                                   ]
 
 #跨服运营活动表名定义
 CrossActName_Lianqi = "CrossActLianqi" # 炼器 - 跨服

--
Gitblit v1.8.0