#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package CrossActionControl # # @todo:¿ç·þ»î¶¯×Ü¿ª¹ØÂß¼­ # @author hxp # @date 2020-01-13 # @version 1.0 # # ÏêϸÃèÊö: ¿ç·þ»î¶¯×Ü¿ª¹ØÂß¼­ # ¿ç·þ»î¶¯µÄʱ¼äÒÔ¿ç·þ·þÎñÆ÷Ϊ׼£¬ËùÓеÄ״̬¿ØÖÆÓÉ¿ç·þ·þÎñÆ÷¿ØÖƲ¢¹ã²¥×Ó·þÎñÆ÷ # ×Ó·þ½ö×ö¾ßÌå»î¶¯Âß¼­ # #------------------------------------------------------------------------------- #"""Version = 2020-01-13 17:00""" #------------------------------------------------------------------------------- import GameWorld import ShareDefine import PlayerControl import IpyGameDataPY import CrossActCTGBillboard import CrossRealmMsg import PyGameData import ChConfig import datetime import time ( CrossAct_ReloadSign, # ÐÅÏ¢ÖØÔØ±ê¼Ç CrossAct_TodayInfo, # µ±ÈյĻÐÅÏ¢ CrossAct_CfgIDInfo, # ´¦ÀíµÄcfgIDÐÅÏ¢ ) = range(3) def OnPlayerLogin(curPlayer): return def OnServerClose(): if not GameWorld.IsCrossServer(): return GameWorld.GetUniversalRecMgr().Delete(ShareDefine.Def_UniversalGameRecType_CrossActInfo) if not PyGameData.g_crossActInfoDict: return GameWorld.Log("±£´æ¿ç·þÔËÓª»î¶¯ÐÅϢͨÓüǼ: ") # ±£´æ»î¶¯ÖÐµÄ recDataList = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossActInfo) for actName, actInfoDict in PyGameData.g_crossActInfoDict.items(): for cfgID, actInfo in actInfoDict.items(): if not actInfo.get(ShareDefine.ActKey_State): # ·Ç»î¶¯Öеģ¬ÒѾ­½áËã¹ýÁË£¬²»ÐèÒª´æ´¢ continue state = actInfo.get(ShareDefine.ActKey_State, 0) actID = actInfo.get(ShareDefine.ActKey_ID, 0) templateID = actInfo.get(ShareDefine.ActKey_TemplateID, 0) serverIDRangeList = actInfo.get(ShareDefine.ActKey_ServerIDRangeList, "") recData = recDataList.AddRec() recData.SetStrValue1(actName) recData.SetStrValue3(str(serverIDRangeList)) recData.SetValue1(cfgID) recData.SetValue2(state) recData.SetValue3(actID) recData.SetValue4(templateID) GameWorld.Log(" actName=%s,cfgID=%s,state=%s,actID=%s,templateID=%s,serverIDRangeList=%s" % (actName, cfgID, state, actID, templateID, serverIDRangeList)) return def GetCrossActZoneID(actName, serverGroupID): ## »ñÈ¡×Ó·þIDËùÊô¿ç·þ»î¶¯·ÖÇø£¬ ¿ç·þ¡¢×Ó·þͨÓà actInfoDict = GetCrossActInfoByServerGroupID(actName, serverGroupID) if not actInfoDict: return cfgID = actInfoDict.get(ShareDefine.ActKey_CfgID) ipyDataInfo = actInfoDict.get(ShareDefine.ActKey_IpyDataInfo) if not ipyDataInfo: GameWorld.ErrLog("ActKey_IpyDataInfoΪ¿Õ, ÕÒ²»µ½¿ç·þ»î¶¯ËùÊô·ÖÇø! actName=%s, serverGroupID=%s, cfgID=%s" % (actName, serverGroupID, cfgID)) return return ipyDataInfo.get("ZoneID") def GetCrossActInfoByServerGroupID(actName, serverGroupID): '''»ñÈ¡×Ó·þIDËùÊô¿ç·þ»î¶¯ÐÅÏ¢£¬ ¿ç·þ¡¢×Ó·þͨÓà @param serverGroupID: ·þÎñÆ÷ID»ò·þÎñÆ÷·ÖID ¿ç·þ»î¶¯±íÅäÖõÄÊÇ·þÎñÆ÷ID£¬¶ø×Ó·þºÏ·þºóÒÔÖ÷·þµÄ·þÎñÆ÷ID×÷Ϊ·þÎñÆ÷×éID£¬ËùÒÔÁ½ÖÖ·þÎñÆ÷IDÔڴ˺¯ÊýÖÐͨÓà @return: None or ActKey_IpyDataInfo ''' crossActInfoDict = PyGameData.g_crossActInfoDict if crossActInfoDict and actName in crossActInfoDict: curActInfoDict = crossActInfoDict[actName] for actInfoDict in curActInfoDict.values(): if not actInfoDict.get(ShareDefine.ActKey_State, 0): continue serverIDRangeList = actInfoDict.get(ShareDefine.ActKey_ServerIDRangeList) if not serverIDRangeList: continue for groupInfo in serverIDRangeList: if (isinstance(groupInfo, int) and serverGroupID == groupInfo) \ or ((isinstance(groupInfo, tuple) or isinstance(groupInfo, list)) \ and len(groupInfo) == 2 and groupInfo[0] <= serverGroupID <= groupInfo[1]): return actInfoDict GameWorld.DebugLog("ÕÒ²»µ½·þÎñÆ÷×éID¶ÔÓ¦¿ç·þ»î¶¯·ÖÇø! actName=%s, serverGroupID=%s" % (actName, serverGroupID)) return def GetCrossActInfoByCfgID(actName, cfgID): crossActInfoDict = GetCrossActInfoDict() if actName not in crossActInfoDict: return curActInfoDict = crossActInfoDict[actName] if cfgID not in curActInfoDict: return return curActInfoDict[cfgID] def GetCrossActInfoDict(): if PyGameData.g_crossActInfoDict == None: PyGameData.g_crossActInfoDict = {} # ÏȼÓÔØÍ¨ÓüǼ´æ´¢ÖеĻÐÅÏ¢ recDataList = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossActInfo) GameWorld.Log("¼ÓÔØÍ¨ÓüǼÖеĿç·þÔËÓª»î¶¯ÐÅÏ¢: %s" % recDataList.Count()) for index in xrange(recDataList.Count()): recData = recDataList.At(index) actName = recData.GetStrValue1() strValue3 = recData.GetStrValue3() serverIDRangeList = eval(strValue3) if strValue3 else [] cfgID = recData.GetValue1() state = recData.GetValue2() actID = recData.GetValue3() templateID = recData.GetValue4() if not state: continue if actName not in PyGameData.g_crossActInfoDict: PyGameData.g_crossActInfoDict[actName] = {} actInfoDict = PyGameData.g_crossActInfoDict[actName] # »î¶¯ID¡¢×´Ì¬¡¢Ä£°åÐÅÏ¢µ¥¶À´æ´¢£¬ÖØÖûÅжÏÓà dbInfo = {ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_State:state, ShareDefine.ActKey_TemplateID:templateID, ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ServerIDRangeList:serverIDRangeList} actInfo = {} actInfo.update(dbInfo) actInfo[ShareDefine.ActKey_DBInfo] = dbInfo actInfoDict[cfgID] = actInfo GameWorld.Log(" actName=%s,cfgID=%s, %s" % (actName, cfgID, actInfoDict)) return PyGameData.g_crossActInfoDict def __GetParseIpyDataList(ipyDataMgr, actName, actInfoDict): ## »ñÈ¡ÐèÒª´¦ÀíµÄºÏ·¨·Ö×é»î¶¯ÅäÖÃÁÐ±í£¬ÒѾ­ÔڻÖеıØÐëÒª´¦Àí groupNameList = [] # È·±£·Ö×é˳Ðò groupInfo = {} actCfgCount = getattr(ipyDataMgr, "Get%sCount" % actName)() for cfgIndex in xrange(actCfgCount): ipyData = getattr(ipyDataMgr, "Get%sByIndex" % actName)(cfgIndex) actGroupName = ipyData.GetActGroupName() if actGroupName not in groupInfo: groupInfo[actGroupName] = [] groupNameList.append(actGroupName) groupIpyDataList = groupInfo[actGroupName] groupIpyDataList.append(ipyData) parseIpyDataList = [] for actGroupName in groupNameList: groupIpyDataList = groupInfo[actGroupName] allOpen = False cfgIDList = [] allServerIDRangeList = [] for ipyData in groupIpyDataList: cfgID = ipyData.GetCfgID() cfgIDList.append(cfgID) serverIDRangeList = ipyData.GetServerIDRangeList() if cfgID in actInfoDict and actInfoDict[cfgID]: actInfo = actInfoDict[cfgID] # ÒѾ­ÔڻÖеļǼ±ØÐëÒª´¦Àí parseIpyDataList.append(ipyData) if actName in ShareDefine.CrossActLockServerGroupIDList: serverIDRangeList = actInfo[ShareDefine.ActKey_ServerIDRangeList] GameWorld.Log(" ʹÓÃÒѾ­ÔڻÖеļǼµÄÇø·þ·Ö×é: cfgID=%s,serverIDRangeList=%s" % (cfgID, serverIDRangeList)) # ûÅäÖõÄÈ«·þ¿ª·Å if not serverIDRangeList: allOpen = True else: allServerIDRangeList.extend(serverIDRangeList) if allOpen and len(groupIpyDataList) > 1: GameWorld.ErrLog(" ͬ×é»î¶¯·þÎñÆ÷IDÅäÖÃÒì³££¬ÓÐÈ«·þ¿ª·ÅµÄ£¬Ö»ÄÜÅäÖÃ1Ìõ£¬²»´¦Àí! actGroupName=%s,cfgIDList=%s" % (actGroupName, cfgIDList)) continue errorServerIDList = [] for i in xrange(len(allServerIDRangeList)): checkIDA, checkIDB = allServerIDRangeList[i] for j in xrange(i): serverIDA, serverIDB = allServerIDRangeList[j] if serverIDA <= checkIDA <= serverIDB: errorServerIDList.append(checkIDA) if serverIDA <= checkIDB <= serverIDB: errorServerIDList.append(checkIDB) if errorServerIDList: GameWorld.ErrLog(" ͬ×é»î¶¯·þÎñÆ÷IDÅäÖÃÒì³££¬Óн»²æ£¬²»´¦Àí! actGroupName=%s,cfgIDList=%s,errorServerIDList=%s" % (actGroupName, cfgIDList, errorServerIDList)) continue for ipyData in groupIpyDataList: cfgID = ipyData.GetCfgID() if cfgID in actInfoDict and actInfoDict[cfgID]: continue parseIpyDataList.append(ipyData) return parseIpyDataList def __GetCrossActInfo(isRefreshState=True): # @return: isReload, CrossActInfo key = "CrossActInfo" CrossActInfo = IpyGameDataPY.GetConfigEx(key) serverTime = GameWorld.GetServerTime() curDateStr = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day) curHour = serverTime.hour reloadSignHour = 0 if curHour < 5 else 5 reloadSign = "%s %s" % (curDateStr, reloadSignHour) if CrossActInfo and CrossActInfo[CrossAct_ReloadSign] == reloadSign: #GameWorld.DebugLog("ÒѾ­¼ÓÔØ¹ý±¾ÈÕ¿ç·þÔËÓª»î¶¯´¦ÀíÐÅÏ¢£¡reloadSign=%s" % reloadSign) return False, CrossActInfo # ÒòΪºóÃæµÄʱ¼äÅж϶¼ÊǾ«È·µ½·ÖµÄ£¬¶ø´¦Àí´ËÂß¼­µÄʱºò¿ÉÄܲ»ÊÇ0Ã룬ËùÒÔÕâÀïµÄdatetimeÈ¡µ±Ç°Ê±¼ä¾«È·µ½·ÖµÄ curDateTimeStr = "%s %02d:%02d:00" % (curDateStr, serverTime.hour, serverTime.minute) curDateTime = datetime.datetime.strptime(curDateTimeStr, ChConfig.TYPE_Time_Format) actTimeInfoDict = {} actCfgIDInfoDict = {} ipyDataMgr = IpyGameDataPY.IPY_Data() GameWorld.Log("=============================================================") GameWorld.Log("¼ÓÔØ±¾ÈÕ¿ç·þÔËÓª»î¶¯ÐÅÏ¢: %s, reloadSign=%s =====" % (curDateTime, reloadSign)) crossActInfoDict = GetCrossActInfoDict() GameWorld.Log(" crossActInfoDict=%s" % crossActInfoDict) for actName in ShareDefine.CrossActNameList: # È¡³ö±¾»î¶¯ËùÊô±¾·þIDµÄËùÓÐÅäÖà GameWorld.Log("¼ÓÔØ¿ç·þÔËÓª»î¶¯: actName=%s" % (actName)) if not hasattr(ipyDataMgr, "Get%sCount" % actName): GameWorld.ErrLog(" ûÓиÿç·þÔËÓª»î¶¯ÀàÐͶÔÓ¦»î¶¯Ê±¼ä±í! actName=%s" % actName) continue curActInfoDict = crossActInfoDict.get(actName, {}) # ÑéÖ¤·þÎñÆ÷ID²»Öظ´µÄÅäÖà parseIpyDataList = __GetParseIpyDataList(ipyDataMgr, actName, curActInfoDict) for ipyData in parseIpyDataList: cfgID = ipyData.GetCfgID() actGroupName = ipyData.GetActGroupName() startDateStr = ipyData.GetStartDate() endDateStr = ipyData.GetEndDate() GameWorld.Log(" cfgID=%s,actGroupName==%s,startDateStr=%s,endDateStr=%s,curDateTime=%s" % (cfgID, actGroupName, startDateStr, endDateStr, curDateTime)) if not startDateStr: startDateStr = curDateStr GameWorld.Log(" ¿ªÊ¼ÈÕÆÚΪ¿Õ£¬Ä¬ÈÏÿÌ죬½ñÈÕΪ: startDateStr=%s" % startDateStr) if not endDateStr: endDateStr = curDateStr GameWorld.Log(" ½áÊøÈÕÆÚΪ¿Õ£¬Ä¬ÈÏÿÌ죬½ñÈÕΪ: endDateStr=%s" % endDateStr) 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)) 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µã GameWorld.Log(" resetType=%s,startDayDate=%s,endDayDate=%s,startHMStrList=%s,endHMStrList=%s" % (resetType, startDayDate, endDayDate, startHMStrList, endHMStrList)) if curDateTime < startDayDate or curDateTime >= endDayDate: isActTime = False if cfgID not in curActInfoDict or not curActInfoDict[cfgID]: GameWorld.Log(" ·Ç»î¶¯Ê±¼ä£¡²»´¦Àí£¡") continue else: isActTime = True GameWorld.Log(" ÐèÒª´¦ÀíµÄ¿ç·þÔËÓª»î¶¯ÐÅÏ¢: cfgID=%s,isActTime=%s" % (cfgID, isActTime)) startList = [] # [startDateTime, ...] endList = [] # [endDateTime, ...] startNotifyDict = {} # {notifyDateTime:notifyInfo, ...} endNotifyDict = {} # {notifyDateTime:notifyInfo, ...} loopNotifyDict = {} # {notifyDateTime:notifyInfo, ...} notifyDict = {} # ûÅäÖÃʱ·ÖµÄ´ú±íÈ«Ìì if not startHMStrList: startDateTime = startDayDate endDateTime = endDayDate startList.append(startDateTime) endList.append(endDateTime) # ÿÌ찴ʱ¶Î¿ªÆôµÄ£¬Ö§³Ö¶àʱ¶Î else: for hmIndex, startHMStr in enumerate(startHMStrList): if hmIndex >= len(endHMStrList): break 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) GameWorld.Log(" startList=%s" % (startList)) GameWorld.Log(" end List=%s" % (endList)) 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 # ¹ã²¥ - Ïà¶Ôʵ¼Ê½áÊøÊ±¼ä 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 # ¹ã²¥ - Ñ­»·¹ã²¥ 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 = curDateTime + 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 if startNotifyDict or endNotifyDict or loopNotifyDict: GameWorld.Log(" startNotifyDict: %s, %s" % (len(startNotifyDict.keys()), sorted(startNotifyDict.keys()))) GameWorld.Log(" end NotifyDict: %s, %s" % (len(endNotifyDict.keys()), sorted(endNotifyDict.keys()))) GameWorld.Log(" loop NotifyDict: %s, %s" % (len(loopNotifyDict.keys()), sorted(loopNotifyDict.keys()))) notifyDict.update(startNotifyDict) notifyDict.update(endNotifyDict) notifyDict.update(loopNotifyDict) if actName not in actTimeInfoDict: actTimeInfoDict[actName] = {} actTimeInfoDict[actName][cfgID] = [ipyData, startList, endList, notifyDict] if actName not in actCfgIDInfoDict: actCfgIDInfoDict[actName] = [[], []] endCfgIDList, actCfgIDList = actCfgIDInfoDict[actName] if actName not in crossActInfoDict: crossActInfoDict[actName] = {} curActInfoDict = crossActInfoDict[actName] if cfgID not in curActInfoDict: curActInfoDict[cfgID] = {} curCfgActInfoDict = curActInfoDict[cfgID] # ipyData »î¶¯Ê±¼ä±íÐÅÏ¢ÓÉ¿ç·þ·þÎñÆ÷ͬ²½×Ó·þ£¬»î¶¯ÄÚÈÝÈ¡×Ó·þ×Ô¼ºµÄ ipyDataDict = {} for k, v in ipyData.__dict__.items(): if k in ["NotifyInfoStart", "NotifyInfoEnd", "NotifyInfoLoop", "ServerIDRangeList"]: continue ipyDataDict[k] = v ipyDataDict.update({"StartDate":startDateStr, "EndDate":endDateStr}) GameWorld.Log(" ipyDataDict=%s" % ipyDataDict) curCfgActInfoDict.update({ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_IpyDataInfo:ipyDataDict}) if ShareDefine.ActKey_ServerIDRangeList not in curCfgActInfoDict or actName not in ShareDefine.CrossActLockServerGroupIDList: # ûÓеϰÔòʹÓÃÅäÖÃÖе쬷ÀÖ¹ÅäÖÃÐ޸ĵ¼Ö·þÎñÆ÷ID·ÖÇø±ä¶¯ÒýÆðµÄ»î¶¯Êý¾ÝÒì³££¬³ý·Çºǫ́¹¤¾ßÇ¿ÖÆÐÞ¸Ä curCfgActInfoDict[ShareDefine.ActKey_ServerIDRangeList] = ipyData.GetServerIDRangeList() actID, dayIndex, templateID = 0, 0, 0 if isActTime: ''' ×¢£º ¼ì²éÊÇ·ñÒѾ­´æÔڻÖеķÖ×飬ÓеĻ°Ç¿Öƽ«ÆäÖÃΪ½áËã״̬£¬ÓÐÇÒ½öÓÐÒ»¸ö»î¶¯ÖеÄ×飬ºóÃæµÄÇ¿ÖÆ¸²¸ÇÇ°ÃæµÄ parseIpyDataList È·±£Í¬Ò»»î¶¯×éÃûµÄserverID²»»áÖØ¸´ ÕâÀï½øÒ»²½È·±£²»Í¬»î¶¯×éÃûµÄ²»»áͬʱ¿ªÆô»î¶¯£¬ÓÐÇÒ½öÓÐÒ»¸ö»î¶¯ÖеĻ×é ''' for befIpyData in parseIpyDataList: befCfgID = befIpyData.GetCfgID() befActGroupName = befIpyData.GetActGroupName() if befActGroupName == actGroupName: break if befCfgID not in actCfgIDList: continue actCfgIDList.remove(befCfgID) if befCfgID in curActInfoDict: befCfgActInfoDict = curActInfoDict[befCfgID] befCfgActInfoDict[ShareDefine.ActKey_ID] = 0 # »î¶¯IDÇ¿ÖÆÖÃΪ0 if befCfgID in endCfgIDList: continue endCfgIDList.append(befCfgID) GameWorld.Log(" Ç°Ãæ´æÔڻµÄ·Ö×飬ÔòÇ¿ÖÆ½áÊø»î¶¯£¡ befCfgID=%s,befActGroupName=%s" % (befCfgID, befActGroupName)) if cfgID not in actCfgIDList: actCfgIDList.append(cfgID) dayIndex = (curDateTime - startDayDate).days actIDDateTime = startDayDate isDayReset = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset() # °´Ê±¶Î¿ªµÄĬÈÏÿÌìÖØÖà if isDayReset or (startHMStrList and endHMStrList): actIDDateTime += datetime.timedelta(days=dayIndex) actID = int(time.mktime(actIDDateTime.timetuple())) # ĬÈÏÈ¡¿ªÊ¼Ê±¼äµãµÄtimeÖµ×÷Ϊ»î¶¯ID GameWorld.Log(" isDayReset=%s,actIDDateTime=%s,actID=%s" % (isDayReset, actIDDateTime, actID)) # Ä£°åID if hasattr(ipyData, "TemplateIDList"): templateIDList = ipyData.GetTemplateIDList() templateID = templateIDList[-1] if dayIndex >= len(templateIDList) else templateIDList[dayIndex] # ÆäËûÌØÊâÄ£°åID»ñÈ¡´¦Àí£¬ÓÐÐèÒªµÄµ¥¶À´¦Àí¼´¿É£¬¸ù¾Ý»î¶¯¹æÔò×ÔÐÐÀ©Õ¹... else: if cfgID not in endCfgIDList: endCfgIDList.append(cfgID) curCfgActInfoDict.update({ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_TemplateID:templateID, ShareDefine.ActKey_DayIndex:dayIndex}) CrossActInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, actTimeInfoDict, actCfgIDInfoDict]) GameWorld.Log("±¾ÈÕ¿ç·þÔËÓª»î¶¯ÐÅÏ¢¼ÓÔØÍê±Ï!reloadSign=%s,isRefreshState=%s" % (reloadSign, isRefreshState)) GameWorld.Log(" actTimeInfoDict=%s" % actTimeInfoDict) GameWorld.Log(" actCfgIDInfoDict=%s" % actCfgIDInfoDict) GameWorld.Log(" crossActInfoDict=%s" % crossActInfoDict) GameWorld.Log("=============================================================") if isRefreshState: Dispose_CrossActState(True) return True, CrossActInfo def Dispose_CrossActState(reloadRefresh=False): isReload, CrossActInfo = __GetCrossActInfo(False) # ÕâÀï±ØÐë´«False isReload = isReload or reloadRefresh actTimeInfoDict = CrossActInfo[CrossAct_TodayInfo] actCfgIDInfoDict = CrossActInfo[CrossAct_CfgIDInfo] crossActInfoDict = GetCrossActInfoDict() # ÕâÀïʱ¼äÐ辫ȷµ½·ÖÖÓ£¬²»È»ºóÃæµÄ±È½Ï»áÆ¥Åä²»µ½ 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) actChangeList = [] sysnCrossActInfoDict = {} for actName in ShareDefine.CrossActNameList: if actName not in actTimeInfoDict or actName not in crossActInfoDict or actName not in actCfgIDInfoDict: continue timeInfoDict = actTimeInfoDict[actName] endCfgIDList, actCfgIDList = actCfgIDInfoDict[actName] # ¿ÉÄÜÒ»ÌõcfgID´¦Àí½áÊø£¬ÁíÒ»ÌõcfgID´¦Àí¿ªÊ¼£¬Ò²¿ÉÄÜͬһÌõcfgID¼´½áÊøÍ¬Ê±ÓÖ¿ªÊ¼£¨ÈçÿÌìÖØÖõģ© cfgIDList = endCfgIDList + actCfgIDList for cfgID in cfgIDList: if cfgID not in timeInfoDict: continue ipyData, startList, endList, notifyDict = timeInfoDict[cfgID] state = 0 # ĬÈÏ¹Ø±Õ cfgID = ipyData.GetCfgID() groupName = ipyData.GetActGroupName() zoneID = ipyData.GetZoneID() if cfgID not in crossActInfoDict[actName]: crossActInfoDict[actName][cfgID] = {} actInfoDict = crossActInfoDict[actName][cfgID] # ״̬ if cfgID not in endCfgIDList: for dIndex, startDateTime in enumerate(startList): endDateTime = endList[dIndex] if startDateTime <= curDateTime < endDateTime: state = dIndex + 1 # Ò²ÊÇ´ú±íµÚ¼¸¸öʱ¼ä¶Î break serverIDRangeList = actInfoDict.get(ShareDefine.ActKey_ServerIDRangeList) # È«·þ¹ã²¥ÌáʾÐÅÏ¢ if curDateTime in notifyDict: if serverIDRangeList != None: notifyKey, paramList = notifyDict[curDateTime] country = 0 serverGroupIDList = [] crossNotifyList = [] crossNotifyList.append([ShareDefine.CrossNotify_CrossAct, [country, notifyKey, paramList], serverIDRangeList]) PlayerControl.CrossNotifyEx(serverGroupIDList, crossNotifyList) dbInfo = actInfoDict.get(ShareDefine.ActKey_DBInfo, {}) dbState = dbInfo.get(ShareDefine.ActKey_State, 0) dbCfgID = dbInfo.get(ShareDefine.ActKey_CfgID, 0) dbActID = dbInfo.get(ShareDefine.ActKey_ID, 0) dbTemplateID = dbInfo.get(ShareDefine.ActKey_TemplateID, 0) dbServerIDRangeList = dbInfo.get(ShareDefine.ActKey_ServerIDRangeList, None) forceReset = False if dbCfgID == cfgID and dbServerIDRangeList != serverIDRangeList: forceReset = True actID = actInfoDict.get(ShareDefine.ActKey_ID, 0) templateID = actInfoDict.get(ShareDefine.ActKey_TemplateID, 0) if not isReload and dbState == state and dbActID == actID and not forceReset: #ÒѾ­ÊÇÕâ¸ö״̬ÁË continue GameWorld.Log("¿ç·þÔËÓª»î¶¯×´Ì¬: actName=%s,cfgID=%s,groupName=%s,zoneID=%s,dbState=%s -> state=%s, dbActID=%s -> actID=%s,forceReset=%s" % (actName, cfgID, groupName, zoneID, dbState, state, dbActID, actID, forceReset)) # ¸üÐÂ״̬ actInfoDict[ShareDefine.ActKey_State] = state dbInfo = {ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_State:state, ShareDefine.ActKey_TemplateID:templateID, ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ServerIDRangeList:serverIDRangeList} actInfoDict[ShareDefine.ActKey_DBInfo] = dbInfo #GameWorld.Log(" »î¶¯×´Ì¬Í¬²½ÐÅÏ¢: actName=%s,cfgID=%s,groupName=%s,zoneID=%s,actInfoDict=%s" % (actName, cfgID, groupName, zoneID, actInfoDict)) if actName not in sysnCrossActInfoDict: sysnCrossActInfoDict[actName] = {} sysnCrossActInfoDict[actName][cfgID] = actInfoDict if dbActID != actID or forceReset: GameWorld.Log(" »î¶¯ID±ä¸ü: actName=%s,cfgID=%s,groupName=%s,zoneID=%s,dbActID=%s -> actID=%s,forceReset=%s,dbTemplateID=%s" % (actName, cfgID, groupName, zoneID, dbActID, actID, forceReset, dbTemplateID)) if actName == ShareDefine.CrossActName_CTGBillboard: CrossActCTGBillboard.OnActIDChange(cfgID, dbTemplateID, state) else: actChangeList.append([actName, ipyData, state, cfgID, groupName, zoneID, dbActID, actID, forceReset, dbTemplateID]) # ·Ç»î¶¯ÖеĴ¦ÀíÍê¹Ø±Õºó£¬×îºóɾ³ý if not state: del crossActInfoDict[actName][cfgID] if not crossActInfoDict[actName]: del crossActInfoDict[actName] #GameWorld.Log(" ÒÆ³ý½áÊøµÄ»î¶¯: actName=%s,cfgID=%s,crossActInfoDict=%s" % (actName, cfgID, crossActInfoDict)) # ͬ²½×Ó·þÎñÆ÷ if sysnCrossActInfoDict: serverGroupIDList = [] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossActInfo, sysnCrossActInfoDict, serverGroupIDList) # ÐèÒªµÈ»î¶¯µÈͬ²½µ½×Ó·þºó²Å´¦ÀíÒÔÏÂÂß¼­£¬²»È»¿ÉÄܵ¼ÖÂ×Ó·þûÓлʱ¼äÃ÷ϸÒýÆð»î¶¯Òì³£ for changeInfo in actChangeList: actName, ipyData, state, cfgID, groupName, zoneID, dbActID, actID, forceReset, dbTemplateID = changeInfo GameWorld.Log(" »î¶¯ID±ä¸ü: actName=%s,cfgID=%s,groupName=%s,zoneID=%s,dbActID=%s -> actID=%s,forceReset=%s,dbTemplateID=%s" % (actName, cfgID, groupName, zoneID, dbActID, actID, forceReset, dbTemplateID)) if actName == ShareDefine.CrossActName_LuckyCloudBuy: import CrossLuckyCloudBuy CrossLuckyCloudBuy.OnLuckyCloudBuyReset(ipyData, state) elif actName == ShareDefine.CrossActName_AllRecharge: import CrossActAllRecharge CrossActAllRecharge.OnActIDChange(ipyData, state) return def Sync_CrossActInfoToClientServer(serverGroupID=0): ''' ͬ²½¿ç·þÔËÓª»î¶¯ÐÅÏ¢µ½×Ó·þÎñÆ÷ @param serverGroupID: Ϊ0ʱͬ²½ËùÓÐ×Ó·þ ''' isReload, _ = __GetCrossActInfo() if isReload: # Èç¹ûÊÇÖØ¶ÁµÄ£¬ÔòÔÚÄÚ²ãÒѾ­Í¬²½ÁË£¬´Ë´¦²»Öظ´Í¬²½ return # ͬ²½×Ó·þÎñÆ÷ sysnCrossActInfoDict = GetCrossActInfoDict() serverGroupIDList = [serverGroupID] if serverGroupID else [] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossActInfo, sysnCrossActInfoDict, serverGroupIDList) return ## ================================================================================================ def CrossServerMsg_CrossActInfo(sysnCrossActInfoDict): ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¿ç·þÔËÓª»î¶¯×´Ì¬ GameWorld.Log("===== ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¿ç·þÔËÓª»î¶¯×´Ì¬: %s" % sysnCrossActInfoDict) if PyGameData.g_crossActInfoDict == None or not sysnCrossActInfoDict: PyGameData.g_crossActInfoDict = {} for actName, syncActInfoDict in sysnCrossActInfoDict.items(): for cfgID, syncActInfo in syncActInfoDict.items(): if actName not in PyGameData.g_crossActInfoDict: PyGameData.g_crossActInfoDict[actName] = {} actInfoDict = PyGameData.g_crossActInfoDict[actName] actInfoDict[cfgID] = syncActInfo if actName == ShareDefine.CrossActName_LuckyCloudBuy: import CrossLuckyCloudBuy CrossLuckyCloudBuy.Sync_LuckyCloudBuyRoundInfo(None) GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossActInfo % actName, syncActInfoDict) # ɾ³ý·Ç»î¶¯ÖÐµÄ for actName, actInfoDict in PyGameData.g_crossActInfoDict.items(): for cfgID, actInfo in actInfoDict.items(): if not actInfo.get(ShareDefine.ActKey_State, 0): del PyGameData.g_crossActInfoDict[actName][cfgID] return def GetPlayerCrossActInfo(curPlayer, actName): ## »ñÈ¡¿ç·þÍæ¼Ò¶ÔÓ¦µÄ¿ç·þ»î¶¯ÐÅÏ¢ if PyGameData.g_crossActInfoDict == None: return {} actInfoDict = PyGameData.g_crossActInfoDict.get(actName, {}) if not actInfoDict: return {} playerServerID = GameWorld.GetPlayerServerID(curPlayer) for actInfo in actInfoDict.values(): if not actInfo.get(ShareDefine.ActKey_State, 0): continue if ShareDefine.ActKey_ServerIDRangeList not in actInfo: continue serverIDRangeList = actInfo[ShareDefine.ActKey_ServerIDRangeList] if not serverIDRangeList: # È«·þ¿ªÆô return actInfo for serverIDA, serverIDB in serverIDRangeList: if serverIDA <= playerServerID <= serverIDB: return actInfo return {} def SendMapServerCrossActionState(): # µØÍ¼Æô¶¯³É¹¦Ê±Í¨Öª¿ç·þ»î¶¯Ïà¹Ø×´Ì¬ - ±¾·þµØÍ¼£¬¿ç·þµØÍ¼²»ÐèҪ֪ͨ if PyGameData.g_crossActInfoDict == None: return sysnCrossActInfoDict = PyGameData.g_crossActInfoDict for actName in ShareDefine.CrossActNameList: actInfoDict = sysnCrossActInfoDict.get(actName, {}) GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossActInfo % actName, actInfoDict) return ## ================================================================================================ def __GetTodayCrossDailyActionInfo(): # »ñÈ¡±¾ÈÕ´ý´¦ÀíµÄÈÕ³£»î¶¯ÐÅÏ¢ key = "TodayCrossDailyActionInfo" curTime = int(time.time()) curDateStr = GameWorld.ChangeTimeNumToStr(curTime, ChConfig.TYPE_Time_YmdFormat) # µ±ÌìÈÕÆÚ loadSign = curDateStr TodayDailyActionInfo = IpyGameDataPY.GetConfigEx(key) if TodayDailyActionInfo and TodayDailyActionInfo[0] == loadSign: GameWorld.DebugLog("ÒѾ­¼ÓÔØ¹ý±¾ÈÕ¿ç·þÈÕ³£»î¶¯´¦ÀíÐÅÏ¢£¡loadSign=%s" % loadSign) return TodayDailyActionInfo[1] todayActionInfo = [] dayTime = GameWorld.GetServerTime() weekDay = str(dayTime.weekday() + 1) # ¸ñʽΪjson, µ±Ç°ÐÇÆÚ¼¸, 1´ú±íÐÇÆÚ1 GameWorld.Log("===== ¼ÓÔØ½ñÌì¿ç·þÈÕ³£»î¶¯ÐÅÏ¢ =====") GameWorld.Log("µ±Ç°ÐÇÆÚ%s" % weekDay) dailyTimeInfoList = [] ipyDataMgr = IpyGameDataPY.IPY_Data() for i in xrange(ipyDataMgr.GetCrossDailyActionCount()): dailyIpyData = ipyDataMgr.GetCrossDailyActionByIndex(i) dailyID = dailyIpyData.GetDailyID() openTimeDict = dailyIpyData.GetOpenTimeDict() # ûÓÐʱ¼ä¿ØÖƵ쬴ú±íÓÀ¾Ã¿ª·Å if not openTimeDict: todayActionInfo.append([dailyID]) GameWorld.Log(" Ôö¼Ó±¾ÈÕ³£¿ª¿ç·þÈÕ³£»î¶¯ÐÅÏ¢: dailyID=%s" % dailyID) continue #Èç¹ûÐÇÆÚkeyÖдæÔÚ "0" ´ú±íÿÈÕ¶¼¿ªÆô if "0" not in openTimeDict and weekDay not in openTimeDict: GameWorld.Log(" ²»ÊÇ¿ç·þÈÕ³£»î¶¯¿ªÆôÐÇÆÚ: dailyID=%s,openWeekLimit=%s" % (dailyID, openTimeDict.keys())) continue openTimeList = openTimeDict["0"] if "0" in openTimeDict else openTimeDict[weekDay] dailyTimeInfoList.append([openTimeList, dailyIpyData]) GameWorld.Log(" -----------------------") for openTimeList, ipyData in dailyTimeInfoList: dailyID = ipyData.GetDailyID() notifyInfoDict = ipyData.GetNotifyInfo() openList = [] # [(ʱ,·Ö), ...] overList = [] # [(ʱ,·Ö), ...] goonStateDict = {} # {״̬:[(aDateTime, bDateTime)], ...} notifyDict = {} # {(ʱ,·Ö):[notifyKey, [²ÎÊý]], ...} OpenState = 1 # ¶¨Ò忪Æô״̬Ϊ1 for hour, minute in openTimeList: openTimeStr = "%s %02d:%02d:%02d" % (curDateStr, hour, minute, 0) # ¾«È·¿ªÆôʱ¼ä openDateTime = datetime.datetime.strptime(openTimeStr, ChConfig.TYPE_Time_Format) openList.append((openDateTime.hour, openDateTime.minute)) # ¾«È·¹Ø±Õʱ¼ä overDateTime = openDateTime + datetime.timedelta(minutes=ipyData.GetDuration()) overList.append((overDateTime.hour, overDateTime.minute)) # goon ¿ªÆô״̬ openStateTimeList = goonStateDict.get(OpenState, []) openStateTimeList.append((openDateTime, overDateTime)) goonStateDict[OpenState] = openStateTimeList # goon ÆäËû״̬£¬´ýÀ©Õ¹ # ... # ¹ã²¥ for notifyMinute, notifyInfo in notifyInfoDict.items(): notifyDateTime = openDateTime + datetime.timedelta(minutes=notifyMinute) notifyDict[(notifyDateTime.hour, notifyDateTime.minute)] = notifyInfo todayActionInfo.append([dailyID, openList, overList, goonStateDict, notifyDict]) GameWorld.Log(" Ôö¼Ó±¾ÈÕ¿ç·þÈÕ³£»î¶¯ÐÅÏ¢: dailyID=%s,openList=%s,overList=%s,goonStateDict=%s,notifyDict=%s" % (dailyID, openList, overList, goonStateDict, notifyDict)) TodayDailyActionInfo = IpyGameDataPY.SetConfigEx(key, [loadSign, todayActionInfo]) GameWorld.Log("±¾ÈÕ¿ç·þÈÕ³£»î¶¯ÐÅÏ¢¼ÓÔØÍê±Ï! loadSign=%s" % loadSign) GameWorld.Log("=============================================================") return TodayDailyActionInfo[1] def Dispose_CrossDailyActionState(): # ¿ç·þÈÕ³£»î¶¯×´Ì¬±ä¸ü¼ì²é´¦Àí todayDailyActionInfo = __GetTodayCrossDailyActionInfo() if not todayDailyActionInfo: return gameWorld = GameWorld.GetGameWorld() dayTime = GameWorld.GetServerTime() curHourMinute = (dayTime.hour, dayTime.minute) sysnCrossDailyActionStateDict = {} for actionInfo in todayDailyActionInfo: dailyActionID = actionInfo[0] state = 0 # ĬÈÏ¹Ø±Õ # ³¤¶ÈΪ1µÄ´ú±í³£¿ªµÄ»î¶¯ if len(actionInfo) == 1: state = 1 else: #openList = [] # [(ʱ,·Ö), ...] #overList = [] # [(ʱ,·Ö), ...] #goonStateDict = {} # {״̬:[(aDateTime, bDateTime)], ...} #notifyDict = {} # {(ʱ,·Ö):[notifyKey, [²ÎÊý]], ...} openList, overList, goonStateDict, notifyDict = actionInfo[1:] # ¾«È·Æ¥Å俪Æô if curHourMinute in openList: state = 1 # ¾«È·Æ¥Å乨±Õ elif curHourMinute in overList: state = 0 # goon ״̬ else: for goonState, openStateTimeList in goonStateDict.items(): for dateTimeInfo in openStateTimeList: if dateTimeInfo[0] < dayTime < dateTimeInfo[1]: state = goonState break # È«·þ¹ã²¥ÌáʾÐÅÏ¢ if curHourMinute in notifyDict: notifyKey, paramList = notifyDict[curHourMinute] serverGroupIDList = [] PlayerControl.WorldNotifyCross(serverGroupIDList, 0, notifyKey, paramList) dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID beforeState = gameWorld.GetDictByKey(dictName) if beforeState == state: #ÒѾ­ÊÇÕâ¸ö״̬ÁË continue if state: if dailyActionID == ShareDefine.CrossDailyActionID_YaomoBoss: GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ActionBossRebornSign % dailyActionID, int(time.time())) sysnCrossDailyActionStateDict[dailyActionID] = state #֪ͨMapserver,ÉèÖÃ×Öµä GameWorld.SendMapServerMsgEx(dictName, state) #¸üÐÂ×ÖµäÖµ gameWorld.SetDict(dictName, state) GameWorld.Log("¿ç·þÈÕ³£»î¶¯×´Ì¬±ä¸ü: dailyActionID=%s,state=%s,dictName=%s" % (dailyActionID, state, dictName)) # ͬ²½×Ó·þÎñÆ÷ if sysnCrossDailyActionStateDict: serverGroupIDList = [] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossDailyActionState, sysnCrossDailyActionStateDict, serverGroupIDList) return def SendMapServerCrossDailyActionState(): # µØÍ¼Æô¶¯³É¹¦Ê±Í¨Öª±¾ÈÕ½øÐÐÖеÄÈÕ³£»î¶¯×´Ì¬ todayDailyActionInfo = __GetTodayCrossDailyActionInfo() if not todayDailyActionInfo: return gameWorld = GameWorld.GetGameWorld() for actionInfo in todayDailyActionInfo: dailyActionID = actionInfo[0] dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID state = gameWorld.GetDictByKey(dictName) if state: GameWorld.SendMapServerMsgEx(dictName, state) return def CrossServerMsg_CrossDailyActionState(msgData): gameWorld = GameWorld.GetGameWorld() for dailyActionID, state in msgData.items(): dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID #֪ͨMapserver,ÉèÖÃ×Öµä GameWorld.SendMapServerMsgEx(dictName, state) #¸üÐÂ×ÖµäÖµ gameWorld.SetDict(dictName, state) GameWorld.Log("ÊÕµ½¿ç·þÈÕ³£»î¶¯×´Ì¬±ä¸ü: dailyActionID=%s,state=%s,dictName=%s" % (dailyActionID, state, dictName)) return