| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #---------------------------------------------------------------------  | 
| #  | 
| #---------------------------------------------------------------------  | 
| ##@package GameWorldActionControl  | 
| # @todo: Ö»×öÊÀ½ç֪ͨºÍ»î¶¯µÄ×Ü¿ª¹ØÂß¼£¨°´Ê±¼ä£©  | 
| #  | 
| # @author: hch  | 
| # @date 2010-3-31  | 
| # @version 1.1  | 
| #  | 
| # @note: Ö»×öÊÀ½ç֪ͨºÍ»î¶¯µÄ×Ü¿ª¹ØÂß¼(°´Ê±¼ä)  | 
| #  | 
| # @change: "2018-7-16 12:00" hxp Ôö¼ÓÔËÓª»î¶¯Ê±¼ä¿ØÖÆÖ§³Ö£»Ôö¼Ó¶à±¶¾Ñé»î¶¯¡¢Ïû·Ñ·µÀû»î¶¯  | 
| #  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2018-7-16 12:00"""  | 
| #---------------------------------------------------------------------  | 
| import ChConfig  | 
| import datetime  | 
| import GameWorld  | 
| import PlayerControl  | 
| import ShareDefine  | 
| import PlayerDBGSEvent  | 
| import CrossRealmPK  | 
| import GameWorldFamilyWar  | 
| import PlayerFamilyParty  | 
| import IpyGameDataPY  | 
| import PlayerXMZZ  | 
| import PlayerFamilySWRH  | 
| import GameWorldBoss  | 
| 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  | 
| import PlayerStore  | 
|   | 
| from types import IntType  | 
| import time  | 
| #---------------------------------------------------------------------  | 
|   | 
| #ÄêÔÂÈÕʱ¼ä¸ñʽ  | 
| Time_YmdFormat = ChConfig.TYPE_Time_YmdFormat  | 
|   | 
| ATTR_CALL_TIME = ['weekday', 'year', 'month', 'day', 'hour', 'minute']  | 
|   | 
| (  | 
| OperationAction_ReloadSign, # ÐÅÏ¢ÖØÔØ±ê¼Ç  | 
| OperationAction_TodayInfo, # µ±ÈյĻÐÅÏ¢  | 
| OperationAction_MapServerInfo, # Í¬²½µØÍ¼µÄ»î¶¯ÐÅÏ¢  | 
| ) = range(3)  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|       | 
|     if GameWorld.IsCrossServer():  | 
|         # ¿ç·þ²»´¦ÀíÔËÓª»î¶¯  | 
|         return  | 
|       | 
|     # Íæ¼ÒµÇ¼µÄ²»´¥·¢ÖØÔػ£¬²»È»¸ÕºÃÔÚ0µã·þÎñÆ÷´¦ÀíOnDay֮ǰµÇ¼µÄʱºò»áÓÐÎÊÌâ  | 
|     isReload, OperationActionInfo = __GetOperationActionInfo(needReload=False)  | 
|     if not OperationActionInfo:  | 
|         return  | 
|     operationActionDict = OperationActionInfo[OperationAction_TodayInfo]  | 
|       | 
|     if isReload:  | 
|         return  | 
|       | 
|     # ¶à±¶¾Ñé»î¶¯½øÐÐÖÐ  | 
|     if ShareDefine.OperationActionName_ExpRate in operationActionDict:  | 
|         ipyData = operationActionDict[ShareDefine.OperationActionName_ExpRate][0]  | 
|         if ipyData:  | 
|             Sync_OperationAction_ExpRate(ipyData, curPlayer)  | 
|   | 
|     # ÏɽçÊ¢µä»î¶¯½øÐÐÖÐ  | 
|     if ShareDefine.OperationActionName_FairyCeremony in operationActionDict:  | 
|         ipyData = operationActionDict[ShareDefine.OperationActionName_FairyCeremony][0]  | 
|         if ipyData:  | 
|             PlayerFairyCeremony.Sync_OperationAction_FairyCeremony(ipyData, curPlayer)  | 
|     # ÐÂÏɽçÊ¢µä»î¶¯½øÐÐÖÐ  | 
|     if ShareDefine.OperationActionName_NewFairyCeremony in operationActionDict:  | 
|         ipyData = operationActionDict[ShareDefine.OperationActionName_NewFairyCeremony][0]  | 
|         if ipyData:  | 
|             PlayerNewFairyCeremony.Sync_OperationAction_NewFairyCeremony(ipyData, curPlayer)  | 
|     # ¶à±¶ÐÞÐеã»î¶¯½øÐÐÖÐ  | 
|     if ShareDefine.OperationActionName_RealmPoint in operationActionDict:  | 
|         ipyData = operationActionDict[ShareDefine.OperationActionName_RealmPoint][0]  | 
|         if ipyData:  | 
|             Sync_OperationAction_RealmPoint(ipyData, curPlayer)  | 
|     # ½ÚÈÕºì°ü»î¶¯½øÐÐÖÐ  | 
|     if ShareDefine.OperationActionName_FeastRedPacket in operationActionDict:  | 
|         ipyData = operationActionDict[ShareDefine.OperationActionName_FeastRedPacket][0]  | 
|         if ipyData:  | 
|             PlayerFamilyRedPacket.Sync_FeastRedPacket(ipyData, curPlayer)  | 
|     # ÐÒÔ˼ø±¦»î¶¯½øÐÐÖÐ  | 
|     if ShareDefine.OperationActionName_LuckyTreasure in operationActionDict:  | 
|         PlayerUniversalGameRec.SendUniversalGameRecInfo(curPlayer, ShareDefine.Def_UniversalGameRecType_LuckyTreasure)  | 
|     return  | 
|   | 
| def SendMapServerOperationActionState():  | 
|     # µØÍ¼Æô¶¯³É¹¦Ê±Í¨Öª±¾ÈÕÔËÐлÏà¹Ø×´Ì¬  | 
|       | 
|     if GameWorld.IsCrossServer():  | 
|         # ¿ç·þ²»´¦ÀíÔËÓª»î¶¯  | 
|         return  | 
|     CrossActionControl.SendMapServerCrossActionState()  | 
|       | 
|     isReload, OperationActionInfo = __GetOperationActionInfo()  | 
|     mapServerInfoDict = OperationActionInfo[OperationAction_MapServerInfo]  | 
|       | 
|     if isReload:  | 
|         # Èç¹ûÊÇÖØ¶ÁµÄ£¬ÔòÔÚÄÚ²ãÒѾͬ²½ÁË£¬´Ë´¦²»Öظ´Í¬²½  | 
|         return  | 
|       | 
|     for actName in ShareDefine.OperationActionNameList:  | 
|         sendMapServerMsgDict = mapServerInfoDict.get(actName, {})  | 
|         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 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"  | 
|     openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1  | 
|     isMixServer = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServer)  | 
|     mixServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MixServerDay) + 1  | 
|     OperationActionInfo = IpyGameDataPY.GetConfigEx(key)  | 
|     serverTime = GameWorld.GetServerTime()  | 
|     curHour = serverTime.hour  | 
|     reloadSignHour = 0 if curHour < 5 else 5  | 
|     reloadSign = [openServerDay, isMixServer, mixServerDay, reloadSignHour]  | 
|     if OperationActionInfo and OperationActionInfo[OperationAction_ReloadSign] == reloadSign:  | 
|         #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)  | 
|       | 
|     startDateInCustomCanOpenList = IpyGameDataPY.GetFuncEvalCfg("OperationAction", 2) # ¿ªÊ¼ÌìÔÚ¶¨ÖÆÌìÄÚÔÚ¶¨ÖÆÌì½áÊøºó¿É¼ÌÐø¿ªÆôµÄ»î¶¯ÁÐ±í  | 
|     customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) # ¶¨ÖÆÔËÓª»î¶¯×î´ó¿ª·þÌì  | 
|     maxCustomServerDayMix = IpyGameDataPY.GetFuncCfg("MixServer", 1) # ¶¨ÖÆÔËÓª»î¶¯×î´óºÏ·þÌì  | 
|     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, curWorldLV=%s" % (curWeekday, curWorldLV))  | 
|       | 
|     for actName in ShareDefine.OperationActionNameList:  | 
|           | 
|         if actName not in mapServerOperationActionDict:  | 
|             mapServerOperationActionDict[actName] = {}  | 
|               | 
|         # È¡³ö±¾»î¶¯ËùÊô±¾·þIDµÄËùÓÐÅäÖà  | 
|         GameWorld.Log("¼ÓÔØÔËÓª»î¶¯: actName=%s,platform=%s,serverGroupID=%s" % (actName, platform, serverGroupID))  | 
|         curServerActIpyDataList = __GetOperationActionServerIpyDataList(ipyDataMgr, platform, serverGroupID, actName)  | 
|         GameWorld.Log("    ¿É´¦ÀíÌõÊý=%s" % (len(curServerActIpyDataList)))  | 
|         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()  | 
|             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)  | 
|                   | 
|             # ¿ª·þ³£¹æ£º  ¿ª·þÌì > ÈÕÆÚ > ÖÜ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  | 
|                   | 
|             # ºÏ·þ»î¶¯: Ö»ÊܺϷþÌìÓ°Ïì  | 
|             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, "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  | 
|               | 
|             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  | 
|               | 
|             # ÔÚÐèÒª´¦ÀíµÄʱ¼äÄÚ¸½¼ÓÊÀ½çµÈ¼¶¿ªÆôÏÞÖÆ£¬Î´´ïµ½×îµÍÊÀ½çµÈ¼¶ÒªÇóµÄ²»¿ª£¬»î¶¯Ê±¼ä´Óδ´ïµ½µ½´ïµ½Ò²²»¿ª  | 
|             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, ...}  | 
|             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))  | 
|               | 
|             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 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 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  | 
|                       | 
|     OperationActionInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, operationTodayActionDict, mapServerOperationActionDict])  | 
|     __SaveActWorldLVLimitInfo(actWorldLVLimitInfoNew)  | 
|       | 
|     GameWorld.Log("±¾ÈÕÔËÓª»î¶¯ÐÅÏ¢¼ÓÔØÍê±Ï!reloadSign=%s,isRefreshState=%s" % (reloadSign, isRefreshState))  | 
|     GameWorld.Log("    operationTodayActionDict=%s" % operationTodayActionDict)  | 
|     GameWorld.Log("    mapServerOperationActionDict=%s" % mapServerOperationActionDict)  | 
|     GameWorld.Log("=============================================================")  | 
|     if isRefreshState:  | 
|         Dispose_OperationActionState(True)  | 
|           | 
|     return True, OperationActionInfo  | 
|   | 
| def __GetOperationActionServerIpyDataList(ipyDataMgr, platform, serverGroupID, 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, "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:  | 
|             isExcept = False  | 
|             for serverGroupIDInfo in serverGroupIDListExcept:  | 
|                 if (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID) \  | 
|                     or ((isinstance(serverGroupIDInfo, list) or isinstance(serverGroupIDInfo, tuple)) \  | 
|                         and len(serverGroupIDInfo) == 2 and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]):  | 
|                     isExcept = True  | 
|                     break  | 
|             if isExcept:  | 
|                 continue  | 
|               | 
|         if not serverGroupIDList:  | 
|             curServerActIpyDataList.append(ipyData)  | 
|         else:  | 
|             for serverGroupIDInfo in serverGroupIDList:  | 
|                 if (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID) \  | 
|                     or ((isinstance(serverGroupIDInfo, list) or isinstance(serverGroupIDInfo, tuple)) \  | 
|                         and len(serverGroupIDInfo) == 2 and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]):  | 
|                     curServerActIpyDataList.append(ipyData)  | 
|                     break  | 
|                   | 
|     return curServerActIpyDataList  | 
|   | 
| def __GetOperationActionDisableWeekIpyDataInfo(actName, curDateTime, curServerActIpyDataList):  | 
|     ## »ñÈ¡²»¿ÉÓõİ´ÐÇÆÚX¿ªÆôµÄÅäÖÃÊý¾ÝÐÅÏ¢£¬°´ÐÇÆÚX¿ªÆôµÄ »î¶¯ÓÅÏȼ¶Ð¡ÓÚ°´Èͮ򵀣¬µ±ÓÐÖØµþʱÒÔÈÕÆÚµÄΪ׼  | 
|     #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()  | 
|         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"):  | 
|             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])  | 
|               | 
|         # °´ÈÕÆÚµÄ  | 
|         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])  | 
|               | 
|         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  | 
|     operationTodayActionDict = OperationActionInfo[OperationAction_TodayInfo]  | 
|     mapServerInfoDict = OperationActionInfo[OperationAction_MapServerInfo]  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     # ÕâÀïʱ¼äÐ辫ȷµ½·ÖÖÓ£¬²»È»ºóÃæµÄ±È½Ï»áÆ¥Åä²»µ½  | 
|     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)  | 
|       | 
|     for actName in ShareDefine.OperationActionNameList:  | 
|           | 
|         if actName not in mapServerInfoDict:  | 
|             continue  | 
|           | 
|         if actName in ShareDefine.MultiActNumOperationActNameList:  | 
|             curActMapInfoDictList = mapServerInfoDict[actName].values()  | 
|         else:  | 
|             curActMapInfoDictList = [mapServerInfoDict[actName]]  | 
|               | 
|         for sendMapServerMsgDict in curActMapInfoDictList:  | 
|               | 
|             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 # ´ú±íµÚ¼¸¸öʱ¼ä¶Î  | 
|                             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)  | 
|                       | 
|             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:  | 
|                 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("    sendMapServerMsgDict: %s" % (sendMapServerMsgDict))  | 
|               | 
|             if actName in ShareDefine.MultiActNumOperationActNameList:  | 
|                 mapServerInfoDict[actName][actNum] = sendMapServerMsgDict  | 
|             else:  | 
|                 mapServerInfoDict[actName] = sendMapServerMsgDict  | 
|     return  | 
|   | 
| def Sync_OperationAction_ExpRate(ipyData, curPlayer=None):  | 
|     if not ipyData:  | 
|         return  | 
|     if len(ipyData.GetStartTimeList()) != len(ipyData.GetEndTimeList()):  | 
|         return  | 
|     startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)  | 
|     multiExpRateInfo = ChPyNetSendPack.tagGCMultiExpRateInfo()  | 
|     multiExpRateInfo.Clear()  | 
|     multiExpRateInfo.StartDate = startDateStr  | 
|     multiExpRateInfo.EndtDate = endDateStr  | 
|     multiExpRateInfo.ActivityTime = []  | 
|     for i, startTime in enumerate(ipyData.GetStartTimeList()):  | 
|         endTime = ipyData.GetEndTimeList()[i]  | 
|         timeInfo = ChPyNetSendPack.tagGCMultiExpRateTime()  | 
|         timeInfo.StartTime = startTime  | 
|         timeInfo.EndtTime = endTime  | 
|         multiExpRateInfo.ActivityTime.append(timeInfo)  | 
|     multiExpRateInfo.ActivityTimeCount = len(multiExpRateInfo.ActivityTime)  | 
|     multiExpRateInfo.LimitLV = ipyData.GetLVLimit()  | 
|     multiExpRateInfo.AddExpRate = ipyData.GetAddExpRate()  | 
|       | 
|     if not curPlayer:  | 
|         # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(i)  | 
|             if curPlayer == None or not curPlayer.GetInitOK():  | 
|                 continue  | 
|             NetPackCommon.SendFakePack(curPlayer, multiExpRateInfo)  | 
|     else:  | 
|         NetPackCommon.SendFakePack(curPlayer, multiExpRateInfo)  | 
|     return  | 
|   | 
|   | 
| def Sync_OperationAction_RealmPoint(ipyData, curPlayer=None):  | 
|     ##¶à±¶ÐÞÐеã»î¶¯ÐÅϢ֪ͨ  | 
|     if not ipyData:  | 
|         return  | 
|     startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)  | 
|     multiRealmPointInfo = ChPyNetSendPack.tagGCMultiRealmPointInfo()  | 
|     multiRealmPointInfo.Clear()  | 
|     multiRealmPointInfo.StartDate = startDateStr  | 
|     multiRealmPointInfo.EndtDate = endDateStr  | 
|     multiRealmPointInfo.Multiple = ipyData.GetMultiple()  | 
|     multiRealmPointInfo.LimitLV = ipyData.GetLVLimit()  | 
|     multiRealmPointInfo.LimitPoint = ipyData.GetPointLimit()  | 
|     if not curPlayer:  | 
|         # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(i)  | 
|             if curPlayer == None or not curPlayer.GetInitOK():  | 
|                 continue  | 
|             NetPackCommon.SendFakePack(curPlayer, multiRealmPointInfo)  | 
|     else:  | 
|         NetPackCommon.SendFakePack(curPlayer, multiRealmPointInfo)  | 
|     return  | 
|   | 
|   | 
| ##--------------------------------------------------------------------------------------------------  | 
|   | 
| def __GetTodayDailyActionInfo():  | 
|     # »ñÈ¡±¾ÈÕ´ý´¦ÀíµÄÈÕ³£»î¶¯ÐÅÏ¢  | 
|     key = "TodayDailyActionInfo"  | 
|     openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1  | 
|     isMixServer = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServer)  | 
|     mixServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MixServerDay) + 1  | 
|     loadSign = [openServerDay, isMixServer, mixServerDay]  | 
|     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  | 
|     curTime = int(time.time())  | 
|     curDateStr = GameWorld.ChangeTimeNumToStr(curTime, ChConfig.TYPE_Time_YmdFormat) # µ±ÌìÈÕÆÚ  | 
|       | 
|     openServerWeekday = GameWorldProcess.GetOpenServerWeekday() # ·þÎñÆ÷¿ª·þʱÊÇÐÇÆÚ¼¸  | 
|     curMaxCustomServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) - openServerWeekday + 1 # ×î´óÓÐЧ¶¨ÖÆ¿ª·þÌì  | 
|     maxCustomServerDayMix = IpyGameDataPY.GetFuncCfg("MixServer", 1)  | 
|     GameWorld.Log("===== ¼ÓÔØ½ñÌìÈÕ³£»î¶¯ÐÅÏ¢ =====")  | 
|     GameWorld.Log("¿ª·þÊÇÐÇÆÚ%s, ¿ª·þµÚ%sÌì, µ±Ç°ÐÇÆÚ%s" % (openServerWeekday, openServerDay, weekDay))  | 
|     GameWorld.Log("×î´óÓÐЧ¶¨ÖÆ¿ª·þÌì: %s" % (curMaxCustomServerDay))  | 
|     GameWorld.Log("ÊÇ·ñºÏ·þ: %s, ºÏ·þÌì: %s, ×î´ó¶¨ÖƺϷþÌì: %s" % (isMixServer, mixServerDay, maxCustomServerDayMix))  | 
|       | 
|     customDailyIDList = []  | 
|     dailyTimeInfoList = []  | 
|     # Ôݹ̶¨Ç°2Öܶ¨ÖÆÓÐЧ, Îª·½±ãGMÃüÁî²âÊÔ£¬ÕâÀïÓÿª·þÌì×öÅжϣ¬²»Óÿª·þÖÜ  | 
|     if openServerDay <= curMaxCustomServerDay:  | 
|         customIpyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("DailyActionCustom", openServerWeekday)  | 
|         if not customIpyDataList:  | 
|             customIpyDataList = []  | 
|         GameWorld.Log("    ±¾Öܶ¨ÖƵĿª·þÈÕ³£»î¶¯ÌõÊý: %s" % len(customIpyDataList))  | 
|         customIDList = []  | 
|         todayCustomIDList = []  | 
|         for customIpyData in customIpyDataList:  | 
|             dataID = customIpyData.GetID()  | 
|             dailyID = customIpyData.GetDailyID()  | 
|             if dailyID not in customDailyIDList:  | 
|                 customDailyIDList.append(dailyID)  | 
|             customIDList.append(dataID)  | 
|             if customIpyData.GetOpenServerDay() == openServerDay:  | 
|                 todayCustomIDList.append(dataID)  | 
|                 customType = 1  | 
|                 dailyTimeInfoList.append([customType, customIpyData.GetOpenTimeList(), customIpyData])  | 
|                 GameWorld.Log("    Ôö¼Ó±¾ÈÕ¿ª·þÈÕ³£»î¶¯ÐÅÏ¢: customType=%s,dailyID=%s,dataID=%s" % (customType, dailyID, dataID))  | 
|         GameWorld.Log("    ±¾Öܶ¨ÖƵĿª·þÈÕ³£ÅäÖñíIDÁбí: %s" % (customIDList))  | 
|         GameWorld.Log("    ±¾Öܶ¨ÖƵĿª·þÈÕ³£»î¶¯IDÁбí: %s" % (customDailyIDList))  | 
|         GameWorld.Log("    ½ñÌì¶¨ÖÆµÄ¿ª·þÈÕ³£±íIDÁбí=%s" % (todayCustomIDList))  | 
|     elif isMixServer and mixServerDay <= maxCustomServerDayMix:  | 
|         todayCustomIDList = [] # ½ñÌì¶¨ÖÆµÄÊý¾Ý±íID  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetDailyActionCustomMixCount()):  | 
|             customIpyData = ipyDataMgr.GetDailyActionCustomMixByIndex(i)  | 
|             dataID = customIpyData.GetID()  | 
|             dailyID = customIpyData.GetDailyID()  | 
|             if dailyID not in customDailyIDList:  | 
|                 customDailyIDList.append(dailyID)  | 
|             if customIpyData.GetMixServerDay() == mixServerDay:  | 
|                 todayCustomIDList.append(dataID)  | 
|                 customType = 2  | 
|                 dailyTimeInfoList.append([customType, customIpyData.GetOpenTimeList(), customIpyData])  | 
|                 GameWorld.Log("    Ôö¼Ó±¾ÈպϷþÈÕ³£»î¶¯ÐÅÏ¢: customType=%s,dailyID=%s,dataID=%s" % (customType, dailyID, dataID))  | 
|         GameWorld.Log("    ¶¨ÖƵĺϷþÈÕ³£»î¶¯IDÁбí: %s" % (customDailyIDList))  | 
|         GameWorld.Log("    ½ñÌì¶¨ÖÆµÄºÏ·þÈÕ³£±íIDÁбí=%s" % (todayCustomIDList))  | 
|     else:  | 
|         GameWorld.Log("    ³¬¹ý×î´ó¶¨ÖÆ¿ª·þÌ죬²»¶¨ÖÆ£¬×ß³£¹æÈÕ³£ÅäÖã¡")  | 
|       | 
|     GameWorld.Log("    ´¦Àí³£¹æÈÕ³£»î¶¯ÅäÖÃ")  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     dailyActionCount = ipyDataMgr.GetDailyActionCount()  | 
|     for i in xrange(dailyActionCount):  | 
|         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)  | 
|             continue  | 
|           | 
|         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]  | 
|         customType = 0  | 
|         dailyTimeInfoList.append([customType, openTimeList, dailyIpyData])  | 
|           | 
|     GameWorld.Log("    -----------------------")  | 
|     for customType, 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("    Ôö¼Ó±¾ÈÕÏÞʱÈÕ³£»î¶¯ÐÅÏ¢: customType=%s,dailyID=%s,openList=%s,overList=%s,goonStateDict=%s,notifyDict=%s"   | 
|                       % (customType, dailyID, openList, overList, goonStateDict, notifyDict))  | 
|           | 
|     TodayDailyActionInfo = IpyGameDataPY.SetConfigEx(key, [loadSign, todayActionInfo])  | 
|     GameWorld.Log("±¾ÈÕÈÕ³£»î¶¯ÐÅÏ¢¼ÓÔØÍê±Ï! loadSign=%s" % loadSign)  | 
|     GameWorld.Log("=============================================================")  | 
|     return TodayDailyActionInfo[1]  | 
|   | 
| def Dispose_DailyActionState():  | 
|     # ÈÕ³£»î¶¯×´Ì¬±ä¸ü¼ì²é´¦Àí  | 
|       | 
|     if GameWorld.IsCrossServer():  | 
|         CrossActionControl.Dispose_CrossDailyActionState()  | 
|       | 
|     todayDailyActionInfo = __GetTodayDailyActionInfo()  | 
|     if not todayDailyActionInfo:  | 
|         return  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     dayTime = GameWorld.GetServerTime()  | 
|     curHourMinute = (dayTime.hour, dayTime.minute)  | 
|       | 
|     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]  | 
|                 PlayerControl.WorldNotify(0, notifyKey, paramList)  | 
|                   | 
|         dictName = ShareDefine.Def_Notify_WorldKey_DailyActionState % dailyActionID  | 
|         beforeState = gameWorld.GetDictByKey(dictName)  | 
|         if beforeState == state:  | 
|             #ÒѾÊÇÕâ¸ö״̬ÁË  | 
|             continue  | 
|           | 
|         if state:  | 
|             # Æï³èÕù¶á»î¶¯¿ªÊ¼Ç°Í¬²½ÓÐЧÈËÊýµ½µØÍ¼  | 
|             if dailyActionID == ShareDefine.DailyActionID_FamilyRobBoss:  | 
|                 GameWorldBoss.SyncMapServer_HorsePetRobBossPlayerCount()  | 
|                 GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ActionBossRebornSign % dailyActionID, int(time.time()))  | 
|                   | 
|         #֪ͨMapserver,ÉèÖÃ×Öµä  | 
|         GameWorld.SendMapServerMsgEx(dictName, state)  | 
|         #¸üÐÂ×ÖµäÖµ  | 
|         gameWorld.SetDict(dictName, state)  | 
|         GameWorld.Log("ÈÕ³£»î¶¯×´Ì¬±ä¸ü: dailyActionID=%s,state=%s,dictName=%s" % (dailyActionID, state, dictName))  | 
|         __DoLogic_GameServer_ActionState(dictName, state, beforeState)  | 
|           | 
|     return  | 
|   | 
| 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  | 
|       | 
|     for actionInfo in todayDailyActionInfo:  | 
|         dailyActionID = actionInfo[0]  | 
|         dictName = ShareDefine.Def_Notify_WorldKey_DailyActionState % dailyActionID   | 
|         state = gameWorld.GetDictByKey(dictName)  | 
|         if state:  | 
|             GameWorld.SendMapServerMsgEx(dictName, state)  | 
|     return  | 
|   | 
| ## -------------------------------------------------------------------------------------------------  | 
| def __GetFBStateEndTimeNotResetIDList():  | 
|     key = "FBStateEndTimeNotReset" # ½áÊøÊ±¼ä״̬²»ÖØÖÃΪ0µÄÊý¾ÝID  | 
|     notResetIDList = IpyGameDataPY.GetConfigEx(key)  | 
|     if notResetIDList == None:  | 
|         mapStateTimeDict = {}  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetFBStateTimeCount()):  | 
|             fbStateTimeIpyData = ipyDataMgr.GetFBStateTimeByIndex(i)  | 
|             dataID = fbStateTimeIpyData.GetID()  | 
|             dataMapID = fbStateTimeIpyData.GetDataMapID()  | 
|             startWeekDay, startHour, startMinute = fbStateTimeIpyData.GetStartWeekday(), fbStateTimeIpyData.GetStartHour(), fbStateTimeIpyData.GetStartMinute()  | 
|             endWeekDay, endHour, endMinute = startWeekDay, fbStateTimeIpyData.GetEndHour(), fbStateTimeIpyData.GetEndMinute()  | 
|             startTimeList, endTimeDict = mapStateTimeDict.get(dataMapID, [[], {}])  | 
|             startTimeList.append([startWeekDay, startHour, startMinute])  | 
|             endTimeDict[dataID] = [endWeekDay, endHour, endMinute]  | 
|             mapStateTimeDict[dataMapID] = [startTimeList, endTimeDict]  | 
|               | 
|         FBStateEndTimeNotResetIDList = []  | 
|         for dataMapID, timeInfo in mapStateTimeDict.items():  | 
|             startTimeList, endTimeDict = timeInfo  | 
|             for dataID, endTime in endTimeDict.items():  | 
|                 # ½áÊøÊ±¼äÊôÓÚijһÌõµÄ¿ªÆôʱ¼ä£¬Ôò²»ÖØÖ㬾ßÌå״̬ÓÉÁíÒ»Ìõ¾ö¶¨  | 
|                 if endTime in startTimeList:  | 
|                     FBStateEndTimeNotResetIDList.append(dataID)  | 
|         FBStateEndTimeNotResetIDList.sort()  | 
|           | 
|         # ¼ÓÔØ¿ª·þ¶¨ÖÆ±í  | 
|         customStateTimeDict = {}  | 
|         for i in xrange(ipyDataMgr.GetFBStateTimeCustomCount()):  | 
|             customIpyData = ipyDataMgr.GetFBStateTimeCustomByIndex(i)  | 
|             dataID = customIpyData.GetID()  | 
|             dataMapID = customIpyData.GetDataMapID()  | 
|             openWeek, openDay = customIpyData.GetOpenServerWeek(), customIpyData.GetOpenServerDay()  | 
|             startHour, startMinute = customIpyData.GetStartHour(), customIpyData.GetStartMinute()  | 
|             endHour, endMinute = customIpyData.GetEndHour(), customIpyData.GetEndMinute()  | 
|             startTimeList, endTimeDict = customStateTimeDict.get(dataMapID, [[], {}])  | 
|             startTimeList.append([openWeek, openDay, startHour, startMinute])  | 
|             endTimeDict[dataID] = [openWeek, openDay, endHour, endMinute]  | 
|             customStateTimeDict[dataMapID] = [startTimeList, endTimeDict]  | 
|               | 
|         FBStateEndTimeNotResetCustomIDList = []  | 
|         for dataMapID, timeInfo in customStateTimeDict.items():  | 
|             startTimeList, endTimeDict = timeInfo  | 
|             for dataID, endTime in endTimeDict.items():  | 
|                 # ½áÊøÊ±¼äÊôÓÚijһÌõµÄ¿ªÆôʱ¼ä£¬Ôò²»ÖØÖ㬾ßÌå״̬ÓÉÁíÒ»Ìõ¾ö¶¨  | 
|                 if endTime in startTimeList:  | 
|                     FBStateEndTimeNotResetCustomIDList.append(dataID)  | 
|         FBStateEndTimeNotResetCustomIDList.sort()  | 
|           | 
|         # ¼ÓÔØºÏ·þ¶¨ÖÆ±í  | 
|         customMixStateTimeDict = {}  | 
|         for i in xrange(ipyDataMgr.GetFBStateTimeCustomMixCount()):  | 
|             customIpyData = ipyDataMgr.GetFBStateTimeCustomMixByIndex(i)  | 
|             dataID = customIpyData.GetID()  | 
|             dataMapID = customIpyData.GetDataMapID()  | 
|             openMixDay = customIpyData.GetMixServerDay()  | 
|             startHour, startMinute = customIpyData.GetStartHour(), customIpyData.GetStartMinute()  | 
|             endHour, endMinute = customIpyData.GetEndHour(), customIpyData.GetEndMinute()  | 
|             startTimeList, endTimeDict = customMixStateTimeDict.get(dataMapID, [[], {}])  | 
|             startTimeList.append([openMixDay, startHour, startMinute])  | 
|             endTimeDict[dataID] = [openMixDay, endHour, endMinute]  | 
|             customMixStateTimeDict[dataMapID] = [startTimeList, endTimeDict]  | 
|               | 
|         FBStateEndTimeNotResetCustomMixIDList = []  | 
|         for dataMapID, timeInfo in customMixStateTimeDict.items():  | 
|             startTimeList, endTimeDict = timeInfo  | 
|             for dataID, endTime in endTimeDict.items():  | 
|                 # ½áÊøÊ±¼äÊôÓÚijһÌõµÄ¿ªÆôʱ¼ä£¬Ôò²»ÖØÖ㬾ßÌå״̬ÓÉÁíÒ»Ìõ¾ö¶¨  | 
|                 if endTime in startTimeList:  | 
|                     FBStateEndTimeNotResetCustomMixIDList.append(dataID)  | 
|         FBStateEndTimeNotResetCustomMixIDList.sort()  | 
|           | 
|         notResetIDList = IpyGameDataPY.SetConfigEx(key, [FBStateEndTimeNotResetIDList, FBStateEndTimeNotResetCustomIDList, FBStateEndTimeNotResetCustomMixIDList])  | 
|         GameWorld.Log("¼ÓÔØ¸±±¾×´Ì¬½áÊøÊ±¼ä²»ÐèÒªÖØÖÃ״ֵ̬µÄÊý¾ÝIDÁбí:")  | 
|         GameWorld.Log("    ²»ÐèÒªÖØÖõij£¹æ³£¹æID: %s" % FBStateEndTimeNotResetIDList)  | 
|         GameWorld.Log("    ²»ÐèÒªÖØÖõĿª·þ¶¨ÖÆID: %s" % FBStateEndTimeNotResetCustomIDList)  | 
|         GameWorld.Log("    ²»ÐèÒªÖØÖõĺϷþ¶¨ÖÆID: %s" % FBStateEndTimeNotResetCustomMixIDList)  | 
|     return notResetIDList  | 
|   | 
| def __GetTodayFBStateTimeInfo():  | 
|     key = "TodayFBStateTimeInfo"  | 
|     openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1  | 
|     isMixServer = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServer)  | 
|     mixServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_MixServerDay) + 1  | 
|     loadSign = [openServerDay, isMixServer, mixServerDay]  | 
|     TodayFBStateTimeInfo = IpyGameDataPY.GetConfigEx(key)  | 
|     if TodayFBStateTimeInfo and TodayFBStateTimeInfo[0] == loadSign:  | 
|         #GameWorld.DebugLog("ÒѾ¼ÓÔØ¹ý±¾ÈÕ¸±±¾×´Ì¬´¦ÀíÐÅÏ¢£¡loadSign=%s" % loadSign)  | 
|         return TodayFBStateTimeInfo[1]  | 
|       | 
|     openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1  | 
|     curDateTime = GameWorld.GetServerTime()  | 
|     curWeekDay, curHour, curMinute = curDateTime.weekday() + 1, curDateTime.hour, curDateTime.minute  | 
|       | 
|     openServerWeekday = GameWorldProcess.GetOpenServerWeekday() # ·þÎñÆ÷¿ª·þʱÊÇÐÇÆÚ¼¸  | 
|     if openServerWeekday <= 0:  | 
|         GameWorld.ErrLog("»ñÈ¡¿ª·þÊÇÐÇÆÚ¼¸Êý¾Ý´íÎó£¡openServerWeekday=%s" % openServerWeekday)  | 
|         return []  | 
|       | 
|     curMaxCustomServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1) - openServerWeekday + 1 # ×î´óÓÐЧ¶¨ÖÆ¿ª·þÌì  | 
|     maxCustomServerDayMix = IpyGameDataPY.GetFuncCfg("MixServer", 1)  | 
|     GameWorld.Log("===== ¼ÓÔØ½ñÌ츱±¾×´Ì¬Ê±¼ä±í =====")  | 
|     GameWorld.Log("¿ª·þÊÇÐÇÆÚ%s, ¿ª·þµÚ%sÌì, µ±Ç°ÐÇÆÚ%s,%sµã%s·Ö £¡" % (openServerWeekday, openServerDay, curWeekDay, curHour, curMinute))  | 
|     GameWorld.Log("×î´óÓÐЧ¶¨ÖÆ¿ª·þÌì: %s" % (curMaxCustomServerDay))  | 
|     GameWorld.Log("ÊÇ·ñºÏ·þ: %s, ºÏ·þÌì: %s, ×î´ó¶¨ÖƺϷþÌì: %s" % (isMixServer, mixServerDay, maxCustomServerDayMix))  | 
|       | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|       | 
|     customMapIDList = [] # ±¾ÖÜÓж¨ÖƵĸ±±¾Êý¾ÝµØÍ¼IDÁÐ±í  | 
|     fbStateTimeInfoList = []  | 
|     # Ôݹ̶¨Ç°2Öܶ¨ÖÆÓÐЧ, Îª·½±ãGMÃüÁî²âÊÔ£¬ÕâÀïÓÿª·þÌì×öÅжϣ¬²»Óÿª·þÖÜ  | 
|     if openServerDay <= curMaxCustomServerDay:  | 
|         customIpyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("FBStateTimeCustom", openServerWeekday)  | 
|         if not customIpyDataList:  | 
|             customIpyDataList = []  | 
|         GameWorld.Log("    ±¾Öܶ¨ÖƵĿª·þ¸±±¾»î¶¯ÌõÊý: %s" % len(customIpyDataList))  | 
|         customIDList = [] # ±¾Öܶ¨ÖƵÄÊý¾Ý±íID  | 
|         todayCustomIDList = [] # ½ñÌì¶¨ÖÆµÄÊý¾Ý±íID  | 
|         for customIpyData in customIpyDataList:  | 
|             dataID = customIpyData.GetID()  | 
|             dataMapID = customIpyData.GetDataMapID()  | 
|             if dataMapID not in customMapIDList:  | 
|                 customMapIDList.append(dataMapID)  | 
|             customIDList.append(dataID)  | 
|             if customIpyData.GetOpenServerDay() == openServerDay:  | 
|                 todayCustomIDList.append(dataID)  | 
|                 customType, startWeekDay, endWeekDay = 1, curWeekDay, curWeekDay  | 
|                 fbStateTimeInfoList.append([customType, startWeekDay, endWeekDay, customIpyData])  | 
|                 GameWorld.Log("    ½ñÌìÒª´¦ÀíµÄ¿ª·þ¸±±¾×´Ì¬ÅäÖÃ: customType=%s,dataID=%s" % (customType, dataID))  | 
|         GameWorld.Log("    ±¾Öܶ¨ÖƵĿª·þ¸±±¾±íIDÁбí: %s" % (customIDList))  | 
|         GameWorld.Log("    ±¾Öܶ¨ÖƵĿª·þ¸±±¾µØÍ¼Áбí: %s" % (customMapIDList))  | 
|         GameWorld.Log("    ½ñÌì¶¨ÖÆµÄ¿ª·þ¸±±¾±íIDÁбí=%s" % (todayCustomIDList))  | 
|     elif isMixServer and mixServerDay <= maxCustomServerDayMix:  | 
|         todayCustomIDList = [] # ½ñÌì¶¨ÖÆµÄÊý¾Ý±íID  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetFBStateTimeCustomMixCount()):  | 
|             customIpyData = ipyDataMgr.GetFBStateTimeCustomMixByIndex(i)  | 
|             dataID = customIpyData.GetID()  | 
|             dataMapID = customIpyData.GetDataMapID()  | 
|             if dataMapID not in customMapIDList:  | 
|                 customMapIDList.append(dataMapID)  | 
|             if customIpyData.GetMixServerDay() == mixServerDay:  | 
|                 todayCustomIDList.append(dataID)  | 
|                 customType, startWeekDay, endWeekDay = 2, curWeekDay, curWeekDay  | 
|                 fbStateTimeInfoList.append([customType, startWeekDay, endWeekDay, customIpyData])  | 
|                 GameWorld.Log("    ½ñÌìÒª´¦ÀíµÄºÏ·þ¸±±¾×´Ì¬ÅäÖÃ: customType=%s,dataID=%s" % (customType, dataID))  | 
|         GameWorld.Log("    ¶¨ÖƵĺϷþ¸±±¾µØÍ¼Áбí: %s" % (customMapIDList))  | 
|         GameWorld.Log("    ½ñÌì¶¨ÖÆµÄºÏ·þ¸±±¾±íIDÁбí=%s" % (todayCustomIDList))  | 
|     else:  | 
|         GameWorld.Log("    ³¬¹ý×î´ó¶¨ÖÆ¿ª·þÌ죬²»¶¨ÖÆ£¬×ß³£¹æ¸±±¾×´Ì¬Ê±¼ä£¡")  | 
|           | 
|     GameWorld.Log("    ´¦Àí³£¹æ¸±±¾×´Ì¬Ê±¼äÅäÖÃ")  | 
|     for i in xrange(ipyDataMgr.GetFBStateTimeCount()):  | 
|         fbStateTimeIpyData = ipyDataMgr.GetFBStateTimeByIndex(i)  | 
|         dataID = fbStateTimeIpyData.GetID()  | 
|         dataMapID = fbStateTimeIpyData.GetDataMapID()  | 
|         # Êǵ±Ì쿪·þÌì¶¨ÖÆ»î¶¯µÄ²»´¦Àí³£¹æ»î¶¯  | 
|         if dataMapID in customMapIDList:  | 
|             GameWorld.Log("    dataID=%s,dataMapID=%s, ÔÚ±¾Öܶ¨ÖƵĸ±±¾µØÍ¼ÁбíÀï,²»´¦Àí£¡" % (dataID, dataMapID))  | 
|             continue  | 
|         # Ôݲ»Ö§³Ö¿çÌìµÄ»î¶¯  | 
|         customType, startWeekDay, endWeekDay = 0, fbStateTimeIpyData.GetStartWeekday(), fbStateTimeIpyData.GetStartWeekday()  | 
|         if curWeekDay != startWeekDay:  | 
|             GameWorld.Log("    dataID=%s,dataMapID=%s, ²»ÊDZ¾ÌìµÄ¸±±¾»î¶¯,²»´¦Àí£¡ curWeekDay=%s,startWeekDay=%s"   | 
|                           % (dataID, dataMapID, curWeekDay, startWeekDay))  | 
|             continue   | 
|         fbStateTimeInfoList.append([customType, startWeekDay, endWeekDay, fbStateTimeIpyData])  | 
|         GameWorld.Log("    ½ñÌìÒª´¦ÀíµÄ¸±±¾×´Ì¬ÅäÖÃ: customType=%s,dataID=%s" % (customType, dataID))  | 
|           | 
|     TodayFBStateTimeInfo = IpyGameDataPY.SetConfigEx(key, [loadSign, fbStateTimeInfoList])  | 
|     GameWorld.Log("±¾ÈÕ¸±±¾»î¶¯×´Ì¬ÐÅÏ¢¼ÓÔØÍê±Ï! loadSign=%s" % loadSign)  | 
|     GameWorld.Log("=============================================================")  | 
|     return TodayFBStateTimeInfo[1]  | 
|   | 
| def Dispose_FBStateTime():  | 
|     ## ¸±±¾×´Ì¬Ê±¼ä±í״̬´¦Àí, Ö§³Ö goon×÷Ó㬿ª¹Ø·þ״̬²»ÊÜÓ°Ï죬·þÎñÆ÷ÖØÐÂÆô¶¯»á×Ô¶¯±ä¸üΪËùÓÐʱ¼ä¶ÎµÄ״ֵ̬  | 
|       | 
|     FBStateEndTimeNotResetIDList, FBStateEndTimeNotResetCustomIDList, FBStateEndTimeNotResetCustomMixIDList = __GetFBStateEndTimeNotResetIDList()  | 
|     #openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1  | 
|     curDateTime = GameWorld.GetServerTime()  | 
|     curWeekDay, curHour, curMinute = curDateTime.weekday() + 1, curDateTime.hour, curDateTime.minute  | 
|       | 
|     curTimeWHM = curWeekDay * 10000 + curHour * 100 + curMinute  | 
|       | 
|     #openServerWeekday = GameWorldProcess.GetOpenServerWeekday() # ·þÎñÆ÷¿ª·þʱÊÇÐÇÆÚ¼¸  | 
|     #GameWorld.DebugLog("¸±±¾×´Ì¬Ê±¼ä±í״̬´¦Àí...¿ª·þÊÇÐÇÆÚ%s, ¿ª·þµÚ%sÌì, µ±Ç°ÐÇÆÚ%s,%sµã%s·Ö"   | 
|     #                   % (openServerWeekday, openServerDay, curWeekDay, curHour, curMinute))  | 
|     #GameWorld.DebugLog("    FBStateEndTimeNotResetIDList=%s" % (FBStateEndTimeNotResetIDList))  | 
|     #GameWorld.DebugLog("    FBStateEndTimeNotResetCustomIDList=%s" % (FBStateEndTimeNotResetCustomIDList))  | 
|     #GameWorld.DebugLog("    FBStateEndTimeNotResetCustomMixIDList=%s" % (FBStateEndTimeNotResetCustomMixIDList))  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     fbStateTimeInfoList = __GetTodayFBStateTimeInfo()  | 
|       | 
|     for customType, startWeekDay, endWeekDay, ipyData in fbStateTimeInfoList:  | 
|         dataID = ipyData.GetID()  | 
|         dataMapID = ipyData.GetDataMapID()  | 
|         #GameWorld.DebugLog("    customType=%s,dataID=%s,dataMapID=%s" % (customType, dataID, dataMapID))  | 
|         startHour, startMinute = ipyData.GetStartHour(), ipyData.GetStartMinute()  | 
|         endHour, endMinute = ipyData.GetEndHour(), ipyData.GetEndMinute()  | 
|         # ÐÇÆÚÅäÖÃ0´ú±íÿÌì  | 
|         if startWeekDay == 0:  | 
|             startWeekDay = curWeekDay  | 
|         if endWeekDay == 0:  | 
|             endWeekDay = curWeekDay  | 
|         startTimeWHM = startWeekDay * 10000 + startHour * 100 + startMinute # °üº¬¸ÃÖµ  | 
|         endTimeWHM = endWeekDay * 10000 + endHour * 100 + endMinute # ²»º¬¸ÃÖµ  | 
|         #GameWorld.DebugLog("    ID=%s,dataMapID=%s,curTimeWHM=%s,startTimeWHM=%s,endTimeWHM=%s" % (dataID, dataMapID, curTimeWHM, startTimeWHM, endTimeWHM))  | 
|           | 
|         # È«·þ¹ã²¥key·ÖÖÓ²îÖµ¶Ô±Èʱ¼äΪ¿ªÊ¼Ê±¼ä, Ö§³ÖÕý¸ºÊ±¼ä²î  | 
|         notifyInfoDict = ipyData.GetNotifyInfoDict()  | 
|         if notifyInfoDict:  | 
|             startDateTime = curDateTime + datetime.timedelta(days=(startWeekDay - curWeekDay))  | 
|             startDateTime = datetime.datetime(startDateTime.year, startDateTime.month, startDateTime.day, startHour, startMinute, 0)  | 
|             diffDateTime = curDateTime - startDateTime  | 
|             diffMinute = (diffDateTime.days * 24 * 3600 + diffDateTime.seconds) / 60 # µ±Ç°Ê±¼äÓ뿪ʼʱ¼äÏà²î·ÖÖÓÊý  | 
|             #GameWorld.DebugLog("        ¹ã²¥ÅжÏ: curDateTime=%s,startDateTime=%s,diffDays=%s,diffSeconds=%s,diffMinute=%s"   | 
|             #                   % (curDateTime, startDateTime, diffDateTime.days, diffDateTime.seconds, diffMinute))  | 
|             if diffMinute in notifyInfoDict:  | 
|                 notifyKey, paramList = notifyInfoDict[diffMinute]  | 
|                 PlayerControl.WorldNotify(0, notifyKey, paramList)  | 
|                 #GameWorld.DebugLog("        Ö´Ðй㲥: notifyKey=%s, paramList=%s" % (notifyKey, paramList))  | 
|                   | 
|         isUpdate, isReset = False, False  | 
|         # Ö§³ÖÖ»ÅäÖÿªÆôʱ¼äʱ£¬×ö¾«È·Æ¥Åä  | 
|         if curTimeWHM == startTimeWHM:  | 
|             isUpdate = True  | 
|             #GameWorld.DebugLog("        µ±Ç°ÊÇ¿ªÊ¼Ê±¼ä!")  | 
|         # ÊǽáÊøÊ±¼ä  | 
|         elif curTimeWHM == endTimeWHM:  | 
|             if (customType == 1 and dataID not in FBStateEndTimeNotResetCustomIDList) \  | 
|                 or (customType == 2 and dataID not in FBStateEndTimeNotResetCustomMixIDList) \  | 
|                 or (not customType and dataID not in FBStateEndTimeNotResetIDList):  | 
|                 isReset = True  | 
|             #GameWorld.DebugLog("        µ±Ç°ÊǽáÊøÊ±¼ä! isReset=%s,FBStateEndTimeNotResetIDList=%s" % (isReset, FBStateEndTimeNotResetIDList))  | 
|         # ½áÊøÊ±¼äÊÇÏÂÖÜ  | 
|         elif endTimeWHM and endTimeWHM <= startTimeWHM:  | 
|             isUpdate = (curTimeWHM > startTimeWHM or curTimeWHM < endTimeWHM)  | 
|             #GameWorld.DebugLog("        ½áÊøÊ±¼äÊÇÏÂÖÜ! isUpdate=%s" % isUpdate)  | 
|         else:  | 
|             isUpdate = (startTimeWHM < curTimeWHM < endTimeWHM)  | 
|             #GameWorld.DebugLog("        ³£¹æÅжÏ: isUpdate=%s" % isUpdate)  | 
|               | 
|         if isReset:  | 
|             updCanEnter = 0  | 
|             updStateValue = 0  | 
|         elif isUpdate:  | 
|             updCanEnter = ipyData.GetCanEnter()  | 
|             updStateValue = ipyData.GetStateValue()  | 
|         else:  | 
|             #GameWorld.DebugLog("        µ±Ç°Ê±¼ä¸±±¾×´Ì¬²»±ä£¡")  | 
|             continue  | 
|           | 
|         canEnterKey = ShareDefine.Def_Notify_WorldKey_FBCanEnter % dataMapID  | 
|         if gameWorld.GetDictByKey(canEnterKey) != updCanEnter:  | 
|             GameWorld.SendMapServerMsgEx(canEnterKey, updCanEnter) #֪ͨMapserver,ÉèÖÃ×Öµä  | 
|             gameWorld.SetDict(canEnterKey, updCanEnter) #¸üÐÂ×ÖµäÖµ  | 
|             if updCanEnter:  | 
|                 SaveFBOpenRecord(dataMapID)  | 
|             GameWorld.Log("¸±±¾ÊÇ·ñ¿É½øÈë±ä¸ü: dataMapID=%s,updCanEnter=%s,canEnterKey=%s" % (dataMapID, updCanEnter, canEnterKey))  | 
|         #else:  | 
|         #    GameWorld.DebugLog("        ¸±±¾¿É·ñ½øÈëÒѾÊǸÃÖµ: dataMapID=%s,updCanEnter=%s,canEnterKey=%s" % (dataMapID, updCanEnter, canEnterKey))              | 
|               | 
|         fbFuncStateKey = ShareDefine.Def_Notify_WorldKey_FBFuncState % dataMapID  | 
|         beforeState = gameWorld.GetDictByKey(fbFuncStateKey)  | 
|         if beforeState != updStateValue:  | 
|             GameWorld.SendMapServerMsgEx(fbFuncStateKey, updStateValue) #֪ͨMapserver,ÉèÖÃ×Öµä  | 
|             gameWorld.SetDict(fbFuncStateKey, updStateValue) #¸üÐÂ×ÖµäÖµ  | 
|             GameWorld.Log("¸±±¾×´Ì¬±ä¸ü: dataMapID=%s,updStateValue=%s,fbFuncStateKey=%s" % (dataMapID, updStateValue, fbFuncStateKey))  | 
|             __DoLogic_GameServer_ActionState(fbFuncStateKey, updStateValue, beforeState)  | 
|         #else:  | 
|         #    GameWorld.DebugLog("        ¸±±¾×´Ì¬ÒѾÊǸÃÖµ: dataMapID=%s,updStateValue=%s,fbFuncStateKey=%s" % (dataMapID, updStateValue, fbFuncStateKey))  | 
|               | 
|               | 
|     return  | 
|   | 
| def SaveFBOpenRecord(mapID):  | 
|     #¼Ç¼¸±±¾¿ªÆôʱ¼ä  | 
|     #{mapid:['0315','0316'],..}  | 
|     curTime = GameWorld.GetServerTime()  | 
|     curDayStr = '%02d%02d' % (curTime.month, curTime.day)  | 
|       | 
|     fbOpenRecord = {}  | 
|     recType = ShareDefine.Def_UniversalGameRecType_LimitFBOpenRecord  | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()    | 
|     recTypeListData = universalRecMgr.GetTypeList(recType)  | 
|     findRecData = None  | 
|     for index in range(recTypeListData.Count()):  | 
|         universalRecData = recTypeListData.At(index)  | 
|         recMapID = universalRecData.GetValue1()  | 
|         if recMapID == mapID:  | 
|             findRecData = universalRecData  | 
|         fbOpenRecord[recMapID] = eval(universalRecData.GetStrValue1())  | 
|           | 
|     if not findRecData:  | 
|         findRecData = recTypeListData.AddRec()  | 
|         findRecData.SetValue1(mapID)  | 
|         findRecData.SetStrValue1(str([curDayStr]))  | 
|         fbOpenRecord[mapID] = [curDayStr]  | 
|     else:  | 
|         recordList = eval(findRecData.GetStrValue1())  | 
|         if curDayStr not in recordList:  | 
|             recordList.append(curDayStr)  | 
|             if len(recordList) > 3: #Ö»´æ×î½ü3´Î  | 
|                 del recordList[0]  | 
|             findRecData.SetStrValue1(str(recordList))  | 
|             fbOpenRecord[mapID] = recordList  | 
|         else:  | 
|             return  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FBOpenRecord, fbOpenRecord)  | 
|     return  | 
|   | 
| def GetFBOpenRecord():  | 
|     #»ñÈ¡¸±±¾¿ªÆôʱ¼ä¼Ç¼  | 
|     fbOpenRecord = {}  | 
|     recType = ShareDefine.Def_UniversalGameRecType_LimitFBOpenRecord  | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()    | 
|     recTypeListData = universalRecMgr.GetTypeList(recType)  | 
|     for index in range(recTypeListData.Count()):  | 
|         universalRecData = recTypeListData.At(index)  | 
|         recMapID = universalRecData.GetValue1()  | 
|         recordList = eval(universalRecData.GetStrValue1())  | 
|         fbOpenRecord[recMapID] = recordList  | 
|     return fbOpenRecord  | 
|   | 
| def SendMapServerFBFuncState():  | 
|     # µØÍ¼Æô¶¯³É¹¦Ê±Í¨Öª±¾ÈÕ½øÐÐÖеĸ±±¾×´Ì¬  | 
|       | 
|     fbEnterTimeLimitMapIDList = []  | 
|       | 
|     sendMapIDList = []  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetFBStateTimeCount()):  | 
|         fbStateTimeIpyData = ipyDataMgr.GetFBStateTimeByIndex(i)  | 
|         dataMapID = fbStateTimeIpyData.GetDataMapID()  | 
|           | 
|         if fbStateTimeIpyData.GetCanEnter() and dataMapID not in fbEnterTimeLimitMapIDList:  | 
|             fbEnterTimeLimitMapIDList.append(dataMapID)  | 
|               | 
|         if dataMapID not in sendMapIDList:  | 
|             canEnterKey = ShareDefine.Def_Notify_WorldKey_FBCanEnter % dataMapID   | 
|             canEnter = gameWorld.GetDictByKey(canEnterKey)  | 
|             if canEnter:  | 
|                 GameWorld.SendMapServerMsgEx(canEnterKey, canEnter)  | 
|                   | 
|             fbFuncStateKey = ShareDefine.Def_Notify_WorldKey_FBFuncState % dataMapID   | 
|             fbFuncState = gameWorld.GetDictByKey(fbFuncStateKey)  | 
|             if fbFuncState:  | 
|                 GameWorld.SendMapServerMsgEx(fbFuncStateKey, fbFuncState)  | 
|                   | 
|             sendMapIDList.append(dataMapID)  | 
|           | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FBEnterTimeLimiitMapID, fbEnterTimeLimitMapIDList)  | 
|     fbOpenRecord = GetFBOpenRecord()  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FBOpenRecord, fbOpenRecord)  | 
|     return  | 
|   | 
| ## µ±Ç°Ê±¼äÓëÖ¸¶¨Ê±¼ä±È½Ï  | 
| #  @param curTime µ±Ç°·þÎñÆ÷ʱ¼ä   | 
| #  @param timeInfo Ö¸¶¨Ê±¼ä [[3,4(ÐÇÆÚ¼¸)], Ä꣬Ô£¬ÈÕ£¬Ê±£¬·Ö]   | 
| #  @return ´óÓÚ·µ»Ø1£¬Ð¡ÓÚ·µ»Ø-1£¬Ïàͬ·µ»Ø0  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.Òì³£ºÍ²»³É±È½ÏÌõ¼þ(ÐÇÆÚ¼¸²»¶Ô)·µ»ØNone  | 
| def CompareActTime(curTime, timeInfo):  | 
|     for index, callObj in enumerate(ATTR_CALL_TIME):  | 
|         #È¥³ý²»±È½ÏµÄÔªËØ  | 
|         if timeInfo[index] == '-':  | 
|             continue  | 
|           | 
|         if hasattr(curTime, callObj) != True:  | 
|             GameWorld.Log('###ϵͳʱ¼ä»ñµÃÒì³££¬ÎÞ´ËÊôÐÔ')  | 
|             return  | 
|           | 
|         curCallObj = getattr(curTime, callObj)  | 
|   | 
|         #ÓÅÏÈÐÇÆÚ¼¸ÌØÊâÑéÖ¤  | 
|         if type(curCallObj) != IntType:  | 
|             wday = curCallObj() + 1  | 
|             if wday not in timeInfo[index]:  | 
|                 return  | 
|               | 
|             continue  | 
|           | 
|         if curCallObj == timeInfo[index]:  | 
|             continue  | 
|           | 
|         #µ±Ç°Ê±¼ä´óÓÚÖ¸¶¨Ê±¼ä  | 
|         if curCallObj > timeInfo[index]:  | 
|             return ChConfig.Def_Cmp_Greater  | 
|         #СÓÚ  | 
|         return ChConfig.Def_Cmp_Lower  | 
|     #µÈÓÚ  | 
|     return ChConfig.Def_Cmp_Equ  | 
|   | 
| ## ÑéÖ¤»î¶¯ÊÇ·ñÔڻʱ¼ä¶Î£¨³¤Ê±¼ä¶Î£©  | 
| #  @param curTime µ±Ç°Ê±¼ä  | 
| #  @param actSect Ê±¼ä¶Î  | 
| #  @return ²¼¶ûÖµ  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def IsAtActTime(curTime, actSect):  | 
|     #ÎÞʱ¼ä¶ÎÏÞÖÆ  | 
|     if not actSect:  | 
|         return True  | 
|       | 
|     #Ôڻʱ¼ä¶Î  | 
|     if GameWorld.GetDateTimeByStr(actSect[0]) \  | 
|                 <= curTime <= GameWorld.GetDateTimeByStr(actSect[1]):  | 
|         return True  | 
|       | 
|     return False  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##´¦ÀíGameServer»î¶¯×´Ì¬  | 
| # @param dictName ×ÖµäÃû  | 
| # @param isOpen ÊÇ·ñ¿ªÆô  | 
| # @param beforeState ×´Ì¬±ä¸üǰµÄÖµ£¬²¿·ÖÅжϴ¦Àí  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks   | 
| def __DoLogic_GameServer_ActionState(dictName, isOpen, beforeState=0):  | 
|     #ÏÉÃËÑç»á   | 
|     if dictName == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyParty:  | 
|         PlayerFamilyParty.FamilyPartyStateChange(isOpen, beforeState)  | 
|     #ÏÉÃËÁªÈü  | 
|     elif dictName == ShareDefine.Def_Notify_WorldKey_FBFuncState % ChConfig.Def_FBMapID_FamilyWar:  | 
|         GameWorldFamilyWar.OnFamilyWarStateChange(isOpen)  | 
|     #ÏÉħ֮Õù  | 
|     elif dictName == ShareDefine.Def_Notify_WorldKey_FBFuncState % ChConfig.Def_FBMapID_XMZZ:  | 
|         PlayerXMZZ.OnXMZZStateChange(dictName, isOpen)  | 
|     #ÊØÎÀÈË»Ê  | 
|     elif dictName == ShareDefine.Def_Notify_WorldKey_FBFuncState % ChConfig.Def_FBMapID_FamilyInvade:  | 
|         PlayerFamilySWRH.OnSWRHStateChange(dictName, isOpen)  | 
|     #Æï³èÕù¶á  | 
|     elif dictName == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss:  | 
|         GameWorldBoss.OnHorsePetRobBossActionChange(isOpen)  | 
|     #¿ç·þPK  | 
|     elif dictName == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossReamPK:  | 
|         CrossRealmPK.OnCrossRealmPKDailyActionStateChange(isOpen)  | 
|     #ÏÉÃËBOSS  | 
|     elif dictName in [ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyBoss1]:  | 
|         PlayerFamilyBoss.OnAllFamilyBossStateChange(isOpen)  | 
|     #Æï³èBOSS  | 
|     elif dictName in [ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_HorsePetBoss]:  | 
|         PlayerHorsePetBoss.OnHorsePetBossStateChange(isOpen)  | 
|       | 
|     return  | 
|   | 
| #-------------------------------------------------------------------------------  |