From d2e8880933fca8e8d8a8f0205bdd9ea95f4ec665 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 20 十二月 2023 15:58:14 +0800
Subject: [PATCH] 10024 【主干】【港台】【砍树】新增三种战令(增加战令类型4:古宝总星级)
---
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py | 826 +++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 528 insertions(+), 298 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
index 5608c72..f8a3320 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
@@ -33,10 +33,13 @@
import PlayerFamilyRedPacket
import PlayerFairyCeremony
import PlayerNewFairyCeremony
+import PlayerActGarbageSorting
+import PlayerActBossTrial
import PlayerUniversalGameRec
import GameWorldAverageLv
import PlayerFamilyBoss
import PlayerHorsePetBoss
+import CrossActionControl
import GameWorldProcess
import ChPyNetSendPack
import NetPackCommon
@@ -63,7 +66,10 @@
# 跨服不处理运营活动
return
- isReload, OperationActionInfo = __GetOperationActionInfo()
+ # 玩家登录的不触发重载活动,不然刚好在0点服务器处理OnDay之前登录的时候会有问题
+ isReload, OperationActionInfo = __GetOperationActionInfo(needReload=False)
+ if not OperationActionInfo:
+ return
operationActionDict = OperationActionInfo[OperationAction_TodayInfo]
if isReload:
@@ -106,6 +112,7 @@
if GameWorld.IsCrossServer():
# 跨服不处理运营活动
return
+ CrossActionControl.SendMapServerCrossActionState()
isReload, OperationActionInfo = __GetOperationActionInfo()
mapServerInfoDict = OperationActionInfo[OperationAction_MapServerInfo]
@@ -114,18 +121,79 @@
# 如果是重读的,则在内层已经同步了,此处不重复同步
return
- gameWorld = GameWorld.GetGameWorld()
for actName in ShareDefine.OperationActionNameList:
- dictName = ChConfig.Def_WorldKey_OperationActionState % actName
- state = gameWorld.GetDictByKey(dictName)
-
sendMapServerMsgDict = mapServerInfoDict.get(actName, {})
- sendMapServerMsgDict[ShareDefine.ActKey_State] = state
- GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_OperationActionInfo % actName, sendMapServerMsgDict)
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ for actNumMapMsgDict in sendMapServerMsgDict.values():
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_OperationActionInfo % actName, actNumMapMsgDict)
+ else:
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_OperationActionInfo % actName, sendMapServerMsgDict)
return
-def __GetOperationActionInfo(isRefreshState=True):
+def GetOperationActNum(actName, ipyData=None):
+ ''' 获取运营活动分组编号
+ 加入了分组编号概念,但由于有些活动配表还是旧规则配置,为了做规则兼容旧配表,减少配置表改动及代码改动这里做下自适应分配默认分组编号
+ 活动类型定义:
+ 1-默认(仅可配置开服天、日期、周循环W开头+数字,优先级 开服天 > 日期 > 周x)
+ 非开服配置的开服前X天不开,不受合服影响,功能配置表可配置前X天后交叉可开,每日重置的活动前X天后默认可开
+ 2-合服(仅可配置Mix开头+数字,如Mix1代表合服第1天,以此类推)
+ 3-节日(仅可配置日期,不受开服、合服影响)
+
+ 活动分组编号 = 活动类型 * 10 + 不同界面编号
+ '''
+ if ipyData and hasattr(ipyData, "ActNum"):
+ return ipyData.GetActNum()
+
+ # 原节日活动的还是默认节日活动
+ if actName in ShareDefine.FeastOperationActionNameList:
+ return ShareDefine.ActType_Feast * 10
+
+ # 其他默认常规,这里不考虑合服类型的了,新版本合服类型已独立出去,按 ipyData 配置
+ return ShareDefine.ActType_OpenComm * 10
+
+def GetOperationActType(actNum):
+ ## 运营活动类型
+ return actNum / 10
+
+def __SaveActWorldLVLimitInfo(actWorldLVLimitInfo):
+ GameWorld.GetUniversalRecMgr().Delete(ShareDefine.Def_UniversalGameRecType_ActWorldLVLimitInfo)
+ recDataList = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_ActWorldLVLimitInfo)
+ GameWorld.Log("保存运营活动世界等级限制开启信息: %s" % len(actWorldLVLimitInfo))
+ for actName, cfgLimitInfoDict in actWorldLVLimitInfo.items():
+ for cfgID, limitInfo in cfgLimitInfoDict.items():
+ recStartDateStr, recEndDateStr, recLimitWorldLV, recWorldLV = limitInfo
+ recData = recDataList.AddRec()
+ recData.SetStrValue1(recStartDateStr)
+ recData.SetStrValue2(recEndDateStr)
+ recData.SetStrValue3(actName)
+ recData.SetValue1(cfgID)
+ recData.SetValue2(recLimitWorldLV)
+ recData.SetValue3(recWorldLV)
+ GameWorld.Log(" actName=%s,cfgID=%s,recStartDateStr=%s,recEndDateStr=%s,recLimitWorldLV=%s,recWorldLV=%s"
+ % (actName, cfgID, recStartDateStr, recEndDateStr, recLimitWorldLV, recWorldLV))
+ return
+
+def __GetActWorldLVLimitInfo():
+ actWorldLVLimitInfo = {}
+ recDataList = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_ActWorldLVLimitInfo)
+ GameWorld.Log("加载运营活动世界等级限制开启信息: %s" % recDataList.Count())
+ for index in xrange(recDataList.Count()):
+ recData = recDataList.At(index)
+ recStartDateStr = recData.GetStrValue1()
+ recEndDateStr = recData.GetStrValue2()
+ actName = recData.GetStrValue3()
+ cfgID = recData.GetValue1()
+ recLimitWorldLV = recData.GetValue2()
+ recWorldLV = recData.GetValue3()
+ if actName not in actWorldLVLimitInfo:
+ actWorldLVLimitInfo[actName] = {}
+ actWorldLVLimitInfo[actName][cfgID] = [recStartDateStr, recEndDateStr, recLimitWorldLV, recWorldLV]
+ GameWorld.Log(" actName=%s,cfgID=%s,recStartDateStr=%s,recEndDateStr=%s,recLimitWorldLV=%s,recWorldLV=%s"
+ % (actName, cfgID, recStartDateStr, recEndDateStr, recLimitWorldLV, recWorldLV))
+ return actWorldLVLimitInfo
+
+def __GetOperationActionInfo(isRefreshState=True, needReload=True):
# @return: isReload, OperationActionInfo
key = "OperationActionInfo"
@@ -141,6 +209,9 @@
#GameWorld.DebugLog("已经加载过本日运营活动处理信息!openServerDay=%s" % openServerDay)
return False, OperationActionInfo
+ if not needReload:
+ 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)
@@ -148,63 +219,137 @@
startDateInCustomCanOpenList = IpyGameDataPY.GetFuncEvalCfg("OperationAction", 2) # 开始天在定制天内在定制天结束后可继续开启的活动列表
customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) # 定制运营活动最大开服天
maxCustomServerDayMix = IpyGameDataPY.GetFuncCfg("MixServer", 1) # 定制运营活动最大合服天
- operationActionDict = {}
+ operationTodayActionDict = {}
mapServerOperationActionDict = {}
+ platform = GameWorld.GetPlatform()
serverGroupID = GameWorld.GetServerGroupID()
ipyDataMgr = IpyGameDataPY.IPY_Data()
curWeekday = curDateTime.weekday() + 1 # 今天星期几, 1代表星期1
+ curWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
+ actWorldLVLimitInfoOld = __GetActWorldLVLimitInfo()
+ actWorldLVLimitInfoNew = {}
GameWorld.Log("===== 加载本日运营活动信息: %s, serverGroupID=%s,openServerDay=%s,customMaxServerDay=%s,isMixServer=%s,mixServerDay=%s,maxCustomServerDayMix=%s,reloadSign=%s ====="
% (curDateTime, serverGroupID, openServerDay, customMaxServerDay, isMixServer, mixServerDay, maxCustomServerDayMix, reloadSign))
- GameWorld.Log(" 今日周%s" % (curWeekday))
+ GameWorld.Log(" 今日周%s, curWorldLV=%s" % (curWeekday, curWorldLV))
for actName in ShareDefine.OperationActionNameList:
+ if actName not in mapServerOperationActionDict:
+ mapServerOperationActionDict[actName] = {}
+
# 取出本活动所属本服ID的所有配置
- GameWorld.Log("加载运营活动: actName=%s" % (actName))
- curServerActIpyDataList = __GetOperationActionServerIpyDataList(ipyDataMgr, serverGroupID, actName)
+ GameWorld.Log("加载运营活动: actName=%s,platform=%s,serverGroupID=%s" % (actName, platform, serverGroupID))
+ curServerActIpyDataList = __GetOperationActionServerIpyDataList(ipyDataMgr, platform, serverGroupID, actName)
GameWorld.Log(" 可处理条数=%s" % (len(curServerActIpyDataList)))
- disableWeekIpyDataInfo, customOpenServerDayState, customMixServerDayState = __GetOperationActionDisableWeekIpyDataInfo(actName, curDateTime, curServerActIpyDataList)
- GameWorld.Log(" 是否有配开服天活动=%s, 是否有配合服天活动=%s" % (customOpenServerDayState, customMixServerDayState))
- needStartList = [] # [startDateTime, ...]
- needEndList = [] # [endDateTime, ...]
- needNotifyDict = {} # {notifyDateTime:[notifyKey, [参数]], ...}
- activityIpyData = None # 活动中的的配置,取需要处理的配置中开始时间最晚的,反之开关时间头尾相连的时候无法开启后面的活动
- # 注意:每个活动配置会有多个活动时间点,但是有且只能生效一条活动配置,换句话说就是每个活动配置时间不允许交叉
+ actNumDisableWeekIpyDataInfo, disableWeekCfgIDDict = __GetOperationActionDisableWeekIpyDataInfo(actName, curDateTime, curServerActIpyDataList)
+
for ipyData in curServerActIpyDataList:
+ platformList = [] if not hasattr(ipyData, "PlatformList") else ipyData.GetPlatformList()
serverGroupIDList = [] if not hasattr(ipyData, "ServerGroupIDList") else ipyData.GetServerGroupIDList()
serverGroupIDListExcept = [] if not hasattr(ipyData, "ServerGroupIDListExcept") else ipyData.GetServerGroupIDListExcept()
cfgID = ipyData.GetCfgID()
startDateStr = ipyData.GetStartDate()
endDateStr = ipyData.GetEndDate()
- GameWorld.Log(" cfgID=%s,serverGroupIDList=%s,Except=%s,startDateStr=%s,endDateStr=%s,openServerDay=%s,isMixServer=%s,mixServerDay=%s,maxCustomServerDayMix=%s,curDateTime=%s"
- % (cfgID, serverGroupIDList, serverGroupIDListExcept, startDateStr, endDateStr, openServerDay, isMixServer, mixServerDay, maxCustomServerDayMix, curDateTime))
- if cfgID in disableWeekIpyDataInfo:
- startWeekDate, endWeekDate, ymdCfgID, ymdStartDate, ymdEndDate = disableWeekIpyDataInfo[cfgID]
- GameWorld.Log(" 按星期开启的在按日期开启的时间内,不处理! cfgID=%s,%s(%s) ~ %s(%s) in ymdCfgID=%s,%s ~ %s"
- % (cfgID, startWeekDate, startDateStr, endWeekDate, endDateStr, ymdCfgID, ymdStartDate, ymdEndDate))
- continue
+ actNum = GetOperationActNum(actName, ipyData)
+ actType = GetOperationActType(actNum)
+ GameWorld.Log(" cfgID=%s,actNum=%s,startDateStr=%s,endDateStr=%s,openServerDay=%s,isMixServer=%s,mixServerDay=%s,curDateTime=%s,platformList=%s,serverGroupIDList=%s,Except=%s"
+ % (cfgID, actNum, startDateStr, endDateStr, openServerDay, isMixServer, mixServerDay, curDateTime, platformList, serverGroupIDList, serverGroupIDListExcept))
+
+ actIDDateTimeSpec = None # 特殊指定的活动ID日期
+ startDateSync = None # 特殊同步前端显示用的开始日期,一般用于与开服前X天交叉的活动
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ # 多活动分组编号的需要把所有配置的 actNum 都登记进来,以确保地图能正确进行逻辑
+ if actNum not in mapServerOperationActionDict[actName]:
+ mapServerOperationActionDict[actName][actNum] = {ShareDefine.ActKey_ActNum:actNum}
+
+ curActTodayInfo = operationTodayActionDict.get(actName, {}).get(actNum)
+ else:
+ curActTodayInfo = operationTodayActionDict.get(actName)
+
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)
- # 活动优先级为 开服天=合服天>运营日期>运营周天
- # 按开服天开的
- 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))
+
+ # 开服常规: 开服天 > 日期 > 周x (不受合服天影响,合服活动新增一套独立的活动,还是走运营活动配置)
+ if actType == ShareDefine.ActType_OpenComm:
+ actByWeek = (startDateStr.startswith("W") and endDateStr.startswith("W")) # 按周x开
+ actByDate = (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))
+
+ # 常规配置: 开服前X天不开,不受合服影响,功能配置表可配置 开服前X天后交叉可开,每日重置的活动默认可开
+ elif actByWeek or actByDate:
+ if openServerDay <= customMaxServerDay:
+ GameWorld.Log(" 按日期/周开的在开服定制限制天内,不处理! cfgID=%s,%s ~ %s,openServerDay=%s" % (cfgID, startDateStr, endDateStr, openServerDay))
+ continue
+
+ disableWeekIpyDataInfo = actNumDisableWeekIpyDataInfo.get(actNum, {})
+ if cfgID in disableWeekIpyDataInfo:
+ startWeekDate, endWeekDate, ymdCfgID, ymdStartDate, ymdEndDate = disableWeekIpyDataInfo[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, 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=(customMaxServerDay - 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
- 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))
- elif startDateStr.startswith("Mix") and endDateStr.startswith("Mix"):
+
+ # 合服活动: 只受合服天影响
+ 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
@@ -213,47 +358,22 @@
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))
+ 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:
- if startDateStr.startswith("W") and endDateStr.startswith("W"):
- startWeekday = int(startDateStr[1:])
- endWeekday = int(endDateStr[1:])
- startWeekDate = curDateTime + datetime.timedelta(days=(startWeekday-curWeekday))
- endWeekDate = curDateTime + datetime.timedelta(days=(endWeekday-curWeekday))
- startDateStr = "%d-%d-%d" % (startWeekDate.year, startWeekDate.month, startWeekDate.day)
- endDateStr = "%d-%d-%d" % (endWeekDate.year, endWeekDate.month, endWeekDate.day)
- GameWorld.Log(" 星期X转化为日期: %s ~ %s" % (startDateStr, endDateStr))
-
- if actName not in ShareDefine.FeastOperationActionNameList:
- if customOpenServerDayState and openServerDay <= customMaxServerDay:
- GameWorld.Log(" 按日期/周开的在开服定制限制天内,不处理! cfgID=%s,%s ~ %s,openServerDay=%s" % (cfgID, startDateStr, endDateStr, openServerDay))
- continue
- curServerOpenDateTime = curDateTime + datetime.timedelta(days=(1-openServerDay)) # 开服第一天的日期
- 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 customOpenServerDayState and curServerOpenDateTime <= curStartDateTime <= customMaxServerDateTime:
- if actName not in startDateInCustomCanOpenList:
- GameWorld.Log(" 按日期/周开的开始日期在开服定制限制天内,不处理! cfgID=%s,curServerOpenDateTime=%s<=curStartDateTime=%s<=customMaxServerDateTime=%s" % (cfgID, curServerOpenDateTime, curStartDateTime, customMaxServerDateTime))
- continue
-
- if isMixServer:
- if customMixServerDayState and mixServerDay <= maxCustomServerDayMix:
- GameWorld.Log(" 按日期/周开的在合服定制限制天内,不处理! cfgID=%s,%s ~ %s,mixServerDay=%s" % (cfgID, startDateStr, endDateStr, mixServerDay))
- continue
- mixStartServerDateTime = curDateTime + datetime.timedelta(days=(1-mixServerDay)) # 合服第一天的日期
- customMaxServerDateTime = curDateTime + datetime.timedelta(days=(maxCustomServerDayMix-mixServerDay))
- curStartDateTime = datetime.datetime.strptime("%s %02d:%02d:%02d" % (startDateStr, customMaxServerDateTime.hour, customMaxServerDateTime.minute,
- customMaxServerDateTime.second), ChConfig.TYPE_Time_Format)
- if customMixServerDayState and mixStartServerDateTime <= curStartDateTime <= customMaxServerDateTime:
- if actName not in startDateInCustomCanOpenList:
- GameWorld.Log(" 按日期/周开的开始日期在合服定制限制天内,不处理! cfgID=%s,mixStartServerDateTime=%s<=curStartDateTime=%s<=customMaxServerDateTime=%s" % (cfgID, mixStartServerDateTime, curStartDateTime, customMaxServerDateTime))
- continue
-
+ GameWorld.Log(" 非法配置,未知活动类型,不处理! cfgID=%s,actNum=%s" % (cfgID, actNum))
+ continue
+
if hasattr(ipyData, "GetStartTimeList") and hasattr(ipyData, "GetEndTimeList"):
startHMStrList = ipyData.GetStartTimeList()
endHMStrList = ipyData.GetEndTimeList()
@@ -284,58 +404,98 @@
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
+
+ # 在需要处理的时间内附加世界等级开启限制,未达到最低世界等级要求的不开,活动时间从未达到到达到也不开
+ limitWorldLV = 0 if not hasattr(ipyData, "GetLimitWorldLV") else ipyData.GetLimitWorldLV() # 限制开启世界等级
+ if limitWorldLV:
+ GameWorld.Log(" limitWorldLV=%s,curWorldLV=%s" % (limitWorldLV, curWorldLV))
+ recInfoType = ""
+ worldLVLimitInfo = actWorldLVLimitInfoOld.get(actName, {})
+ # 注: 该逻辑是在活动时间内的额外处理,所以需要判断此逻辑的前提理论上都在活动时间内,故只要有记录则以当时的记录为准
+ if cfgID in worldLVLimitInfo:
+ recInfoType = "Old"
+ recStartDateStr, recEndDateStr, recLimitWorldLV, recWorldLV = worldLVLimitInfo[cfgID]
+ else:
+ recInfoType = "New"
+ recStartDateStr, recEndDateStr, recLimitWorldLV, recWorldLV = startDateStr, endDateStr, limitWorldLV, curWorldLV
+
+ if actName not in actWorldLVLimitInfoNew:
+ actWorldLVLimitInfoNew[actName] = {}
+ actWorldLVLimitInfoNew[actName][cfgID] = [recStartDateStr, recEndDateStr, recLimitWorldLV, recWorldLV]
+
+ if recLimitWorldLV > recWorldLV:
+ GameWorld.Log(" 活动时间内,但服务器世界等级未达到开启活动世界等级,不处理!recLimitWorldLV=%s > recWorldLV=%s %s"
+ % (recLimitWorldLV, recWorldLV, recInfoType))
+ continue
+
startList = [] # [startDateTime, ...]
endList = [] # [endDateTime, ...]
startNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
endNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
loopNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
- isActivity = False # 有需要处理开关时间的(开始、结束)
+ notifyDict = {}
+
+ isActTime = (startDayDate <= curDateTime < endDayDate)
+ isEnd = (curDateTime == endDayDate)
isNotify = False
isAdvanceNotice = False
- isEnd = False
+
# 没配置时分的代表全天, 只要开始或结束时分没配都算
if not startHMStrList or not endHMStrList:
startDateTime = startDayDate
endDateTime = endDayDate
startList.append(startDateTime)
endList.append(endDateTime)
- # 同一个活动类型是不允许时间上配置有重叠的,所以一个活动类型满足活动中的时间的有且仅有一条配置
- # 策划可能同时配置多个时间,但是活动中的有且仅有一条配置
- if startDayDate <= curDateTime <= endDayDate:
- needStartList.append(startDateTime)
- needEndList.append(endDateTime)
- isActivity = True
- isEnd = (curDateTime == endDayDate)
-
+
# 每天按时段开启的,支持多时段
- elif startDayDate <= curDateTime <= endDayDate:
- isEnd = (curDateTime == endDayDate)
- if not isEnd:
- 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)
-
- needStartList.append(startDateTime)
- needEndList.append(endDateTime)
- isActivity = True
-
- if advanceMinutes and startDayDate:
- advanceNoticeDateTime = startDayDate + datetime.timedelta(minutes=-advanceMinutes)
+ 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))
- GameWorld.Log(" needStartList=%s" % (needStartList))
- GameWorld.Log(" need EndList=%s" % (needEndList))
for dtIndex, startDateTime in enumerate(startList):
endDateTime = endList[dtIndex]
@@ -361,7 +521,7 @@
loopCount, loopMaxCount = 0, 100
while loopMinutes and loopNotifyKey and loopCount < loopMaxCount:
loopCount += 1
- notifyDateTime = startDateTime + datetime.timedelta(minutes=loopMinutes*loopCount)
+ 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:
@@ -372,50 +532,55 @@
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()))
- needNotifyDict.update(startNotifyDict)
- needNotifyDict.update(endNotifyDict)
- needNotifyDict.update(loopNotifyDict)
+ notifyDict.update(startNotifyDict)
+ notifyDict.update(endNotifyDict)
+ notifyDict.update(loopNotifyDict)
- if not isActivity and not isNotify and not isAdvanceNotice:
- continue
+ GameWorld.Log(" 需要处理的运营活动信息: cfgID=%s,isActTime=%s,isEnd=%s,isNotify=%s,isAdvanceNotice=%s" % (cfgID, isActTime, isEnd, isNotify, isAdvanceNotice))
- 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 (isActivity and not isEnd):
- activityIpyData = ipyData
- activityInfoDict = {ShareDefine.ActKey_CfgID:cfgID}
- if actName == ShareDefine.OperationActionName_LoginAward:
- #活动每天的世界等级
- activityInfoDict[ShareDefine.ActKey_WorldLVList] = GameWorldAverageLv.GetWorldLVListByTime(startDayDate, (endDayDate - startDayDate).days)
+ # 兼容新旧运营活动逻辑处理数据
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ if actName not in operationTodayActionDict:
+ operationTodayActionDict[actName] = {} # 今日有需要处理的才初始化
+ operationTodayActionDict[actName][actNum] = [ipyData, startList, endList, notifyDict]
+ else:
+ operationTodayActionDict[actName] = [ipyData, startList, endList, notifyDict]
+
+ 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 startDayDate <= curDateTime < endDayDate:
- dayIndex = 0
- actIDDateTime = startDayDate
- isDayRest = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
- # 按时段开的默认每天重置
- if isDayRest or (startHMStrList and endHMStrList):
- dayIndex = (curDateTime - startDayDate).days
- actIDDateTime += datetime.timedelta(days=dayIndex)
- actID = int(time.mktime(actIDDateTime.timetuple())) # 默认取开始时间点的time值作为活动ID
- activityInfoDict[ShareDefine.ActKey_DayIndex] = dayIndex
- activityInfoDict[ShareDefine.ActKey_ID] = actID
- GameWorld.Log(" isDayRest=%s,actIDDateTime=%s,actID=%s" % (isDayRest, actIDDateTime, actID))
-
- needStartList.sort()
- needEndList.sort()
+ if startDateSync:
+ activityInfoDict[ShareDefine.ActKey_StartDateSync] = startDateSync
+ GameWorld.Log(" startDateSync=%s" % (startDateSync))
+ dayIndex = (curDateTime - startDayDate).days
+ actIDDateTime = startDayDate
+ isDayRest = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
+ # 按时段开的默认每天重置
+ if isDayRest or (startHMStrList and endHMStrList):
+ actIDDateTime += datetime.timedelta(days=dayIndex)
+ if actIDDateTimeSpec:
+ actIDDateTime = actIDDateTimeSpec
+ actID = int(time.mktime(actIDDateTime.timetuple())) # 默认取开始时间点的time值作为活动ID
+ activityInfoDict[ShareDefine.ActKey_DayIndex] = dayIndex
+ activityInfoDict[ShareDefine.ActKey_ID] = actID
+ GameWorld.Log(" isDayRest=%s,actIDDateTime=%s,actID=%s" % (isDayRest, actIDDateTime, actID))
+ GameWorld.Log(" activityInfoDict=%s" % (activityInfoDict))
+
+ # 兼容新旧运营活动逻辑处理数据
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ mapServerOperationActionDict[actName][actNum] = activityInfoDict
+ else:
mapServerOperationActionDict[actName] = activityInfoDict
- GameWorld.Log(" activityInfoDict=%s" % (activityInfoDict))
- if activityIpyData or needStartList or needEndList or needNotifyDict:
- # activityIpyData 可能为None
- operationActionDict[actName] = [activityIpyData, needStartList, needEndList, needNotifyDict]
-
- OperationActionInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, operationActionDict, mapServerOperationActionDict])
+ OperationActionInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, operationTodayActionDict, mapServerOperationActionDict])
+ __SaveActWorldLVLimitInfo(actWorldLVLimitInfoNew)
GameWorld.Log("本日运营活动信息加载完毕!reloadSign=%s,isRefreshState=%s" % (reloadSign, isRefreshState))
- GameWorld.Log(" operationActionDict=%s" % operationActionDict)
+ GameWorld.Log(" operationTodayActionDict=%s" % operationTodayActionDict)
GameWorld.Log(" mapServerOperationActionDict=%s" % mapServerOperationActionDict)
GameWorld.Log("=============================================================")
if isRefreshState:
@@ -423,7 +588,7 @@
return True, OperationActionInfo
-def __GetOperationActionServerIpyDataList(ipyDataMgr, serverGroupID, actName):
+def __GetOperationActionServerIpyDataList(ipyDataMgr, platform, serverGroupID, actName):
## 获取运营活动本服务器对应的配置数据列表
if not hasattr(ipyDataMgr, "Get%sCount" % actName):
@@ -434,8 +599,12 @@
actCfgCount = getattr(ipyDataMgr, "Get%sCount" % actName)()
for cfgIndex in xrange(actCfgCount):
ipyData = getattr(ipyDataMgr, "Get%sByIndex" % actName)(cfgIndex)
+ platformList = [] if not hasattr(ipyData, "PlatformList") else ipyData.GetPlatformList()
serverGroupIDList = [] if not hasattr(ipyData, "ServerGroupIDList") else ipyData.GetServerGroupIDList()
serverGroupIDListExcept = [] if not hasattr(ipyData, "ServerGroupIDListExcept") else ipyData.GetServerGroupIDListExcept()
+
+ if platformList and platform not in platformList:
+ continue
# 排除的服务器组ID列表
if serverGroupIDListExcept:
@@ -463,55 +632,74 @@
def __GetOperationActionDisableWeekIpyDataInfo(actName, curDateTime, curServerActIpyDataList):
## 获取不可用的按星期X开启的配置数据信息,按星期X开启的 活动优先级小于按日期的,当有重叠时以日期的为准
- disableWeekIpyDataInfo = {}
- curWeekday = curDateTime.weekday() + 1 # 今天星期几, 1代表星期1
- customOpenServerDayState, customMixServerDayState = False, False # 是否有配开服天、合服天活动
- weekIpyDataList, ymdIpyDatList = [], []
+ #curWeekday = curDateTime.weekday() + 1 # 今天星期几, 1代表星期1
+ actNumWeekYMDIpyDataInfo = {} # {actNum:[weekIpyDataList, ymdIpyDatList], ...}
+ disableWeekCfgIDDict = {} # {cfgID:[startDateStr, endDateStr], ...}
+
+ curDateTimeYmdStr = "%d-%d-%d" % (curDateTime.year, curDateTime.month, curDateTime.day)
+ curDateTimeYmd = GameWorld.ChangeStrToDatetime(curDateTimeYmdStr, ChConfig.TYPE_Time_YmdFormat)
+
for ipyData in curServerActIpyDataList:
+ cfgID = ipyData.GetCfgID()
startDateStr = ipyData.GetStartDate()
endDateStr = ipyData.GetEndDate()
- if startDateStr.isdigit() or startDateStr.startswith("Mix"):
- # 开服天、合服天的不处理
- if startDateStr.isdigit():
- customOpenServerDayState = True
- else:
- customMixServerDayState = True
+ actNum = GetOperationActNum(actName, ipyData)
+ actType = GetOperationActType(actNum)
+ # 这里只处理常规运营活动,日期优先级大于周
+ if actType != ShareDefine.ActType_OpenComm:
continue
+
+ if actNum not in actNumWeekYMDIpyDataInfo:
+ weekIpyDataList, ymdIpyDatList = [], []
+ actNumWeekYMDIpyDataInfo[actNum] = [weekIpyDataList, ymdIpyDatList]
+ weekIpyDataList, ymdIpyDatList = actNumWeekYMDIpyDataInfo[actNum]
# 按星期X的
if startDateStr.startswith("W"):
- startWeekday = int(startDateStr[1:])
- endWeekday = int(endDateStr[1:])
- startWeekDate = curDateTime + datetime.timedelta(days=(startWeekday-curWeekday))
- endWeekDate = curDateTime + datetime.timedelta(days=(endWeekday-curWeekday))
- weekIpyDataList.append([ipyData, startWeekDate, endWeekDate])
+ startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
+ startWeekDate = GameWorld.ChangeStrToDatetime(startDateStr, ChConfig.TYPE_Time_YmdFormat)
+ endWeekDate = GameWorld.ChangeStrToDatetime(endDateStr, ChConfig.TYPE_Time_YmdFormat)
+ if startWeekDate > curDateTimeYmd or curDateTimeYmd > endWeekDate: # 还未开始的循环 or 已经强制结束的循环
+ disableWeekCfgIDDict[cfgID] = [startDateStr, endDateStr]
+ else:
+ weekIpyDataList.append([ipyData, startWeekDate, endWeekDate])
+
# 按日期的
- else:
+ elif startDateStr.count("-") == 2:
ymdIpyData = ipyData
ymdStartDate = datetime.datetime.strptime("%s %02d:%02d:00" % (startDateStr, curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)
ymdEndDate = datetime.datetime.strptime("%s %02d:%02d:00" % (endDateStr, curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)
ymdIpyDatList.append([ymdIpyData, ymdStartDate, ymdEndDate])
- for ipyData, startWeekDate, endWeekDate in weekIpyDataList:
- cfgID = ipyData.GetCfgID()
- for ymdIpyData, ymdStartDate, ymdEndDate in ymdIpyDatList:
- if ymdStartDate <= startWeekDate <= ymdEndDate or ymdStartDate <= endWeekDate <= ymdEndDate \
- or (actName in ShareDefine.FeastOperationActionNameList and ymdStartDate <= curDateTime <= ymdEndDate):
- ymdCfgID = ymdIpyData.GetCfgID()
- disableWeekIpyDataInfo[cfgID] = [startWeekDate, endWeekDate, ymdCfgID, ymdStartDate, ymdEndDate]
-
- return disableWeekIpyDataInfo, customOpenServerDayState, customMixServerDayState
+ else:
+ # 只处理按星期、按日期的,其他的不处理
+ pass
+
+ actNumDisableWeekIpyDataInfo = {} # {actNum:{cfgID:[info], ...}, ...}
+ for actNum, weekYMDIpyDataInfo in actNumWeekYMDIpyDataInfo.items():
+ weekIpyDataList, ymdIpyDatList = weekYMDIpyDataInfo
+ for ipyData, startWeekDate, endWeekDate in weekIpyDataList:
+ cfgID = ipyData.GetCfgID()
+ for ymdIpyData, ymdStartDate, ymdEndDate in ymdIpyDatList:
+ if ymdStartDate <= startWeekDate <= ymdEndDate or ymdStartDate <= endWeekDate <= ymdEndDate:
+ if actNum not in actNumDisableWeekIpyDataInfo:
+ actNumDisableWeekIpyDataInfo[actNum] = {}
+ ymdCfgID = ymdIpyData.GetCfgID()
+ actNumDisableWeekIpyDataInfo[actNum][cfgID] = [startWeekDate, endWeekDate, ymdCfgID, ymdStartDate, ymdEndDate]
+
+ return actNumDisableWeekIpyDataInfo, disableWeekCfgIDDict
def Dispose_OperationActionState(reloadRefresh=False):
# 运营活动状态处理, 每天0点会强制同步当天的运营活动详情到地图服务器
if GameWorld.IsCrossServer():
# 跨服不处理运营活动
+ CrossActionControl.Dispose_CrossActState(reloadRefresh)
return
isReload, OperationActionInfo = __GetOperationActionInfo(False) # 这里必须传False
isReload = isReload or reloadRefresh
- operationActionDict = OperationActionInfo[OperationAction_TodayInfo]
+ operationTodayActionDict = OperationActionInfo[OperationAction_TodayInfo]
mapServerInfoDict = OperationActionInfo[OperationAction_MapServerInfo]
gameWorld = GameWorld.GetGameWorld()
@@ -521,138 +709,164 @@
curDateTime = datetime.datetime.strptime("%d-%d-%d %d:%d:00" % (curDateTime.year, curDateTime.month, curDateTime.day,
curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)
- startDateInCustomCanOpenList = IpyGameDataPY.GetFuncEvalCfg("OperationAction", 2) # 开始天在定制天内在定制天结束后可继续开启的活动列表
-
for actName in ShareDefine.OperationActionNameList:
- state = 0 # 默认关闭
- ipyData = None
+ if actName not in mapServerInfoDict:
+ continue
- if actName in operationActionDict:
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ curActMapInfoDictList = mapServerInfoDict[actName].values()
+ else:
+ curActMapInfoDictList = [mapServerInfoDict[actName]]
- #startList = [] # [startDateTime, ...]
- #endList = [] # [endDateTime, ...]
- #notifyDict = {} # {notifyDateTime:[notifyKey, [参数]], ...}
- #ipyData 可能为 None
- ipyData, startList, endList, notifyDict = operationActionDict[actName]
+ for sendMapServerMsgDict in curActMapInfoDictList:
- if actName in startDateInCustomCanOpenList:
- # 由于某些活动的开始天允许和前定制X天有交叉的情况出现(实际不开,会等定制结束后才接下去开)
- # 所以会有时间交叉的情况出现,这种活动goon单独判断
- # 为防止动到其他活动,允许交叉的活动另外处理,理论上可以统一逻辑,为保险起见分开处理
-
- # 精确匹配开启
- if curDateTime in startList:
- state = startList.index(curDateTime) + 1 # 也是代表第几个时间段
- # 精确匹配关闭
- elif curDateTime in endList:
- state = 0
-
- # goon 状态
- for dIndex, startDateTime in enumerate(startList):
- endDateTime = endList[dIndex]
- if startDateTime < curDateTime < endDateTime:
- state = dIndex + 1
- break
-
- else:
- # 精确匹配开启
- if curDateTime in startList:
- state = startList.index(curDateTime) + 1 # 也是代表第几个时间段
- # 精确匹配关闭
- elif curDateTime in endList:
- state = 0
- # goon 状态
+ state = 0 # 默认关闭
+ ipyData = None
+
+ actNum = sendMapServerMsgDict.get(ShareDefine.ActKey_ActNum, 0)
+
+ if actName in operationTodayActionDict:
+ todayActInfoList = []
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ if actNum in operationTodayActionDict[actName]:
+ todayActInfoList = operationTodayActionDict[actName][actNum]
else:
+ todayActInfoList = operationTodayActionDict[actName]
+
+ if isinstance(todayActInfoList, list) and len(todayActInfoList) == 4:
+ #startList = [] # [startDateTime, ...]
+ #endList = [] # [endDateTime, ...]
+ #notifyDict = {} # {notifyDateTime:[notifyKey, [参数]], ...}
+ #ipyData 可能为 None
+ ipyData, startList, endList, notifyDict = todayActInfoList
+
+ # 状态
for dIndex, startDateTime in enumerate(startList):
endDateTime = endList[dIndex]
- if startDateTime < curDateTime < endDateTime:
- state = dIndex + 1
+ if startDateTime <= curDateTime < endDateTime:
+ state = dIndex + 1 # 代表第几个时间段
break
+
+ # 全服广播提示信息
+ if curDateTime in notifyDict:
+ notifyKey, paramList = notifyDict[curDateTime]
+ PlayerControl.WorldNotify(0, notifyKey, paramList)
+
+ dictName = ChConfig.Def_WorldKey_OperationActionState % actName
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ dictName += "_%s" % actNum
+ preState = gameWorld.GetDictByKey(dictName)
+ if not isReload and preState == state:
+ #已经是这个状态了
+ continue
+ GameWorld.Log("运营活动变更: actName=%s,actNum=%s,preState=%s,state=%s,dictName=%s" % (actName, actNum, preState, state, dictName))
+ #更新字典值
+ gameWorld.SetDict(dictName, state)
+
+ dbOperationActIDKey = PlayerDBGSEvent.Def_OperationActID % actName
+ dbOperationActWorldLVKey = PlayerDBGSEvent.Def_OActWorldLV % actName
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ dbOperationActIDKey += "_%s" % actNum
+ dbOperationActWorldLVKey += "_%s" % actNum
+
+ dbActID = PlayerDBGSEvent.GetDBGSTrig_ByKey(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))
+ PlayerDBGSEvent.SetDBGSTrig_ByKey(dbOperationActIDKey, curActID)
+
+ # 结束旧的
+ if dbActID:
+ if actName == ShareDefine.OperationActionName_BossTrial:
+ PlayerActBossTrial.OnActEnd(actNum, ipyData, dayIndex)
+
+ if curActID:
+ if actName in ShareDefine.NeedWorldLVOperationActNameList:
+ #记录开启时世界等级
+ worldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
+ PlayerDBGSEvent.SetDBGSTrig_ByKey(dbOperationActWorldLVKey, worldLV)
+ GameWorld.Log(" 记录活动开启时世界等级: worldLV=%s" % (worldLV))
+
+ #此处为活动开启时
+ if actName == ShareDefine.OperationActionName_BossReborn:
+ #重置BOSS复活点
+ GameWorldBoss.ResetBossRebornPoint()
+ 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)
+ elif actName == ShareDefine.OperationActionName_GarbageSorting:
+ PlayerActGarbageSorting.OnActStart(actNum)
+ elif actName == ShareDefine.OperationActionName_BossTrial:
+ PlayerActBossTrial.OnActStart(actNum)
+ else:
+ if actName == ShareDefine.OperationActionName_GarbageSorting:
+ PlayerActGarbageSorting.OnActEnd(actNum)
+
+ else:
+ GameWorld.Log(" dbActID不变: dbActID=%s,curActID=%s" % (dbActID, curActID))
+
+ if ipyData and actName in ShareDefine.NeedWorldLVOperationActNameList:
+ actWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(dbOperationActWorldLVKey)
+ sendMapServerMsgDict[ShareDefine.ActKey_WorldLV] = actWorldLV
+ GameWorld.Log(" 活动世界等级: actWorldLV=%s" % (actWorldLV))
+
+ if actName == ShareDefine.OperationActionName_ExpRate:
+ if isReload and ipyData:
+ Sync_OperationAction_ExpRate(ipyData)
- # 全服广播提示信息
- if curDateTime in notifyDict:
- notifyKey, paramList = notifyDict[curDateTime]
- PlayerControl.WorldNotify(0, notifyKey, paramList)
-
- dictName = ChConfig.Def_WorldKey_OperationActionState % actName
- preState = gameWorld.GetDictByKey(dictName)
- if not isReload and preState == state:
- #已经是这个状态了
- continue
- #更新字典值
- gameWorld.SetDict(dictName, state)
- sendMapServerMsgDict = mapServerInfoDict.get(actName, {})
-
- dbOperationActIDKey = PlayerDBGSEvent.Def_OperationActID % actName
- curActID = sendMapServerMsgDict.get(ShareDefine.ActKey_ID)
- 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:
- #记录开启时世界等级
- worldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
- PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_OActWorldLV % actName, worldLV)
-
- #此处为活动开启时
- if actName == ShareDefine.OperationActionName_BossReborn:
- #重置BOSS复活点
- GameWorldBoss.ResetBossRebornPoint()
+ elif actName == ShareDefine.OperationActionName_BossReborn:
+ if isReload and ipyData:
+ GameWorldBoss.SetBossRebornNeedPoint(True)
+
+ elif actName == ShareDefine.OperationActionName_HorsePetFeast:
+ if preState != state and state:
+ relatedID = "%s|%s" % (actName, actNum)
+ GameWorld.Log(" 骑宠盛宴开始: relatedID=%s" % (relatedID))
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ActionBossRebornSign % relatedID, int(time.time()))
+
elif actName == ShareDefine.OperationActionName_FairyCeremony:
- #重置仙界盛典
- PlayerFairyCeremony.ResetFairyCeremony()
+ if isReload and ipyData:
+ PlayerFairyCeremony.Sync_OperationAction_FairyCeremony(ipyData)
+ if preState != state and state == 0:
+ PlayerFairyCeremony.OnFairyCeremonyEnd()
elif actName == ShareDefine.OperationActionName_NewFairyCeremony:
- #重置仙界盛典
- PlayerNewFairyCeremony.ResetNewFairyCeremony()
+ 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 ipyData:
- PlayerFamilyRedPacket.OnResetFeastRedPacket(ipyData, dayIndex)
- elif actName == ShareDefine.OperationActionName_FlashSale:
- #限时抢购重置购买次数 本次活动每场不能重复
- #dayIndex = sendMapServerMsgDict.get(ShareDefine.ActKey_DayIndex, 0)
- PlayerStore.ResetFlashSaleBuyCnt(ipyData)
-
- if actName in ShareDefine.NeedWorldLVOperationActNameList:
- actWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_OActWorldLV % actName)
- sendMapServerMsgDict[ShareDefine.ActKey_WorldLV] = actWorldLV
-
- if actName == ShareDefine.OperationActionName_ExpRate:
- if isReload and ipyData:
- Sync_OperationAction_ExpRate(ipyData)
-
- elif actName == ShareDefine.OperationActionName_CostRebate:
- if isReload and ipyData:
- pass
- elif actName == ShareDefine.OperationActionName_BossReborn:
- if isReload and ipyData:
- GameWorldBoss.SetBossRebornNeedPoint(True)
-
- elif actName == ShareDefine.OperationActionName_FairyCeremony:
- if isReload and ipyData:
- 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) # 运营活动不单独通知活动状态,需与活动信息整合后一起通知
-
- sendMapServerMsgDict[ShareDefine.ActKey_State] = state
- GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_OperationActionInfo % actName, sendMapServerMsgDict)
-
- GameWorld.Log("运营活动变更: actName=%s,preState=%s,state=%s,dictName=%s, %s" % (actName, preState, state, dictName, sendMapServerMsgDict))
+ if isReload and ipyData:
+ PlayerFamilyRedPacket.Sync_FeastRedPacket(ipyData)
+
+ #通知Mapserver,设置字典
+ #GameWorld.SendMapServerMsgEx(dictName, state) # 运营活动不单独通知活动状态,需与活动信息整合后一起通知
+
+ sendMapServerMsgDict[ShareDefine.ActKey_State] = state
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_OperationActionInfo % actName, sendMapServerMsgDict)
+
+ GameWorld.Log(" sendMapServerMsgDict: %s" % (sendMapServerMsgDict))
+
+ if actName in ShareDefine.MultiActNumOperationActNameList:
+ mapServerInfoDict[actName][actNum] = sendMapServerMsgDict
+ else:
+ mapServerInfoDict[actName] = sendMapServerMsgDict
return
def Sync_OperationAction_ExpRate(ipyData, curPlayer=None):
@@ -660,11 +874,11 @@
return
if len(ipyData.GetStartTimeList()) != len(ipyData.GetEndTimeList()):
return
- openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
+ startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
multiExpRateInfo = ChPyNetSendPack.tagGCMultiExpRateInfo()
multiExpRateInfo.Clear()
- multiExpRateInfo.StartDate = GameWorld.GetOperationActionDateStr(ipyData.GetStartDate(), openServerDay)
- multiExpRateInfo.EndtDate = GameWorld.GetOperationActionDateStr(ipyData.GetEndDate(), openServerDay)
+ multiExpRateInfo.StartDate = startDateStr
+ multiExpRateInfo.EndtDate = endDateStr
multiExpRateInfo.ActivityTime = []
for i, startTime in enumerate(ipyData.GetStartTimeList()):
endTime = ipyData.GetEndTimeList()[i]
@@ -693,11 +907,11 @@
##多倍修行点活动信息通知
if not ipyData:
return
- openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
+ startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
multiRealmPointInfo = ChPyNetSendPack.tagGCMultiRealmPointInfo()
multiRealmPointInfo.Clear()
- multiRealmPointInfo.StartDate = GameWorld.GetOperationActionDateStr(ipyData.GetStartDate(), openServerDay)
- multiRealmPointInfo.EndtDate = GameWorld.GetOperationActionDateStr(ipyData.GetEndDate(), openServerDay)
+ multiRealmPointInfo.StartDate = startDateStr
+ multiRealmPointInfo.EndtDate = endDateStr
multiRealmPointInfo.Multiple = ipyData.GetMultiple()
multiRealmPointInfo.LimitLV = ipyData.GetLVLimit()
multiRealmPointInfo.LimitPoint = ipyData.GetPointLimit()
@@ -793,6 +1007,10 @@
dailyIpyData = ipyDataMgr.GetDailyActionByIndex(i)
dailyID = dailyIpyData.GetDailyID()
+ if dailyID in [ShareDefine.DailyActionID_CrossBattlefield]:
+ GameWorld.Log(" 不需要处理的日常活动! dailyID=%s" % dailyID)
+ continue
+
# 是当天开服天定制活动的不处理常规活动
if dailyID in customDailyIDList:
GameWorld.Log(" 常规活动ID配置是今天的定制活动ID,不处理!: dailyID=%s" % dailyID)
@@ -860,6 +1078,9 @@
def Dispose_DailyActionState():
# 日常活动状态变更检查处理
+ if GameWorld.IsCrossServer():
+ CrossActionControl.Dispose_CrossDailyActionState()
+
todayDailyActionInfo = __GetTodayDailyActionInfo()
if not todayDailyActionInfo:
return
@@ -925,11 +1146,20 @@
def SendMapServerDailyActionState():
# 地图启动成功时通知本日进行中的日常活动状态
+ gameWorld = GameWorld.GetGameWorld()
+ if GameWorld.IsCrossServer():
+ CrossActionControl.SendMapServerCrossDailyActionState()
+ else:
+ for dailyActionID in ShareDefine.CrossDailyActionIDList:
+ dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID
+ state = gameWorld.GetDictByKey(dictName)
+ if state:
+ GameWorld.SendMapServerMsgEx(dictName, state)
+
todayDailyActionInfo = __GetTodayDailyActionInfo()
if not todayDailyActionInfo:
return
- gameWorld = GameWorld.GetGameWorld()
for actionInfo in todayDailyActionInfo:
dailyActionID = actionInfo[0]
dictName = ShareDefine.Def_Notify_WorldKey_DailyActionState % dailyActionID
--
Gitblit v1.8.0