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.

456 lines
18 KiB

1 month ago
/*
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<SSRealmRoleBriefReq>();
uint dbServerId = DBServerSelect.GetDBServerID(req.AccountType, req.AccountID.GetString());
AccountServerUtils.GetPacketSender().SendToServerByID<SSRealmRoleBriefReq>(dbServerId, packet, packet.ObjectID, packet.ServerID);
}
private void OnRealmRoleBriefRes(uint remoteAppID, StructPacket packet)
{
ref SSRealmRoleBriefRes res = ref packet.GetMessage<SSRealmRoleBriefRes>();
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<SSUpdateRealmRoleBrief>();
uint dbServerId = DBServerSelect.GetDBServerID(req.AccountType, req.AccountID.GetString());
AccountServerUtils.GetPacketSender().SendToServerByID<SSUpdateRealmRoleBrief>(dbServerId, packet, packet.ObjectID, packet.ServerID);
}
private void OnPayGoogleReq(uint remoteAppID, StructPacket packet)
{
ref var req = ref packet.GetMessage<SSPayGoogleReq>();
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<SSPayGoogleReq>(packet);
}
private void SSSendGift(uint remoteAppID, StructPacket packet)
{
ref var req = ref packet.GetMessage<SSSendGift>();
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);
}
}
}