#!/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 CrossRealmPlayer import CrossRealmMsg import ShareDefine import CrossBoss import random #--------------------------------------------------------------------- #--------------------------------------------------------------------- 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): ## ÊÕµ½×Ó·þÇëÇó½øÈ붯̬·ÖÅäµÄ¿ç·þ¸±±¾ playerID = msgData["PlayerID"] dataMapID = msgData["DataMapID"] funcLineID = msgData["FuncLineID"] if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing: zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(dataMapID, serverGroupID) if not zoneIpyData: return zoneID = zoneIpyData.GetZoneID() bossID = msgData["BossID"] if not CrossBoss.GetCrossBossIsAliveOrCanReborn(zoneID, bossID): GameWorld.DebugLog("µ±Ç°¿ç·þÑýÍõËÀÍö״̬£¬²»¿É½øÈë! serverGroupID=%s,funcLineID=%s,zoneID=%s,bossID=%s" % (serverGroupID, funcLineID, zoneID, bossID)) return mapCopyLineInfo = __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID) if not mapCopyLineInfo: return mapID, copyMapID, isOpenNew = mapCopyLineInfo # Èç¹ûÊǵȴýÏß·Æô¶¯ÖеÄÖ±½Ó·µ»Ø£¬µÈÆô¶¯ºÃºóÔÙ֪ͨ¿É½øÈë if __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID): return else: return playerIDList = [playerID] retInfo = [playerIDList, dataMapID, mapID, copyMapID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) return def CrossServerMsg_EnterFBRet(msgData, tick): ## ÊÕµ½¿ç·þ·þÎñÆ÷¶¯Ì¬·ÖÅäµÄ¿ç·þ¸±±¾½øÈëÐÅÏ¢ playerIDList, dataMapID, mapID, copyMapID = msgData if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing: mapPosInfo = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 2) else: return posX, posY = mapPosInfo[:2] dist = mapPosInfo[2] if len(mapPosInfo) > 2 else 0 if dist > 0: posX, posY = random.randint(posX - dist, posX + dist), random.randint(posY - dist, posY + dist) for playerID in playerIDList: curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not curPlayer: continue CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, posX, posY) return def __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID): ## »ñÈ¡¿ç·þ·ÖÇø¶ÔÓ¦¶¯Ì¬·ÖÅäµÄ¸±±¾µØÍ¼ÐéÄâÏß·ÐÅÏ¢ isOpenNew = False zoneLineKey = (zoneID, funcLineID) if dataMapID not in PyGameData.g_crossDynamicLineInfo: PyGameData.g_crossDynamicLineInfo[dataMapID] = {} zoneLineDict = PyGameData.g_crossDynamicLineInfo[dataMapID] # ¿ç·þ¶¯Ì¬Ïß·ÐÅÏ¢ {dataMapID:{(zoneID, funcLineID):[mapID, copyMapID], ...}, ...} if zoneLineKey in zoneLineDict: mapID, copyMapID = zoneLineDict[zoneLineKey] GameWorld.DebugLog("ÒÑ´æÔڸ÷ÖÇø¹¦ÄÜÏß·ID£¬²»ÐèÒªÖØÐ·ÖÅä: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s" % (zoneID, funcLineID, mapID, copyMapID)) return mapID, copyMapID, isOpenNew if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing: mapIDList = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 1) # ÆäËûµØÍ¼´ýÀ©Õ¹ else: return usedMapCopyList = zoneLineDict.values() # ÒѾ­Ê¹ÓÃÖеĵØÍ¼ÐéÄâÏß· openMapID, openCopyMapID = 0, 0 for mapID in mapIDList: maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(mapID, 0) for copyMapID in xrange(maxCopyMapCount): if [mapID, copyMapID] not in usedMapCopyList: openMapID, openCopyMapID = mapID, copyMapID break if openMapID: break if not openMapID: GameWorld.ErrLog("ûÓпÕÓàµÄÐéÄâÏß·£¬ÎÞ·¨¶¯Ì¬¿ªÆô¿ç·þ¸±±¾!dataMapID=%s, funcLineID=%s, zoneID=%s, mapIDList=%s" % (dataMapID, funcLineID, zoneID, mapIDList)) return isOpenNew = True mapID, copyMapID = openMapID, openCopyMapID zoneLineDict[zoneLineKey] = [mapID, copyMapID] propertyID = zoneID * 1000 + funcLineID GameWorld.DebugLog("²»´æÔڸ÷ÖÇø¹¦ÄÜÏß·ID£¬ÖØÐ·ÖÅä: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s,propertyID=%s" % (zoneID, funcLineID, mapID, copyMapID, propertyID)) # ֪ͨµØÍ¼¿ªÆôеĵØÍ¼ÐéÄâ·ÖÏß msgInfo = str([copyMapID, propertyID]) GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, mapID, "OpenFB", msgInfo, len(msgInfo)) return mapID, copyMapID, isOpenNew def __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID): ## Ìí¼Ó¿ç·þÍæ¼Ò½øÈëµÈ´ý¶¯Ì¬¸±±¾ÐéÄâÏß·¿ªÆô¶ÓÁÐ if mapID not in PyGameData.g_crossDynamicLineOpeningInfo: PyGameData.g_crossDynamicLineOpeningInfo[mapID] = {} openingMapCopyIDDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID] # ¿ç·þ¶¯Ì¬Ïß·ÕýÔÚ¿ªÆôÖеÄÏß·ÐÅÏ¢ {mapID:{copyMapID:{playerID:serverGroupID, ...}, ...}, ...} if isOpenNew or copyMapID in openingMapCopyIDDict: if copyMapID not in openingMapCopyIDDict: openingMapCopyIDDict[copyMapID] = {} waitingPlayerDict = openingMapCopyIDDict[copyMapID] waitingPlayerDict[playerID] = serverGroupID GameWorld.Log("Ìí¼ÓÍæ¼Ò½øÈëµÈ´ý¿ç·þ¶¯Ì¬¸±±¾ÐéÄâÏß·¿ªÆô¶ÓÁÐ: mapID=%s,copyMapID=%s,isOpenNew=%s,playerID=%s,serverGroupID=%s" % (mapID, copyMapID, isOpenNew, playerID, serverGroupID)) GameWorld.Log(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo) return True return False def OnCrossDynamicLineOpen(mapID, copyMapID): ## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÐéÄâÏß·Æô¶¯³É¹¦ if mapID not in PyGameData.g_crossDynamicLineOpeningInfo: return openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID] waitingPlayerDict = openingCopyMapDict.pop(copyMapID, {}) if not waitingPlayerDict: return # ֪ͨ×Ó·þµÈ´ýÖеÄÍæ¼Ò¿ÉÒÔ½øÈ븱±¾ serverPlayerIDListDict = {} for playerID, serverGroupID in waitingPlayerDict.items(): if serverGroupID not in serverPlayerIDListDict: serverPlayerIDListDict[serverGroupID] = [] playerIDList = serverPlayerIDListDict[serverGroupID] playerIDList.append(playerID) dataMapID = GetRecordMapID(mapID) GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·Æô¶¯³É¹¦£¬Í¨Öª×Ó·þµÈ´ýÍæ¼Ò¿É½øÈë: dataMapID=%s,mapID=%s,copyMapID=%s,serverPlayerIDListDict=%s" % (dataMapID, mapID, copyMapID, serverPlayerIDListDict)) for serverGroupID, playerIDList in serverPlayerIDListDict.items(): retInfo = [playerIDList, dataMapID, mapID, copyMapID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) GameWorld.DebugLog(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo) 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, mapCopyInfo in zoneLineDict.items(): if mapCopyInfo[0] == mapID and mapCopyInfo[1] == copyMapID: zoneLineDict.pop(key) break openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo.get(mapID, {}) openingCopyMapDict.pop(copyMapID, {}) GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) GameWorld.DebugLog(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo) return def OnCrossDynamicMapReset(mapID, copyMapCount): ## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÖØÖà dataMapID = GetRecordMapID(mapID) GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·µØÍ¼ÖØÖà dataMapID=%s,mapID=%s,copyMapCount=%s" % (dataMapID, mapID, copyMapCount)) PyGameData.g_crossMapCopyMapCountDict[mapID] = copyMapCount zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {}) for key, mapCopyInfo in zoneLineDict.items(): if mapCopyInfo[0] == mapID: zoneLineDict.pop(key) PyGameData.g_crossDynamicLineOpeningInfo.pop(mapID, None) return ## ÇëÇó½øÈ븱±¾·ÖÏß # @param curPlayer: ÇëÇóÍæ¼Ò # @param queryCallName: ÇëÇ󻨵÷Ãû # @param sendCMD: ÇëÇóµÄÃüÁî ¸ù¾ÝÇëÇóÀàÐͺÍÇëÇóÃüÁîÀ´¾ö¶¨×îÖÕ²Ù×÷ # @return None def EnterFBLine(curPlayer, queryCallName, sendCMD, tick): 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: 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