#!/usr/bin/python # -*- coding: GBK -*- #--------------------------------------------------------------------- # #--------------------------------------------------------------------- ##@package PlayerFB # @todo: Íæ¼Ò¸±±¾ # # @author: hxp # @date 2013-08-23 # @version 1.5 # # @note # @change: "2014-04-16 18:00" hxp Ôö¼Ó¼Ò×åboss¸±±¾½øÈëÅÐ¶Ï # @change: "2015-01-09 10:30" hxp ¸ÄΪGetRouteServerIndex # @change: "2015-03-20 15:00" hxp Ìõ¼þÅжÏÐÞ¸Ä # @change: "2015-10-22 23:00" hxp Ôö¼Ó¿ç·þPK # @change: "2017-01-04 12:00" hxp Ôö¼ÓÒì½çÈëÇÖ #--------------------------------------------------------------------- #"""Version = 2017-01-04 12:00""" #--------------------------------------------------------------------- import GameWorldBoss import PlayerFamilyBoss import PlayerHorsePetBoss import GameWorldFamilyWar import PlayerControl import PyGameData import IpyGameDataPY import PlayerDBGSEvent import PlayerTeam import GameWorld import ChConfig import IPY_PlayerDefine import CrossBattlefield import CrossRealmPlayer import CrossChampionship import DataRecordPack import CrossRealmMsg import ShareDefine import CrossBoss import time DynamicShuntType_No = 0 # ²»·ÖÁ÷ DynamicShuntType_Fill = 1 # ÌîÂúʽ·ÖÁ÷£¬°´´æÔÚµÄÏß·ÈËÊý¶àµÄÓÅÏÈÌî³ä£¬¶¼Âúºó¿ªÆôÐÂÏß· DynamicShuntType_Equally = 2 # ¾ù̯ʽ·ÖÁ÷£¬°´´æÔÚµÄÏß·ÈËÊýÉÙµÄÓÅÏÈÌî³ä£¬¶¼Âúºó¿ªÆôÐÂÏß· #--------------------------------------------------------------------- ## ¿ç·þµØÍ¼¶¯Ì¬·ÖÅäµÄ¹¦ÄÜÏß·£¬Èç¹ûÓÐÈËÊýÉÏÏ޵ģ¬Ôòͬ·ÖÇøÍ¬µØÍ¼Íæ·¨µÄ¿ÉÄÜͬʱ´æÔÚ¶à¸öÏàͬ¹¦ÄÜÏß·µÄÊý¾Ý ## {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...} class CrossFuncLineInfo(): def __init__(self): self.realMapID = 0 self.copyMapID = 0 self.newFuncLineNum = 0 self.funcLineDataCache = None # ¹¦ÄÜÏß·×Ô¶¨Ò建´æÊý¾Ý return def OnCopyMapClose(self): self.realMapID = 0 self.copyMapID = 0 return ## ¿ç·þµØÍ¼¶¯Ì¬·ÖÅäµÄÐéÄâÏß·ÐÅÏ¢ {(mapID, copyMapID):CrossCopyMapInfo, ...} class CrossCopyMapInfo(): def __init__(self, zoneID, funcLineID): self.zoneID = zoneID self.funcLineID = funcLineID self.newFuncLineNum = 0 self.realMapID = 0 self.copyMapID = 0 self.openState = IPY_PlayerDefine.fbosClosed self.fbPlayerDict = {} # ¸±±¾ÖеÄÍæ¼ÒÐÅÏ¢ {playerID:serverGroupID, ...} self.waitPlayerDict = {} # µÈ´ý½øÈëµÄÍæ¼ÒÐÅÏ¢ {playerID:[serverGroupID, tick], ...} self.offlinePlayerDict = {} # µôÏßµÄÍæ¼ÒÐÅÏ¢£¬·ÇÖ÷¶¯Í˳öµÄ {playerID:serverGroupID, ...} self.enterPlayerIDList = [] # ÓнøÈë¹ý´Ë·ÖÏßµÄÍæ¼ÒIDÁÐ±í£¬²»»áÇå³ý [playerID, ...] return def GetCopyMapPlayerCount(self, includeOffline, tick): ## »ñÈ¡¸Ã·ÖÏßÍæ¼ÒÊý # @param includeOffline: ÊÇ·ñ°üº¬ÀëÏßÍæ¼Ò # ÒÆ³ýÇëÇó½øÈ볬ʱµÄÍæ¼Ò for waitPlayerID, playerInfo in self.waitPlayerDict.items(): _, requestTick = playerInfo if tick - requestTick > 60000: # ÇëÇó½øÈëʱ¼ä±£Áô1·ÖÖÓ self.waitPlayerDict.pop(waitPlayerID) # ÅжÏÊÇ·ñ³¬¹ýÈËÊýÉÏÏÞ fbPlayerCount, waitPlayerCount = len(self.fbPlayerDict), len(self.waitPlayerDict) totalPlayerCount = fbPlayerCount + waitPlayerCount if includeOffline: totalPlayerCount += len(self.offlinePlayerDict) return totalPlayerCount def IsMustCopyMapPlayer(self, playerID): ## ÊÇ·ñ±Ø¶¨ÔÚ´Ë·ÖÏßµÄÍæ¼Ò£¬ ÔÚÇëÇó¶ÓÁÐÀï »ò Ôø¾­½øÈëµ½¸Ã·ÖÏߵ쬶¼Ç¿ÖÆÈÏΪÊôÓڸ÷ÖÏßµÄÍæ¼Ò return playerID in self.waitPlayerDict or playerID in self.enterPlayerIDList def OnRequestEnterCrossCopyMap(self, playerID, tick, copyMapPlayerMax, includeOffline): if not copyMapPlayerMax or self.IsMustCopyMapPlayer(playerID): return True return self.GetCopyMapPlayerCount(includeOffline, tick) < copyMapPlayerMax #--------------------------------------------------------------------- def GetFBLineIpyData(mapID, lineID, isDefaultLine=True): mapID = GetRecordMapID(mapID) fbLineIpyData = IpyGameDataPY.GetIpyGameDataNotLog("FBLine", mapID, lineID) if not fbLineIpyData and isDefaultLine: #GameWorld.DebugLog("ûÓÐÖ¸¶¨¹¦ÄÜÏß·µÄÔòĬÈÏÈ¡0£¬ÔÙûÓеϰ¾ÍÊDz»ÐèÒªµÄmapID=%s, lineID=%s" % (mapID, lineID)) fbLineIpyData = IpyGameDataPY.GetIpyGameDataNotLog("FBLine", mapID, 0) return fbLineIpyData ## »ñÈ¡¼Ç¼ֵµÄmapID # @param mapID ËùÒª²éµÄmapID # @return # @remarks Ò»°ãÓÃÓÚ¼¸ÕŵØÍ¼¹«ÓÃÒ»·Ý´æ´¢¼Ç¼£¬Èç×é¶Ó¸±±¾½øÈë´ÎÊý£¬CDʱ¼äµÈÊý¾ÝÐè¹²Ïí def GetRecordMapID(mapID): DataMapIDDict = IpyGameDataPY.GetConfigEx("DataMapIDDict") if not DataMapIDDict: dMapIDDict = {} ipyDataMgr = IpyGameDataPY.IPY_Data() for i in xrange(ipyDataMgr.GetFBLineCount()): ipyData = ipyDataMgr.GetFBLineByIndex(i) dMapID = ipyData.GetDataMapID() mID = ipyData.GetMapID() dMapIDList= dMapIDDict.get(dMapID, []) if mID not in dMapIDList: dMapIDList.append(mID) dMapIDDict[dMapID] = dMapIDList for dMapID in dMapIDDict.keys(): if len(dMapIDDict[dMapID]) == 1: dMapIDDict.pop(dMapID) DataMapIDDict = IpyGameDataPY.SetConfigEx("DataMapIDDict", dMapIDDict) #GameWorld.Log("¼ÓÔØDataMapIDDict=%s" % DataMapIDDict) for dataMapID, mapIDList in DataMapIDDict.items(): if mapID in mapIDList: return dataMapID return mapID def ClientServerMsg_EnterFB(serverGroupID, msgData, tick): ## ÊÕµ½×Ó·þÇëÇó½øÈ붯̬·ÖÅäµÄ¿ç·þ¸±±¾ playerID = msgData["PlayerID"] mapID = msgData["MapID"] funcLineID = msgData["FuncLineID"] playerLV = msgData["LV"] if mapID == ChConfig.Def_FBMapID_CrossChampionship: CrossChampionship.OnRequestChampionshipVSRoom(playerID, serverGroupID) return zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID) if not zoneIpyData: return zoneID = zoneIpyData.GetZoneID() openHour, openMinute = None, None dynamicShuntType = DynamicShuntType_Fill includeOffline = False tagCopyMapObj = None # »ù´¡ÑéÖ¤ÊÇ·ñ¿É½øÈëµÈ ¼° Êý¾Ý×¼±¸ if mapID == ChConfig.Def_FBMapID_CrossDemonKing: bossID = msgData["BossID"] if not CrossBoss.GetCrossBossIsAliveOrCanReborn(zoneID, bossID): GameWorld.ErrLog("µ±Ç°¿ç·þÑýÍõËÀÍö״̬£¬²»¿É½øÈë! funcLineID=%s,zoneID=%s,bossID=%s" % (funcLineID, zoneID, bossID), playerID) return elif mapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]: pass elif mapID == ChConfig.Def_FBMapID_CrossBattlefield: openTimeInfo = CrossBattlefield.GetCrossBattlefieldOpenTime(serverGroupID, zoneID, playerID) if not openTimeInfo: #GameWorld.ErrLog("·Ç»î¶¯Ê±¼ä»ò먦Æô! funcLineID=%s,zoneID=%s" % (funcLineID, zoneID), playerID) return dynamicShuntType = DynamicShuntType_Equally isCallBattle, openHour, openMinute = openTimeInfo if isCallBattle: # ÕÙ¼¯³¡´ÎĬÈÏ funcLineID Ϊ0£¬²»·ÖµÈ¼¶£¬²»·ÖÁ÷ funcLineID = 0 dynamicShuntType = DynamicShuntType_No includeOffline = True else: return dynamicLineMaxPlayerCountDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 2) copyMapPlayerMin, copyMapPlayerMax = dynamicLineMaxPlayerCountDict.get(mapID, [0, 0]) # 0Ϊ²»ÏÞÖÆÈËÊý£¬Ä¬Èϲ»ÏÞÖÆ # ³ý¸ö±ðµØÍ¼Í⣬×îÓÅÏȽøÈëÉϴνøÈëµÄδ¹Ø±Õ·ÖÏß if mapID not in []: for _, copyMapObj in PyGameData.g_crossDynamicLineCopyMapInfo.items(): if copyMapObj.IsMustCopyMapPlayer(playerID): tagCopyMapObj = copyMapObj break # Èç¹ûûÓнøÈë¹ý£¬Ôò°´¹¦ÄÜ¿´ÊÇ·ñÓÐÌØÊâÖ¸¶¨¹æÔò if tagCopyMapObj == None: if mapID == ChConfig.Def_FBMapID_CrossBattlefield: if isCallBattle: copyMapPlayerMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCall", 2) tagCopyMapObj = CrossBattlefield.GetCallPlayerCopymapObj(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, includeOffline, tick) # Èç¹û»¹Ã»ÓÐÈ¡µ½¶ÔÓ¦µÄ·ÖÁ÷Ïߣ¬Ôò°´Ä¬ÈϹæÔò´¦Àí if tagCopyMapObj == None and dynamicShuntType: # ·ÇÌØÊ⶯̬¹æÔò£¬×ß³£¹æÂß¼­ dynamicLineLVRangeDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 4) if mapID in dynamicLineLVRangeDict: lvRangeList = dynamicLineLVRangeDict[mapID] for lvFuncLineID, lvRange in enumerate(lvRangeList): if lvRange[0] <= playerLV <= lvRange[1]: funcLineID = lvFuncLineID copyMapPlayerMin, copyMapPlayerMax = lvRange[2], lvRange[3] GameWorld.DebugLog("½øÈë¿ç·þµØÍ¼µÈ¼¶×Ô¶¯ÊÊÅ书ÄÜÏß·ID: mapID=%s,playerLV=%s,funcLineID=%s,copyMapPlayerMin=%s,copyMapPlayerMax=%s" % (mapID, playerLV, funcLineID, copyMapPlayerMin, copyMapPlayerMax)) break shuntPlayerMax = copyMapPlayerMax minCountTimeDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 3) # ·ÖÁ÷ÏÂÏÞÈËÊýÓÐЧʱ¼äÅäÖ㬵¥Î»Ã룬{dataMapID:Ãë, ...} if mapID in minCountTimeDict: playerMinTimeSet = minCountTimeDict[mapID] curTime = GameWorld.GetServerTime() if openHour == None or openMinute == None: GameWorld.ErrLog("¸±±¾¿ªÆôʱ¼äδ֪! mapID=%s,funcLineID=%s,zoneID=%s" % (mapID, funcLineID, zoneID), playerID) return openDateTimeStr = "%d-%02d-%02d %02d:%02d:00" % (curTime.year, curTime.month, curTime.day, openHour, openMinute) openDateTime = GameWorld.ChangeStrToDatetime(openDateTimeStr) passTime = curTime - openDateTime ''' ÔÚÏߣ¨°üº¬ÇëÇóÖУ© <= µ¥³¡ÏÂÏÞÖµ ÔÚÏߣ¨°üº¬ÇëÇóÖУ©+ ÀëÏß <= µ¥³¡ÉÏÏÞÖµ ǰXÃë´óÓÚ µ¥³¡ÏÂÏÞÖµ ¿ªÐÂÒ»³¡ ÈÎÒâʱ¿Ì´óÓÚ µ¥³¡ÉÏÏÞÖµ ±Ø¿ªÐÂÒ»³¡ ''' if passTime.seconds <= playerMinTimeSet: shuntPlayerMax = copyMapPlayerMin includeOffline = False else: shuntPlayerMax = copyMapPlayerMax includeOffline = True tagCopyMapObj = __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, shuntPlayerMax, copyMapPlayerMax, includeOffline, tick, dynamicShuntType) if not tagCopyMapObj: PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBFull") GameWorld.ErrLog("ÕÒ²»µ½¿É·ÖÁ÷µÄ¸±±¾Ïß·! mapID=%s,funcLineID=%s,zoneID=%s" % (mapID, funcLineID, zoneID), playerID) return realMapID, copyMapID, openState = tagCopyMapObj.realMapID, tagCopyMapObj.copyMapID, tagCopyMapObj.openState if openState == IPY_PlayerDefine.fbosWaitForClose: PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBClose") GameWorld.ErrLog("·ÖÁ÷µÄ¸±±¾Ïß·¹Ø±ÕÖÐ! mapID=%s,funcLineID=%s,zoneID=%s,realMapID=%s,copyMapID=%s,openState=%s" % (mapID, funcLineID, zoneID, realMapID, copyMapID, openState), playerID) return tagCopyMapObj.waitPlayerDict[playerID] = [serverGroupID, tick] GameWorld.DebugLog(" ·ÖÅä½øÈë¿ç·þ³¡¾°: realMapID=%s, copyMapID=%s, openState=%s" % (realMapID, copyMapID, openState), playerID) if openState == IPY_PlayerDefine.fbosOpen: funcLineID = tagCopyMapObj.funcLineID playerIDList = [playerID] # ·ÖÁ÷µØÍ¼µÄµØÍ¼Êý¾ÝIDÖ±½ÓʹÓó¡¾°ID£¬ÒòΪ·ÖÁ÷µØÍ¼Êµ¼ÊÉÏÊÇÁ½ÕŲ»Í¬µÄµØÍ¼£¬ËùÒÔÖ±½ÓʹÓó¡¾°ID£¬²»È»»áµ¼ÖÂÉÏ´«¿ç·þÍæ¼ÒÊý¾ÝÊ±×ø±êΪ0 retInfo = [playerIDList, mapID, realMapID, realMapID, copyMapID, funcLineID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) dataDict = {} dataDict.update(msgData) dataDict.update({"mapID":mapID, "realMapID":realMapID, "copyMapID":copyMapID, "realFuncLineID":funcLineID, "openState":openState}) DataRecordPack.SendEventPack("CrossFBRequest", dataDict) return tagCopyMapObj def CrossServerMsg_EnterFBRet(msgData, tick): ## ÊÕµ½¿ç·þ·þÎñÆ÷¶¯Ì¬·ÖÅäµÄ¿ç·þ¸±±¾½øÈëÐÅÏ¢ playerIDList, dataMapID, mapID, realMapID, copyMapID, funcLineID = msgData for playerID in playerIDList: curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not curPlayer: continue CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, realMapID, mapID, copyMapID, lineID=funcLineID) return def __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, shuntPlayerMax, copyMapPlayerMax, includeOffline, tick, dynamicShuntType): '''»ñÈ¡¿ç·þ·ÖÇø¶ÔÓ¦¶¯Ì¬·ÖÅäµÄ¸±±¾µØÍ¼ÐéÄâÏß·ÐÅÏ¢, ÓÉÓÚÐèÒªÖ§³Ö¶àµØÍ¼·ÖÁ÷£¬ËùÒÔÖ±½ÓÓÉGameServer¹ÜÀí·ÖÅä ÿ¸ö¹¦ÄÜÏß·֧³Ö°´ÈËÊý·ÖÁ÷£¬³¬¹ý×î´óÈËÊýºó¿É¿ªÆôÒ»ÌõÏàͬ¹¦ÄÜÏß·µÄÐéÄâÏß·½øÐзÖÁ÷£¬ËùÒÔͬһ·ÖÇøÍ¬Ò»µØÍ¼µÄ¹¦ÄÜÏß·ID¿ÉÄܶÔÓ¦¶àÌõÐéÄâÏß· ·ÖÁ÷·½Ê½£º DynamicShuntType_Fill = 1 # ÌîÂúʽ·ÖÁ÷£¬°´´æÔÚµÄÏß·ÈËÊý¶àµÄÓÅÏÈÌî³ä£¬¶¼Âúºó¿ªÆôÐÂÏß· DynamicShuntType_Equally = 2 # ¾ù̯ʽ·ÖÁ÷£¬°´´æÔÚµÄÏß·ÈËÊýÉÙµÄÓÅÏÈÌî³ä£¬¶¼Âúºó¿ªÆôÐÂÏß· ·ÖÁ÷¹æÔò: ʱ¼ä½ö¾ö¶¨·ÖÁ÷ÈËÊý£¬²»Ó°Ïì³£¹æ·ÖÅäÂß¼­ 1. ÓÅÏÈ·ÖÅäµ½ÈËÊýСÓÚ·ÖÁ÷ÈËÊýµÄ³¡´Î 2. ³¬¹ý·ÖÁ÷ÈËÊýµÄ³¡´ÎÒÀ´ÎÍùÈËÊýÉٵij¡´Î·ÖÅä 3. µ±µ±Ç°ÒÑ¿ª·ÅµÄ³¡´Î¶¼´ïµ½ÈËÊý·ÖÁ÷ÈËÊý£¬Ôò¿ªÆôг¡´Î£¬Ã»ÓпÕÏеij¡£¬ÔòÍùδ´ïµ½ÈËÊýÉÏÏ޵ij¡´ÎÒÀ´Î·ÖÅ䣬ֱµ½´ïµ½ËùÓг¡´ÎÉÏÏÞ ¹ØÓÚ shuntPlayerMax µÄÑ¡Ôñ£º ¿É¸ù¾Ý¸±±¾¹æÔòÖÆ¶¨ ÈçǰX·ÖÖÓÄÚ¿ÉÉ趨һ¸öСÓÚ copyMapPlayerMax µÄ·ÖÁ÷ÈËÊýÖµ¿ìËÙÆÌÂú¸÷·ÖÁ÷³¡´Î µ±´óÓÚX·ÖÖÓºóÔò¿ÉÉèÖà shuntPlayerMax = copyMapPlayerMax ½øÐб¥ºÍ·ÖÁ÷ µ±ËùÓзÖÁ÷³¡´Î´ïµ½ shuntPlayerMax ºó£¬¿É³¢ÊÔ¿ªÆôзÖÁ÷Ïß·£¬½øÐзÖÁ÷ shuntPlayerMax < copyMapPlayerMax µÄÇé¿ö£¬Èç¹ûûÓа취¿ªÆôзÖÁ÷Ïß·£¬Ôò¿É¼ÌÐøÇ¿ÖÆ¸ù¾Ý·ÖÁ÷ÀàÐÍ·ÖÅäÏß·£¬Ö»ÒªÎ´´ïµ½ copyMapPlayerMax ÈËÊý£¬»¹ÊÇ¿ÉÒÔ½øÈ븱±¾µÄ shuntPlayerMax >= copyMapPlayerMax µÄÇé¿ö£¬Èç¹ûûÓа취¿ªÆôзÖÁ÷Ïß·£¬Ôò±êʶ¸±±¾ËùÓÐÏß·ÒÑ´ïµ½±¥ºÍ״̬£¬²»ÄÜÔÙ½øÈ븱±¾ÁË µ± shuntPlayerMax Ϊ 0 ʱ£¬´ï±ê²»ÏÞÖÆÈËÊýÉÏÏÞ£¬¼°²»·ÖÁ÷£¬¶¼ÔÚͬһÌõÏß·£¬Ò»°ã¿ç·þ¸±±¾²»½¨ÒéÉèÖÃΪ0£¬ÈËÊýÌ«¶à£¬²»ºÏÀí @param shuntPlayerMax: ·ÖÁ÷×î´óÈËÊýÏÞÖÆ @param copyMapPlayerMax: ʵ¼Ê×î´ó¿ÉÈÝÄɵÄÈËÊýÏÞÖÆ£¬Ò»°ã´óÓÚµÈÓÚ·ÖÁ÷ÈËÊýÏÞÖÆ @param includeOffline: ÊÇ·ñ°üº¬±¾Ïß·ÀëÏßÍæ¼Ò @param dynamicShuntType: ·ÖÁ÷ÀàÐÍ£¬¿ÉÑ¡Ôñ ÌîÂúʽ·ÖÁ÷ »ò ¾ù̯ʽ·ÖÁ÷ ''' zoneLineKey = (zoneID, funcLineID) zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) funcLineObjList = zoneLineDict.get(zoneLineKey, []) isPlayerFullMax = (shuntPlayerMax >= copyMapPlayerMax) GameWorld.DebugLog("»ñÈ¡¶¯Ì¬·ÖÁ÷Ïß·: serverGroupID=%s,mapID=%s,funcLineID=%s,zoneID=%s,shuntPlayerMax=%s,copyMapPlayerMax=%s,includeOffline=%s,dynamicShuntType=%s" % (serverGroupID, mapID, funcLineID, zoneID, shuntPlayerMax, copyMapPlayerMax, includeOffline, dynamicShuntType), playerID) #GameWorld.DebugLog(" funcLineObjList=%s" % funcLineObjList, playerID) canUseShuntLine = False # ÊÇ·ñÖ±½ÓʹÓ÷ÖÁ÷Ïß·£¬Èç¹û·ñµÄ»°£¬µ±ÈËÊýδ´ïµ½ÕæÕý±¥ºÍʱ£¬Ôò»¹¿ÉÖ±½Ó·ÖÅä¶ÔÓ¦·ÖÁ÷ÀàÐ͵ÄÏß· minPlayerCount, maxPlayerCount = 0, 0 minCopyMapObj, maxCopyMapObj = None, None for _, funcLineObj in enumerate(funcLineObjList, 1): realMapID, copyMapID = funcLineObj.realMapID, funcLineObj.copyMapID #GameWorld.DebugLog(" realMapID=%s, copyMapID=%s" % (realMapID, copyMapID)) if not realMapID: continue key = (realMapID, copyMapID) if key not in PyGameData.g_crossDynamicLineCopyMapInfo: GameWorld.ErrLog("ÒѾ­·ÖÅäµÄÐéÄâÏß·²»´æÔÚ»º´æ¶ÔÓ¦¹ØÏµÀzoneID=%s,funcLineID=%s,realMapID=%s,copyMapID=%s" % (zoneID, funcLineID, realMapID, copyMapID)) continue copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] openState = copyMapObj.openState if openState == IPY_PlayerDefine.fbosWaitForClose: # ûÓÐÏÞÖÆ·ÖÁ÷ÈËÊýµÄÇé¿ö£¬´ú±í¶¼ÔÚͬһ³¡£¬ÕâÖÖÇé¿öϵ±¸±±¾ÒѾ­ÔڹرյÄ״̬Ï£¬Ôò´ú±íÒѾ­½áÊøÁË£¬²»¿ÉÔÙ½øÈë if not shuntPlayerMax: PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBClose") return #GameWorld.DebugLog(" ÐéÄâÏß·µÈ´ý¹Ø±ÕÖÐ! realMapID=%s,copyMapID=%s" % (realMapID, copyMapID)) continue if not shuntPlayerMax or copyMapObj.IsMustCopyMapPlayer(playerID): return copyMapObj playerCount = copyMapObj.GetCopyMapPlayerCount(includeOffline, tick) if minCopyMapObj == None or playerCount < minPlayerCount: minPlayerCount = playerCount minCopyMapObj = copyMapObj if maxCopyMapObj == None or playerCount > maxPlayerCount: maxPlayerCount = playerCount maxCopyMapObj = copyMapObj # ´æÔÚÏß·δ´ïµ½¹æ¶¨µÄ·ÖÁ÷ÈËÊý£¬Ôò¿ÉÖ±½ÓʹÓ÷ÖÁ÷Ïß· if playerCount < shuntPlayerMax: canUseShuntLine = True #GameWorld.DebugLog(" isPlayerFullMax=%s,canUseShuntLine=%s" % (isPlayerFullMax, canUseShuntLine)) dynamicShuntCopyMap = None # ·ÖÁ÷ÀàÐ;ö¶¨µÄ·ÖÁ÷Ïß· # ¾ù̯ʽ if dynamicShuntType == DynamicShuntType_Equally: dynamicShuntCopyMap = minCopyMapObj # ÌîÂúʽ elif dynamicShuntType == DynamicShuntType_Fill: dynamicShuntCopyMap = maxCopyMapObj else: return shuntCopyMap = None if canUseShuntLine: shuntCopyMap = dynamicShuntCopyMap #GameWorld.DebugLog(" shuntCopyMap=%s" % shuntCopyMap) if not shuntCopyMap: isLog = isPlayerFullMax shuntCopyMap = __OpenNewFuncLine(mapID, zoneID, funcLineID, isLog) # ¼´ shuntPlayerMax < copyMapPlayerMax µÄÇé¿ö if not shuntCopyMap and not isPlayerFullMax: shuntCopyMap = dynamicShuntCopyMap if not shuntCopyMap: return shuntCopyMap.waitPlayerDict[playerID] = [serverGroupID, tick] return shuntCopyMap def __OpenNewFuncLine(mapID, zoneID, funcLineID, isLog=True): ## пª¹¦ÄÜÏß··ÖÁ÷ if mapID not in PyGameData.g_crossDynamicLineInfo: PyGameData.g_crossDynamicLineInfo[mapID] = {} zoneLineDict = PyGameData.g_crossDynamicLineInfo[mapID] # ¿ç·þ¶¯Ì¬Ïß·ÐÅÏ¢ {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...} zoneLineKey = (zoneID, funcLineID) if zoneLineKey not in zoneLineDict: zoneLineDict[zoneLineKey] = [] funcLineObjList = zoneLineDict[zoneLineKey] dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1) dynamicMapIDList = dynamicLineMapDict.get(mapID, [mapID]) openMapID, openCopyMapID = 0, 0 maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(dynamicMapIDList[0], 0) # Íâ²ãΪÐéÄâÏß·×ÜÊý±éÀú£¬ÄÚ²ãΪ·ÖÁ÷µØÍ¼£¬ÕâÑù¿ÉÒÔ¾ùÔÈ·ÖÁ÷µ½¸÷¸ö·ÖÁ÷µØÍ¼£¬¼õÉÙµ¥µØÍ¼Ñ¹Á¦ for copyMapID in xrange(maxCopyMapCount): for realMapID in dynamicMapIDList: if copyMapID >= PyGameData.g_crossMapCopyMapCountDict.get(realMapID, 0): continue if (realMapID, copyMapID) not in PyGameData.g_crossDynamicLineCopyMapInfo: openMapID, openCopyMapID = realMapID, copyMapID break if openMapID: break if not openMapID: if isLog: GameWorld.ErrLog("ûÓпÕÓàµÄÐéÄâÏß·£¬ÎÞ·¨¶¯Ì¬¿ªÆô¿ç·þ¸±±¾! mapID=%s,zoneID=%s,funcLineID=%s,dynamicMapIDList=%s" % (mapID, zoneID, funcLineID, dynamicMapIDList)) return realMapID, copyMapID = openMapID, openCopyMapID newFuncLineObj = None for funcLineObj in funcLineObjList: if not funcLineObj.realMapID: newFuncLineObj = funcLineObj break if newFuncLineObj == None: newFuncLineObj = CrossFuncLineInfo() funcLineObjList.append(newFuncLineObj) newFuncLineNum = 1 lineNumList = [lineObj.newFuncLineNum for lineObj in funcLineObjList] for num in xrange(1, len(lineNumList) + 1): if num not in lineNumList: newFuncLineNum = num break GameWorld.DebugLog(" lineNumList=%s,newFuncLineNum=%s" % (lineNumList, newFuncLineNum)) newFuncLineObj.realMapID = realMapID newFuncLineObj.copyMapID = copyMapID newFuncLineObj.newFuncLineNum = newFuncLineNum copyMapObj = CrossCopyMapInfo(zoneID, funcLineID) copyMapObj.realMapID = realMapID copyMapObj.copyMapID = copyMapID copyMapObj.newFuncLineNum = newFuncLineNum key = (realMapID, copyMapID) PyGameData.g_crossDynamicLineCopyMapInfo[key] = copyMapObj propertyID = int("%d%03d%02d" % (zoneID, funcLineID, newFuncLineNum)) GameWorld.Log(" пª·ÖÇø¶¯Ì¬¸±±¾¹¦ÄÜÏß·: zoneID=%s,funcLineID=%s,newFuncLineNum=%s,realMapID=%s,copyMapID=%s,propertyID=%s" % (zoneID, funcLineID, newFuncLineNum, realMapID, copyMapID, propertyID)) # ֪ͨµØÍ¼¿ªÆôеĵØÍ¼ÐéÄâ·ÖÏß funcLineDataCache = newFuncLineObj.funcLineDataCache msgInfo = str([copyMapID, propertyID, funcLineDataCache]) GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "OpenFB", msgInfo, len(msgInfo)) return copyMapObj def SendMapOpenFBEx(realMapID, copyPropertyList): ## ֪ͨµØÍ¼¿ªÆô¸±±¾Ïß· # @param realMapID: µØÍ¼ID # @param copyPropertyList: [[copyMapID, propertyID], ...] msgInfo = str(copyPropertyList) GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "OpenFBEx", msgInfo, len(msgInfo)) GameWorld.Log("SendMapOpenFBEx: realMapID=%s,msgInfo=%s" % (realMapID, msgInfo)) return def OpenCrossDynamicLineBySys(zoneID, mapID, funcLineIDList, checkExist): ## ϵͳ¿ªÆô¿ç·þ¶¯Ì¬Ïß· GameWorld.Log(" ϵͳ¿ªÆô¿ç·þ¶¯Ì¬Ïß·: zoneID=%s, mapID=%s, funcLineIDList=%s, checkExist=%s" % (zoneID, mapID, funcLineIDList, checkExist)) for funcLineID in funcLineIDList: if checkExist: fincLineObj = None zoneLineKey = (zoneID, funcLineID) zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) funcLineObjList = zoneLineDict.get(zoneLineKey, []) for funcLineObj in funcLineObjList: if funcLineObj.realMapID: fincLineObj = funcLineObj break if fincLineObj: GameWorld.ErrLog("ÒѾ­´æÔÚ¿ª·ÅÖеÄÏß·£¬²»Öظ´¿ªÆô¶¯Ì¬¸±±¾Ïß·! mapID=%s, funcLineID=%s, zoneID=%s, realMapID=%s, copyMapID=%s" % (mapID, funcLineID, zoneID, funcLineObj.realMapID, funcLineObj.copyMapID)) continue __OpenNewFuncLine(mapID, zoneID, funcLineID) return def GetCrossDynamicLineZoneID(mapID, realMapID, copyMapID): ## »ñÈ¡¿ç·þ¶¯Ì¬·ÖÅäµÄÐéÄâÏß·¶ÔÓ¦·ÖÇøID zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) for key, funcLineObjList in zoneLineDict.items(): for funcLineObj in funcLineObjList: if funcLineObj.realMapID == realMapID and funcLineObj.copyMapID == copyMapID: zoneID = key[0] return zoneID return 0 def OnCrossDynamicLineStateChange(msgList): mapID, realMapID, copyMapID, state = msgList[:4] if state == IPY_PlayerDefine.fbosWaitForClose: funcLineDataCache = msgList[3] OnCrossDynamicLineWaitForClose(realMapID, copyMapID, funcLineDataCache) elif state == IPY_PlayerDefine.fbosClosed: OnCrossDynamicLineClose(realMapID, copyMapID) elif state == IPY_PlayerDefine.fbosOpen: OnCrossDynamicLineOpen(mapID, realMapID, copyMapID) return def OnCrossDynamicLineOpen(mapID, realMapID, copyMapID): ## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÐéÄâÏß·Æô¶¯³É¹¦ key = (realMapID, copyMapID) if key not in PyGameData.g_crossDynamicLineCopyMapInfo: return copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] copyMapObj.openState = IPY_PlayerDefine.fbosOpen funcLineID = copyMapObj.funcLineID # ֪ͨ×Ó·þµÈ´ýÖеÄÍæ¼Ò¿ÉÒÔ½øÈ븱±¾ serverPlayerIDListDict = {} for playerID, playerInfo in copyMapObj.waitPlayerDict.items(): serverGroupID = playerInfo[0] if serverGroupID not in serverPlayerIDListDict: serverPlayerIDListDict[serverGroupID] = [] playerIDList = serverPlayerIDListDict[serverGroupID] playerIDList.append(playerID) recordMapID = GetRecordMapID(realMapID) GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·Æô¶¯³É¹¦£¬Í¨Öª×Ó·þµÈ´ýÍæ¼Ò¿É½øÈë: recordMapID=%s,mapID=%s,realMapID=%s,copyMapID=%s,serverPlayerIDListDict=%s" % (recordMapID, mapID, realMapID, copyMapID, serverPlayerIDListDict)) for serverGroupID, playerIDList in serverPlayerIDListDict.items(): retInfo = [playerIDList, recordMapID, mapID, realMapID, copyMapID, funcLineID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) return def OnCrossDynamicLineWaitForClose(realMapID, copyMapID, funcLineDataCache): ## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÐéÄâÏß·¹Ø±Õ mapID = GetRecordMapID(realMapID) GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·µÈ´ý¹Ø±Õ mapID=%s,realMapID=%s,copyMapID=%s,funcLineDataCache=%s" % (mapID, realMapID, copyMapID, funcLineDataCache)) zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) for key, funcLineObjList in zoneLineDict.items(): for funcLineObj in funcLineObjList: if funcLineObj.realMapID == realMapID and funcLineObj.copyMapID == copyMapID: funcLineObj.funcLineDataCache = funcLineDataCache zoneID, funcLineID = key GameWorld.Log(" ·ÖÇø¶ÔÓ¦¹¦ÄÜÏß·ÐéÄâ·ÖÏߵȴý¹Ø±Õ: zoneID=%s,mapID=%s,funcLineID=%s" % (zoneID, mapID, funcLineID)) break key = (realMapID, copyMapID) if key in PyGameData.g_crossDynamicLineCopyMapInfo: copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] copyMapObj.openState = IPY_PlayerDefine.fbosWaitForClose #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) return def OnCrossDynamicLineClose(mapID, copyMapID): ## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÐéÄâÏß·¹Ø±Õ dataMapID = GetRecordMapID(mapID) GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·¹Ø±Õ dataMapID=%s,mapID=%s,copyMapID=%s" % (dataMapID, mapID, copyMapID)) zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {}) for key, funcLineObjList in zoneLineDict.items(): for funcLineObj in funcLineObjList: if funcLineObj.realMapID == mapID and funcLineObj.copyMapID == copyMapID: funcLineObj.OnCopyMapClose() zoneID, funcLineID = key GameWorld.Log(" ·ÖÇø¶ÔÓ¦¹¦ÄÜÏß·ÐéÄâ·ÖÏ߹رÕ: zoneID=%s,dataMapID%s,funcLineID=%s" % (zoneID, dataMapID, funcLineID)) if not funcLineObj.funcLineDataCache: funcLineObjList.remove(funcLineObj) break key = (mapID, copyMapID) copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo.pop(key, None) if not copyMapObj: return #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) playerCount = 0 zoneID = copyMapObj.zoneID funcLineID = copyMapObj.funcLineID playerCountInfo = [playerCount] SyncClientServerCrossFBFuncLinePlayerCount(zoneID, mapID, funcLineID, playerCountInfo) #Èç¹ûÐéÄâ·ÖÏ߹رÕʱ£¬ÓеôÏßµÄÍæ¼Ò£¬Ôò֪ͨ×Ó·þÖØÖÃÕâÐ©Íæ¼ÒµÄ¿ç·þ״̬ for playerID, serverGroupID in copyMapObj.offlinePlayerDict.items(): CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_ExitCrossServer, playerID, [serverGroupID]) return def OnCrossDynamicMapReset(msgList): ## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÖØÖà realMapID, copyMapCount = msgList mapID = GetRecordMapID(realMapID) GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·µØÍ¼ÖØÖà mapID=%s,realMapID=%s,copyMapCount=%s" % (mapID, realMapID, copyMapCount)) PyGameData.g_crossMapCopyMapCountDict[realMapID] = copyMapCount zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) for key, funcLineObjList in zoneLineDict.items(): for funcLineObj in funcLineObjList: if funcLineObj.realMapID == realMapID: funcLineObj.OnCopyMapClose() for key in PyGameData.g_crossDynamicLineCopyMapInfo.keys(): if key[0] == realMapID: PyGameData.g_crossDynamicLineCopyMapInfo.pop(key) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) return def PlayerLoginLoadCrossMapOK(curPlayer): ## Íæ¼ÒµÇ¼¿ç·þµØÍ¼ mapID, copyMapID = curPlayer.GetRealMapID(), curPlayer.GetFBID() key = (mapID, copyMapID) if key not in PyGameData.g_crossDynamicLineCopyMapInfo: return copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] playerID = curPlayer.GetPlayerID() serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer) copyMapObj.waitPlayerDict.pop(playerID, None) copyMapObj.offlinePlayerDict.pop(playerID, None) copyMapObj.fbPlayerDict[playerID] = serverGroupID if playerID not in copyMapObj.enterPlayerIDList: copyMapObj.enterPlayerIDList.append(playerID) #GameWorld.DebugLog("Íæ¼ÒµÇ¼¶¯Ì¬·ÖÅäµÄ¿ç·þµØÍ¼: GetMapID=%s,GetRealMapID=%s,GetFBID()=%s,serverGroupID=%s" # % (curPlayer.GetMapID(), mapID, copyMapID, serverGroupID), playerID) #GameWorld.DebugLog(" ¸±±¾ÖеÄÍæ¼ÒID: %s" % copyMapObj.fbPlayerDict) #GameWorld.DebugLog(" µÈ´ýÖеÄÍæ¼ÒID: %s" % copyMapObj.waitPlayerDict) #GameWorld.DebugLog(" ÀëÏßÖеÄÍæ¼ÒID: %s" % copyMapObj.offlinePlayerDict) playerCount = len(copyMapObj.fbPlayerDict) # µÈ´ý½øÈëµÄÔÝʱ²»Ëã zoneID = copyMapObj.zoneID funcLineID = copyMapObj.funcLineID playerCountInfo = [playerCount] SyncClientServerCrossFBFuncLinePlayerCount(zoneID, mapID, funcLineID, playerCountInfo) return def SyncClientServerCrossFBFuncLinePlayerCount(zoneID, mapID, funcLineID, playerCountInfo): ## ͬ²½×Ó·þ¿ç·þ¸±±¾¹¦ÄÜÏß·ÈËÊý ## ×¢Ò⣺ ´ËÈËÊý²»ÊÇÒ»¸ö¾«È·ÈËÊýÖµ£¬Ö»ÊÇÒ»¸ö´ó¸ÅÈËÊýÖµ£¬²»Óúܾ«È·£¬ÔÝÊ±Ö»Íæ¼Ò½øÈëʱͬ²½ÈËÊýÐÅÏ¢£¬Íæ¼ÒÍ˳öÔݲ»´¦Àí mapID = GetRecordMapID(mapID) if mapID not in ChConfig.Def_NeedCountFBFuncLinePlayerCrossMap: return zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(mapID, zoneID) if not zoneIpyData: return serverGroupIDList = zoneIpyData.GetServerGroupIDList() playerCountInfo = [mapID, funcLineID, playerCountInfo] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FBPlayerCount, playerCountInfo, serverGroupIDList) return def OnPlayerDisconnectCrossServer(curPlayer): ## Íæ¼ÒÀ뿪¿ç·þ·þÎñÆ÷ mapID, copyMapID = curPlayer.GetRealMapID(), curPlayer.GetFBID() key = (mapID, copyMapID) if key not in PyGameData.g_crossDynamicLineCopyMapInfo: return copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] playerID = curPlayer.GetPlayerID() copyMapObj.waitPlayerDict.pop(playerID, None) copyMapObj.fbPlayerDict.pop(playerID, None) crossMapID = PlayerControl.GetCrossMapID(curPlayer) # ²»ÊÇÖ÷¶¯Í˳öµÄ if crossMapID: copyMapObj.offlinePlayerDict[playerID] = PlayerControl.GetPlayerServerGroupID(curPlayer) #GameWorld.DebugLog("Íæ¼ÒÍ˳ö¶¯Ì¬·ÖÅäµÄ¿ç·þµØÍ¼: GetMapID=%s,GetRealMapID=%s,GetFBID()=%s,crossMapID=%s" # % (curPlayer.GetMapID(), mapID, copyMapID, crossMapID), playerID) #GameWorld.DebugLog(" ¸±±¾ÖеÄÍæ¼ÒID: %s" % copyMapObj.fbPlayerDict) #GameWorld.DebugLog(" µÈ´ýÖеÄÍæ¼ÒID: %s" % copyMapObj.waitPlayerDict) #GameWorld.DebugLog(" ÀëÏßÖеÄÍæ¼ÒID: %s" % copyMapObj.offlinePlayerDict) return def CrossServerMsg_FBPlayerCount(msgData): ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¸±±¾¹¦ÄÜÏß·ÈËÊýÐÅÏ¢ mapID, funcLineID, playerCountInfo = msgData if mapID not in PyGameData.g_crossFBFuncLinePlayerCountInfo: PyGameData.g_crossFBFuncLinePlayerCountInfo[mapID] = {} fbLinePlayerInfoDict = PyGameData.g_crossFBFuncLinePlayerCountInfo[mapID] fbLinePlayerInfoDict[funcLineID] = playerCountInfo return ##-------------------------------------------------------------------------------------------------- ## ÇëÇó½øÈ븱±¾·ÖÏß # @param curPlayer: ÇëÇóÍæ¼Ò # @param queryCallName: ÇëÇ󻨵÷Ãû # @param sendCMD: ÇëÇóµÄÃüÁî ¸ù¾ÝÇëÇóÀàÐͺÍÇëÇóÃüÁîÀ´¾ö¶¨×îÖÕ²Ù×÷ # @return None def EnterFBLine(curPlayer, queryCallName, sendCMD, tick): playerID = curPlayer.GetPlayerID() GameWorld.Log("EnterFBLine()...queryCallName=%s,sendCMD=%s" % (queryCallName, sendCMD), curPlayer.GetPlayerID()) playerManager = GameWorld.GetPlayerManager() try: mapInfo = eval(sendCMD) except Exception, e: GameWorld.ErrLog("EnterFBLine() sendCMD=%s error" % sendCMD) return if not mapInfo or len(mapInfo) < 2: GameWorld.ErrLog("EnterFBLine() sendCMD=%s error!" % sendCMD) return #if mapInfo and len(mapInfo) == 2: tagMapID = mapInfo[0] tagLineID = mapInfo[1] fbLineIpyData = GetFBLineIpyData(tagMapID, tagLineID) sceneMapID = tagMapID if not fbLineIpyData else fbLineIpyData.GetMapID() gameMap = GameWorld.GetMap(sceneMapID) if not gameMap: GameWorld.ErrLog("Ä¿±ê¸±±¾µØÍ¼²»´æÔÚ!tagMapID=%s,sceneMapID=%s" % (tagMapID, sceneMapID), curPlayer.GetPlayerID()) return # ×é¶Ó¸±±¾, ÓжÓÎéµÄÇé¿ö²ÅÑéÖ¤ÆäËû¶ÓÔ±¿É·ñ½øÈ룬·ñÔò´ú±íµ¥È˽øÈë if gameMap.GetMapFBType() == ChConfig.fbtTeam: if tagMapID == ChConfig.Def_FBMapID_Love: onlyDoubleTeam = IpyGameDataPY.GetFuncCfg("LoveFB", 1) if onlyDoubleTeam: if PlayerTeam.CheckTeamOnLineCount(curPlayer.GetTeam(), includeTJG=False) != 2: PlayerControl.NotifyCode(curPlayer, "OnlyTwoMemTeamCanEnter", [tagMapID]) return PlayerTeam.OnEnterFBTeamAsk(curPlayer, PlayerTeam.TeamFBAskType_Enter, tagMapID, tagLineID, tick) return #·âħ̳¸±±¾ÅжÏÀïÃæµÄBOSSÊÇ·ñµ½ÁËË¢ÐÂʱ¼ä if tagMapID in ChConfig.WorldBossFBMapIDList: bossID = mapInfo[2] if not GameWorldBoss.GetBossIsAliveOrCanReborn(bossID): return elif tagMapID == ChConfig.Def_FBMapID_FamilyWar: if not GameWorldFamilyWar.CheckPlayerCanEnterFamilyWarFBMap(curPlayer): return elif tagMapID == ChConfig.Def_FBMapID_FamilyBossMap: if not PlayerFamilyBoss.CheckIsFamilyBossFBOpen(curPlayer.GetFamilyID(), tagMapID): GameWorld.Log("EnterFBLine mapID=%s is familyBossFB, but is not open!" % tagMapID) return #ÊØÎÀÈË»Ê ÊÇ·ñÒÑ²Î¼Ó elif tagMapID == ChConfig.Def_FBMapID_FamilyInvade: if curPlayer.GetFamilyID() in PyGameData.g_swrhJoinRecord: PlayerControl.NotifyCode(curPlayer, "TheEmperor1") return #¶àÏÉÃËBOSS ÊÇ·ñÒѽáÊø elif tagMapID == ChConfig.Def_FBMapID_AllFamilyBoss: if not PlayerFamilyBoss.IsInAllFamilyBoss(tagLineID): #»î¶¯Î´¿ªÆô return if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_AllFamilyBossTime): #BOSSÒѱ»»÷ɱ return #Æï³èBOSS ÊÇ·ñÒѽáÊø elif tagMapID == ChConfig.Def_FBMapID_HorsePetBoss: if not PlayerHorsePetBoss.IsInHorsePetBoss(): #»î¶¯Î´¿ªÆô return if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime % tagLineID): #BOSSÒѱ»»÷ɱ return # MapServer_QueryPlayer(int srcPlayerID, int queryType, int queryID, int mapID, char *callName, char *cmd,WORD cmdLen, int RouteServerIndex) playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_EnterFB, 0, tagMapID, queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex()) return def Send_CrossServerMsg_EnterVSRoomRet(vsRoomDict, serverGroupIDList=None): ## ·¢ËÍ×Ó·þ¿ç·þ¶ÔÕ½·¿¼äÇëÇó½øÈë½á¹û # @param vsRoomDict: {roomID:{playerID:playerInfo, ...}, } # playerInfo key # serverGroupID ËùÊô·þÎñÆ÷·Ö×éID # regMapInfo ´«ËÍ¿ç·þ×¢²áÐÅÏ¢ [registerMap, mapID, dataMapID, copyMapID, posX, posY] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterVSRoomRet, vsRoomDict, serverGroupIDList) return def CrossServerMsg_EnterVSRoomRet(msgData, tick): ## ¿ç·þ¶ÔÕ½·¿¼äÇëÇó½øÈë½á¹û curServerGroupID = GameWorld.GetServerGroupID() GameWorld.DebugLog("=== ¿ç·þPK¶ÔÕ½·¿¼äÇëÇó½øÈë½á¹û === curServerGroupID=%s" % curServerGroupID) vsRoomDict = msgData for roomID, playerDict in vsRoomDict.items(): GameWorld.DebugLog(" roomID=%s,playerDict=%s" % (roomID, playerDict)) for playerID, playerInfo in playerDict.items(): if "serverGroupID" in playerInfo: serverGroupID = playerInfo["serverGroupID"] if serverGroupID != curServerGroupID: GameWorld.DebugLog(" ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID)) continue player = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not player: GameWorld.DebugLog(" Íæ¼Ò²»ÔÚÏß, playerID=%s" % (playerID)) continue if PlayerControl.GetIsTJG(player): GameWorld.DebugLog(" Íæ¼ÒÍÑ»úÖÐ, playerID=%s" % (playerID)) continue if "regMapInfo" not in playerInfo: continue regMapInfo = playerInfo["regMapInfo"] if len(regMapInfo) != 6: continue registerMap, mapID, dataMapID, copyMapID, posX, posY = regMapInfo PlayerControl.SetVsRoomId(player, roomID, True) # ֪ͨµØÍ¼Íæ¼ÒÆ¥Åä³É¹¦, ÉÏ´«Êý¾Ý, ×¼±¸½øÈë¿ç·þ·þÎñÆ÷ CrossRealmPlayer.SendCrossRealmReg(player, registerMap, mapID, dataMapID, copyMapID, posX, posY) return