5424 【后端】【1.4】跨服竞技场开发(流程调通版,可匹配、PK、结算,其他功能没有)
| | |
| | | import PyGameData
|
| | | import traceback
|
| | | import GMCommon
|
| | | import ShareDefine
|
| | | import os
|
| | | #---------------------------------------------------------------------
|
| | | g_broadCastList = []
|
| | |
| | | if callFunc != None:
|
| | | extendParamList = callFunc(curPlayer)
|
| | | alist.extend(extendParamList)
|
| | | MergeChildMsg.SendMergerChildToCenterStringData(ChConfig.Def_SendGMCMD, alist)
|
| | | MergeChildMsg.SendMergerChildToCenterStringData(ShareDefine.ClientServerMsg_GMCMD, alist)
|
| | | return
|
| | |
|
| | | callFunc = GameWorld.GetExecFunc(Commands, "%s.%s"%(callFunName, "OnExec"))
|
| | |
| | | return cmdDict
|
| | |
|
| | | ## 收到子服务器发送的GM命令
|
| | | def ClientServer_SendGMCMD(cmdMsgList, tick):
|
| | | def ClientServerMsg_GMCMD(cmdMsgList, tick):
|
| | | if len(cmdMsgList) == 0:
|
| | | return
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package CrossRealmMsg
|
| | | #
|
| | | # @todo:跨服信息管理
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服信息管理
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import IPY_GameServer
|
| | | import CrossRealmPlayer
|
| | | import CrossRealmPK
|
| | | import GMShell
|
| | |
|
| | | import traceback
|
| | |
|
| | | def SendMsgToCrossServer(msgType, dataMsg):
|
| | | ## 发送信息到跨服服务器上
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | if not dataMsg:
|
| | | return
|
| | | sendMsg = str({"MsgType":msgType, "Data":dataMsg, "ServerGroupID":GameWorld.GetServerGroupID()})
|
| | | GameWorld.Log("SendMsgToCrossServer => %s" % (sendMsg)) |
| | | GameWorld.GetGameWorld().SendMergerChildToCenterStringData(sendMsg, len(sendMsg))
|
| | | return
|
| | |
|
| | | def OnCrossServerReceiveMsg(recvMsg, tick):
|
| | | ## 跨服服务器收到信息处理
|
| | | try:
|
| | | GameWorld.Log("OnCrossServerReceiveMsg: %s" % recvMsg)
|
| | | msgDict = eval(recvMsg)
|
| | | |
| | | msgType = msgDict.get("MsgType", -1) |
| | | msgData = msgDict.get("Data", "")
|
| | | serverGroupID = msgDict.get("ServerGroupID", 0)
|
| | | |
| | | if msgType == ShareDefine.ClientServerMsg_PKMatch:
|
| | | CrossRealmPK.ClientServerMsg_PKMatch(serverGroupID, msgData, tick)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_PKCancel:
|
| | | CrossRealmPK.ClientServerMsg_PKCancel(msgData, tick)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_PKPrepareOK:
|
| | | CrossRealmPK.ClientServerMsg_PKPrepareOK(msgData, tick)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_GMCMD:
|
| | | GMShell.ClientServerMsg_GMCMD(msgData, tick)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_ServerInitOK:
|
| | | ClientServerMsg_ServerInitOK(serverGroupID, msgData, tick)
|
| | | |
| | | else:
|
| | | GameWorld.ErrLog("没有该信息类型逻辑处理!")
|
| | | |
| | | except:
|
| | | GameWorld.ErrLog("OnCrossServerReceiveMsg:%s; except:%s" % (recvMsg, traceback.format_exc()))
|
| | | if GameWorld.GetGameWorld().GetDebugLevel():
|
| | | raise BaseException(str(traceback.format_exc()))
|
| | | return
|
| | |
|
| | | def ClientServerMsg_ServerInitOK(serverGroupID, msgData, tick):
|
| | | ''' 收到子服启动成功通知 |
| | | 当子服启动成功后,可同步一次跨服服务器活动状态及活动数据给子服
|
| | | '''
|
| | | GameWorld.Log("收到跨服子服启动成功通知!")
|
| | | CrossRealmPK.ClientServerMsg_ServerInitOK(serverGroupID, tick)
|
| | | return
|
| | |
|
| | | ## ================================================================================================
|
| | |
|
| | | def SendMsgToClientServer(msgType, dataMsg, serverGroupIDList=[]):
|
| | | ''' 广播信息到子服务器上
|
| | | @param serverGroupIDList: 发送指定的服务器组ID列表,内部已经针对列表中组ID去重,
|
| | | 所以外部逻辑可直接添加,不用考虑组ID重复问题,没有指定服务器组ID时,默认广播所有子服
|
| | | '''
|
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | if not dataMsg:
|
| | | return
|
| | | sendMsg = str({"MsgType":msgType, "Data":dataMsg})
|
| | | GameWorld.Log("SendMsgToClientServer => serverGroupIDList=%s, sendMsg=%s" % (serverGroupIDList, sendMsg))
|
| | | if not serverGroupIDList:
|
| | | GameWorld.GetGameWorld().SendBroadcastMergeClient(sendMsg)
|
| | | else:
|
| | | serverGroupIDList = list(set(serverGroupIDList)) # 去重
|
| | | for serverGroupID in serverGroupIDList:
|
| | | GameWorld.GetGameWorld().SendMergeMsgToClientByGroupID(serverGroupID, sendMsg)
|
| | | return
|
| | |
|
| | | def OnClientServerReceiveMsg(index, tick):
|
| | | ## 子服收到跨服服务器信息
|
| | | dataPack = IPY_GameServer.IPY_MGBroadcastMergeClient()
|
| | | dataMsg = dataPack.GetData()
|
| | | GameWorld.Log("OnClientServerReceiveMsg: %s" % dataMsg)
|
| | | |
| | | try:
|
| | | msgDict = eval(dataMsg)
|
| | | msgType = msgDict.get("MsgType", -1) |
| | | msgData = msgDict.get("Data", "")
|
| | | |
| | | if msgType == ShareDefine.CrossServerMsg_ExitCrossServer:
|
| | | CrossRealmPlayer.CrossServerMsg_ExitCrossServer(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_Notify:
|
| | | PlayerControl.CrossServerMsg_Notify(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PKMatchReqRet:
|
| | | CrossRealmPK.CrossServerMsg_PKMatchReqRet(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PKMatchResult:
|
| | | CrossRealmPK.CrossServerMsg_PKMatchResult(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PKReadyOKRoomList:
|
| | | CrossRealmPK.CrossServerMsg_PKReadyOKRoomList(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PKTimeoutRoomList:
|
| | | CrossRealmPK.CrossServerMsg_PKTimeoutRoomList(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PKOverInfo:
|
| | | CrossRealmPK.CrossServerMsg_PKOverInfo(msgData)
|
| | | |
| | | else:
|
| | | GameWorld.ErrLog("没有该信息类型逻辑处理!")
|
| | | |
| | | except:
|
| | | GameWorld.ErrLog("OnClientServerReceiveMsg:%s; except:%s" % (dataMsg, traceback.format_exc()))
|
| | | if GameWorld.GetGameWorld().GetDebugLevel():
|
| | | raise BaseException(str(traceback.format_exc()))
|
| | | |
| | | return
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package CrossRealmPK
|
| | | #
|
| | | # @todo:跨服PK竞技场
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服PK竞技场
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PlayerControl
|
| | | import CrossRealmMsg
|
| | | import CrossRealmPlayer
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import IpyGameDataPY
|
| | | import ShareDefine
|
| | | import PyGameData
|
| | | import ChConfig
|
| | |
|
| | | import operator
|
| | | import random
|
| | | |
| | | PKPlayerState_Matching = 0
|
| | | PKPlayerState_Fighting = 1
|
| | |
|
| | | class CrossPKPlayer():
|
| | | ## 跨服PK玩家类
|
| | | |
| | | def __init__(self):
|
| | | self.accID = ""
|
| | | self.playerID = 0
|
| | | self.playerName = ""
|
| | | self.playerJob = 0
|
| | | self.playerLV = 0
|
| | | self.maxHP = 0
|
| | | self.fightPower = 0
|
| | | self.pkScore = 0
|
| | | self.danLV = 0
|
| | | self.matchTick = 0
|
| | | self.cWinCount = 0 # 连胜次数
|
| | | self.ondayScore = 0 # 过天时的积分
|
| | | self.serverGroupID = 0 # 所属服务器ID,一个服务器ID由多个服组成
|
| | | self.pkZoneID = 0 # 所属赛区ID,一个赛区由多个服务器ID组成
|
| | | self.seasonID = 0 # 赛季ID
|
| | | return
|
| | | |
| | | class CrossPKRoom():
|
| | | ## 跨服PK房间类
|
| | | |
| | | def __init__(self):
|
| | | self.pkZoneID = 0
|
| | | self.roomID = 0
|
| | | self.mapID = 0
|
| | | self.openTick = 0 # 开房时间
|
| | | self.readyTick = 0 # 玩家都准备好的时间
|
| | | self.roomState = ShareDefine.Def_VsRoom_State_WaitPlayer # 默认状态
|
| | | self.roomPlayerIDList = [] # 对战玩家ID列表
|
| | | self.readyPlayerIDList = [] # 已经准备好的玩家ID列表
|
| | | self.isMapOpen = False # 地图是否已经开启该房间,未开启的房间超时后,本次匹配视为无效,有玩家进地图才会开启副本分线
|
| | | return
|
| | | |
| | | ################################################################################
|
| | |
|
| | | def OnPlayerLogin(curPlayer):
|
| | | if not GameWorld.IsCrossServer():
|
| | | __OnLoginNotifyPKOverInfo(curPlayer)
|
| | | return
|
| | |
|
| | | ## 玩家离线处理
|
| | | def OnLeaveServer(curPlayer): |
| | | # 发送取消匹配
|
| | | SendCancelCrossRealmPKMatch(curPlayer, "PlayerDisconnect")
|
| | | return
|
| | |
|
| | | def IsCrossRealmPKOpen():
|
| | | ## 跨服PK匹配赛是否开启
|
| | | return 1
|
| | | return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState) == ChConfig.Def_Action_Open
|
| | |
|
| | | def ClientServerMsg_ServerInitOK(serverGroupID, tick):
|
| | | ## 子服启动成功
|
| | | GameWorld.Log("同步跨服PK赛季信息及状态到子服: serverGroupID=%s" % (serverGroupID))
|
| | | seasonInfo = {"SeasonID":1, "SeasonState":1, "MatchState":1}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, [serverGroupID])
|
| | | return
|
| | |
|
| | | def SendCancelCrossRealmPKMatch(curPlayer, reason): |
| | | ## 发送取消匹配
|
| | | |
| | | # 跨服服务器不处理
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | # 非活动中不处理
|
| | | if not IsCrossRealmPKOpen():
|
| | | return
|
| | | |
| | | # # 如果是要登陆到跨服服务器的,不发送取消
|
| | | # if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IsLoginToMergeServer):
|
| | | # GameWorld.DebugLog("本次离线为要登陆跨服服务器的自动离线行为,不发送取消匹配!", curPlayer.GetPlayerID())
|
| | | # curPlayer.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)
|
| | | # return
|
| | |
|
| | | vsRoomID = curPlayer.GetVsRoomId()
|
| | | if vsRoomID and PlayerControl.GetCrossRealmState(curPlayer) == 1:
|
| | | GameWorld.DebugLog("玩家跨服PK状态,不能取消匹配!vsRoomID=%s" % vsRoomID, curPlayer.GetPlayerID())
|
| | | return
|
| | | |
| | | dataMsg = {"accID":curPlayer.GetAccID(), # 账号
|
| | | "playerID":curPlayer.GetPlayerID(), # 玩家ID
|
| | | "playerName":curPlayer.GetName(), # 跨服子服玩家名
|
| | | "reason":reason, # 取消原因
|
| | | "vsRoomID":vsRoomID, # 对战房间ID
|
| | | }
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKCancel, dataMsg)
|
| | | PlayerControl.SetVsRoomId(curPlayer, 0)
|
| | | GameWorld.Log("发送取消跨服PK匹配到跨服服务器:dataMsg=%s" % str(dataMsg), curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def ClientServerMsg_PKMatch(serverGroupID, playerInfoDict, tick):
|
| | | ## 请求匹配
|
| | | |
| | | if not GameWorld.IsMergeServer():
|
| | | GameWorld.ErrLog("非跨服服务器不处理跨服PK匹配请求!")
|
| | | return
|
| | | |
| | | if not IsCrossRealmPKOpen():
|
| | | GameWorld.Log("跨服匹配PK活动未开启,不允许请求匹配!")
|
| | | return
|
| | | |
| | | seasonID = playerInfoDict["seasonID"] # 赛季ID
|
| | | pkZoneID = playerInfoDict["pkZoneID"] # 所属赛区
|
| | | accID = playerInfoDict["accID"] # 角色账号
|
| | | playerID = playerInfoDict["playerID"] # 角色ID
|
| | | playerName = playerInfoDict["playerName"] # 玩家名
|
| | | job = playerInfoDict["playerJob"] # ְҵ
|
| | | playerLV = playerInfoDict["playerLV"] # ְҵ
|
| | | maxHP = playerInfoDict["maxHP"] # ְҵ
|
| | | fightPower = playerInfoDict["fightPower"] # 战斗力
|
| | | pkScore = playerInfoDict["pkScore"] # 当前积分
|
| | | danLV = playerInfoDict["danLV"] # 当前段位
|
| | | cWinCount = playerInfoDict["cWinCount"] # 连胜次数
|
| | | ondayScore = playerInfoDict["ondayScore"] # 过天时的积分
|
| | | |
| | | zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
|
| | | # if playerID in zoneMatchPlayerList:
|
| | | # GameWorld.Log("玩家正在匹配中,无法重复发起匹配!playerID=%s,accID=%s" % (playerID, accID))
|
| | | # CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])
|
| | | # return
|
| | | # if playerID in PyGameData.g_crossPKPlayerDict:
|
| | | # GameWorld.Log("玩家正在战斗中,无法重复发起匹配!playerID=%s,accID=%s" % (playerID, accID))
|
| | | # CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, -2], [serverGroupID])
|
| | | # return
|
| | | |
| | | pkPlayer = CrossPKPlayer()
|
| | | pkPlayer.accID = accID
|
| | | pkPlayer.playerID = playerID
|
| | | pkPlayer.playerName = playerName
|
| | | pkPlayer.playerJob = job
|
| | | pkPlayer.playerLV = playerLV
|
| | | pkPlayer.maxHP = maxHP
|
| | | pkPlayer.pkScore = pkScore
|
| | | pkPlayer.danLV = danLV
|
| | | pkPlayer.fightPower = fightPower
|
| | | pkPlayer.matchTick = tick
|
| | | pkPlayer.cWinCount = cWinCount
|
| | | pkPlayer.ondayScore = ondayScore
|
| | | pkPlayer.serverGroupID = serverGroupID
|
| | | pkPlayer.pkZoneID = pkZoneID
|
| | | pkPlayer.seasonID = seasonID
|
| | | PyGameData.g_crossPKPlayerDict[playerID] = pkPlayer
|
| | | |
| | | # 加入赛区匹配列表
|
| | | zoneMatchPlayerList.append(playerID)
|
| | | PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList
|
| | | |
| | | GameWorld.Log("玩家加入匹配: seasonID=%s,pkZoneID=%s,serverGroupID=%s,accID=%s,playerID=%s,pkScore=%s,fightPower=%s,cWinCount=%s,len(zoneMatchPlayerList)=%s" |
| | | % (seasonID, pkZoneID, serverGroupID, accID, playerID, pkScore, fightPower, cWinCount, len(zoneMatchPlayerList)))
|
| | | |
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])
|
| | | return
|
| | |
|
| | | def ClientServerMsg_PKCancel(playerInfoDict, tick):
|
| | | ## 取消匹配
|
| | | |
| | | if not GameWorld.IsMergeServer():
|
| | | GameWorld.ErrLog("非跨服服务器不处理取消跨服PK匹配!")
|
| | | return
|
| | | |
| | | # 非活动中不处理
|
| | | if not IsCrossRealmPKOpen():
|
| | | return
|
| | | |
| | | accID = playerInfoDict["accID"] # 角色账号
|
| | | playerID = playerInfoDict["playerID"] # 玩家ID
|
| | | reason = playerInfoDict["reason"] # 取消原因
|
| | | vsRoomID = playerInfoDict["vsRoomID"] # 所属对战房间ID
|
| | | if vsRoomID in PyGameData.g_crossPKRoomDict:
|
| | | pkRoom = PyGameData.g_crossPKRoomDict[vsRoomID]
|
| | | if pkRoom.isMapOpen or pkRoom.readyTick:
|
| | | GameWorld.Log("跨服对战房间已经开启了线路,或者双方数据都已传输完毕,不可再取消匹配!vsRoomID=%s" % vsRoomID)
|
| | | return
|
| | | |
| | | GameWorld.Log("玩家取消匹配: reason=%s,accID=%s,playerID=%s,vsRoomID=%s" % (reason, accID, playerID, vsRoomID))
|
| | | |
| | | pkZoneID = 0
|
| | | if playerID in PyGameData.g_crossPKPlayerDict:
|
| | | pkPlayer = PyGameData.g_crossPKPlayerDict.pop(playerID)
|
| | | pkZoneID = pkPlayer.pkZoneID
|
| | | GameWorld.Log(" 移除PK玩家: pkZoneID=%s,accID=%s,playerID=%s" % (pkZoneID, accID, playerID))
|
| | | |
| | | zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
|
| | | if playerID in zoneMatchPlayerList:
|
| | | zoneMatchPlayerList.remove(playerID)
|
| | | GameWorld.Log(" 从匹配队列中删除,匹配队列剩余人数=%s" % (len(zoneMatchPlayerList)))
|
| | | |
| | | #取消所有存在该玩家的房间,子服不一定知道玩家当前最新所属房间ID, 故只能通过遍历删除已经为玩家创建的房间
|
| | | for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():
|
| | | if playerID not in pkRoom.roomPlayerIDList:
|
| | | continue
|
| | | |
| | | for roomPlayerID in pkRoom.roomPlayerIDList:
|
| | | if roomPlayerID == playerID:
|
| | | GameWorld.Log(" 自己不处理: roomID=%s,playerID=%s" % (roomID, playerID))
|
| | | continue
|
| | | |
| | | zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
|
| | | zoneMatchPlayerList.append(roomPlayerID)
|
| | | PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList
|
| | | GameWorld.Log(" 将之前匹配的对手重新加入匹配队列: roomID=%s,roomPlayerID=%s,当前匹配人数=%s" |
| | | % (roomID, roomPlayerID, len(zoneMatchPlayerList)))
|
| | | |
| | | PyGameData.g_crossPKRoomDict.pop(roomID)
|
| | | GameWorld.Log(" 移除房间: popRoomID=%s" % (roomID))
|
| | | break
|
| | | |
| | | return
|
| | |
|
| | | def ClientServerMsg_PKPrepareOK(playerInfoDict, tick):
|
| | | ## 玩家跨服对战数据准备OK
|
| | | |
| | | if not GameWorld.IsMergeServer():
|
| | | GameWorld.ErrLog("非跨服服务器不处理取消跨服PK匹配!")
|
| | | return
|
| | | |
| | | accID = playerInfoDict["accID"] # 玩家账号
|
| | | playerID = playerInfoDict["playerID"] # 玩家ID
|
| | | vsRoomID = playerInfoDict["vsRoomID"] # 所属对战房间ID
|
| | | if playerID not in PyGameData.g_crossPKPlayerDict:
|
| | | GameWorld.ErrLog("玩家跨服对战数据准备OK, 但找不到该对战玩家信息!vsRoomID=%s,playerID=%s" % (vsRoomID, playerID))
|
| | | return
|
| | | #pkPlayer = PyGameData.g_crossPKPlayerDict[playerID]
|
| | | |
| | | if vsRoomID not in PyGameData.g_crossPKRoomDict:
|
| | | GameWorld.ErrLog("玩家跨服对战数据准备OK, 但找不到该对战房间(%s)!可能对手已取消!" % vsRoomID)
|
| | | return
|
| | | vsRoom = PyGameData.g_crossPKRoomDict[vsRoomID]
|
| | | |
| | | if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:
|
| | | GameWorld.ErrLog("玩家跨服对战数据准备OK, 但房间状态非等待状态, state=%s!" % vsRoom.roomState)
|
| | | return
|
| | | |
| | | if playerID not in vsRoom.readyPlayerIDList:
|
| | | vsRoom.readyPlayerIDList.append(playerID)
|
| | | |
| | | GameWorld.Log("玩家跨服PK准备完毕: accID=%s,playerID=%s,vsRoomID=%s" % (accID, playerID, vsRoomID))
|
| | | return
|
| | |
|
| | | def __ReadyOKRoomPlayerProcess(tick):
|
| | | ## 玩家跨服PK已准备好的房间处理
|
| | | |
| | | #GameWorld.Log("===已准备好的对战房间处理===")
|
| | | serverGroupIDList = []
|
| | | sendReadyOKRoomList = []
|
| | | for roomID, vsRoom in PyGameData.g_crossPKRoomDict.items():
|
| | | |
| | | # 非等待状态的房间不处理
|
| | | if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:
|
| | | continue
|
| | | |
| | | if not vsRoom.roomPlayerIDList:
|
| | | continue
|
| | | |
| | | pkZoneID = 0
|
| | | isAllReady = True
|
| | | roomGroupIDList = []
|
| | | readyMemberDict = {} # 已准备好的玩家信息
|
| | | for roomPlayerID in vsRoom.roomPlayerIDList:
|
| | | if roomPlayerID not in vsRoom.readyPlayerIDList or roomPlayerID not in PyGameData.g_crossPKPlayerDict:
|
| | | isAllReady = False
|
| | | break
|
| | | roomPlayer = PyGameData.g_crossPKPlayerDict[roomPlayerID]
|
| | | pkZoneID = roomPlayer.pkZoneID
|
| | | roomGroupIDList.append(roomPlayer.serverGroupID)
|
| | | readyMemberDict[roomPlayerID] = {"ServerGroupID":roomPlayer.serverGroupID, "Name":roomPlayer.playerName, |
| | | "Job":roomPlayer.playerJob, "LV":roomPlayer.playerLV, "MaxHP":roomPlayer.maxHP}
|
| | | |
| | | if not isAllReady:
|
| | | continue
|
| | | vsRoom.roomState = ShareDefine.Def_VsRoom_State_PrepareFight
|
| | | vsRoom.readyTick = tick
|
| | | GameWorld.Log(" 准备好的房间: pkZoneID=%s,roomID=%s,mapID=%s,readyMemberDict=%s" % (pkZoneID, roomID, vsRoom.mapID, str(readyMemberDict)))
|
| | | |
| | | sendReadyOKRoomList.append([roomID, readyMemberDict])
|
| | | serverGroupIDList += roomGroupIDList
|
| | | |
| | | # 将已准备好的房间广播到子服
|
| | | if sendReadyOKRoomList:
|
| | | GameWorld.Log(" 已准备好的对战房间数: %s" % len(sendReadyOKRoomList))
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKReadyOKRoomList, sendReadyOKRoomList, serverGroupIDList)
|
| | | |
| | | return
|
| | |
|
| | | def OnPKMatchProcess(tick):
|
| | | ## 玩家跨服PK匹配定时处理逻辑
|
| | | |
| | | # 非跨服服务器不处理跨服PK匹配逻辑
|
| | | if not GameWorld.IsMergeServer():
|
| | | return
|
| | | |
| | | if not IsCrossRealmPKOpen():
|
| | | return
|
| | | |
| | | # 同步子服排行榜
|
| | | #__SyncBillboardToClientServer(False, tick)
|
| | | |
| | | processTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 1)
|
| | | processTickKey = "PKMatchLastTick"
|
| | | lastProcessTick = GameWorld.GetGameWorld().GetDictByKey(processTickKey)
|
| | | if tick - lastProcessTick < processTick:
|
| | | return
|
| | | GameWorld.GetGameWorld().SetDict(processTickKey, tick)
|
| | | |
| | | # 处理超时的房间
|
| | | __DoCheckRoomTimeout(tick)
|
| | | # 通知已准备好的房间玩家可进入跨服
|
| | | __ReadyOKRoomPlayerProcess(tick)
|
| | | |
| | | maxGroupCnt = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 2)
|
| | | outTimeTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 3)
|
| | | |
| | | # 每个赛区单独匹配
|
| | | for pkZoneID, matchPlayerIDList in PyGameData.g_crossPKZoneMatchPlayerDict.items():
|
| | | matchPlayerCount = len(matchPlayerIDList)
|
| | | if matchPlayerCount < 2:
|
| | | #GameWorld.Log("匹配PK人数不足,不处理!pkZoneID=%s, 总人数:%s" % (pkZoneID, matchPlayerCount))
|
| | | continue
|
| | | |
| | | GameWorld.Log("★★★★★★★★★★开始跨服PK匹配(pkZoneID=%s, 总人数:%s)★★★★★★★★★★" % (pkZoneID, matchPlayerCount))
|
| | | |
| | | matchPlayerList = []
|
| | | for matchPlayerID in matchPlayerIDList:
|
| | | if matchPlayerID not in PyGameData.g_crossPKPlayerDict:
|
| | | continue
|
| | | matchPlayerList.append(PyGameData.g_crossPKPlayerDict[matchPlayerID])
|
| | | # 按匹配时间、积分升序排序
|
| | | matchTickSortList = sorted(matchPlayerList, key=operator.attrgetter("matchTick"))
|
| | | scoreSortList = sorted(matchPlayerList, key=operator.attrgetter("pkScore"))
|
| | | |
| | | matchPlayerVSList = [] # 成功匹配玩家对战列表
|
| | | |
| | | # 优先匹配等待超时玩家
|
| | | __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick)
|
| | | |
| | | if len(matchPlayerVSList) < maxGroupCnt:
|
| | | # 再按积分段匹配玩家
|
| | | __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList)
|
| | | |
| | | # 给成功匹配的玩家非配对战房间
|
| | | matchPlayerVSList = matchPlayerVSList[:maxGroupCnt]
|
| | | __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick)
|
| | | GameWorld.Log("==========匹配结束(总匹配队伍:%s)==========" % len(matchPlayerVSList))
|
| | | return
|
| | |
|
| | |
|
| | | def __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick):
|
| | | '''匹配超时玩家
|
| | | 匹配中的玩家按积分排序,最后一个默认匹配上一个,第一个默认匹配下一个,其他匹配前后积分差绝对值较小的一个
|
| | | '''
|
| | | GameWorld.Log(" ==优先匹配超时等待玩家==最大等待时间:%s, tick=%s" % (outTimeTick, tick))
|
| | | GameWorld.Log(" scoreSortListLen=%s" % len(scoreSortList))
|
| | | for i, matchPlayer in enumerate(matchTickSortList): |
| | | # 只有一个玩家
|
| | | if len(scoreSortList) <= 1:
|
| | | GameWorld.Log(" 当前玩家数%s<=1,不再匹配!" % len(scoreSortList))
|
| | | break
|
| | | |
| | | if tick - matchPlayer.matchTick < outTimeTick:
|
| | | GameWorld.Log(" i=%s,玩家未超时,不再匹配!" % (i))
|
| | | break
|
| | | |
| | | GameWorld.Log(" i=%s,超时玩家, %s-%s=%s >= outTimeTick(%s)" |
| | | % (i, tick, matchPlayer.matchTick, tick - matchPlayer.matchTick, outTimeTick))
|
| | | # 已经被匹配走了
|
| | | if matchPlayer not in scoreSortList:
|
| | | GameWorld.Log(" 已经被匹配走了!")
|
| | | continue
|
| | | |
| | | outTimeIndex = scoreSortList.index(matchPlayer)
|
| | | # 最后一个默认匹配上一个
|
| | | if outTimeIndex == len(scoreSortList) - 1: |
| | | vsIndex = outTimeIndex - 1
|
| | | GameWorld.Log(" 超时玩家积分排序索引%s,最后一个,默认匹配上一个索引%s!" % (outTimeIndex, vsIndex))
|
| | | # 第一个默认匹配下一个
|
| | | elif outTimeIndex == 0:
|
| | | vsIndex = outTimeIndex + 1
|
| | | GameWorld.Log(" 超时玩家积分排序索引%s,第一个,默认匹配下一个索引%s!" % (outTimeIndex, vsIndex))
|
| | | # 其他情况匹配积分较近的一个
|
| | | else:
|
| | | preIndex = outTimeIndex - 1
|
| | | nextIndex = outTimeIndex + 1
|
| | | prePlayer = scoreSortList[preIndex]
|
| | | nextPlayer = scoreSortList[nextIndex]
|
| | | preDiff = abs(prePlayer.pkScore - matchPlayer.pkScore)
|
| | | nextDiff = abs(matchPlayer.pkScore - nextPlayer.pkScore)
|
| | | vsIndex = preIndex if preDiff <= nextDiff else nextIndex
|
| | | GameWorld.Log(" 超时玩家积分排序索引-积分(%s-%s),上一个(%s-%s),下一个(%s-%s),preDiff=%s,nextDiff=%s,vsIndex=%s" |
| | | % (outTimeIndex, matchPlayer.pkScore, preIndex, prePlayer.pkScore,
|
| | | nextIndex, nextPlayer.pkScore, preDiff, nextDiff, vsIndex))
|
| | | |
| | | if outTimeIndex > vsIndex: |
| | | scoreSortList.pop(outTimeIndex)
|
| | | vsPlayer = scoreSortList.pop(vsIndex)
|
| | | elif outTimeIndex < vsIndex:
|
| | | vsPlayer = scoreSortList.pop(vsIndex)
|
| | | scoreSortList.pop(outTimeIndex)
|
| | | else:
|
| | | continue
|
| | | |
| | | # 加入成功匹配列表
|
| | | matchPlayerVSList.append([matchPlayer, vsPlayer])
|
| | | |
| | | return
|
| | |
|
| | | def __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList):
|
| | | ''' 匹配积分分段玩家
|
| | | 匹配中的玩家按段位积分归组,归组后,随机段位顺序,每个段位组中的玩家随机两两PK
|
| | | '''
|
| | | GameWorld.Log(" ==匹配积分分段玩家== maxGroupCnt=%s,scoreSortListLen=%s" % (maxGroupCnt, len(scoreSortList)))
|
| | | danPlayerListDict = {} # 按积分分段列表分散玩家
|
| | | for matchPlayer in scoreSortList:
|
| | | danLV = matchPlayer.danLV
|
| | | danPlayerList = danPlayerListDict.get(danLV, [])
|
| | | danPlayerList.append(matchPlayer)
|
| | | danPlayerListDict[danLV] = danPlayerList
|
| | | |
| | | # 按分段玩家随机匹配
|
| | | danList = danPlayerListDict.keys()
|
| | | random.shuffle(danList) # 打乱段位顺序
|
| | | |
| | | GameWorld.Log(" 积分分段个数: %s, %s" % (len(danList), danList))
|
| | | |
| | | # 日志输出分组明细
|
| | | for danLV in danList:
|
| | | strList = []
|
| | | for player in danPlayerListDict[danLV]:
|
| | | strList.append((player.playerID, player.pkScore, player.fightPower))
|
| | | GameWorld.Log(" 积分段组, danLV=%s, %s" % (danLV, str(strList)))
|
| | | |
| | | doCount = 0
|
| | | while len(matchPlayerVSList) < maxGroupCnt and doCount < maxGroupCnt:
|
| | | doCount += 1
|
| | | isMatchOK = False
|
| | | for danLV in danList:
|
| | | danPlayerList = danPlayerListDict[danLV]
|
| | | danPlayerCount = len(danPlayerList)
|
| | | if danPlayerCount < 2:
|
| | | GameWorld.Log(" 段位人数少于2个,此段位本轮轮空!doCount=%s,danLV=%s" % (doCount, danLV))
|
| | | continue
|
| | | |
| | | vsIndexList = random.sample(xrange(danPlayerCount), 2) # 随机取两个索引对战
|
| | | vsIndexList.sort()
|
| | | aPlayer = danPlayerList.pop(vsIndexList[1])
|
| | | bPlayer = danPlayerList.pop(vsIndexList[0])
|
| | | |
| | | matchPlayerVSList.append([aPlayer, bPlayer])
|
| | | isMatchOK = True
|
| | | GameWorld.Log(" 成功匹配玩家: aPlayerID=%s,aScore=%s,aFP=%s VS bPlayerID=%s,bScore=%s,bFP=%s" |
| | | % (aPlayer.playerID, aPlayer.pkScore, aPlayer.fightPower, bPlayer.playerID, bPlayer.pkScore, bPlayer.fightPower))
|
| | | |
| | | if len(matchPlayerVSList) >= maxGroupCnt:
|
| | | GameWorld.Log(" 已经达到最大匹配数! 已匹配对战数=%s, 不再匹配!doCount=%s" % (len(matchPlayerVSList), doCount))
|
| | | break
|
| | | |
| | | if not isMatchOK:
|
| | | GameWorld.Log(" 已经没有满足匹配条件的玩家! 不再匹配!doCount=%s" % (doCount))
|
| | | break
|
| | | |
| | | return
|
| | |
|
| | | def __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick):
|
| | | ## 设置对战房间
|
| | | |
| | | if not matchPlayerVSList:
|
| | | return
|
| | | |
| | | vsRoomDict = {}
|
| | | serverGroupIDList = []
|
| | | zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
|
| | | |
| | | mapIDList = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 4)
|
| | | GameWorld.Log("===给配对的玩家开房间(pkZoneID=%s,配对数:%s)===" % (pkZoneID, len(matchPlayerVSList)))
|
| | | for aPlayer, bPlayer in matchPlayerVSList:
|
| | | |
| | | if not aPlayer or not bPlayer:
|
| | | continue
|
| | | |
| | | aPlayerID = aPlayer.playerID
|
| | | bPlayerID = bPlayer.playerID
|
| | | if aPlayerID not in PyGameData.g_crossPKPlayerDict or bPlayerID not in PyGameData.g_crossPKPlayerDict:
|
| | | GameWorld.ErrLog("玩家匹配数据异常!aPlayerID=%s,bPlayerID=%s" % (aPlayerID, bPlayerID))
|
| | | continue
|
| | | |
| | | roomID = __GetNewRoomID()
|
| | | if not roomID:
|
| | | GameWorld.ErrLog("无法创建房间!该房间已经存在!PyGameData.g_crossPKRoomID=%s" % PyGameData.g_crossPKRoomID)
|
| | | continue
|
| | | mapID = random.choice(mapIDList)
|
| | | |
| | | newRoom = CrossPKRoom()
|
| | | newRoom.pkZoneID = pkZoneID
|
| | | newRoom.roomID = roomID
|
| | | newRoom.mapID = mapID
|
| | | newRoom.openTick = tick
|
| | | newRoom.roomPlayerIDList = [aPlayerID, bPlayerID]
|
| | | PyGameData.g_crossPKRoomDict[roomID] = newRoom
|
| | | |
| | | aServerGroupID, bServerGroupID = aPlayer.serverGroupID, bPlayer.serverGroupID
|
| | | GameWorld.Log(" 开房:pkZoneID=%s,mapID=%s,roomID=%s,aPlayerID=%s,bPlayerID=%s" % (pkZoneID, mapID, roomID, aPlayerID, bPlayerID))
|
| | | vsRoomDict[roomID] = [mapID, [[aServerGroupID, aPlayerID], [bServerGroupID, bPlayerID]]]
|
| | | |
| | | serverGroupIDList.append(aServerGroupID)
|
| | | serverGroupIDList.append(bServerGroupID)
|
| | | |
| | | # 移除匹配队列
|
| | | if aPlayerID in zoneMatchPlayerList:
|
| | | zoneMatchPlayerList.remove(aPlayerID)
|
| | | if bPlayerID in zoneMatchPlayerList:
|
| | | zoneMatchPlayerList.remove(bPlayerID)
|
| | | PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList
|
| | | |
| | | # 将匹配结果广播到子服
|
| | | if vsRoomDict:
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchResult, vsRoomDict, serverGroupIDList)
|
| | | |
| | | return
|
| | |
|
| | | def __GetNewRoomID():
|
| | | ## 获取新房间ID, 房间号直接自增,一定不会重复,除非自增一轮后房间ID还没有释放
|
| | | for _ in xrange(100):
|
| | | newRoomID = PyGameData.g_crossPKRoomID + 1
|
| | | if newRoomID > 65530:
|
| | | newRoomID = 1
|
| | | PyGameData.g_crossPKRoomID = newRoomID
|
| | | if newRoomID not in PyGameData.g_crossPKRoomDict:
|
| | | return newRoomID
|
| | | return 0
|
| | |
|
| | | def __DoCheckRoomTimeout(tick):
|
| | | ## 处理超时的房间
|
| | | |
| | | timeoutRoomDict = {}
|
| | | serverGroupIDList = []
|
| | | #roomTimeout = IpyGameDataPY.GetFuncCfg("CheckRoomTimeout", 1) * 1000 # 这个时间尽量长点,目前暂时不确定玩家从准备好到进入到地图的时长
|
| | | roomTimeout = 180 * 1000 # 这个时间尽量长点,目前暂时不确定玩家从准备到进入到地图的时长
|
| | | for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():
|
| | | if pkRoom.isMapOpen or not pkRoom.readyTick:
|
| | | continue
|
| | | if tick - pkRoom.readyTick <= roomTimeout:
|
| | | continue
|
| | | pkZoneID = pkRoom.pkZoneID
|
| | | GameWorld.Log("PK房间等待玩家进来超时,没有玩家进来,关闭该房间!pkZoneID=%s,roomID=%s,openTick=%s,readyTick=%s,tick=%s" |
| | | % (pkZoneID, roomID, pkRoom.openTick, pkRoom.readyTick, tick))
|
| | | roomPlayerInfo = []
|
| | | for roomPlayerID in pkRoom.roomPlayerIDList:
|
| | | pkPlayer = PyGameData.g_crossPKPlayerDict.pop(roomPlayerID, None)
|
| | | if not pkPlayer:
|
| | | continue
|
| | | serverGroupID = pkPlayer.serverGroupID
|
| | | GameWorld.Log(" 移除玩家,玩家需重新手动匹配,serverGroupID=%s,roomPlayerID=%s" % (serverGroupID, roomPlayerID))
|
| | | serverGroupIDList.append(serverGroupID)
|
| | | roomPlayerInfo.append([serverGroupID, roomPlayerID])
|
| | | timeoutRoomDict[roomID] = roomPlayerInfo
|
| | | PyGameData.g_crossPKRoomDict.pop(roomID)
|
| | | |
| | | # 将超时房间广播到子服
|
| | | if timeoutRoomDict:
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKTimeoutRoomList, timeoutRoomDict, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def MapServer_CrossPKRoomOpen(msgList):
|
| | | roomID = msgList[0]
|
| | | if roomID not in PyGameData.g_crossPKRoomDict:
|
| | | GameWorld.ErrLog("MapServer_CrossPKRoomOpen => PK房间不存在!roomID=%s" % roomID)
|
| | | return
|
| | | pkRoom = PyGameData.g_crossPKRoomDict[roomID]
|
| | | pkRoom.isMapOpen = True
|
| | | GameWorld.Log("MapServer_CrossPKRoomOpen => roomID=%s" % roomID)
|
| | | return
|
| | |
|
| | | def MapServer_MergePKOver(infoList):
|
| | | ## 收到MapServer副本跨服PK结果同步
|
| | | |
| | | GameWorld.Log("收到MapServer_跨服PK战斗结果: %s" % str(infoList))
|
| | | |
| | | roomID, winnerID, loserID, roundWinnerIDList, overType = infoList
|
| | | |
| | | if roomID not in PyGameData.g_crossPKRoomDict:
|
| | | GameWorld.ErrLog("跨服PK房间数据不存在!roomID=%s" % roomID)
|
| | | return
|
| | | vsRoom = PyGameData.g_crossPKRoomDict.pop(roomID)
|
| | | #vsRoom = PyGameData.g_crossPKRoomDict[roomID]
|
| | | roomPlayerIDList = vsRoom.roomPlayerIDList
|
| | | if not winnerID and not loserID:
|
| | | GameWorld.ErrLog("地图没有结算跨服PK胜负玩家,随机玩家获胜!")
|
| | | if not roomPlayerIDList or len(roomPlayerIDList) != 2:
|
| | | return
|
| | | winnerID, loserID = roomPlayerIDList
|
| | | elif not loserID:
|
| | | for roomPlayerID in roomPlayerIDList:
|
| | | if roomPlayerID != winnerID:
|
| | | loserID = roomPlayerID
|
| | | break
|
| | | |
| | | if winnerID not in roomPlayerIDList or loserID not in roomPlayerIDList:
|
| | | GameWorld.ErrLog("跨服PK房间及玩家不匹配,不结算!roomID=%s,winnerID=%s,loserID=%s,roomPlayerIDList=%s" |
| | | % (roomID, winnerID, loserID, vsRoom.roomPlayerIDList))
|
| | | return
|
| | | |
| | | if winnerID not in PyGameData.g_crossPKPlayerDict:
|
| | | GameWorld.ErrLog("跨服PK房间获取不到玩家PK数据, roomID=%s,winnerID=%s" % (roomID, winnerID))
|
| | | return
|
| | | if loserID not in PyGameData.g_crossPKPlayerDict:
|
| | | GameWorld.ErrLog("跨服PK房间获取不到玩家PK数据, roomID=%s,loserID=%s" % (roomID, loserID))
|
| | | return
|
| | | |
| | | winner = PyGameData.g_crossPKPlayerDict.pop(winnerID)
|
| | | loser = PyGameData.g_crossPKPlayerDict.pop(loserID)
|
| | | #winner = PyGameData.g_crossPKPlayerDict[winnerID]
|
| | | #loser = PyGameData.g_crossPKPlayerDict[loserID]
|
| | | seasonID = winner.seasonID
|
| | | |
| | | cWinCount = winner.cWinCount
|
| | | winnerScore, loserScore = winner.pkScore, loser.pkScore
|
| | | winnerDanLV, loserDanLV = winner.danLV, loser.danLV
|
| | | winnerDayScore, loserDayScore = max(0, winnerScore - winner.ondayScore), max(0, loserScore - loser.ondayScore) # 今日已获得积分,正积分
|
| | | |
| | | GameWorld.Log("winnerDayScore=%s,winnerScore=%s,winnerDanLV=%s,cWinCount=%s" % (winnerDayScore, winnerScore, winnerDanLV, cWinCount))
|
| | | GameWorld.Log("loserDayScore=%s,loserScore=%s,loserDanLV=%s" % (loserDayScore, loserScore, loserDanLV))
|
| | | |
| | | winIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", winnerDanLV)
|
| | | loseIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", loserDanLV)
|
| | | if not winIpyData or not loseIpyData:
|
| | | GameWorld.ErrLog("跨服PK房间段位数据异常! roomID=%s,winnerDanLV=%s,loserDanLV=%s" % (roomID, winnerDanLV, loserDanLV))
|
| | | |
| | | baseScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKScore", 2) # 胜负保底分
|
| | | wBaseScore = baseScoreList[0] if len(baseScoreList) > 0 else 0
|
| | | lBaseScore = baseScoreList[1] if len(baseScoreList) > 1 else 0
|
| | | wExScore = eval(IpyGameDataPY.GetFuncCompileCfg("CrossRealmPKScore", 3)) # 胜方附加分
|
| | | lExScore = 0
|
| | | |
| | | winnerAddScore = wBaseScore + wExScore
|
| | | loserAddScore = lBaseScore + lExScore
|
| | | |
| | | dayMaxScore = IpyGameDataPY.GetFuncCfg("CrossRealmPKScore", 1) # 每日获得积分上限,0为不限制
|
| | | if dayMaxScore:
|
| | | if winnerAddScore > 0:
|
| | | winnerAddScore = min(dayMaxScore - winnerDayScore, winnerAddScore)
|
| | | if loserAddScore > 0:
|
| | | loserAddScore = min(dayMaxScore - loserDayScore, loserAddScore)
|
| | | |
| | | winner.pkScore += winnerAddScore
|
| | | loser.pkScore += loserAddScore
|
| | | |
| | | winner.cWinCount += 1
|
| | | loser.cWinCount = 0
|
| | | |
| | | if winIpyData and winIpyData.GetLVUpScore() and winner.pkScore >= winIpyData.GetLVUpScore():
|
| | | winner.danLV += 1
|
| | | |
| | | if loseIpyData and loseIpyData.GetLVUpScore() and loser.pkScore >= loseIpyData.GetLVUpScore():
|
| | | loser.danLV += 1
|
| | | |
| | | GameWorld.Log("wBaseScore=%s,wExScore=%s,winnerAddScore=%s,updScore=%s,updDanLV=%s,updCWinCount=%s" % (wBaseScore, wExScore, winnerAddScore, winner.pkScore, winner.danLV, winner.cWinCount))
|
| | | GameWorld.Log("lBaseScore=%s,lExScore=%s,loserAddScore=%s,updScore=%s,updDanLV=%s,updCWinCount=%s" % (lBaseScore, lExScore, loserAddScore, loser.pkScore, loser.danLV, loser.cWinCount))
|
| | | |
| | | timeStr = GameWorld.GetCurrentDataTimeStr()
|
| | | playerOverDict = {}
|
| | | # 通知客户端战斗结果
|
| | | for playerID in [winnerID, loserID]:
|
| | | if playerID == winnerID:
|
| | | serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \
|
| | | winner.serverGroupID, winner.pkScore, winner.danLV, winner.cWinCount, winnerAddScore, loser.playerID, loser.playerName
|
| | | else:
|
| | | serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \
|
| | | loser.serverGroupID, loser.pkScore, loser.danLV, loser.cWinCount, loserAddScore, winner.playerID, winner.playerName
|
| | | |
| | | player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | notifyState = True if player else False
|
| | | |
| | | playerOverDict[playerID] = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList] \
|
| | | + [serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]
|
| | | if not player:
|
| | | continue
|
| | | |
| | | overPack = ChPyNetSendPack.tagGCCrossRealmPKOverInfo()
|
| | | overPack.TimeStr = timeStr
|
| | | overPack.OverType = overType
|
| | | overPack.WinnerID = winnerID
|
| | | overPack.RoundWinnerID = roundWinnerIDList
|
| | | overPack.RoundCount = len(overPack.RoundWinnerID)
|
| | | overPack.AddScore = addScore
|
| | | overPack.Score = pkScore
|
| | | overPack.DanLV = danLV
|
| | | overPack.CWinCnt = cWinCount
|
| | | overPack.TagName = tagPlayerName
|
| | | overPack.TagNameLen = len(overPack.TagName)
|
| | | NetPackCommon.SendFakePack(player, overPack)
|
| | | |
| | | GameWorld.Log("同步玩家PK结果: serverGroupID=%s,roomID=%s,addScore=%s,pkScore=%s,danLV=%s,cWinCount=%s,tagPlayerID=%s" |
| | | % (serverGroupID, roomID, addScore, pkScore, danLV, cWinCount, tagPlayerID), playerID)
|
| | | |
| | | serverGroupIDList = [winner.serverGroupID, loser.serverGroupID]
|
| | | GameWorld.Log("同步子服战斗结果: seasonID=%s,timeStr=%s,roomID=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s" |
| | | % (seasonID, timeStr, roomID, overType, winnerID, roundWinnerIDList))
|
| | | # 同步子服
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKOverInfo, playerOverDict, serverGroupIDList)
|
| | | return
|
| | |
|
| | | ##================================== 以下是子服逻辑 ==========================================
|
| | |
|
| | | def CrossServerMsg_PKMatchReqRet(retInfo):
|
| | | ## 跨服PK匹配请求结果
|
| | | playerID, result = retInfo
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | if result == -2:
|
| | | PlayerControl.NotifyCode(curPlayer, "InCrossPKing")
|
| | | return
|
| | | |
| | | if result == 1:
|
| | | NetPackCommon.SendFakePack(curPlayer, ChPyNetSendPack.tagGCCrossRealmPKStartMatch())
|
| | | |
| | | return
|
| | |
|
| | | def CrossServerMsg_PKMatchResult(vsRoomDict):
|
| | | ## 跨服PK匹配结果
|
| | | curServerGroupID = GameWorld.GetServerGroupID()
|
| | | actionType = ShareDefine.Def_MergeAction_MergePK
|
| | | mapPosList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKMatch", 5)
|
| | | GameWorld.Log("=== 收到PK匹配结果处理 === curServerGroupID=%s" % curServerGroupID)
|
| | | if not mapPosList:
|
| | | GameWorld.ErrLog("没有配置对战地图进入坐标!")
|
| | | return
|
| | | |
| | | for roomID, roomInfo in vsRoomDict.items():
|
| | | mapID, playerList = roomInfo
|
| | | GameWorld.Log(" roomID=%s,playerList=%s" % (roomID, playerList))
|
| | | for i, playerInfo in enumerate(playerList):
|
| | | serverGroupID, playerID = playerInfo
|
| | | if serverGroupID != curServerGroupID:
|
| | | GameWorld.DebugLog(" 不是本服玩家,不处理!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
|
| | | PlayerControl.SetVsRoomId(player, roomID, True)
|
| | | # 通知地图玩家匹配成功, 上传数据, 准备进入跨服服务器
|
| | | posX, posY = mapPosList[i] if len(mapPosList) > i else mapPosList[0]
|
| | | CrossRealmPlayer.SendCrossRealmReg(player, actionType, mapID, mapID, 0, posX, posY)
|
| | | |
| | | return
|
| | |
|
| | | def CrossServerMsg_PKReadyOKRoomList(readyOKRoomList):
|
| | | ## 子服接收玩家已准备好的PK房间信息, 此房间里的玩家可传送进入跨服
|
| | | |
| | | curServerGroupID = GameWorld.GetServerGroupID()
|
| | | GameWorld.Log("===收到跨服服务器通知已准备好的对战PK房间信息处理=== curServerGroupID=%s" % curServerGroupID)
|
| | | # serverGroupID, playerName, playerJob
|
| | | |
| | | for roomID, readyMemberDict in readyOKRoomList:
|
| | | for playerID, playerInfo in readyMemberDict.items():
|
| | | serverGroupID = playerInfo["ServerGroupID"]
|
| | | playerName = playerInfo["Name"]
|
| | | |
| | | if serverGroupID != curServerGroupID:
|
| | | GameWorld.DebugLog(" 不是本服玩家,不处理!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
|
| | | player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 1)
|
| | | |
| | | matchPlayer = ChPyNetSendPack.tagGCCrossRealmPKMatchPlayer()
|
| | | for readyPlayerID, readyPlayerInfo in readyMemberDict.items():
|
| | | if readyPlayerID != playerID:
|
| | | matchPlayer.PlayerID = readyPlayerID
|
| | | matchPlayer.PlayerName = readyPlayerInfo["Name"]
|
| | | matchPlayer.NameLen = len(matchPlayer.PlayerName)
|
| | | matchPlayer.Job = readyPlayerInfo["Job"]
|
| | | matchPlayer.LV = readyPlayerInfo["LV"]
|
| | | matchPlayer.MaxHP = readyPlayerInfo["MaxHP"]
|
| | | break
|
| | | |
| | | PlayerControl.SetCrossRealmState(player, 1)
|
| | | |
| | | # 通知匹配成功,可进入跨服
|
| | | matchOKPack = ChPyNetSendPack.tagGCCrossRealmPKMatchOK()
|
| | | matchOKPack.RoomID = roomID
|
| | | matchOKPack.PlayerName = playerName
|
| | | matchOKPack.NameLen = len(matchOKPack.PlayerName)
|
| | | matchOKPack.MatchPlayer = [matchPlayer]
|
| | | matchOKPack.MatchPlayerCount = len(matchOKPack.MatchPlayer)
|
| | | NetPackCommon.SendFakePack(player, matchOKPack)
|
| | | GameWorld.Log(" 通知玩家进入跨服PK对战房间! roomID=%s,playerID=%s,matchPlayerID=%s" % (roomID, playerID, matchPlayer.PlayerID))
|
| | | |
| | | # 到这里默认认为一定会有结果的,所以本服直接增加次数
|
| | | #player.MapServer_QueryPlayerResult(0, 0, 'MergePKAddCnt', "", 0)
|
| | | return
|
| | |
|
| | | def CrossServerMsg_PKTimeoutRoomList(timeoutRoomDict):
|
| | | ## 子服接收已超时的PK房间信息, 此房间里的玩家重置跨服状态
|
| | | |
| | | curServerGroupID = GameWorld.GetServerGroupID()
|
| | | GameWorld.Log("===收到跨服服务器通知已超时的对战PK房间信息处理=== curServerGroupID=%s" % curServerGroupID)
|
| | | |
| | | for roomID, roomPlayerInfo in timeoutRoomDict.items():
|
| | | if not roomPlayerInfo:
|
| | | continue
|
| | | serverGroupID, playerID = roomPlayerInfo
|
| | | |
| | | if serverGroupID != curServerGroupID:
|
| | | GameWorld.DebugLog(" 不是本服玩家,不处理!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
|
| | | playerVSRoomID = player.GetVsRoomId()
|
| | | if playerVSRoomID and playerVSRoomID != roomID:
|
| | | GameWorld.DebugLog(" 房间ID不同, playerID=%s" % (playerID))
|
| | | continue
|
| | | player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)
|
| | | PlayerControl.SetCrossRealmState(player, 0)
|
| | | |
| | | return
|
| | |
|
| | | def CrossServerMsg_PKOverInfo(playerOverDict):
|
| | | ## 子服接收跨服PK结果信息
|
| | | |
| | | curServerGroupID = GameWorld.GetServerGroupID()
|
| | | GameWorld.Log("===收到跨服服务器同步的跨服PK结果=== curServerGroupID=%s" % curServerGroupID)
|
| | | |
| | | for playerID, overInfo in playerOverDict.items():
|
| | | roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, \
|
| | | serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo
|
| | | if serverGroupID != curServerGroupID:
|
| | | GameWorld.DebugLog(" 不是本服玩家,不处理!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))
|
| | | continue
|
| | | |
| | | sendMapOverInfo = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]
|
| | | player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not player or PlayerControl.GetIsTJG(player):
|
| | | GameWorld.Log(" 玩家不在线 或脱机中,先缓存,玩家上线后再同步,playerID=%s" % (playerID))
|
| | | PyGameData.g_crossPKUnNotifyOverInfo[playerID] = sendMapOverInfo
|
| | | continue
|
| | | |
| | | sysMsg = str(sendMapOverInfo)
|
| | | player.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))
|
| | | GameWorld.Log("通知地图跨服PK结算: roomID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s, pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s,mapID=%s" |
| | | % (roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState, player.GetMapID()), playerID)
|
| | | return
|
| | |
|
| | | def __OnLoginNotifyPKOverInfo(curPlayer):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID not in PyGameData.g_crossPKUnNotifyOverInfo:
|
| | | return
|
| | | overInfo = PyGameData.g_crossPKUnNotifyOverInfo.pop(playerID)
|
| | | PlayerControl.SetCrossRealmState(curPlayer, 0)
|
| | | sysMsg = str(overInfo)
|
| | | curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))
|
| | | GameWorld.Log("玩家上线通知地图未结算的跨服PK结算: mapID=%s,overInfo=%s" % (curPlayer.GetMapID(), overInfo), playerID)
|
| | | return
|
| | |
|
| | |
|
| | |
| | | # 详细描述: 王者争霸(跨服PK赛周积分排名前32可获得争霸资格)
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | """Version = 2015-11-19 14:00"""
|
| | | #"""Version = 2015-11-19 14:00"""
|
| | | #---------------------------------------------------------------------
|
| | | import ReadChConfig
|
| | | import PlayerControl
|
| | |
| | | import PlayerCompensation
|
| | | import PlayerUniversalGameRec
|
| | | import PlayerMergeRegister
|
| | | import CrossRealmPlayer
|
| | | import GameWorldMergePK
|
| | | import PlayerDBGSEvent
|
| | | import MergeBroadcast
|
| | |
| | | lastNotifyTime = gameWorld.GetDictByKey(notifyTimeKey)
|
| | | if tick - lastNotifyTime >= notifyCD * 1000:
|
| | | mark = loginNotifyDict[playerRecRank]
|
| | | mergeName = PlayerControl.GetMergePlayerName(accID, curPlayer.GetName())
|
| | | mergeName = CrossRealmPlayer.GetCrossPlayerName(curPlayer)
|
| | | PlayerControl.MergeWorldNotify(0, mark, [mergeName])
|
| | | gameWorld.SetDict(notifyTimeKey, tick)
|
| | | else:
|
| | |
| | | #import MergeBroadcast
|
| | | #import GameWorldMixServerCampaign
|
| | | #import GameWorldMergeKing
|
| | | #import GameWorldMergePK
|
| | | #import PlayerManorWar
|
| | | import GameWorldBoss
|
| | | #import GameWorldActionTeHui
|
| | |
| | | import ReadChConfig
|
| | | import EventReport
|
| | | #import ReloadModule
|
| | | import MergeChildMsg
|
| | | import CrossRealmMsg
|
| | | import CrossRealmPK
|
| | | #import MergePlayer
|
| | | import PlayerFBHelpBattle
|
| | | import PlayerFamilyRedPacket
|
| | |
| | | #跨服广播
|
| | | #MergeBroadcast.OnBroadcastProccee(tick)
|
| | | #跨服PK匹配
|
| | | #GameWorldMergePK.OnPKMatchProcess(tick)
|
| | | CrossRealmPK.OnPKMatchProcess(tick)
|
| | | #跨服王者争霸
|
| | | #GameWorldMergeKing.OnMergeKingProcess(tick)
|
| | |
|
| | |
| | | #GameWorldBoss.CheckResetBossKilledCntOnServerInit()
|
| | | #GameWorldActionTeHui.OnGameServerInitOK() # 特惠活动初始化
|
| | | #子服启动成功告知跨服主服
|
| | | #===========================================================================
|
| | | # serverGroupID = GameWorld.GetServerGroupID()
|
| | | # if GameWorld.IsMergeOpen() and not GameWorld.IsMergeServer():
|
| | | # GameWorld.Log("通知跨服主服务器启动成功, 可接收最新跨服活动状态及数据...")
|
| | | # dataMsg = {"Platform":GameWorld.GetPlatform(), "ServerID":GameWorld.GetServerSID(), "ServerGroupID":serverGroupID}
|
| | | # MergeChildMsg.SendMergerChildToCenterStringData(ChConfig.Def_ClientServerInitOK, dataMsg)
|
| | | # |
| | | # GameWorld.Log("服务器启动成功: ServerGroupID=%s" % serverGroupID)
|
| | | #===========================================================================
|
| | | serverGroupID = GameWorld.GetServerGroupID()
|
| | | if GameWorld.IsCrossRealmOpen() and not GameWorld.IsCrossServer():
|
| | | GameWorld.Log("通知跨服主服务器启动成功, 可接收最新跨服活动状态及数据...")
|
| | | dataMsg = {"ServerGroupID":serverGroupID}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_ServerInitOK, dataMsg)
|
| | | |
| | | GameWorld.Log("服务器启动成功: ServerGroupID=%s" % serverGroupID)
|
| | | return
|
| | |
|
| | | def DoCheckNewServerOpen(tick):
|
| | |
| | | import ChPyNetSendPack
|
| | | import traceback
|
| | | import ChMapToGamePyPack
|
| | | import MergeChildMsg
|
| | | import CrossRealmMsg
|
| | | #-------------------------------------------------------------------------------
|
| | | #---全局变量---
|
| | |
|
| | |
| | | # Log("ReadPyPackTable: moudle: %s"%dir(moudle))
|
| | |
|
| | | for index in range(regCnt):
|
| | | if not config.get(section, "PacketCMD_%s"%(index + 1)):
|
| | | continue
|
| | | cmd = config.get(section, "PacketCMD_%s"%(index + 1))
|
| | | subCmd = config.get(section, "PacketSubCMD_%s"%(index + 1))
|
| | | callFunc = config.get(section, "PacketCallFunc_%s"%(index + 1))
|
| | | if not cmd or not subCmd or not callFunc:
|
| | | continue
|
| | |
|
| | | cmd = int(cmd, 16)
|
| | | subCmd = int(subCmd, 16)
|
| | |
| | | #以下添加后续处理函数
|
| | | #...
|
| | | #...
|
| | | MergeChildMsg.Recv_MergerChildToCenterProcess(packData, tick)
|
| | | CrossRealmMsg.OnCrossServerReceiveMsg(packData, tick)
|
| | | except Exception:
|
| | | Log("跨服子服自定义封包消息处理失败")
|
| | | return
|
| | |
| | | import PlayerBourse
|
| | | import GameWorldActionTeHui
|
| | | import PlayerXMZZ
|
| | | import GameWorldMergePK
|
| | | import GameWorldShopItem
|
| | | import MergeChildMsg
|
| | | import PlayerTruck
|
| | |
| | | import PyGameData
|
| | | import GMShell
|
| | | import IPY_PlayerDefine
|
| | | import CrossRealmPK
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | PyGameData.g_todayPlayerLVDict[curPlayer.GetID()] = curPlayer.GetLV()
|
| | | #副本助战
|
| | | PlayerFBHelpBattle.OnHelpPlayerLogin(curPlayer)
|
| | | #跨服PK
|
| | | CrossRealmPK.OnPlayerLogin(curPlayer)
|
| | |
|
| | | GMShell.OnPlayerLogin(curPlayer)
|
| | | GMT_CTG.OnPlayerLogin(curPlayer)
|
| | |
| | | def __Func_PlayerDisconnect(curPlayer, tick):
|
| | |
|
| | | #跨服匹配PK
|
| | | #GameWorldMergePK.OnLeaveServer(curPlayer)
|
| | | CrossRealmPK.OnLeaveServer(curPlayer)
|
| | |
|
| | | #组队玩家离线
|
| | | PlayerTeam.DoPlayerLogOffTeamLogic(curPlayer, tick)
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package CrossRealmPlayer
|
| | | #
|
| | | # @todo:跨服玩家
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服玩家
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import CrossRealmMsg
|
| | | import ReadChConfig
|
| | | import ChConfig
|
| | | import PlayerControl
|
| | |
|
| | | # 获取玩家跨服服务器上的名字
|
| | | def GetCrossPlayerName(curPlayer):
|
| | | # 通过游戏账号中的平台标志获取名称,目前为spid
|
| | | playerName = curPlayer.GetPlayerName()
|
| | | nameFormat = ReadChConfig.GetPyMongoConfig("Merge", "NameFormat", True)
|
| | | if not nameFormat:
|
| | | return playerName
|
| | | |
| | | opName = ReadChConfig.GetPyMongoConfig("Merge", "OpName_%s" % GameWorld.GetPlayerPlatform(curPlayer))
|
| | |
|
| | | return (nameFormat%{"opname":opName, "sid":GameWorld.GetPlayerServerID(curPlayer)}).decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName
|
| | |
|
| | | def CrossServerMsg_ExitCrossServer(msgData):
|
| | | ## 收到跨服服务器同步的玩家退出跨服服务器
|
| | | playerID = msgData
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | PlayerControl.SetCrossRealmState(curPlayer, 0)
|
| | | return
|
| | |
|
| | | def SendCrossRealmReg(curPlayer, actionType, mapID=0, dataMapID=0, copyMapID=0, posX=0, posY=0):
|
| | | # 发送跨服账号注册上传数据
|
| | | |
| | | # 设置上传数据的活动类型
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MergeRegisterType, actionType)
|
| | | sysMsg = str([actionType, mapID, dataMapID, copyMapID, posX, posY])
|
| | | curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossRealmReg", sysMsg, len(sysMsg)) |
| | | GameWorld.Log("SendCrossRealmReg actionType=%s,mapID=%s,dataMapID=%s,copyMapID=%s,posX=%s,posY=%s" |
| | | % (actionType, mapID, dataMapID, copyMapID, posX, posY), curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def OnCrossRealmRegOK(playerID, msgList, tick): |
| | | ## 跨服报名结果
|
| | | |
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | #newAccount, newName = msgList
|
| | | |
| | | actionType = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MergeRegisterType)
|
| | | GameWorld.Log("跨服报名成功 , actionType=%s" % (actionType), playerID)
|
| | | |
| | | # 跨服PK上传数据完毕,通知跨服服务器,准备完毕
|
| | | if actionType == ShareDefine.Def_MergeAction_MergePK:
|
| | | regVSRoomID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MergeRegisterRoomID) |
| | | vsRoomID = curPlayer.GetVsRoomId()
|
| | | |
| | | if regVSRoomID != vsRoomID:
|
| | | GameWorld.Log("上传跨服服务器的 regVSRoomID=%s 与玩家当前的 roomID=%s 不同!不发送准备完毕!" |
| | | % (regVSRoomID, vsRoomID), playerID)
|
| | | return
|
| | | |
| | | dataMsg = {
|
| | | "accID":curPlayer.GetAccID(), # 角色账号ID
|
| | | "playerID":playerID, # 角色ID
|
| | | "vsRoomID":vsRoomID, # 所属对战房间ID
|
| | | }
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKPrepareOK, dataMsg)
|
| | | GameWorld.Log("通知跨服服务器, 玩家匹配PK准备完毕!%s" % str(dataMsg), playerID)
|
| | | |
| | | # 其他的,在上传数据完毕后,使用通用的通知可进入跨服
|
| | | else:
|
| | | NotifyCanEnterMergeServer(curPlayer, actionType)
|
| | | |
| | | # hxp 2015.09.10 跨服boss,后面的暂时不需要
|
| | | return
|
| | |
|
| | |
|
| | | def NotifyCanEnterMergeServer(curPlayer, actionType):
|
| | | # 通用包,通知客户端可进入跨服服务器
|
| | | # mapID, lineID = 0, 0
|
| | | # mapPosInfo = GetMergeActionMapPos(actionType)
|
| | | # if mapPosInfo:
|
| | | # mapID = mapPosInfo[0]
|
| | | # lineID = mapPosInfo[2]
|
| | | # |
| | | # canEnterMServer = ChPyNetSendPack.tagCanEnterMergeServer()
|
| | | # canEnterMServer.Clear()
|
| | | # canEnterMServer.ActionType = actionType
|
| | | # canEnterMServer.MapID = mapID
|
| | | # canEnterMServer.LineID = lineID
|
| | | # canEnterMServer.NewAccID = newAccID
|
| | | # canEnterMServer.NewAccIDLen = len(canEnterMServer.NewAccID)
|
| | | # canEnterMServer.NewPsw = newPwd
|
| | | # canEnterMServer.NewPswLen = len(canEnterMServer.NewPsw)
|
| | | # NetPackCommon.SendFakePack(curPlayer, canEnterMServer)
|
| | | return
|
| | |
|
| | |
|
| | |
| | | # @change: "2015-07-14 21:00" xdh 聊天信息原附加值改为Extras
|
| | | # @change: "2015-10-28 00:00" hxp 增加设置对战房间ID
|
| | | # @change: "2015-11-05 12:00" hxp 增加跨服全服广播
|
| | | # @change: "2015-11-06 16:30" hxp 增加GetMergePlayerName
|
| | | # @change: "2017-06-22 15:00" hxp 跨服广播增加条件过滤子服是否提醒;跨服服务器全服广播同步子服
|
| | | #---------------------------------------------------------------------
|
| | | #"""Version = 2017-06-22 15:00"""
|
| | |
| | | import IPY_GameServer
|
| | | import MergeBroadcast
|
| | | import IpyGameDataPY
|
| | | import CrossRealmMsg
|
| | | import ShareDefine
|
| | | import ChConfig
|
| | | import types
|
| | |
| | |
|
| | | curPlayer.NotifyCode(msgMark, __GetNotifyCodeList(msgParamList))
|
| | | return
|
| | | |
| | |
|
| | | def NotifyCodeToClientServer(serverGroupID, playerID, msgMark, msgParamList=[]):
|
| | | dataMsg = {"Type":"Player", "ID":playerID, "Mark":msgMark, "Param":msgParamList}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Notify, dataMsg, [serverGroupID])
|
| | | return
|
| | |
|
| | | def CrossServerMsg_Notify(notifyInfoDict):
|
| | | notifyType = notifyInfoDict["Type"]
|
| | | notifyID = notifyInfoDict["ID"]
|
| | | if notifyType == "Player":
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(notifyID)
|
| | | if not curPlayer:
|
| | | return
|
| | | NotifyCode(curPlayer, notifyInfoDict["Mark"], notifyInfoDict["Param"])
|
| | | return
|
| | |
|
| | | ## 跨服世界广播
|
| | | # @param country 提示的国家
|
| | | # @param msgMark 提示信息Mark
|
| | |
| | | curPlayer.SetVsRoomId(roomID)
|
| | | if isSetMergeRegRoomID:
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MergeRegisterRoomID, roomID)
|
| | | |
| | | battleIDStr = str(roomID)
|
| | | GameWorld.Log("SetVSRoomID playerID=%s, roomID=%s" % (curPlayer.GetPlayerID(), roomID))
|
| | | curPlayer.MapServer_QueryPlayerResult(0, 0, 'CreatePlayerRoomID', battleIDStr, len(battleIDStr))
|
| | | SetMapServerPlayerAttrValue(curPlayer, "SetVsRoomId", roomID)
|
| | | return
|
| | |
|
| | | ## 根据子服账号及名称获取跨服角色名
|
| | | def GetMergePlayerName(playerAccID, playerName):
|
| | | orgPlayerName = playerName.strip()
|
| | | |
| | | #取帐号后缀作为区服标识
|
| | | parserList = playerAccID.split('@')
|
| | | serverSign = ""
|
| | | if len(parserList) >= 2:
|
| | | serverSign = parserList[-1] |
| | | |
| | | parserList2 = orgPlayerName.split('-')
|
| | | orgNameServerSign = ""
|
| | | nameNotServerSign = parserList2[0]
|
| | | if len(parserList2) >= 2:
|
| | | orgNameServerSign = parserList2[-1]
|
| | | |
| | | if orgNameServerSign:
|
| | | if orgNameServerSign == serverSign:
|
| | | return orgPlayerName
|
| | | else:
|
| | | return "%s-%s" % (nameNotServerSign, serverSign)
|
| | | |
| | | if serverSign:
|
| | | return "%s-%s" % (nameNotServerSign, serverSign)
|
| | | |
| | | return orgPlayerName
|
| | | ## 跨服状态: 0-非跨服状态,1-跨服状态
|
| | | def GetCrossRealmState(curPlayer): return curPlayer.GetExAttr5()
|
| | | def SetCrossRealmState(curPlayer, value):
|
| | | ''' 设置玩家跨服状态
|
| | | @param isExitCrossRealm: 非跨服状态时是否通知前端退出跨服服务器
|
| | | '''
|
| | | curPlayer.SetExAttr5(value)
|
| | | SetMapServerPlayerAttrValue(curPlayer, "SetExAttr5", value)
|
| | | return
|
| | |
|
| | | def SetMapServerPlayerAttrValue(curPlayer, attrName, value, exData=[]):
|
| | | ## 设置地图服务器玩家对应属性值
|
| | | setAttrInfo = str([attrName, value] + exData)
|
| | | curPlayer.MapServer_QueryPlayerResult(0, 0, "SetPlayerAttr", setAttrInfo, len(setAttrInfo))
|
| | | return
|
| | |
|
| | | ## 地图服务器扣物品
|
| | | # @param curPlayer
|
| | |
| | | import PyGameData
|
| | | import PlayerTalk
|
| | | import PlayerStore
|
| | | import CrossRealmPlayer
|
| | | import CrossRealmMsg
|
| | | import CrossRealmPK
|
| | |
|
| | | import time
|
| | | import datetime
|
| | |
| | | PlayerCompensation.SendPersonalItemMailBatch(eval(resultName))
|
| | | return
|
| | |
|
| | | if callName == 'SendMergerChildMsg':
|
| | | operType, dataMsg = eval(resultName)
|
| | | MergeChildMsg.SendMergerChildToCenterStringData(operType, dataMsg)
|
| | | # 如果是恢复跨服PK连胜的,先记录恢复的玩家ID, 等待成功后同步最新结果给玩家
|
| | | if operType == ChConfig.Def_RecoverMergePKWin:
|
| | | GameWorldMergePK.Add_RecoverMergePKWinPlayer(srcPlayerID)
|
| | | if callName == "SendMsgToCrossServer":
|
| | | msgType, dataMsg = eval(resultName)
|
| | | CrossRealmMsg.SendMsgToCrossServer(msgType, dataMsg)
|
| | | return
|
| | | |
| | | if callName == "SendMsgToClientServer":
|
| | | msgType, dataMsg, serverGroupIDList = eval(resultName)
|
| | | CrossRealmMsg.SendMsgToClientServer(msgType, dataMsg, serverGroupIDList)
|
| | | return
|
| | |
|
| | | if callName == 'MergeWorldNotify':
|
| | |
| | | return
|
| | |
|
| | | #跨服赛报名获得新账号
|
| | | if callName == 'MergeRegister':
|
| | | PlayerMergeRegister.MergeWarRegisterNewAcc(srcPlayerID, eval(resultName), tick)
|
| | | return |
| | | #if callName == 'MergeRegister':
|
| | | # PlayerMergeRegister.MergeWarRegisterNewAcc(srcPlayerID, eval(resultName), tick)
|
| | | # return |
| | |
|
| | | #跨服王者争霸
|
| | | if callName == 'MergeKingFB':
|
| | | GameWorldMergeKing.MapServer_MergeKingFB(eval(resultName))
|
| | | return
|
| | |
|
| | | #跨服匹配PK
|
| | | if callName == 'MergePKOver':
|
| | | GameWorldMergePK.MapServer_MergePKOver(eval(resultName))
|
| | | #跨服匹配PK战斗结算
|
| | | if callName == "CrossPKOver":
|
| | | CrossRealmPK.MapServer_MergePKOver(eval(resultName))
|
| | | return
|
| | | |
| | | #跨服匹配房间开启
|
| | | if callName == "CrossPKRoomOpen":
|
| | | CrossRealmPK.MapServer_CrossPKRoomOpen(eval(resultName))
|
| | | return
|
| | |
|
| | | #跨服匹配PK取消匹配
|
| | | if callName == 'MergePKCancel':
|
| | | if callName == "CrossRealmPKCancel":
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | GameWorldMergePK.SendCancelMergePKMatch(curPlayer, resultName)
|
| | | CrossRealmPK.SendCancelCrossRealmPKMatch(curPlayer, resultName)
|
| | | return
|
| | | |
| | | #跨服注册结果
|
| | | if callName == "CrossRealmReg":
|
| | | CrossRealmPlayer.OnCrossRealmRegOK(srcPlayerID, eval(resultName), tick)
|
| | | return
|
| | |
|
| | | #py喇叭聊天
|
| | |
| | | g_fbHelpBattleRecord = {} # 未同步的副本助战记录 {playerID:[FBHelpBattleRecord, ...], ...}
|
| | |
|
| | | g_autoViceleaderDict = {}#自动安排副盟主的玩家记录{familyID:[]}
|
| | | g_forbidAutoViceleaderFamily = [] #禁止自动安排副盟主的仙盟[familyID,..] |
| | | g_forbidAutoViceleaderFamily = [] #禁止自动安排副盟主的仙盟[familyID,..]
|
| | |
|
| | | g_crossPKPlayerDict = {} # 跨服PK玩家字典 {playerID:PKPlayer, ...}
|
| | | g_crossPKZoneMatchPlayerDict = {} # 跨服PK匹配中的玩家字典 {zoneID:[playerID, ...], ...}
|
| | | g_crossPKRoomDict = {} # 跨服PK房间字典 {roomID:PKRoom, ...}
|
| | | g_crossPKRoomID = 0 # 跨服PK当前已经创建到的房间ID,自增创建
|
| | |
|
| | | g_crossPKUnNotifyOverInfo = {} # 跨服PK未同步的结算信息 {player:[overInfo], ...}
|
| | |
|
| | |
| | | PacketSubCMD_1=0x4
|
| | | PacketCallFunc_1=GetDGDBOperResultInfo
|
| | |
|
| | | [MergeBroadCast]
|
| | | ScriptName = Player\MergeBroadCastRecive.py
|
| | | Writer = wdb
|
| | | Releaser = wdb
|
| | | [CrossRealmMsg]
|
| | | ScriptName = GameWorldLogic\CrossRealmMsg.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 1
|
| | | PacketCMD_1=0x4
|
| | | PacketSubCMD_1=0x5
|
| | | PacketCallFunc_1=OnMergeBroadCastPack
|
| | | PacketCallFunc_1=OnClientServerReceiveMsg
|
| | |
|
| | | ;家族
|
| | | [PlayerFamily]
|
| | |
| | | PacketSubCMD_8=0x03
|
| | | PacketCallFunc_8=PySetAdult
|
| | |
|
| | | PacketCMD_9=0xC1
|
| | | PacketSubCMD_9=0x03
|
| | | PacketCallFunc_9=ClientPlayerGetReward
|
| | | PacketCMD_9=
|
| | | PacketSubCMD_9=
|
| | | PacketCallFunc_9=
|
| | |
|
| | | PacketCMD_10=0xB4
|
| | | PacketSubCMD_10=0x04
|
| | |
| | | PacketCallFunc_2 = OnGetManorWarDailyAward
|
| | |
|
| | |
|
| | | ;跨服匹配PK
|
| | | [PlayerMergePK]
|
| | | ScriptName = Player\PlayerMergePK.py
|
| | | ;跨服PK竞技场
|
| | | [PlayerCrossRealmPK]
|
| | | ScriptName = Player\PlayerCrossRealmPK.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 2
|
| | | RegisterPackCount = 3
|
| | |
|
| | | PacketCMD_1=0xC1
|
| | | PacketSubCMD_1=0x09
|
| | | PacketCallFunc_1=OnRequestMergePK
|
| | | PacketSubCMD_1=0x01
|
| | | PacketCallFunc_1=OnCrossRealmPKMatch
|
| | |
|
| | | PacketCMD_2=0xC1
|
| | | PacketSubCMD_2=0x10
|
| | | PacketCallFunc_2=OnRequestRecoverMergePKWin
|
| | | PacketCMD_1=0xC1
|
| | | PacketSubCMD_1=0x02
|
| | | PacketCallFunc_1=OnCrossRealmPKBuy
|
| | |
|
| | | PacketCMD_1=0xC1
|
| | | PacketSubCMD_1=0x03
|
| | | PacketCallFunc_1=OnCrossRealmPKGetAward
|
| | |
|
| | | ;跨服玩家
|
| | | [CrossRealmPlayer]
|
| | | ScriptName = Player\CrossRealmPlayer.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 1
|
| | |
|
| | | PacketCMD_1=0xC1
|
| | | PacketSubCMD_1=0x04
|
| | | PacketCallFunc_1=OnExitCrossRealm
|
| | |
|
| | | ;王者争霸
|
| | | [PlayerMergeKing]
|
| | |
| | | Def_FBMapID_Dogz = 21110
|
| | | #聚魂副本
|
| | | Def_FBMapID_GatherSoul = 31340
|
| | | #跨服竞技场
|
| | | Def_FBMapID_CrossRealmPK = 32010
|
| | | #副本关闭时未拾取的物品邮件发放给玩家
|
| | | #这里只有需要的副本才配置,不做默认逻辑,防止某些副本实际不能给导致刷物品,如麒麟之府
|
| | | Def_SendUnPickItemMailMapIDList = [Def_FBMapID_IceLode, Def_FBMapID_PersonalBoss, Def_FBMapID_MunekadoTrial,
|
| | |
| | | 'SealDemon':[Def_FBMapID_SealDemon, Def_FBMapID_SealDemonEx], #封魔坛
|
| | | 'XMZZ':[Def_FBMapID_XMZZ], #仙魔之争
|
| | | 'Dogz':[Def_FBMapID_Dogz], #神兽副本
|
| | | 'GatherSoul':[Def_FBMapID_GatherSoul],#聚魂副本
|
| | | 'CrossRealmPK':[Def_FBMapID_CrossRealmPK], #跨服竞技场
|
| | | }
|
| | |
|
| | | #特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
|
| | |
| | | Def_PDict_MergeKing_SupportAward = "PD_MergePK_SupportAward" # 跨服王者争霸玩家竞猜积分奖励领取记录
|
| | | Def_PDict_MergeKing_Worship = "PD_MergePK_Worship" # 跨服王者争霸玩家每日膜拜记录
|
| | |
|
| | | # 跨服竞技场
|
| | | Def_PDict_CrossPK_TotalScore = "CrossPK_TotalScore" # 当前总积分
|
| | | Def_PDict_CrossPK_OnDayScore = "CrossPK_OnDayScore" # 今天过天时的积分
|
| | | Def_PDict_CrossPK_DanLV = "CrossPK_DanLV" # 当前段位
|
| | | Def_PDict_CrossPK_PKCount = "CrossPK_PKCount" # 当前总PK次数
|
| | | Def_PDict_CrossPK_WinCount = "CrossPK_WinCount" # 当前胜利次数
|
| | | Def_PDict_CrossPK_CWinCount = "CrossPK_CWinCount" # 跨当前连胜次数
|
| | | Def_PDict_CrossPK_TodayPKCount = "CrossPK_TodayPKCount" # 今日已PK次数
|
| | | Def_PDict_CrossPK_TodayBuyCount = "CrossPK_TodayBuyCount" # 今日已购买PK次数
|
| | |
|
| | | #自动战斗设置记录
|
| | | Def_PDict_AutoFightSetting = "AFSetting_%s_%s"
|
| | |
|
| | |
| | | tttFBAddTime, # 可挑战下一关倒计时 6
|
| | | tttDeadTime, # 死亡倒计时(古神禁地) 7
|
| | | tttPickupItem, # 拾取物品倒计时 8
|
| | | tttWaitPlayer, # 等待对手倒计时 9
|
| | | tttPlayerLeave, # 对手掉线倒计时 10
|
| | | tttMax,
|
| | | ) = range(10)
|
| | | ) = range(12)
|
| | |
|
| | | Def_FBPickupItemTime = 30000
|
| | |
|
| | |
| | | def PlayerLoginInFBCheck(curPlayer, tick):
|
| | | gameMap = GameWorld.GetMap()
|
| | | #如果此地图是自动释放的, 需要检查这个玩家
|
| | | if gameMap.GetMapFBType() == 0:
|
| | | if gameMap.GetMapFBType() in [IPY_GameWorld.fbtNull, IPY_GameWorld.fbtCrossVSRoom]:
|
| | | return False
|
| | |
|
| | | #玩家 在副本中,并且副本不踢出玩家下线
|
| | |
| | | #---------------------------------------------------------------------
|
| | | def SyncDynamicBarrierState(barrierPointList, state, curPlayer=None):
|
| | | '''同步动态障碍物是否有效性
|
| | | @param barrierPointList: 障碍物点列表 [[aPosX,aPosY,bPosX,bPosY], [aPosX,aPosY,bPosX,bPosY], ...]
|
| | | @param barrierPointList: 障碍物点列表 [[aPosX,aPosY,bPosX,bPosY,angle可选], [aPosX,aPosY,bPosX,bPosY,angle可选], ...]
|
| | | @param state: 是否有效
|
| | | @param curPlayer: 指定通知目标玩家,为None时广播本地图所有玩家
|
| | | '''
|
| | |
| | | barrierStatePack.Clear()
|
| | | barrierStatePack.State = state
|
| | | barrierStatePack.BarrierList = []
|
| | | for aPosX, aPosY, bPosX, bPosY in barrierPointList:
|
| | | for posInfo in barrierPointList:
|
| | | aPosX, aPosY, bPosX, bPosY = posInfo[:4]
|
| | | angle = posInfo[4] if len(posInfo) > 4 else 0
|
| | | barrier = ChPyNetSendPack.tagMCDynamicBarrier()
|
| | | barrier.APosX = aPosX
|
| | | barrier.APosY = aPosY
|
| | | barrier.BPosX = bPosX
|
| | | barrier.BPosY = bPosY
|
| | | barrier.Angle = angle
|
| | | barrierStatePack.BarrierList.append(barrier)
|
| | | barrierStatePack.Count = len(barrierStatePack.BarrierList)
|
| | | if curPlayer:
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GameWorldLogic.FBProcess.GameLogic_CrossRealmPK
|
| | | #
|
| | | # @todo:跨服匹配PK
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服匹配PK
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ChPlayer
|
| | | import GameWorld
|
| | | import IPY_GameWorld
|
| | | import PlayerControl
|
| | | import GameWorldProcess
|
| | | import IpyGameDataPY
|
| | | import SkillCommon
|
| | | import FBCommon
|
| | | import ChConfig
|
| | |
|
| | |
|
| | | (
|
| | | Def_Time_MaxWait, # 最长等待时间, 秒
|
| | | Def_Time_MapPrepare, # 准备时间, 秒
|
| | | Def_Time_Fight, # 战斗时间, 秒
|
| | | Def_Time_Protect, # 保护时间,秒,玩家战斗中掉线保护时长
|
| | | Def_Time_Leave, # 结束退出时间, 秒
|
| | | ) = range(5)
|
| | |
|
| | | # 当前副本地图的状态
|
| | | (
|
| | | FB_State_Open,
|
| | | FB_State_Waiting, # 等待对手阶段
|
| | | FB_State_MapPrepare, # 地图准备
|
| | | FB_State_Fight, # 战斗阶段
|
| | | FB_State_Reborn, # 复活阶段
|
| | | FB_State_Leave, # 离开阶段
|
| | | FB_State_Close, # 关闭阶段
|
| | | ) = range(7)
|
| | |
|
| | | # 对战结束类型定义
|
| | | (
|
| | | Def_OverType_LackPlayer, # 缺少对手
|
| | | Def_OverType_PlayerExit, # 对手退出(视为认输)
|
| | | Def_OverType_Kill, # 击杀对手
|
| | | Def_OverType_TimeOut, # PK时间超时
|
| | | ) = range(4)
|
| | |
|
| | | # 副本相关字典key
|
| | | GameFBDict_FBPlayerID = "FBD_FBPlayerID_%s" # 玩家ID, 参数, 进入顺序
|
| | | GameFBDict_PlayerWinCnt = "FBD_PlayerWinCnt_%s" # 玩家已获胜次数, 参数[playerID]
|
| | | GameFBDict_PlayerLeaveTick = "FBD_PlayerLeaveTick_%s" # 玩家已获胜次数, 参数[playerID]
|
| | |
|
| | | FBPDict_PVPDamage = "FBPD_PVPDamage" # 玩家伤害输出
|
| | | FBPDict_PVPDamUpdTick = "FBPD_PVPDamUpdTick" # 更新伤害tick
|
| | | FBPDict_ResetPosX = "FBPD_ResetPosX" # 玩家重置坐标X
|
| | | FBPDict_ResetPosY = "FBPD_ResetPosY" # 玩家重置坐标Y
|
| | | FBPDict_RoundNum = "FBPD_RoundNum" # 玩家当前所属回合数
|
| | |
|
| | | FB_RoundNum = "FB_RoundNum" # 副本当前回合数
|
| | | FB_RoundWinPlayerID = "FB_RoundWinPlayerID_%s" # 回合获胜玩家ID, 参数[回合数]
|
| | |
|
| | | ## 是否能够通过活动查询进入
|
| | | def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
|
| | | return True
|
| | |
|
| | | #def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
|
| | | # posDict = {117401:(40,37), 117403:(10, 7)}
|
| | | # return posDict.get(curPlayer.GetPlayerID())
|
| | |
|
| | | ## 玩家进入副本
|
| | | def DoEnterFB(curPlayer, tick):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | playerVSRoomID = curPlayer.GetVsRoomId()
|
| | | roomID = GameWorld.GetGameWorld().GetPropertyID() |
| | | gameFB = GameWorld.GetGameFB()
|
| | | fbStep = gameFB.GetFBStep()
|
| | | GameWorld.Log("DoEnterFB fbRoomID=%s,playerVSRoomID=%s,fbStep=%s" % (roomID, playerVSRoomID, fbStep), playerID)
|
| | | |
| | | gameFB.SetGameFBDict(GameFBDict_PlayerLeaveTick % playerID, 0)
|
| | |
|
| | | fbRoundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)
|
| | | playerRoundNum = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_RoundNum)
|
| | | if playerRoundNum and fbRoundNum and playerRoundNum != fbRoundNum:
|
| | | # 一般是掉线时上个回合已经结束了
|
| | | GameWorld.DebugLog("玩家进入副本时与当前副本回合数不一致时,重置状态!fbRoundNum=%s,playerRoundNum=%s" |
| | | % (fbRoundNum, playerRoundNum), playerID)
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, fbRoundNum)
|
| | | __ResetPlayerState(gameFB, curPlayer, playerID)
|
| | | |
| | | if fbStep >= FB_State_Leave or not roomID or not playerVSRoomID or roomID != playerVSRoomID:
|
| | | PlayerControl.PlayerLeaveFB(curPlayer)
|
| | | return
|
| | | |
| | | # 非战斗阶段,通知动态障碍点
|
| | | if fbStep < FB_State_Fight:
|
| | | FBCommon.SyncDynamicBarrierState(IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 2), 1, curPlayer) # 准备期间有动态障碍点
|
| | | |
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | |
| | | if fbStep == FB_State_Open:
|
| | | gameFB.SetGameFBDict(GameFBDict_FBPlayerID % 1, playerID)
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosX, curPlayer.GetPosX())
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosY, curPlayer.GetPosY())
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, 1)
|
| | | FBCommon.SetFBStep(FB_State_Waiting, tick)
|
| | | GameWorld.Log(" 第一个进入,设置副本进入等待对手阶段!roomID=%s" % (roomID), playerID)
|
| | | __ResetPlayerState(gameFB, curPlayer, playerID, False)
|
| | | curPlayer.Sync_TimeTick(ChConfig.tttWaitPlayer, 0, fbTimeList[Def_Time_MaxWait] * 1000, True)
|
| | | sendMsg = str([roomID])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossPKRoomOpen", sendMsg, len(sendMsg))
|
| | | |
| | | elif fbStep == FB_State_Waiting:
|
| | | playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)
|
| | | playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)
|
| | | if not playerIDB and playerIDA != playerID:
|
| | | gameFB.SetGameFBDict(GameFBDict_FBPlayerID % 2, playerID)
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosX, curPlayer.GetPosX())
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosY, curPlayer.GetPosY())
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, 1)
|
| | | GameWorld.Log(" 第二个进入的玩家!roomID=%s" % (roomID), playerID)
|
| | | __ResetPlayerState(gameFB, curPlayer, playerID, False)
|
| | | |
| | | if GameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 2:
|
| | | GameWorld.Log(" 两个人都在,设置副本进入战斗倒计时阶段!roomID=%s" % (roomID), playerID)
|
| | | FBCommon.SetFBStep(FB_State_MapPrepare, tick)
|
| | | FBCommon.Sync_Player_TimeTick(ChConfig.tttWaitStart, fbTimeList[Def_Time_MapPrepare] * 1000)
|
| | | gameFB.SetGameFBDict(FB_RoundNum, 1)
|
| | | else:
|
| | | GameWorld.Log(" 对手不在,继续等待!roomID=%s" % (roomID), playerID)
|
| | | |
| | | elif fbStep == FB_State_MapPrepare:
|
| | | notify_tick = fbTimeList[Def_Time_MapPrepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
|
| | | curPlayer.Sync_TimeTick(ChConfig.tttWaitStart, 0, max(notify_tick, 0), True)
|
| | | |
| | | elif fbStep == FB_State_Fight:
|
| | | notify_tick = fbTimeList[Def_Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
|
| | | curPlayer.Sync_TimeTick(ChConfig.tttTowerTake, 0, max(notify_tick, 0), True)
|
| | | |
| | | FBCommon.Notify_FBHelp(curPlayer, __GetFBHelpInfo())
|
| | | return
|
| | |
|
| | | def __GetFBHelpInfo():
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | roundWinerIDList = []
|
| | | roundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)
|
| | | for roundNum in xrange(1, roundNum + 1):
|
| | | winnerID = gameFB.GetGameFBDictByKey(FB_RoundWinPlayerID % roundNum)
|
| | | if not winnerID:
|
| | | break
|
| | | roundWinerIDList.append(winnerID)
|
| | | |
| | | return {"roundNum":roundNum, "roundWinerIDList":roundWinerIDList}
|
| | |
|
| | |
|
| | | ## 玩家退出副本
|
| | | def DoExitFB(curPlayer, tick):
|
| | | # 结算时间
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | fbStep = gameFB.GetFBStep()
|
| | | |
| | | if fbStep >= FB_State_Leave:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | gameFB.SetGameFBDict(GameFBDict_PlayerLeaveTick % playerID, tick)
|
| | | GameWorld.Log("玩家战斗阶段下线!playerID=%s,waitPlayerID=%s" % (playerID, playerID))
|
| | | return
|
| | |
|
| | | ## 获得副本帮助信息
|
| | | def DoFBHelp(curPlayer, tick):
|
| | | return
|
| | |
|
| | | ## 副本总逻辑计时器
|
| | | def OnProcess(tick):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | fbStep = gameFB.GetFBStep()
|
| | | |
| | | if fbStep == FB_State_Waiting:
|
| | | __DoLogic_Waiting(tick)
|
| | | elif fbStep == FB_State_MapPrepare:
|
| | | if not __CheckLeaveProtectTimeout(tick):
|
| | | __DoLogic_MapPrepare(tick)
|
| | | elif fbStep == FB_State_Fight:
|
| | | if not __CheckLeaveProtectTimeout(tick):
|
| | | __DoLogic_MapFight(tick)
|
| | | elif fbStep == FB_State_Reborn:
|
| | | __DoLogic_Reborn(tick)
|
| | | elif fbStep == FB_State_Leave:
|
| | | __DoLogic_LeaveTime(tick)
|
| | | |
| | | return
|
| | |
|
| | | ##等待玩家进入阶段处理
|
| | | def __DoLogic_Waiting(tick):
|
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_MaxWait] * 1000:
|
| | | return
|
| | | |
| | | winner, winnerID, loser, loserID = __GetTimeoutWinerInfo(tick)
|
| | | # 对手没来,直接获胜
|
| | | roomID = GameWorld.GetGameWorld().GetPropertyID()
|
| | | GameWorld.Log("战前等待对手阶段超时,直接结束!roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID))
|
| | | __DoFBPKAllOver(winner, winnerID, loser, loserID, Def_OverType_LackPlayer, tick)
|
| | | return
|
| | |
|
| | | def __CheckLeaveProtectTimeout(tick):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)
|
| | | playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)
|
| | | playerLeaveTickA = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDA)
|
| | | playerLeaveTickB = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDB)
|
| | | if not playerLeaveTickA and not playerLeaveTickB:
|
| | | return
|
| | | |
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | if playerLeaveTickA > playerLeaveTickB:
|
| | | if tick - playerLeaveTickA < fbTimeList[Def_Time_Protect] * 1000:
|
| | | return
|
| | | else:
|
| | | if tick - playerLeaveTickB < fbTimeList[Def_Time_Protect] * 1000:
|
| | | return
|
| | | |
| | | winner, winnerID, loser, loserID = __GetTimeoutWinerInfo(tick)
|
| | | # 对手没来,直接获胜
|
| | | roomID = GameWorld.GetGameWorld().GetPropertyID()
|
| | | GameWorld.Log("战斗中对手离线超时,直接结束!roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID))
|
| | | __DoFBPKAllOver(winner, winnerID, loser, loserID, Def_OverType_PlayerExit, tick)
|
| | | return True
|
| | |
|
| | | def __GetTimeoutWinerInfo(tick):
|
| | | ''' 时间超时,获取获胜的玩家
|
| | | 战斗阶段有两个玩家时优先比较输出
|
| | | 其他情况则在线玩家获胜,如果没有玩家在线,则最迟离线的获胜
|
| | | '''
|
| | | winner, winnerID, loser, loserID = None, 0, None, 0
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | fbStep = gameFB.GetFBStep()
|
| | | copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)
|
| | | playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)
|
| | | |
| | | # 战斗阶段有两个玩家时优先比较输出
|
| | | if fbStep == FB_State_Fight and copyMapPlayerManager.GetPlayerCount() == 2:
|
| | | # 时间到还没分出胜负, 根据以下规则决定胜负,这里用玩家ID处理,防止结算时都掉线了导致没有结果
|
| | | # 伤害输出 > 优先到达时间 > 剩余HP > 最大HP > playerID
|
| | | |
| | | playerInfoList = []
|
| | | for playerID in [playerIDA, playerIDB]:
|
| | | player = copyMapPlayerManager.FindPlayerByID(playerID)
|
| | | pvpDamage = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamage)
|
| | | pvpDamTick = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamUpdTick)
|
| | | sortTick = tick - pvpDamTick
|
| | | curHP = 0 if not player else player.GetHP()
|
| | | curMaxHP = 0 if not player else player.GetMaxHP()
|
| | | playerInfoList.append([pvpDamage, sortTick, curHP, curMaxHP, playerID, player])
|
| | | GameWorld.Log("PK超时: pvpDamge=%s,pvpDamTick=%s,tick=%s,sortTick=%s,HP=%s/%s" |
| | | % (pvpDamage, pvpDamTick, tick, sortTick, curHP, curMaxHP), playerID)
|
| | | |
| | | playerInfoList.sort(reverse=True)
|
| | | GameWorld.Log("PK超时, 进入结算!playerInfoList=%s" % str(playerInfoList))
|
| | | winner = playerInfoList[0][-1] if len(playerInfoList) > 0 else None
|
| | | loser = playerInfoList[1][-1] if len(playerInfoList) > 1 else None
|
| | | winnerID = 0 if not winner else winner.GetPlayerID()
|
| | | loserID = 0 if not loser else loser.GetPlayerID()
|
| | | return winner, winnerID, loser, loserID
|
| | | |
| | | # 其他情况则在线玩家获胜,如果没有玩家在线,则最迟离线的获胜
|
| | | for i in xrange(copyMapPlayerManager.GetPlayerCount()):
|
| | | player = copyMapPlayerManager.GetPlayerByIndex(i)
|
| | | if player == None or player.IsEmpty():
|
| | | continue
|
| | | winner = player
|
| | | winnerID = player.GetPlayerID()
|
| | | break
|
| | | |
| | | if not winner:
|
| | | playerLeaveTickA = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDA)
|
| | | playerLeaveTickB = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDB)
|
| | | # 离线tick较大的就是比较晚离线的
|
| | | if playerLeaveTickA > playerLeaveTickB:
|
| | | winnerID = playerIDA
|
| | | loserID = playerIDB
|
| | | else:
|
| | | winnerID = playerIDB
|
| | | loserID = playerIDA
|
| | | else:
|
| | | loserID = playerIDB if playerIDA == winnerID else playerIDA
|
| | | return winner, winnerID, loser, loserID
|
| | |
|
| | | ##副本准备时间
|
| | | def __DoLogic_MapPrepare(tick):
|
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | GameWorld.DebugLog("__DoLogic_MapPrepare ... %s" % fbTimeList[Def_Time_MapPrepare])
|
| | | if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_MapPrepare] * 1000:
|
| | | return
|
| | | |
| | | FBCommon.SetFBStep(FB_State_Fight, tick)
|
| | | FBCommon.Sync_Player_TimeTick(ChConfig.tttTowerTake, fbTimeList[Def_Time_Fight] * 1000)
|
| | | FBCommon.SyncDynamicBarrierState(IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 2), 0)
|
| | | |
| | | # 通知回合开始
|
| | | helpDict = __GetFBHelpInfo()
|
| | | helpDict["isStart"] = 1
|
| | | copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for i in xrange(copyMapPlayerManager.GetPlayerCount()):
|
| | | player = copyMapPlayerManager.GetPlayerByIndex(i)
|
| | | if player == None or player.IsEmpty():
|
| | | continue
|
| | | FBCommon.Notify_FBHelp(player, helpDict)
|
| | | |
| | | return
|
| | |
|
| | | ##战斗阶段
|
| | | def __DoLogic_MapFight(tick):
|
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_Fight] * 1000:
|
| | | return
|
| | | |
| | | winner, winnerID, loser, loserID = __GetTimeoutWinerInfo(tick)
|
| | | roomID = GameWorld.GetGameWorld().GetPropertyID()
|
| | | GameWorld.Log("PK超时, 进入结算! roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID))
|
| | | __DoLogicAddPlayerWinCnt(winner, winnerID, loser, loserID, Def_OverType_TimeOut, tick)
|
| | | return
|
| | |
|
| | | ##复活阶段阶段
|
| | | def __DoLogic_Reborn(tick):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | |
| | | helpDict = __GetFBHelpInfo()
|
| | | |
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | prepareTime = fbTimeList[Def_Time_MapPrepare] * 1000
|
| | | helpDict["prepareTime"] = prepareTime
|
| | | |
| | | nextRoundNum = gameFB.GetGameFBDictByKey(FB_RoundNum) + 1
|
| | | gameFB.SetGameFBDict(FB_RoundNum, nextRoundNum)
|
| | | |
| | | isWinnerResetState = False
|
| | | copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for i in xrange(copyMapPlayerManager.GetPlayerCount()):
|
| | | player = copyMapPlayerManager.GetPlayerByIndex(i)
|
| | | if player == None or player.IsEmpty():
|
| | | continue
|
| | | |
| | | playerID = player.GetPlayerID()
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, nextRoundNum)
|
| | | |
| | | if player.GetPlayerAction() == IPY_GameWorld.paDie or player.GetHP() <= 0:
|
| | | GameWorld.DebugLog("复活玩家...", player.GetPlayerID())
|
| | | ChPlayer.PlayerRebornByType(player, ChConfig.rebornType_System, tick)
|
| | | __ResetPlayerState(gameFB, player, playerID)
|
| | | else:
|
| | | if isWinnerResetState:
|
| | | __ResetPlayerState(gameFB, player, playerID)
|
| | | |
| | | FBCommon.Notify_FBHelp(player, helpDict)
|
| | | |
| | | GameWorld.Log("开始下一回合: nextRoundNum=%s" % (nextRoundNum))
|
| | | |
| | | # 重置伤害输出
|
| | | playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)
|
| | | playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)
|
| | | gameFB.SetPlayerGameFBDict(playerIDA, FBPDict_PVPDamage, 0)
|
| | | gameFB.SetPlayerGameFBDict(playerIDA, FBPDict_PVPDamUpdTick, tick)
|
| | | gameFB.SetPlayerGameFBDict(playerIDB, FBPDict_PVPDamage, 0)
|
| | | gameFB.SetPlayerGameFBDict(playerIDB, FBPDict_PVPDamUpdTick, tick)
|
| | | |
| | | # 进入准备倒计时,开始下一局准备
|
| | | FBCommon.SetFBStep(FB_State_MapPrepare, tick)
|
| | | #FBCommon.Sync_Player_TimeTick(ChConfig.tttWaitStart, prepareTime)
|
| | | return
|
| | |
|
| | | ##比赛结束的空闲时间
|
| | | def __DoLogic_LeaveTime(tick):
|
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_Leave] * 1000:
|
| | | return
|
| | | FBCommon.SetFBStep(FB_State_Close, tick)
|
| | | GameWorldProcess.CloseFB(tick)
|
| | | return
|
| | |
|
| | | ## PVP伤害相关
|
| | | def OnPVPDamage(curPlayer, damageValue, tagPlayer, tick):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | tagPlayerID = tagPlayer.GetPlayerID()
|
| | | |
| | | gameFB = GameWorld.GetGameFB()
|
| | | curPlayerDamage = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamage)
|
| | | updDamage = min(ChConfig.Def_UpperLimit_DWord, curPlayerDamage + damageValue)
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_PVPDamage, updDamage)
|
| | | gameFB.SetPlayerGameFBDict(playerID, FBPDict_PVPDamUpdTick, tick)
|
| | | GameWorld.DebugLog("OnPVPDamage playerID=%s,tagPlayerID=%s,damageValue=%s,updDamage=%s,tick=%s" |
| | | % (playerID, tagPlayerID, damageValue, updDamage, tick))
|
| | | |
| | | #helpDict = {"PVPDamage":[playerID, updDamage, tick]}
|
| | | #FBCommon.Notify_FBHelp(curPlayer, helpDict)
|
| | | #FBCommon.Notify_FBHelp(tagPlayer, helpDict)
|
| | | return
|
| | |
|
| | | ##处理副本中杀死玩家逻辑
|
| | | def DoFBOnKill_Player(curPlayer, defender, tick):
|
| | | winnerID = curPlayer.GetPlayerID()
|
| | | loserID = defender.GetPlayerID()
|
| | | roomID = GameWorld.GetGameWorld().GetPropertyID()
|
| | | |
| | | GameWorld.Log("DoFBOnKill_Player roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID), winnerID)
|
| | | if GameWorld.GetGameFB().GetFBStep() != FB_State_Fight:
|
| | | return
|
| | | |
| | | __DoLogicAddPlayerWinCnt(curPlayer, winnerID, defender, loserID, Def_OverType_Kill, tick)
|
| | | return True
|
| | |
|
| | | def __DoLogicAddPlayerWinCnt(winner, winnerID, loser, loserID, overType, tick):
|
| | | |
| | | gameFB = GameWorld.GetGameFB()
|
| | | roomID = GameWorld.GetGameWorld().GetPropertyID()
|
| | | |
| | | winnerWinCnt = gameFB.GetGameFBDictByKey(GameFBDict_PlayerWinCnt % winnerID)
|
| | | updWinCnt = winnerWinCnt + 1
|
| | | gameFB.SetGameFBDict(GameFBDict_PlayerWinCnt % winnerID, updWinCnt)
|
| | | |
| | | roundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)
|
| | | gameFB.SetGameFBDict(FB_RoundWinPlayerID % roundNum, winnerID)
|
| | | |
| | | GameWorld.Log("回合结束: roomID=%s,roundNum=%s,winnerID=%s,loserID=%s,updWinCnt=%s" % (roomID, roundNum, winnerID, loserID, updWinCnt))
|
| | | isOver = (updWinCnt >= IpyGameDataPY.GetFuncCfg("CrossRealmPKFB", 3))
|
| | | if not isOver:
|
| | | FBCommon.SetFBStep(FB_State_Reborn, tick)
|
| | | return
|
| | | |
| | | GameWorld.Log(" 已达到最大胜场,获得最终胜利!winnerID=%s" % winnerID)
|
| | | __DoFBPKAllOver(winner, winnerID, loser, loserID, overType, tick)
|
| | | return
|
| | |
|
| | | def __ResetPlayerState(gameFB, player, playerID, resetPos=True):
|
| | | if resetPos:
|
| | | posX = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_ResetPosX)
|
| | | posY = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_ResetPosY)
|
| | | player.ResetPos(posX, posY)
|
| | | |
| | | if player.GetHP() != player.GetMaxHP():
|
| | | player.SetHP(player.GetMaxHP())
|
| | | |
| | | if PlayerControl.GetProDef(player) != PlayerControl.GetMaxProDef(player):
|
| | | PlayerControl.SetProDef(player, PlayerControl.GetMaxProDef(player))
|
| | | |
| | | SkillCommon.ResetAllSkillCD(player)
|
| | | return
|
| | |
|
| | | ## 跨服PK结束处理
|
| | | def __DoFBPKAllOver(winner, winnerID, loser, loserID, overType, tick):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | |
| | | roundWinerIDList = []
|
| | | roundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)
|
| | | for roundNum in xrange(1, roundNum + 1):
|
| | | roundWinerIDList.append(gameFB.GetGameFBDictByKey(FB_RoundWinPlayerID % roundNum))
|
| | | |
| | | #副本状态进入关闭倒计时
|
| | | fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)
|
| | | FBCommon.Sync_Player_TimeTick(ChConfig.tttLeaveMap, fbTimeList[Def_Time_Leave] * 1000)
|
| | | FBCommon.SetFBStep(FB_State_Leave, tick)
|
| | | |
| | | #发送一条消息到GameServer通知PK对战结束,因为地图可能对手没来导致没有失败玩家ID,所以结算统一在GameServer处理
|
| | | overType = 1 if overType in [Def_OverType_LackPlayer, Def_OverType_PlayerExit] else 0
|
| | | roomID = GameWorld.GetGameWorld().GetPropertyID()
|
| | | sendMsg = str([roomID, winnerID, loserID, roundWinerIDList, overType])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossPKOver", sendMsg, len(sendMsg))
|
| | | GameWorld.Log("PK结算SendToGameServer: roomID=%s,winnerID=%s,loserID=%s,roundWinerIDList=%s,overType=%s" |
| | | % (roomID, winnerID, loserID, roundWinerIDList, overType))
|
| | | return
|
| | |
|
| | | #关系有3层,无-友好-敌人
|
| | | def CheckPlayersRelation_IsFriend(curPlayer, curTagPlayer):
|
| | | return not CanAttackPlayer(curPlayer, curTagPlayer)
|
| | |
|
| | | ##副本中,攻击队友逻辑
|
| | | def DoCanAttackTeamer(curPlayer, curTagPlayer):
|
| | | return CanAttackPlayer(curPlayer, curTagPlayer)
|
| | |
|
| | | ##副本中,是否可攻击
|
| | | def CanAttackPlayer(curPlayer, curTagPlayer):
|
| | | fbStep = GameWorld.GetGameFB().GetFBStep()
|
| | | |
| | | if fbStep != FB_State_Fight:
|
| | | GameWorld.DebugLog("非战斗阶段,不可攻击!")
|
| | | return False
|
| | | |
| | | return True
|
| | |
|
| | |
| | | # Log("ReadPyPackTable: moudle: %s"%dir(moudle))
|
| | |
|
| | | for index in range(regCnt):
|
| | | if not config.has_option(section, "PacketCMD_%s"%(index + 1)):
|
| | | continue
|
| | | cmd = config.get(section, "PacketCMD_%s"%(index + 1))
|
| | | subCmd = config.get(section, "PacketSubCMD_%s"%(index + 1))
|
| | | callFunc = config.get(section, "PacketCallFunc_%s"%(index + 1))
|
| | | if not cmd or not subCmd or not callFunc:
|
| | | continue
|
| | |
|
| | | cmd = int(cmd, 16)
|
| | | subCmd = int(subCmd, 16)
|
| | |
| | | import PlayerActTotalRecharge
|
| | | import PlayerSpringSale
|
| | | import PlayerFairyCeremony
|
| | | import CrossRealmPlayer
|
| | | import ChNetSendPack
|
| | | import FamilyRobBoss
|
| | | import FBHelpBattle
|
| | |
| | |
|
| | | # 屏蔽跨服下关闭和子服重复的数据的发送 pushsend接口, notifyall正常发送
|
| | | # !!!必要发送的数据要注意位置
|
| | | if GameWorld.IsMergeServer():
|
| | | if GameWorld.IsCrossServer():
|
| | | curPlayer.SetForbiddenSyncClientState(True)
|
| | |
|
| | | SyncGuideState(curPlayer)
|
| | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FuncChangeLineID, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_HighChangeLineID, 0)
|
| | | #GameWorld.DebugLog("离线超过10秒重置切线临时保存的相关记录值!leaveServerSecond=%s" % leaveServerSecond, curPlayer.GetPlayerID())
|
| | | |
| | | # 离线过久恢复为非跨服状态
|
| | | if PlayerControl.GetCrossRealmState(curPlayer):
|
| | | PlayerControl.SetCrossRealmState(curPlayer, 0)
|
| | | |
| | | # 合服首登处理
|
| | | __DoMixServerFirstLogin(curPlayer)
|
| | | PlayerBillboard.BillboardOnLogin(curPlayer)
|
| | |
| | |
|
| | | # 屏蔽跨服下关闭和子服重复的数据的发送 pushsend接口, notifyall正常发送
|
| | | # !!!必要发送的数据要注意位置
|
| | | if GameWorld.IsMergeServer():
|
| | | if GameWorld.IsCrossServer():
|
| | | curPlayer.SetForbiddenSyncClientState(False)
|
| | | PlayerControl.SetCrossRealmState(curPlayer, 1) # 因为主服上传数据之前该值为1,所以登录跨服后在跨服服务器要设置为1
|
| | |
|
| | | return
|
| | |
|
| | |
| | |
|
| | | def UpdatePlayerServerGroupID(curPlayer):
|
| | | # 更新自己的服务器组ID, 跨服服务器不处理
|
| | | if GameWorld.IsMergeServer():
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | serverGroupID = GameWorld.GetServerGroupID()
|
| | | if not serverGroupID:
|
| | |
| | | #复活冷却时间(秒)
|
| | | rebornTime = GetRebronTime(curPlayer, playerRebornType)
|
| | | #冷却时间到了
|
| | | if not CanRebornByTimeOver(curPlayer, rebornTime):
|
| | | if playerRebornType != ChConfig.rebornType_System and not CanRebornByTimeOver(curPlayer, rebornTime):
|
| | | PlayerControl.NotifyCode(curPlayer, 'RebornCD')
|
| | | return False
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.CrossRealmPlayer
|
| | | #
|
| | | # @todo:跨服玩家
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服玩家
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | | import GameWorld
|
| | | import ReadChConfig
|
| | | import PlayerControl
|
| | | import IPY_GameWorld
|
| | | import ShareDefine
|
| | | import ChConfig
|
| | | import FBLogic
|
| | |
|
| | | # 获取玩家跨服服务器上的名字
|
| | | def GetCrossPlayerName(curPlayer):
|
| | | # 通过游戏账号中的平台标志获取名称,目前为spid
|
| | | playerName = curPlayer.GetPlayerName()
|
| | | nameFormat = ReadChConfig.GetPyMongoConfig("Merge", "NameFormat", True)
|
| | | if not nameFormat:
|
| | | return playerName
|
| | | |
| | | opName = ReadChConfig.GetPyMongoConfig("Merge", "OpName_%s" % GameWorld.GetPlayerPlatform(curPlayer))
|
| | | |
| | | return (nameFormat%{"opname":opName, "sid":GameWorld.GetPlayerServerID(curPlayer)}).decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName
|
| | |
|
| | | #// C1 04 主动退出跨服 #tagCMExitCrossRealm
|
| | | #
|
| | | #struct tagCMExitCrossRealm
|
| | | #{
|
| | | # tagHead Head;
|
| | | #};
|
| | | def OnExitCrossRealm(index, curPackData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | |
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | FBLogic.DoPlayerLeaveFB(curPlayer, tick)
|
| | | |
| | | PlayerExitCrossServer(curPlayer)
|
| | | return
|
| | |
|
| | | def PlayerExitCrossServer(curPlayer):
|
| | | ## 玩家退出跨服服务器
|
| | | |
| | | # 通知子服玩家退出跨服服务器
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | serverGroupID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ServerGroupID)
|
| | | GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_ExitCrossServer, playerID, [serverGroupID])
|
| | | |
| | | # 设置非跨服状态,踢下线
|
| | | PlayerControl.SetCrossRealmState(curPlayer, 0)
|
| | | curPlayer.Kick(IPY_GameWorld.disMapServerClose)
|
| | | GameWorld.Log("PlayerExitCrossServer...", curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def DoEnterCrossRealm(curPlayer):
|
| | | ## 玩家进入跨服处理,本服的逻辑处理
|
| | | curPlayer.SetVisible(False)
|
| | | return
|
| | |
|
| | | def DoExitCrossRealm(curPlayer):
|
| | | ## 玩家退出跨服处理,本服的逻辑处理
|
| | | GameWorld.Log("DoExitCrossRealm...", curPlayer.GetPlayerID())
|
| | | curPlayer.SetVisible(True)
|
| | | if PlayerControl.GetCrossRealmState(curPlayer):
|
| | | PlayerControl.SetCrossRealmState(curPlayer, 0)
|
| | | |
| | | return
|
| | |
| | | import PlayerCostRebate
|
| | | import PlayerFairyCeremony
|
| | | import FunctionNPCCommon
|
| | | import CrossRealmPlayer
|
| | | import ChNetSendPack
|
| | | import PlayerState
|
| | | import QuestCommon
|
| | |
| | | if not curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RouteServerInitOK):
|
| | | #RouteServer未初始化不允许切换地图, 缓存处理
|
| | | GameServerRefresh.Set_PlayerRouteServerInitOK_OnLeaveFB(curPlayer, 1)
|
| | | return
|
| | | |
| | | GameWorld.Log("PlayerLeaveFB...", curPlayer.GetPlayerID())
|
| | | if GameWorld.IsCrossServer():
|
| | | CrossRealmPlayer.PlayerExitCrossServer(curPlayer)
|
| | | return
|
| | |
|
| | | #中立地图回到上一次非中立常规地图
|
| | |
| | | def SetFBFuncLineID(curPlayer, funcLineID): return curPlayer.SetExAttr3(funcLineID, False, False)
|
| | | def GetFBFuncLineID(curPlayer): return curPlayer.GetExAttr3()
|
| | |
|
| | | ## 跨服状态: 0-非跨服状态,1-跨服状态
|
| | | def GetCrossRealmState(curPlayer): return curPlayer.GetExAttr5()
|
| | | def SetCrossRealmState(curPlayer, value): curPlayer.SetExAttr5(value, False, True)
|
| | |
|
| | | ## 铜钱点, 支持铜钱超20亿
|
| | | def GetSilver(curPlayer): return curPlayer.GetExAttr6() * ChConfig.Def_PerPointValue + curPlayer.GetSilver()
|
| | | def SetSilver(curPlayer, totalSilver):
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.PlayerCrossRealmPK
|
| | | #
|
| | | # @todo:跨服PK竞技场
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服PK竞技场
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import CrossRealmPlayer
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import GameWorld
|
| | | import ChConfig
|
| | |
|
| | | def DoPlayerOnDay(curPlayer):
|
| | | totalScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_OnDayScore, totalScore)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, 0)
|
| | | return
|
| | |
|
| | | def IsCrossRealmPKOpen():
|
| | | ## 跨服PK匹配赛是否开启
|
| | | return 1
|
| | | return GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState) == ChConfig.Def_Action_Open
|
| | |
|
| | | def GetCrossPKZoneID():
|
| | | ## 获取本服跨服PK所属赛区
|
| | | return 1
|
| | |
|
| | | def GetSeasonID():
|
| | | ## 获取当前赛季ID
|
| | | return 1
|
| | |
|
| | | def IsCrossRealmPKSeasonOpen():
|
| | | return True
|
| | |
|
| | | #// C1 01 跨服PK匹配 #tagCMCrossRealmPKMatch
|
| | | #
|
| | | #struct tagCMCrossRealmPKMatch
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE Type; // 0-取消匹配; 1-进行匹配
|
| | | #};
|
| | | def OnCrossRealmPKMatch(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | accID = curPlayer.GetAccID()
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | requestType = clientData.Type
|
| | | |
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | if not IsCrossRealmPKOpen():
|
| | | GameWorld.Log("OnRequestMergePK 跨服活动未开启,不可进行匹配!", playerID)
|
| | | PlayerControl.NotifyCode(curPlayer, "GeRen_hgg_21675")
|
| | | return
|
| | | |
| | | GameWorld.Log("收到跨服PK匹配: type=%s,accID=%s" % (requestType, accID), playerID)
|
| | | |
| | | # 进行匹配
|
| | | if requestType == 1:
|
| | | # pkCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_Cnt)
|
| | | # buyCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_BuyCnt)
|
| | | # unUsedBuyCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_UnUsedBuyCnt)
|
| | | # freeCnt, maxBuyCnt, moneyType, buyCostFormat = ReadChConfig.GetEvalChConfig("MergePK_BuyCost")
|
| | | # |
| | | # # 超出免费次数 且 无可用的已购买次数 则需购买次数
|
| | | # if pkCnt >= freeCnt and unUsedBuyCnt <= 0:
|
| | | # |
| | | # if buyCnt >= maxBuyCnt:
|
| | | # GameWorld.Log(" 已达到最大可购买PK次数,不可再买!:buyCnt=%s,maxBuyCnt=%s,pkCnt=%s,unUsedBuyCnt=%s" |
| | | # % (buyCnt, maxBuyCnt, pkCnt, unUsedBuyCnt), playerID)
|
| | | # return
|
| | | # |
| | | # buyCost = eval(buyCostFormat)
|
| | | # infoDict = {"pkCnt":pkCnt, "freeCnt":freeCnt, "buyCnt":buyCnt, "buyCost":buyCost}
|
| | | # if not PlayerControl.PayMoney(curPlayer, moneyType, buyCost, ChConfig.Def_Cost_BuyMergePKCnt, infoDict):
|
| | | # return
|
| | | # |
| | | # # 增加购买次数 及 未使用的购买次数
|
| | | # __SetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_BuyCnt, buyCnt + 1)
|
| | | # __SetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_UnUsedBuyCnt, unUsedBuyCnt + 1)
|
| | | # Sync_MergePKCnt(curPlayer)
|
| | | # |
| | | # GameWorld.Log(" 购买PK次数消耗: pkCnt=%s,freeCnt=%s,buyCnt=%s,moneyType=%s,buyCost=%s" |
| | | # % (pkCnt, freeCnt, buyCnt, moneyType, buyCost), playerID)
|
| | | |
| | | dataMsg = {
|
| | | "seasonID":GetSeasonID(), # 赛季ID
|
| | | "pkZoneID":GetCrossPKZoneID(), # PK赛区
|
| | | "accID":accID,
|
| | | "playerID":playerID,
|
| | | "playerName":CrossRealmPlayer.GetCrossPlayerName(curPlayer),
|
| | | "playerJob":curPlayer.GetJob(),
|
| | | "playerLV":curPlayer.GetLV(),
|
| | | "maxHP":curPlayer.GetMaxHP(),
|
| | | "fightPower":curPlayer.GetFightPower(),
|
| | | "pkScore":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore), # 当前积分
|
| | | "danLV":1, #curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV), # 当前段位
|
| | | "cWinCount":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_CWinCount), # 连胜次数
|
| | | "ondayScore":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_OnDayScore), # 过天时的积分
|
| | | }
|
| | | GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKMatch, dataMsg)
|
| | | GameWorld.Log(" 发送请求匹配到跨服服务器 dataMsg=%s" % str(dataMsg), playerID)
|
| | | |
| | | # 取消匹配
|
| | | else:
|
| | | sendMsg = "Client Cancel!"
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "CrossRealmPKCancel", sendMsg, len(sendMsg))
|
| | | GameWorld.Log(" 发送取消匹配到GameServer sendMsg=%s" % str(sendMsg), playerID)
|
| | | |
| | | return
|
| | |
|
| | | def CrossServerMsg_PKOverInfo(curPlayer, overInfo):
|
| | | ## 收到跨服服务器的PK结算信息
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo
|
| | | isWinner = winnerID == playerID
|
| | | GameWorld.Log("地图收到跨服PK结算: isWinner=%s,roomID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s,pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s" |
| | | % (isWinner, roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState), playerID)
|
| | | curSeasonID = GetSeasonID()
|
| | | if curSeasonID != seasonID:
|
| | | GameWorld.Log(" 非本赛季的结算信息,不处理!curSeasonID=%s,seasonID=%s" % (curSeasonID, seasonID), playerID)
|
| | | return
|
| | | |
| | | # 赛季是否已结算
|
| | | if not IsCrossRealmPKSeasonOpen():
|
| | | GameWorld.Log(" 赛季已经结算过了,不处理!seasonID=%s" % (seasonID), playerID)
|
| | | return
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TotalScore, pkScore)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLV, danLV)
|
| | | |
| | | pkCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_PKCount) + 1
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_PKCount, pkCount)
|
| | | if isWinner:
|
| | | winCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_WinCount) + 1
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_WinCount, winCount)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_CWinCount, cWinCount)
|
| | | else:
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_CWinCount, 0)
|
| | | |
| | | # 同一天的话增加当日PK次数
|
| | | if GameWorld.CheckTimeIsSameServerDayEx(GameWorld.ChangeTimeStrToNum(timeStr)):
|
| | | todayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount) + 1
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, todayPKCount)
|
| | | |
| | | ## 跨服已经通知过了,证明还在跨服服务器,不做以下的处理
|
| | | if notifyState:
|
| | | return
|
| | | |
| | | overPack = ChPyNetSendPack.tagGCCrossRealmPKOverInfo()
|
| | | overPack.TimeStr = timeStr
|
| | | overPack.OverType = overType
|
| | | overPack.WinnerID = winnerID
|
| | | overPack.RoundWinnerID = roundWinnerIDList
|
| | | overPack.RoundCount = len(overPack.RoundWinnerID)
|
| | | overPack.AddScore = addScore
|
| | | overPack.Score = pkScore
|
| | | overPack.DanLV = danLV
|
| | | overPack.CWinCnt = cWinCount
|
| | | overPack.TagName = tagPlayerName
|
| | | overPack.TagNameLen = len(overPack.TagName)
|
| | | NetPackCommon.SendFakePack(curPlayer, overPack)
|
| | | return
|
| | |
|
| | |
|
| | | #// C1 02 跨服PK购买次数 #tagCMCrossRealmPKBuy
|
| | | #
|
| | | #struct tagCMCrossRealmPKBuy
|
| | | #{
|
| | | # tagHead Head;
|
| | | #};
|
| | | def OnCrossRealmPKBuy(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | | #// C1 03 跨服PK领取奖励 #tagCMCrossRealmPKGetAward
|
| | | #
|
| | | #struct tagCMCrossRealmPKGetAward
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE AwardType; // 奖励类型;1-每日匹配奖励,2-每日胜利奖励,3-段位达标奖励,4-赛季结算奖励
|
| | | # BYTE AwardData; // 奖励类型对应领取值;每日匹配奖励时为匹配次数,每日胜利奖励时为胜利次数,段位达标奖励时为领取的段位
|
| | | #};
|
| | | def OnCrossRealmPKGetAward(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | | def SyncCrossRealmPKPlayerInfo(curPlayer):
|
| | | # DWORD Score; // 当前积分
|
| | | # BYTE DanLV; // 当前段位
|
| | | # WORD PKCount; // PK次数
|
| | | # WORD WinCount; // 胜利次数
|
| | | # WORD CWinCount; // 连胜次数
|
| | | # BYTE DayPKCount; // 当日已PK次数
|
| | | # BYTE DayWinCount; // 当日已胜利次数
|
| | | # BYTE DayBuyCount; // 当日已购买次数
|
| | | pkPlayerInfo = ChPyNetSendPack.tagMCCrossRealmPKPlayerInfo()
|
| | | pkPlayerInfo.Score = 0
|
| | | pkPlayerInfo.DanLV = 0
|
| | | return
|
| | | |
| | | def SyncCrossRealmPKAwardState(curPlayer):
|
| | | # DWORD DayPKCountAwardState; // 每日匹配次数奖励记录,二进制位存储是否已领取,按匹配次数升序排序索引代表奖励位
|
| | | # DWORD DayWinCountAwardState; // 每日胜利次数奖励记录,二进制位存储是否已领取,按胜利次数升序排序索引代表奖励位
|
| | | # DWORD DanLVAwardState; // 段位达标奖励记录,二进制位存储是否已领取,按段位代表奖励位
|
| | | # BYTE SeasonAwardState; // 赛季结算奖励是否已领取
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
| | | import PlayerNewGuyCard
|
| | | import PlayerMergeKing
|
| | | import PlayerMergePK
|
| | | import PlayerCrossRealmPK
|
| | | import PlayerPet
|
| | | import ReloadModule
|
| | | import BossHurtMng
|
| | |
| | | NPCCommon.CollNPCTimeOnDay(curPlayer)
|
| | | #副本助战
|
| | | FBHelpBattle.DoPlayerOnDay(curPlayer)
|
| | | #跨服竞技场
|
| | | PlayerCrossRealmPK.DoPlayerOnDay(curPlayer)
|
| | |
|
| | | PlayerTJG.TJGOnDay(curPlayer, onEventType)
|
| | | # 以下为支持两种重置模式切换配置的
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.RemoteQuery.GY_Query_CrossPKOverInfo
|
| | | #
|
| | | # @todo:跨服PK结果同步
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服PK结果同步
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PlayerCrossRealmPK
|
| | |
|
| | |
|
| | | #------------------------------------------------------------------------------ |
| | | ## 跨服赛报名调用接口
|
| | | # @param query_Type 请求类型
|
| | | # @param query_ID 请求的玩家ID
|
| | | # @param packCMDList 发包命令
|
| | | # @param tick 当前时间
|
| | | # @return "True" or "False" or ""
|
| | | # @remarks 函数详细说明.
|
| | | def DoLogic(query_Type, query_ID, packCMDList, tick): |
| | | return
|
| | |
|
| | |
|
| | | #------------------------------------------------------------------------------ |
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | overInfo = eval(funResult)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.Log("GY_Query_CrossPKOverInfo overInfo=%s" % (overInfo), playerID)
|
| | | PlayerCrossRealmPK.CrossServerMsg_PKOverInfo(curPlayer, overInfo)
|
| | | return
|
| | | |
| | | |
| | | |
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.RemoteQuery.GY_Query_CrossRealmReg
|
| | | #
|
| | | # @todo:跨服活动玩家注册
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服活动玩家注册
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import CrossRealmPlayer
|
| | | import IPY_GameWorld
|
| | | import ChPlayer
|
| | |
|
| | |
|
| | | #------------------------------------------------------------------------------ |
| | | ## 跨服赛报名调用接口
|
| | | # @param query_Type 请求类型
|
| | | # @param query_ID 请求的玩家ID
|
| | | # @param packCMDList 发包命令
|
| | | # @param tick 当前时间
|
| | | # @return "True" or "False" or ""
|
| | | # @remarks 函数详细说明.
|
| | | def DoLogic(query_Type, query_ID, packCMDList, tick): |
| | | return
|
| | |
|
| | |
|
| | | #------------------------------------------------------------------------------ |
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | resultInfo = eval(funResult)
|
| | | actionType = resultInfo[0]
|
| | | mapPosInfo = resultInfo[1:]
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.Log("GY_Query_CrossRealmReg DoResult %s" % funResult, playerID)
|
| | |
|
| | | if GameWorld.IsMergeServer():
|
| | | GameWorld.Log(" 跨服服务器不允许上传报名数据!", playerID)
|
| | | return
|
| | | |
| | | if not mapPosInfo:
|
| | | return
|
| | | |
| | | #跨服前更新自己所属服务器组ID
|
| | | ChPlayer.UpdatePlayerServerGroupID(curPlayer)
|
| | | |
| | | mapID, dataMapID, copyMapID, posX, posY = mapPosInfo
|
| | | #curPlayer.SendMergeRegisterPlayer(mapID, dataMapID, copyMapID, posX, posY)
|
| | | curPlayer.SendMergeRegisterPlayerAfterChange(CrossRealmPlayer.GetCrossPlayerName(curPlayer), mapID, dataMapID, copyMapID, posX, posY)
|
| | | GameWorld.Log(" 发送跨服玩家数据注册: actionType=%s,mapID=%s,dataMapID=%s,copyMapID=%s,posX=%s,posY=%s,GetVsRoomId=%s" |
| | | % (actionType, mapID, dataMapID, copyMapID, posX, posY, curPlayer.GetVsRoomId()), playerID)
|
| | | return
|
| | |
|
| | | ## 跨服赛报名结果(上传数据)
|
| | | # @param index 玩家索引
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | def GameServer_MergeRegisterResult(index, tick):
|
| | | registerResult = IPY_GameWorld.IPY_GMMergeRegisterPlayerResult()
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | result = registerResult.GetResult()
|
| | | if not result:
|
| | | errorMsg = registerResult.GetErrorMsg()
|
| | | GameWorld.Log("CrossRealmReg result Error:%s" % errorMsg, playerID)
|
| | | return
|
| | | |
| | | #newAccount = registerResult.GetAccount()
|
| | | #newName = registerResult.GetPwd()
|
| | | |
| | | msgList = str([]) |
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "CrossRealmReg", msgList, len(msgList)) |
| | | GameWorld.Log("GameServer_MergeRegisterResult msgList=%s" % msgList, playerID)
|
| | | return
|
| | | |
| | | |
| | | |
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.RemoteQuery.GY_Query_SetPlayerAttr
|
| | | #
|
| | | # @todo:设置玩家属性
|
| | | # @author hxp
|
| | | # @date 2018-12-21
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 设置玩家属性
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PlayerControl
|
| | | import CrossRealmPlayer
|
| | |
|
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | if not funResult:
|
| | | return
|
| | | setInfo = eval(funResult)
|
| | | if not isinstance(setInfo, list) or len(setInfo) < 2:
|
| | | return
|
| | | |
| | | attrName, value = setInfo[:2]
|
| | | if hasattr(curPlayer, attrName):
|
| | | # 要在更新值之前处理
|
| | | if attrName == "SetExAttr5":
|
| | | if value:
|
| | | CrossRealmPlayer.DoEnterCrossRealm(curPlayer)
|
| | | elif PlayerControl.GetCrossRealmState(curPlayer):
|
| | | CrossRealmPlayer.DoExitCrossRealm(curPlayer)
|
| | | |
| | | callObj = getattr(curPlayer, attrName)
|
| | | callObj(value)
|
| | | GameWorld.Log("SetPlayerAttr curPlayer.%s, value=%s" % (attrName, value), curPlayer.GetPlayerID())
|
| | | |
| | | elif hasattr(PlayerControl, attrName):
|
| | | callObj = getattr(PlayerControl, attrName)
|
| | | callObj(curPlayer, value)
|
| | | GameWorld.Log("SetPlayerAttr PlayerControl.%s, value=%s" % (attrName, value), curPlayer.GetPlayerID())
|
| | | |
| | | return |
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
| | | PacketCallFunc_1=GameSever_PlayerCountByCountry
|
| | |
|
| | | [PlayerMergeWar]
|
| | | ScriptName = Player\RemoteQuery\GY_Query_MergeWarRegister.py
|
| | | Writer = wdb
|
| | | Releaser = wdb
|
| | | ScriptName = Player\RemoteQuery\GY_Query_CrossRealmReg.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 1
|
| | | PacketCMD_1=0x9
|