/* Sog 游戏基础库 2016 by zouwei */ using System; using Sog; using ProtoCSStruct; using Sog.Gate; using System.Linq; namespace Account { public class RootMessageHandler : BaseReloadableService { private ServerApp m_app; private AccountServerData m_data; private AccountMsgHandler m_accountHandler; private CSAccountSvrChgNotify m_accountSvrChgNotify; public override int GetServiceType() { return AccountServiceType.RootMessageHandler; } //销毁的时候置空 public override void Dispose() { m_app = null; m_data = null; } public RootMessageHandler(ServerApp app, AccountServerData serverData, AccountMsgHandler accountHandler) { m_app = app; m_data = serverData; m_accountHandler = accountHandler; m_accountSvrChgNotify = new CSAccountSvrChgNotify(); } public ServerApp GetApp() { return m_app; } public void HandlerMessage(uint remoteAppID, MessageData message) { int iServerType = ServerIDUtils.GetServerType(remoteAppID); if (iServerType == (int)ServerType.AccountGate) { TraceLog.Trace("RootMessageHandler.HandlerMessage recv msg from gate length {0}", message.Header.Length); HandlerGateMessage(remoteAppID, message); } else { TraceLog.Trace("RootMessageHandler.HandlerMessage recv msg from server type {0} length {1}", iServerType, message.Header.Length); HandlerOtherServerMessage(remoteAppID, message); } } 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) { PlayerSession playerSession = AccountServerUtils.GetPlayerTableOp().GetPlayerSession(header.SessionID); if (playerSession == null) { TraceLog.Error("RootMessageHandler.HandlerGateMessage can not find PlayerSession on trans msg, sessionid {0}", header.SessionID); return; } HandlerClientGateMessage(remoteAppID, playerSession, 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) { PlayerSession oldSession = AccountServerUtils.GetPlayerTableOp().GetPlayerSession(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); PlayerSession playerSession = new PlayerSession(sessionID, gateServerID); playerSession.Ip = req.IPAddress; AccountServerUtils.GetPlayerTableOp().AddPlayerSession(sessionID, playerSession); //回应 GateMsgHeader gateHeader; gateHeader.OpCode = (int)GateMsgOpCode.ConnectedRes; gateHeader.SessionID = sessionID; GateService.NotifyGateServer(m_app,gateServerID, ref gateHeader); } private void OnSessionDisconnected(uint gateServerID, long sessionID) { PlayerSession playerSession = AccountServerUtils.GetPlayerTableOp().GetPlayerSession(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); // //处理断线逻辑,这里简单处理,直接删除对象 AccountServerUtils.GetPlayerTableOp().RemoveSession(sessionID); } private void HandlerClientGateMessage(uint gateServerID, PlayerSession 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(PlayerSession playerSession, MessageData message) { try { StructPacket packet = null; bool result = false; try { result = AccountServerUtils.GetProtoPacker().UnpackMessage(message, out packet); } catch (Exception ex) { TraceLog.Error("RootMessageHandler.HandlerClientMessage type {0} UnpackMessage error {1}" , message.Header.Type, ex.Message); return; } if (result) { //预先判断,提高效率 if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail) { if(TraceLog.IsSkipLogMsgID(packet.MsgID)) { // log message TraceLog.TraceDetail("RootMessageHandler.HandlerClientMessage recv from playersession {0} from gateServer {1}, message type {2} length {3} : {4}" , playerSession.SessionID , ServerIDUtils.IDToString(playerSession.GateServerID) , message.Header.Type , message.Header.Length , packet.MessageName()); } else { // 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 = AccountServerUtils.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} name {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(PlayerSession playerSession, StructPacket packet) { switch (packet.MsgID) { case (int)CSMsgID.AccountReq: LoginHandler.ProcessAccountLogin(playerSession, packet); break; case (int)CSMsgID.Ping: SysHandler.ProcessPing(playerSession, packet); break; case (int)CSMsgID.GameListReq: LoginHandler.OnGameListReq(playerSession, packet); break; case (int)CSMsgID.GameareaServeripReq: LoginHandler.OnGameAreaServerIPReq(playerSession, packet); break; default: break; } } private void HandlerServerPacket(uint remoteAppID, StructPacket packet) { switch (packet.MsgID) { case (int)CSMsgID.GameListReq: LoginHandler.OnGameListReq(remoteAppID, packet); break; //httpProxy返回 case (int)SSMsgID.HttpCheckAccountTokenRes: LoginHandler.HttpCheckAccountTokenRes(remoteAppID, packet); break; case (int)SSMsgID.QueryAccountDb: LoginHandler.OnDBAccountAuthRes(remoteAppID, packet); break; // world发来的check req, 校验token后转给DB查询uid case (int)SSMsgID.LoginCheckValidReq: LoginHandler.OnLoginCheckValidReq(remoteAppID, packet); break; // DB返回的check res case (int)SSMsgID.LoginCheckValidRes: LoginHandler.OnLoginCheckValidRes(remoteAppID, packet); break; case (int)CSMsgID.GameListRes: LoginHandler.OnGameListRes(remoteAppID, packet); break; case (int)CSMsgID.GameareaServeripRes: LoginHandler.OnGameAreaServerIPRes(remoteAppID, packet); break; case (int)SSGameMsgID.DealgmcmdNotify: GmCmdSvc.OnWorldNotifyDealGmCmd(packet); break; case (int)SSMsgID.RealmRoleBriefReq: OnRealmRoleBriefReq(remoteAppID, packet); break; case (int)SSMsgID.RealmRoleBriefRes: OnRealmRoleBriefRes(remoteAppID, packet); break; case (int)SSMsgID.UpdateRealmRoleBrief: OnUpdateRealmRoleBrief(remoteAppID, packet); break; case (int)SSGameMsgID.PayGoogleReq: OnPayGoogleReq(remoteAppID, packet); break; case (int)SSMsgID.SendGifts: SSSendGift(remoteAppID, packet); break; default: m_accountHandler.HandlerMessage(remoteAppID, packet); break; } } private void OnRealmRoleBriefReq(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); uint dbServerId = DBServerSelect.GetDBServerID(req.AccountType, req.AccountID.GetString()); AccountServerUtils.GetPacketSender().SendToServerByID(dbServerId, packet, packet.ObjectID, packet.ServerID); } private void OnRealmRoleBriefRes(uint remoteAppID, StructPacket packet) { ref SSRealmRoleBriefRes res = ref packet.GetMessage(); string accountId = res.AccountID.GetString(); var accountInfo = AccountServerUtils.GetAccountTableOp().GetAccountInfo(res.AccountType, accountId); if (accountInfo == null) { TraceLog.Error("RootMessageHandler.OnRealmRoleBriefRes accType {0} accountId {1} no accountInfo" , res.AccountType, accountId); return; } // 更新缓存 accountInfo.roleBriefs.Clear(); for (int i = 0; i < res.RoleList.Count; i++) { accountInfo.roleBriefs.Add(res.RoleList[i]); } TraceLog.Trace("RootMessageHandler.OnRealmRoleBriefRes trigger by GameListReq from gamesvr {0} from account session {1}" , ServerIDUtils.IDToString(res.ClientReq.FromGameSvr), res.ClientReq.FromAccountSession); for (int i = 0; i < res.RoleList.Count; i++) { res.ClientReq.CreateRoleRealms.Add(res.RoleList[i].RealmId); } AccountServerUtils.GetPacketSender().SendToRealmlistServer((int)CSMsgID.GameListReq, ref res.ClientReq, packet.ObjectID); } private void OnUpdateRealmRoleBrief(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); uint dbServerId = DBServerSelect.GetDBServerID(req.AccountType, req.AccountID.GetString()); AccountServerUtils.GetPacketSender().SendToServerByID(dbServerId, packet, packet.ObjectID, packet.ServerID); } private void OnPayGoogleReq(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); AccountInfoOnAccountServer accountInfo = AccountServerUtils.GetAccountTableOp().GetAccountInfo(req.Account.AccountType, req.Account.AccountID.GetString()); if (accountInfo == null) { TraceLog.Error("RootMessageHandler.OnPayGoogleReq get accunt is null! uid:{0} accountType:{1} AccountID:{2}", packet.ObjectID, req.Account.AccountType, req.Account.AccountID.GetString()); return; } req.SessionKey.SetString(accountInfo.session_key); AccountServerUtils.GetPacketSender().SendToHttpProxyPayServer(packet); } private void SSSendGift(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); if(req.Queryed == 1) { //to world if (req.Uid > 0) { var wid = ServerIDUtils.MakeServerID(req.WorldId, (int)ServerType.World, 1); AccountServerUtils.GetPacketSender().SendToServerByID(wid, (int)SSMsgID.SendGifts, ref req, packet.ObjectID); } return; } AccountInfoOnAccountServer accountInfo = AccountServerUtils.GetAccountTableOp().GetAccountInfo(req.AccountType, req.AccountId.GetString()); if (accountInfo == null ) { //db查询 uint iDBServerID = DBServerSelect.GetDBServerID(req.AccountType, req.AccountId.GetString()); AccountServerUtils.GetPacketSender().SendToServerByID(iDBServerID , (int)SSMsgID.SendGifts, ref req, packet.ObjectID); return; } if(accountInfo.roleBriefs.Count == 0) { //db查询 uint iDBServerID = DBServerSelect.GetDBServerID(accountInfo.AccountType, accountInfo.AccountID); AccountServerUtils.GetPacketSender().SendToServerByID(iDBServerID , (int)SSMsgID.SendGifts, ref req, packet.ObjectID); return; } long lastLogin = 0; long lastUid = 0; for(int i = 0; i < accountInfo.roleBriefs.Count; i++) { if (accountInfo.roleBriefs[i].LastLoginTime > lastLogin) { lastLogin = accountInfo.roleBriefs[i].LastLoginTime; lastUid = accountInfo.roleBriefs[i].Uid; } } req.Uid = lastUid; var worldServerID = ServerIDUtils.MakeServerID(req.WorldId,(int)ServerType.World, 1); AccountServerUtils.GetPacketSender().SendToServerByID(worldServerID, (int)SSMsgID.SendGifts, ref req, packet.ObjectID); } } }