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
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);
|
||
|
}
|
||
|
}
|
||
|
}
|