You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

352 lines
13 KiB

1 month ago
/*
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;
}
}
}
}