#!/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 PyDataManager
|
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, funcMapID, funcLineID):
|
self.zoneID = zoneID
|
self.funcMapID = funcMapID
|
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, checkTeam=True):
|
## ÊÇ·ñ±Ø¶¨ÔÚ´Ë·ÖÏßµÄÍæ¼Ò£¬ ÔÚÇëÇó¶ÓÁÐÀï »ò Ôø¾½øÈëµ½¸Ã·ÖÏߵ쬶¼Ç¿ÖÆÈÏΪÊôÓڸ÷ÖÏßµÄÍæ¼Ò
|
if playerID in self.waitPlayerDict or playerID in self.enterPlayerIDList:
|
return True
|
if self.openState != IPY_PlayerDefine.fbosOpen:
|
return False
|
if not checkTeam:
|
return False
|
# ¶ÓÓÑÇ¿ÖÆÔÚÒ»Æð
|
funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
|
teamID = funcTeamMgr.GetPlayerTeamID(playerID, self.funcMapID)
|
if not teamID:
|
return False
|
funcTeam = funcTeamMgr.GetFuncTeam(teamID)
|
if not funcTeam:
|
return False
|
for memID in funcTeam.GetMemberIDList():
|
if memID in self.waitPlayerDict or memID in self.enterPlayerIDList:
|
GameWorld.DebugLog("Ç¿ÖÆºÍ¶ÓÓÑÔÚÒ»ÌõÏß·! funcMapID=%s,memID=%s,realMapID=%s,copyMapID=%s"
|
% (self.funcMapID, memID, self.realMapID, self.copyMapID), playerID)
|
return True
|
return False
|
|
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, mapID, 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)
|
else:
|
key = (realMapID, copyMapID)
|
if key in PyGameData.g_crossDynamicLineCopyMapInfo:
|
copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]
|
copyMapObj.openState = state
|
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_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
|
|