| | |
| | | # 跨服服务器间的封包 既是收包也是发包
|
| | |
|
| | | import GameWorld
|
| | | import ChServerToServerPyPack
|
| | | import ShareDefine
|
| | | import NetPackCommon
|
| | | import ChServerToServerPyPack
|
| | | import TurnAttack
|
| | | import PyGameData
|
| | | import ChPlayer
|
| | |
|
| | | import traceback
|
| | | import cPickle
|
| | | import time
|
| | |
|
| | | def OnTest(netPack):
|
| | |
|
| | | GameWorld.Log("收到跨服包 " + str(netPack.Data))
|
| | |
|
| | |
|
| | | def SendTest():
|
| | | def SendTest(dirType, serverList):
|
| | | pack = ChServerToServerPyPack.tagSSTest()
|
| | | pack.Data = 12
|
| | | #0全广播,1通知主服务器排除合服子服,2通知服务器包含合服子服, 3通知跨服服务器
|
| | | NetPackCommon.SendCrossServerToServerPack(1, "[501]", pack.GetBuffer())
|
| | | NetPackCommon.SendCrossServerToServerPack(dirType, serverList, pack.GetBuffer())
|
| | | return
|
| | |
|
| | | def GetCrossServerID():
|
| | | ## 获取本服务器所属的跨服中心服务器
|
| | | return 0
|
| | |
|
| | | def SendToCrossServer(msgType, dataMsg):
|
| | | ## 发送信息到跨服服务器
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | if not dataMsg:
|
| | | return
|
| | | if msgType not in [ShareDefine.ClientServerMsg_ServerInitOK]:
|
| | | isOpen = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen)
|
| | | if not isOpen:
|
| | | GameWorld.Log("跨服服务器未开启或维护中不发送消息! SendMsgToCrossServer => %s" % msgType)
|
| | | return
|
| | | crossServerID = GetCrossServerID()
|
| | | if not crossServerID:
|
| | | return
|
| | | |
| | | playerID = 0
|
| | | if isinstance(dataMsg, dict):
|
| | | playerID = dataMsg.get("playerID", 0)
|
| | | if not playerID:
|
| | | playerID = dataMsg.get("PlayerID", 0)
|
| | | |
| | | GameWorld.Log("SendMsgToCrossServer => %s, %s, %s" % (msgType, crossServerID, dataMsg), playerID)
|
| | | SendToServer(msgType, dataMsg, [crossServerID], ShareDefine.dirType_Cross, playerID, isLog=False)
|
| | | return
|
| | |
|
| | | def SendToClientServer(msgType, dataMsg, serverIDList=None):
|
| | | ''' 发送信息到子服务器
|
| | | @param serverGroupIDList: 发送指定的服务器组ID列表,内部已经针对列表中组ID去重,
|
| | | 所以外部逻辑可直接添加,不用考虑组ID重复问题,没有指定服务器组ID时,默认广播所有子服
|
| | | '''
|
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | if not PyGameData.g_serverInitOK:
|
| | | GameWorld.ErrLog("跨服服务器未启动好,不允许向子服发送数据! %s, %s, %s" % (msgType, serverIDList, dataMsg))
|
| | | return
|
| | | |
| | | playerID = 0
|
| | | if isinstance(dataMsg, dict):
|
| | | playerID = dataMsg.get("playerID", 0)
|
| | | if not playerID:
|
| | | playerID = dataMsg.get("PlayerID", 0)
|
| | | |
| | | GameWorld.Log("SendToClientServer => %s, %s, %s" % (msgType, serverIDList, dataMsg), playerID)
|
| | | SendToServer(msgType, dataMsg, serverIDList, ShareDefine.dirType_Main, playerID, isLog=False) # 默认发给主服即可
|
| | | return
|
| | |
|
| | | def SendToBattleServer(msgType, dataMsg, playerID=0):
|
| | | SendToServer(msgType, dataMsg, dirType=ShareDefine.dirType_Battle, playerID=playerID)
|
| | | return
|
| | |
|
| | | def SendToServer(msgType, dataMsg, serverIDList=None, dirType=ShareDefine.dirType_Main, playerID=0, isLog=True):
|
| | | '''发送给其他服务器
|
| | | @param msgType: 功能信息类型字符定义
|
| | | @param dataMsg: 发送的数据,任意格式,由功能自行决定
|
| | | @param serverIDList: 指定目标服务器ID 或 服务器ID列表
|
| | | '''
|
| | | |
| | | if isinstance(serverIDList, int):
|
| | | serverIDList = [serverIDList]
|
| | | elif not isinstance(serverIDList, list):
|
| | | serverIDList = []
|
| | | else:
|
| | | serverIDList = list(set(serverIDList)) # 去重
|
| | | |
| | | if isLog:
|
| | | GameWorld.Log("SendToServer => %s, %s, %s" % (msgType, serverIDList, dataMsg), playerID)
|
| | | |
| | | # 协议要用最高级2,可减少长度
|
| | | sendMsg = cPickle.dumps(dataMsg, 2)
|
| | | |
| | | pack = ChServerToServerPyPack.tagSSCommMsg()
|
| | | pack.FromServerID = GameWorld.GetGameWorld().GetServerID()
|
| | | pack.ServerTime = int(time.time())
|
| | | pack.MsgType = msgType
|
| | | pack.TypeLen = len(pack.MsgType)
|
| | | pack.Data = sendMsg
|
| | | pack.Len = len(pack.Data)
|
| | | NetPackCommon.SendCrossServerToServerPack(dirType, serverIDList, pack.GetBuffer())
|
| | | return
|
| | |
|
| | | def OnSSCommMsg(netPack):
|
| | | ## 收到其他服务器发来的消息
|
| | | |
| | | fromServerID = netPack.FromServerID
|
| | | fromServerTime = netPack.ServerTime
|
| | | msgType = netPack.MsgType
|
| | | recvMsg = netPack.Data
|
| | | |
| | | if not PyGameData.g_serverInitOK:
|
| | | GameWorld.Log("服务器未启动好,不处理其他服务器信息! %s, fromServerID=%s" % (msgType, fromServerID))
|
| | | return
|
| | | |
| | | try:
|
| | | dataMsg = cPickle.loads(recvMsg)
|
| | | if GameWorld.IsCrossServer():
|
| | | GameWorld.Log("OnCrossServerReceiveMsg: %s, fromServerID=%s, %s" % (msgType, fromServerID, dataMsg))
|
| | | else:
|
| | | GameWorld.Log("OnClientServerReceiveMsg: %s, fromServerID=%s, %s" % (msgType, fromServerID, dataMsg))
|
| | | |
| | | crossServerID = GetCrossServerID()
|
| | | if crossServerID == fromServerID:
|
| | | __fixCrossServerTime(msgType, fromServerTime)
|
| | | |
| | | if msgType == ShareDefine.SSMsg_BattleRequest:
|
| | | TurnAttack.SSMsg_BattleRequest(dataMsg, fromServerID)
|
| | | elif msgType == ShareDefine.SSMsg_BattleResult:
|
| | | TurnAttack.SSMsg_BattleResult(dataMsg, fromServerID)
|
| | | |
| | | except:
|
| | | GameWorld.RaiseException("服务器接收信息处理报错 \r\n%s" % str(traceback.format_exc()))
|
| | | return
|
| | |
|
| | | def __fixCrossServerTime(msgType, crossServerTime):
|
| | | # 子服矫正跨服服务器时间
|
| | | curServerTime = int(time.time())
|
| | | curServerCrossServerTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCrossServerTimeStr())
|
| | | diffSeconds = curServerCrossServerTime - crossServerTime # 本服计算误差
|
| | | |
| | | PyGameData.g_crossServerTimeInfo = [crossServerTime, curServerTime] # 覆盖更新
|
| | | |
| | | # 误差超过30秒 或强制同步时间的
|
| | | if abs(diffSeconds) >= 30 or msgType == ShareDefine.CrossServerMsg_CrossServerTime:
|
| | | GameWorld.DebugLog("同步跨服服务器时间,本服与跨服服务器时间计算误差! diffSeconds=%s" % (diffSeconds))
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | ChPlayer.Sync_PyServerDataTimeToClient(curPlayer)
|
| | | return
|
| | |
|
| | |
|