/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Collections.Generic; using Sog; using Sog.Gate; using ProtoCSStruct; namespace Version { public class VersionMsgHandler { private ServerApp m_app; private VersionSvc m_versionSvc; private static VersionMsgHandler _instatnce; public VersionMsgHandler(ServerApp app) { m_app = app; m_versionSvc = new VersionSvc(app); _instatnce = this; } public static VersionMsgHandler GetInstance() { return _instatnce; } public VersionSvc GetVersionSvcObj() { return m_versionSvc; } public ServerApp GetApp() { return m_app; } public void Dispose() { m_app = null; m_versionSvc.Dispose(); m_versionSvc = null; } public void HandlerMessage(uint remoteAppID, MessageData message) { int iServerType = ServerIDUtils.GetServerType(remoteAppID); if (iServerType == (int)ServerType.VersionGate) { TraceLog.Trace("VersionMsgHandler.HandlerMessage recv msg from gate length {0}", message.Header.Length); HandlerGateMessage(remoteAppID, message); return; } else { TraceLog.Trace("VersionMsgHandler.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) { HandlerClientGateMessage(remoteAppID, 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; } //int headLength = GateMsgHeaderPacker.GetLength(); } private void OnSessionConnected(uint gateServerID, long sessionID, GateClientConnectedReq req) { TraceLog.Trace("VersionMsgHandler.OnSessionConnected session {0} ip {1} connected, new PlayerSession", sessionID, req.IPAddress); //回应 GateMsgHeader gateHeader; gateHeader.OpCode = (int)GateMsgOpCode.ConnectedRes; gateHeader.SessionID = sessionID; GateService.NotifyGateServer(m_app, gateServerID, ref gateHeader); m_versionSvc.AddClientConnectData(gateServerID, sessionID, req.IPAddress); } private void OnSessionDisconnected(uint gateServerID, long sessionID) { TraceLog.Debug("VersionMsgHandler.OnSessionDisconnected session {0} disconnected, delete PlayerSession" , sessionID); m_versionSvc.RemoveClientConnectData(gateServerID, sessionID); } private void HandlerClientGateMessage(uint gateServerID, MessageData gateMessage) { long sessionID = gateMessage.Header.ObjectID; 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("VersionMsgHandler.HandlerClientGateMessage recv session {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(gateServerID, sessionID, message); } finally { message.FreeData(); } } private void HandlerClientMessage(uint gateServerID, long sessionID, MessageData message) { try { StructPacket packet = null; bool result = false; try { result = VersionServerUtils.GetProtoPacker().UnpackMessage(message, out packet); } catch (Exception ex) { TraceLog.Error("VersionMsgHandler.HandlerClientMessage type {0} UnpackMessage error {1}" , message.Header.Type, ex.Message); return; } //bool result = VersionServerUtils.GetProtoPacker().UnpackMessage(message, out packet); if (result) { //预先判断,提高效率 if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail && TraceLog.IsSkipLogMsgID(packet.MsgID) == false) { // log message TraceLog.TraceDetail("VersionMsgHandler.HandlerClientMessage recv from session {0} from gateServer {1}, message type {2} length {3} : {4}->{5}" , sessionID , ServerIDUtils.IDToString(gateServerID) , message.Header.Type , message.Header.Length , packet.MessageName() , packet.ToString()); } ProcessClientPacket(gateServerID, sessionID, packet); } } catch (Exception ex) { TraceLog.Error("VersionMsgHandler.HandlerClientMessage Received from session:{0} error:{1}", sessionID, ex.Message); //TraceLog.Exception(ex); throw; } } private void HandlerOtherServerMessage(uint remoteAppID, MessageData message) { try { StructPacket packet; bool result = VersionServerUtils.GetProtoPacker().UnpackMessage(message, out packet); if (result) { if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail && TraceLog.IsSkipLogMsgID(packet.MsgID) == false) { // log message TraceLog.TraceDetail("VersionMsgHandler.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()); } ProcessServerPacket(remoteAppID, packet); } } catch (Exception ex) { TraceLog.Error("VersionMsgHandler.HandlerOtherServerMessage Received from server:{0} error:{1}", ServerIDUtils.IDToString(remoteAppID), ex.Message); //TraceLog.Exception(ex); throw; } } private void ProcessClientPacket(uint gateServerID, long sessionID, StructPacket packet) { //来自客户端的消息 switch (packet.MsgID) { case (int)CSMsgID.VersionReq: ProcessVersionReq(gateServerID, sessionID, packet); break; case (int)CSMsgID.QueryLoginsysnoticeReq: SndSysNotice(gateServerID, sessionID, packet); break; } } /// /// 登录界面公告消息回包 /// /// /// /// public void SndSysNotice(uint gateServerID, long sessionID, StructPacket packet) { ref var req = ref packet.GetMessage(); ClientConnectInfo clientInfo = m_versionSvc.GetClientConnData(sessionID); if (clientInfo == null) { TraceLog.Error("VersionMsgHandler.SndSysNotice no clientInfo. session {0}", sessionID); return; } VersionBillUtils.LogLoginNotice(req.DeviceId.ToString(), clientInfo.ip); CSSysLoginNoticeRes res = new CSSysLoginNoticeRes(); string strReqLang = req.Language.GetString().ToLower(); // 什么语言都可以 bool ignoreLang = string.IsNullOrEmpty(strReqLang); int nowSec = (int)VersionServerUtils.GetTimeSecond(); List list = VersionServerUtils.GetVersionServerData().m_NoticeData; foreach (var item in list) { // 不在有效时间内 if ((item.m_startTime > 0 && nowSec < item.m_startTime) || (item.m_endTime > 0 && nowSec > item.m_endTime)) { continue; } string noticeLang = item.language.ToLower(); if (! ignoreLang && noticeLang != strReqLang) { continue; } CSSysLoginNotice Notice = new CSSysLoginNotice(); Notice.Id = item.id; Notice.Title.SetString(item.title); Notice.Content.SetString(item.content); Notice.Sort = item.sort; Notice.StartTime = item.m_startTime; Notice.Pic.SetString(item.pic); Notice.Aotupop = item.aotupop; res.NoticeList.Add(ref Notice); } GateService.SendToGate(0, m_app.GetCluster(), gateServerID, sessionID, (int)CSMsgID.QueryLoginsysnoticeRes, ref res); } private void ProcessVersionReq(uint gateServerID, long sessionID, StructPacket packet) { ref CSVersionCheckReq req = ref packet.GetMessage(); ClientConnectInfo clientInfo = m_versionSvc.GetClientConnData(sessionID); if (clientInfo == null) { TraceLog.Error("VersionMsgHandler.ProcessVersionReq no clientInfo. session {0}", sessionID); return; } VersionCheckReqHandler.ProcessVersionReq(gateServerID, clientInfo, ref req); } private void ProcessServerPacket(uint remoteAppID, StructPacket packet) { //服务端的消息 switch (packet.MsgID) { //接收到OperationServer 公告推送 case (int)SSGameMsgID.ChatNoticeReq: OnServerSetNotice(remoteAppID, packet); break; //OperationServer 删除公告 case (int)SSGameMsgID.ChatDelNotice: OnDelSysNotice(remoteAppID, packet); break; default: TraceLog.Error("VersionMsgHandler.ProcessServerPacket MsgID {0} not handle", packet.MsgID); break; } } /// /// 删除系统公告 /// /// /// public void OnDelSysNotice(uint serverID, StructPacket packet) { var del = packet.GetMessage(); var list = VersionServerUtils.GetVersionServerData().m_NoticeData; for (int i = list.Count - 1; i >= 0; i--) { if (list[i].id == del.Id) { list.RemoveAt(i); break; } } } //添加系统公告 private void OnServerSetNotice(uint remoteAppID, StructPacket packet) { ref SSSysNotice req = ref packet.GetMessage(); SysNoticeServer.AddOneSysNotice(ref req); } public void UpdateClientConnect() { var clientConnData = VersionServerUtils.GetVersionServerData().m_ClientConnectDict; foreach (KeyValuePair pair in clientConnData) { uint gateServerID = pair.Value.uGateServerID; long sessionID = pair.Value.iConnectSessionID; long iConnectTime = pair.Value.iConnectTime; if (AppTime.GetNowSysMs() - iConnectTime >= 10 * 1000) { TraceLog.Debug("VersionMsgHandler.UpdateClientConnect TimeOut Disconnect:{0} ", sessionID); GateService.NotifyGateServerDisconnect(GetApp(), gateServerID, sessionID); m_versionSvc.RemoveClientConnectData(gateServerID, sessionID); break; } } } } }