/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using ProtoCSStruct; using Sog.Gate; namespace Chat { public class RootMessageHandler : BaseReloadableService { private ServerApp m_app; private ChatServerData m_data; public override int GetServiceType() { return ChatServiceType.RootMessageHandler; } //销毁的时候置空 public override void Dispose() { m_app = null; m_data = null; } public RootMessageHandler(ServerApp app, ChatServerData serverData) { m_app = app; m_data = serverData; } public ServerApp GetApp() { return m_app; } public void HandlerMessage(uint remoteAppID, MessageData message) { int iServerType = ServerIDUtils.GetServerType(remoteAppID); if (iServerType == (int)ServerType.ChatGate) { TraceLog.Trace("RootMessageHandler.HandlerMessage recv msg from gate length {0}", message.Header.Length); HandlerGateMessage(remoteAppID, message); return; } else { TraceLog.Trace("RootMessageHandler.HandlerMessage recv msg from server type {0} length {1}", iServerType, message.Header.Length); HandlerOtherServerMessage(remoteAppID, message); return; } } private void HandlerGateMessage(uint remoteAppID, MessageData message) { GateMsgHeader header = new GateMsgHeader(); GateMsgHeaderPacker.UnPack(message.Buffer.Data,ref header); // trans msg to client if (header.OpCode == (int)GateMsgOpCode.Trans) { PlayerOnChat player = ChatServerUtils.GetPlayerTableOp().GetPlayerOnChat(header.SessionID); if (player == null) { TraceLog.Error("RootMessageHandler.HandlerGateMessage can not find PlayerSession on trans msg, sessionid {0}", header.SessionID); return; } HandlerClientGateMessage(remoteAppID, player, message); return; } if (header.OpCode == (int)GateMsgOpCode.ConnectedReq) { GateClientConnectedReq req = GateClientConnectedReq.ParseFrom(message.Buffer.Data, GateMsgHeaderPacker.GetLength()); OnSessionConnected(remoteAppID, header.SessionID, req); return; } if (header.OpCode == (int)GateMsgOpCode.DisconnectedReq) { OnSessionDisconnected(remoteAppID, header.SessionID); return; } if (header.OpCode == (int)GateMsgOpCode.ClientCount) { //通知world(上报gate的连接数量,这个可以 有多个,现在已经支持了) SSGameReportReq gameReportReq = new SSGameReportReq(); gameReportReq.GameSvrid = remoteAppID; gameReportReq.OnlinePlayer = (int)header.SessionID; ChatServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.GameReportReq, ref gameReportReq, 0); return; } } private void OnSessionConnected(uint gateServerID, long sessionID, GateClientConnectedReq req) { PlayerOnChat oldSession = ChatServerUtils.GetPlayerTableOp().GetPlayerOnChat(sessionID); if (oldSession != null) { TraceLog.Error("RootMessageHandler.OnSessionConnected recv gate playersession {0} connected, error! already connected!", sessionID); return; } TraceLog.Trace("RootMessageHandler.OnSessionConnected playersession {0} connected, new PlayerSession", sessionID); PlayerOnChat playerSession = new PlayerOnChat(sessionID, gateServerID); ChatServerUtils.GetPlayerTableOp().AddPlayerSession(sessionID, playerSession); playerSession.IPAddr = req.IPAddress; //回应 GateMsgHeader gateHeader; gateHeader.OpCode = (int)GateMsgOpCode.ConnectedRes; gateHeader.SessionID = sessionID; GateService.NotifyGateServer(m_app,gateServerID, ref gateHeader); } private void OnSessionDisconnected(uint gateServerID, long sessionID) { PlayerOnChat playerSession = ChatServerUtils.GetPlayerTableOp().GetPlayerOnChat(sessionID); if (playerSession == null) { //正常 TraceLog.Debug("RootMessageHandler.OnSessionDisconnected recv gate playersession {0} disconnected, but no this session,skip" , sessionID); return; } TraceLog.Debug("RootMessageHandler.OnSessionDisconnected playersession {0} disconnected, delete PlayerSession" , sessionID); //处理断线逻辑,这里简单处理,直接删除对象 ChatServerUtils.GetPlayerTableOp().RemoveSession(sessionID); } private void HandlerClientGateMessage(uint gateServerID, PlayerOnChat playerSession, MessageData gateMessage) { long sessionID = playerSession.SessionID; int headLength = GateMsgHeaderPacker.GetLength(); MessageData message = new MessageData(); message.Header.Type = gateMessage.Header.Type; message.Header.Length = gateMessage.Header.Length - headLength; if (message.Header.Length < 0) { TraceLog.Trace("RootMessageHandler.HandlerClientGateMessage recv playersession {0} message ,gateMessage length error ", sessionID); return; } message.MallocData(message.Header.Length); //message.Data = new byte[message.Header.Length]; Buffer.BlockCopy(gateMessage.Buffer.Data, headLength, message.Buffer.Data, 0, message.Buffer.Length); try { HandlerClientMessage(playerSession, message); } finally { message.FreeData(); } } private void HandlerClientMessage(PlayerOnChat playerSession, MessageData message) { try { StructPacket packet = null; bool result = false; try { result = ChatServerUtils.GetProtoPacker().UnpackMessage(message, out packet); } catch (Exception ex) { TraceLog.Error("RootMessageHandler.HandlerClientMessage type {0} UnpackMessage error {1}" , message.Header.Type, ex.Message); return; } // StructPacket packet; // bool result = ChatServerUtils.GetProtoPacker().UnpackMessage(message, out packet); if (result) { //预先判断,提高效率 if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail && TraceLog.IsSkipLogMsgID(packet.MsgID) == false) { // log message TraceLog.TraceDetail("RootMessageHandler.HandlerClientMessage recv from playersession {0} from gateServer {1}, message type {2} length {3} : {4}->{5}" , playerSession.SessionID , ServerIDUtils.IDToString(playerSession.GateServerID) , message.Header.Type , message.Header.Length , packet.MessageName() , packet.ToString()); } HandlerClientPacket(playerSession, packet); } } catch (Exception ex) { TraceLog.Error("RootMessageHandler.HandlerClientMessage Received from session:{0} error:{1}", playerSession.SessionID, ex.Message); //TraceLog.Exception(ex); throw; } } private void HandlerOtherServerMessage(uint remoteAppID, MessageData message) { try { StructPacket packet; bool result = ChatServerUtils.GetProtoPacker().UnpackMessage(message, out packet); if (result) { //预先判断,提高效率 if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail && TraceLog.IsSkipLogMsgID(packet.MsgID) == false) { // log message TraceLog.TraceDetail("RootMessageHandler.HandlerOtherServerMessage recv message from server {0}, message type {1} length {2} : {3}->{4}" , ServerIDUtils.IDToString(remoteAppID) , message.Header.Type , message.Header.Length , packet.MessageName() , packet.ToString()); } HandlerServerPacket(remoteAppID, packet); } } catch (Exception ex) { TraceLog.Error("RootMessageHandler.HandlerOtherServerMessage Received from server:{0} error:{1}" , ServerIDUtils.IDToString(remoteAppID), ex.Message); //TraceLog.Exception(ex); throw; } } private void HandlerClientPacket(PlayerOnChat playerSession, StructPacket packet) { switch (packet.MsgID) { case (int)CSGameMsgID.Ping: SysHandler.ProcessPing(playerSession, packet); break; case (int)CSGameMsgID.Chatping: SysHandler.ProcessChatPing(playerSession, packet); break; case (int)CSGameMsgID.QuerySysnoticeReq: SysHandler.OnQuerySysnoticeReq(playerSession, packet); break; case (int)CSGameMsgID.ChatloginReq: ChatSvc.ProcessClientChatLoginReq(playerSession, packet); break; case (int)CSGameMsgID.ChatReq: ChatSvc.ProcessChatReq(playerSession, packet); break; case (int)CSGameMsgID.QueryChatDataReq: ChatSvc.OnQueryChatDataReq(playerSession, packet); break; case (int)CSGameMsgID.ChannelCacheDataReq: ChatSvc.OnChannelCacheDataReq(playerSession, packet); break; default: break; } } private void HandlerServerPacket(uint serverID, StructPacket packet) { switch (packet.MsgID) { case (int)CSGameMsgID.ChatloginReq: ChatSvc.ProcessServerChatLoginReq(serverID, packet); break; case (int)CSGameMsgID.ChatRes: ChatSvc.OnChatRes(serverID, packet); break; case (int)SSGameMsgID.ChatConsumeReq: ChatSvc.OnChatConsumeReq(serverID, packet); break; case (int)CSGameMsgID.GagChatNotify: ChatSvc.OnGagChatNotify(serverID, packet); break; case (int)SSGameMsgID.SysNoticeLamp: //新加,之前没用到这个通知 break; case (int)SSGameMsgID.SysNoticeLampReq: break; case (int)SSGameMsgID.DealgmcmdNotify: GmCmdSvc.OnWorldNotifyDealGmCmd(packet); break; case (int)CSGameMsgID.QueryChatDataRes: ChatSvc.OnQueryChatDataRes(packet); break; case (int)CSGameMsgID.RecvPrivateChatNotify: ChatSvc.OnRecvPrivateChatNotify(packet); break; case (int)SSGameMsgID.PlayerShowinfoUpdate: ChatSvc.OnPlayerShowInfoUpdate(serverID, packet); break; case (int)SSGameMsgID.ChatNoticeReq: ChatSvc.OnUpdateSysNotice(serverID, packet); break; case (int)SSGameMsgID.ChatDelNotice: ChatSvc.OnDelSysNotice(serverID, packet); break; case (int)SSMsgID.RealmBriefRes: RealmlistSvc.OnRealmBriefRes(serverID, packet); break; case (int)SSGameMsgID.NoticeBackgroundsRes: ChatSvc.OnNoticeBackgroundsRes(packet); break; case (int)SSGameMsgID.CheckDirtyStringReq: ChatSvc.OnCheckDirtyStringReq(serverID, packet); break; case (int)SSGameMsgID.GmSetFreezeTimeRes: ChatSvc.OnGmSetFreezeTimeRes(serverID, packet); break; case (int)SSGameMsgID.SaveRoleNotify: ChatSvc.OnSaveRoleNotify(serverID, packet); break; default: break; } } } }