From 84f8b05044e64036c5abb6b840bf0fd96f8c3bc2 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 21 十二月 2018 18:09:32 +0800
Subject: [PATCH] 5424 【后端】【1.4】跨服竞技场开发(流程调通版,可匹配、PK、结算,其他功能没有)
---
ServerPython/CoreServerGroup/GameServer/Script/NetPackCommon.py | 8
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py | 2
ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py | 5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py | 94 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_SetPlayerAttr.py | 59 +
ServerPython/CoreServerGroup/GameServer/ServerCommScript.ini | 10
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py | 909 ++++++++++++++++++++++
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMergeKing.py | 5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py | 498 ++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py | 15
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 10
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py | 64
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKOverInfo.py | 50 +
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py | 43
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py | 80 +
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py | 6
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py | 4
ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py | 115 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py | 229 +++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py | 7
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py | 143 +++
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py | 22
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py | 10
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini | 40
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/ServerScript.ini | 6
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py | 3
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 18
27 files changed, 2,359 insertions(+), 96 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py
index 943407b..e5c6737 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py
@@ -23,6 +23,7 @@
import PyGameData
import traceback
import GMCommon
+import ShareDefine
import os
#---------------------------------------------------------------------
g_broadCastList = []
@@ -92,7 +93,7 @@
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"))
@@ -245,7 +246,7 @@
return cmdDict
## 收到子服务器发送的GM命令
-def ClientServer_SendGMCMD(cmdMsgList, tick):
+def ClientServerMsg_GMCMD(cmdMsgList, tick):
if len(cmdMsgList) == 0:
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
new file mode 100644
index 0000000..db3b4d1
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -0,0 +1,143 @@
+#!/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
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
new file mode 100644
index 0000000..f498649
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
@@ -0,0 +1,909 @@
+#!/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
+
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMergeKing.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMergeKing.py
index 00f9a11..7a13142 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMergeKing.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMergeKing.py
@@ -14,7 +14,7 @@
# 详细描述: 王者争霸(跨服PK赛周积分排名前32可获得争霸资格)
#
#---------------------------------------------------------------------
-"""Version = 2015-11-19 14:00"""
+#"""Version = 2015-11-19 14:00"""
#---------------------------------------------------------------------
import ReadChConfig
import PlayerControl
@@ -23,6 +23,7 @@
import PlayerCompensation
import PlayerUniversalGameRec
import PlayerMergeRegister
+import CrossRealmPlayer
import GameWorldMergePK
import PlayerDBGSEvent
import MergeBroadcast
@@ -644,7 +645,7 @@
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:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
index 52c8054..4e9df57 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -86,7 +86,6 @@
#import MergeBroadcast
#import GameWorldMixServerCampaign
#import GameWorldMergeKing
-#import GameWorldMergePK
#import PlayerManorWar
import GameWorldBoss
#import GameWorldActionTeHui
@@ -96,7 +95,8 @@
import ReadChConfig
import EventReport
#import ReloadModule
-import MergeChildMsg
+import CrossRealmMsg
+import CrossRealmPK
#import MergePlayer
import PlayerFBHelpBattle
import PlayerFamilyRedPacket
@@ -298,7 +298,7 @@
#跨服广播
#MergeBroadcast.OnBroadcastProccee(tick)
#跨服PK匹配
- #GameWorldMergePK.OnPKMatchProcess(tick)
+ CrossRealmPK.OnPKMatchProcess(tick)
#跨服王者争霸
#GameWorldMergeKing.OnMergeKingProcess(tick)
@@ -1251,15 +1251,13 @@
#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):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/NetPackCommon.py b/ServerPython/CoreServerGroup/GameServer/Script/NetPackCommon.py
index ef9b24e..214aff0 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/NetPackCommon.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/NetPackCommon.py
@@ -29,7 +29,7 @@
import ChPyNetSendPack
import traceback
import ChMapToGamePyPack
-import MergeChildMsg
+import CrossRealmMsg
#-------------------------------------------------------------------------------
#---全局变量---
@@ -95,9 +95,13 @@
# 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)
@@ -302,7 +306,7 @@
#以下添加后续处理函数
#...
#...
- MergeChildMsg.Recv_MergerChildToCenterProcess(packData, tick)
+ CrossRealmMsg.OnCrossServerReceiveMsg(packData, tick)
except Exception:
Log("跨服子服自定义封包消息处理失败")
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
index 18b0890..148aff8 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -41,7 +41,6 @@
import PlayerBourse
import GameWorldActionTeHui
import PlayerXMZZ
-import GameWorldMergePK
import GameWorldShopItem
import MergeChildMsg
import PlayerTruck
@@ -70,6 +69,7 @@
import PyGameData
import GMShell
import IPY_PlayerDefine
+import CrossRealmPK
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -172,6 +172,8 @@
PyGameData.g_todayPlayerLVDict[curPlayer.GetID()] = curPlayer.GetLV()
#副本助战
PlayerFBHelpBattle.OnHelpPlayerLogin(curPlayer)
+ #跨服PK
+ CrossRealmPK.OnPlayerLogin(curPlayer)
GMShell.OnPlayerLogin(curPlayer)
GMT_CTG.OnPlayerLogin(curPlayer)
@@ -515,7 +517,7 @@
def __Func_PlayerDisconnect(curPlayer, tick):
#跨服匹配PK
- #GameWorldMergePK.OnLeaveServer(curPlayer)
+ CrossRealmPK.OnLeaveServer(curPlayer)
#组队玩家离线
PlayerTeam.DoPlayerLogOffTeamLogic(curPlayer, tick)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
new file mode 100644
index 0000000..df2e73b
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
@@ -0,0 +1,115 @@
+#!/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
+
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
index ee31aa5..dbdc17d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
@@ -23,7 +23,6 @@
# @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"""
@@ -32,6 +31,7 @@
import IPY_GameServer
import MergeBroadcast
import IpyGameDataPY
+import CrossRealmMsg
import ShareDefine
import ChConfig
import types
@@ -52,7 +52,22 @@
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
@@ -288,38 +303,25 @@
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
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index e5909fc..2f5eb69 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -74,6 +74,9 @@
import PyGameData
import PlayerTalk
import PlayerStore
+import CrossRealmPlayer
+import CrossRealmMsg
+import CrossRealmPK
import time
import datetime
@@ -426,12 +429,14 @@
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':
@@ -534,26 +539,36 @@
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喇叭聊天
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
index aa54042..7a1d26a 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
@@ -84,4 +84,12 @@
g_fbHelpBattleRecord = {} # 未同步的副本助战记录 {playerID:[FBHelpBattleRecord, ...], ...}
g_autoViceleaderDict = {}#自动安排副盟主的玩家记录{familyID:[]}
-g_forbidAutoViceleaderFamily = [] #禁止自动安排副盟主的仙盟[familyID,..]
\ No newline at end of file
+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], ...}
+
diff --git a/ServerPython/CoreServerGroup/GameServer/ServerCommScript.ini b/ServerPython/CoreServerGroup/GameServer/ServerCommScript.ini
index 9ca368e..dba229f 100644
--- a/ServerPython/CoreServerGroup/GameServer/ServerCommScript.ini
+++ b/ServerPython/CoreServerGroup/GameServer/ServerCommScript.ini
@@ -114,15 +114,15 @@
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]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 8a31ebd..b0859b9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -368,9 +368,9 @@
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
@@ -551,21 +551,37 @@
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]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 4e11f33..0f27dab 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1781,6 +1781,8 @@
Def_FBMapID_Dogz = 21110
#聚魂副本
Def_FBMapID_GatherSoul = 31340
+#跨服竞技场
+Def_FBMapID_CrossRealmPK = 32010
#副本关闭时未拾取的物品邮件发放给玩家
#这里只有需要的副本才配置,不做默认逻辑,防止某些副本实际不能给导致刷物品,如麒麟之府
Def_SendUnPickItemMailMapIDList = [Def_FBMapID_IceLode, Def_FBMapID_PersonalBoss, Def_FBMapID_MunekadoTrial,
@@ -1868,7 +1870,7 @@
'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
@@ -3832,6 +3834,16 @@
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"
@@ -5110,8 +5122,10 @@
tttFBAddTime, # 可挑战下一关倒计时 6
tttDeadTime, # 死亡倒计时(古神禁地) 7
tttPickupItem, # 拾取物品倒计时 8
+tttWaitPlayer, # 等待对手倒计时 9
+tttPlayerLeave, # 对手掉线倒计时 10
tttMax,
-) = range(10)
+) = range(12)
Def_FBPickupItemTime = 30000
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
index 8fc44ee..d226d1e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -1229,7 +1229,7 @@
def PlayerLoginInFBCheck(curPlayer, tick):
gameMap = GameWorld.GetMap()
#如果此地图是自动释放的, 需要检查这个玩家
- if gameMap.GetMapFBType() == 0:
+ if gameMap.GetMapFBType() in [IPY_GameWorld.fbtNull, IPY_GameWorld.fbtCrossVSRoom]:
return False
#玩家 在副本中,并且副本不踢出玩家下线
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
index b99b32d..9b8a408 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
@@ -630,7 +630,7 @@
#---------------------------------------------------------------------
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时广播本地图所有玩家
'''
@@ -638,12 +638,15 @@
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:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py
new file mode 100644
index 0000000..44efd77
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py
@@ -0,0 +1,498 @@
+#!/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
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
index 2eeab27..c85c028 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
@@ -95,9 +95,13 @@
# 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)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index f869d0c..9f9f3ca 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -108,6 +108,7 @@
import PlayerActTotalRecharge
import PlayerSpringSale
import PlayerFairyCeremony
+import CrossRealmPlayer
import ChNetSendPack
import FamilyRobBoss
import FBHelpBattle
@@ -249,7 +250,7 @@
# 屏蔽跨服下关闭和子服重复的数据的发送 pushsend接口, notifyall正常发送
# !!!必要发送的数据要注意位置
- if GameWorld.IsMergeServer():
+ if GameWorld.IsCrossServer():
curPlayer.SetForbiddenSyncClientState(True)
SyncGuideState(curPlayer)
@@ -308,7 +309,10 @@
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)
@@ -578,8 +582,9 @@
# 屏蔽跨服下关闭和子服重复的数据的发送 pushsend接口, notifyall正常发送
# !!!必要发送的数据要注意位置
- if GameWorld.IsMergeServer():
+ if GameWorld.IsCrossServer():
curPlayer.SetForbiddenSyncClientState(False)
+ PlayerControl.SetCrossRealmState(curPlayer, 1) # 因为主服上传数据之前该值为1,所以登录跨服后在跨服服务器要设置为1
return
@@ -835,7 +840,7 @@
def UpdatePlayerServerGroupID(curPlayer):
# 更新自己的服务器组ID, 跨服服务器不处理
- if GameWorld.IsMergeServer():
+ if GameWorld.IsCrossServer():
return
serverGroupID = GameWorld.GetServerGroupID()
if not serverGroupID:
@@ -3828,7 +3833,7 @@
#复活冷却时间(秒)
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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py
new file mode 100644
index 0000000..dc048da
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py
@@ -0,0 +1,80 @@
+#!/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index 327f133..16775d0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -84,6 +84,7 @@
import PlayerCostRebate
import PlayerFairyCeremony
import FunctionNPCCommon
+import CrossRealmPlayer
import ChNetSendPack
import PlayerState
import QuestCommon
@@ -1498,6 +1499,11 @@
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
#中立地图回到上一次非中立常规地图
@@ -5708,6 +5714,10 @@
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):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
new file mode 100644
index 0000000..a354518
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
@@ -0,0 +1,229 @@
+#!/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
+
+
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index f38e738..89b4bae 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -73,6 +73,7 @@
import PlayerNewGuyCard
import PlayerMergeKing
import PlayerMergePK
+import PlayerCrossRealmPK
import PlayerPet
import ReloadModule
import BossHurtMng
@@ -548,6 +549,8 @@
NPCCommon.CollNPCTimeOnDay(curPlayer)
#副本助战
FBHelpBattle.DoPlayerOnDay(curPlayer)
+ #跨服竞技场
+ PlayerCrossRealmPK.DoPlayerOnDay(curPlayer)
PlayerTJG.TJGOnDay(curPlayer, onEventType)
# 以下为支持两种重置模式切换配置的
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKOverInfo.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKOverInfo.py
new file mode 100644
index 0000000..127c5d2
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKOverInfo.py
@@ -0,0 +1,50 @@
+#!/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
+
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py
new file mode 100644
index 0000000..b4d8357
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py
@@ -0,0 +1,94 @@
+#!/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
+
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_SetPlayerAttr.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_SetPlayerAttr.py
new file mode 100644
index 0000000..d579639
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_SetPlayerAttr.py
@@ -0,0 +1,59 @@
+#!/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
+
+
+
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/ServerScript.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/ServerScript.ini
index 4a60daf..14ded03 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/ServerScript.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/ServerScript.ini
@@ -174,9 +174,9 @@
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
--
Gitblit v1.8.0