400 lines
13 KiB
C++
400 lines
13 KiB
C++
#include "StdAfx.h"
|
|
#include ".\handler_sa.h"
|
|
#include <PacketStruct_SA.h>
|
|
#include <PacketStruct_SM.h>
|
|
#include <PacketStruct_AT.h>
|
|
#include <PublicStruct.h>
|
|
#include <Constant.h>
|
|
#include "ServerSession.h"
|
|
#include "UserSession.h"
|
|
#include "ServerSessionManager.h"
|
|
#include "User.h"
|
|
#include "UserManager.h"
|
|
#include "World.h"
|
|
#include "UnitServer.h"
|
|
#include "WorldManager.h"
|
|
#include "AgentInfoParser.h"
|
|
#include "AgentInfo.h"
|
|
#include "AgentServerSession.h"
|
|
|
|
|
|
|
|
Handler_SA::Handler_SA(void)
|
|
{
|
|
}
|
|
|
|
Handler_SA::~Handler_SA(void)
|
|
{
|
|
}
|
|
|
|
// Agent Auth
|
|
VOID Handler_SA::OnHandler_SA_SERVER_AUTH_SYN( ServerSession *pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_AUTH_SYN *pRecvMsg = (MSG_SA_SERVER_AUTH_SYN*)pMsg;
|
|
|
|
// 해당 IP의 Agent 정보가 존재하는지 체크
|
|
AgentInfo *pAgentInfo = AgentInfoParser::Instance()->GetAgentInfo( pSession->GetIP() );
|
|
|
|
MSG_SA_SERVER_AUTH_ACK AckMsg;
|
|
|
|
if( pAgentInfo )
|
|
{
|
|
AckMsg.m_byResult = RC_AGENT_AUTH_SUCCESS;
|
|
AckMsg.m_dwAgentKey = pAgentInfo->GetKey();
|
|
pSession->SetServerKey( pAgentInfo->GetKey() );
|
|
ServerSessionManager::Instance()->AddSession( pSession );
|
|
MSGOUT( "[Handler_SA::OnHandler_SA_SERVER_AUTH_SYN] AgentServer Auth Success, Key = %u", pAgentInfo->GetKey() );
|
|
}
|
|
else
|
|
{
|
|
AckMsg.m_byResult = RC_AGENT_AUTH_FAIL;
|
|
AckMsg.m_dwAgentKey = 0;
|
|
MSGOUT( "[Handler_SA::OnHandler_SA_SERVER_AUTH_SYN] AgentServer Auth Fail, Key = %d, 0" );
|
|
}
|
|
|
|
pSession->SendPacket( (BYTE*)&AckMsg, sizeof(AckMsg) );
|
|
}
|
|
|
|
// 서버 시작 결과
|
|
VOID Handler_SA::OnHandler_SA_SERVER_EXECUTE_ACK( ServerSession *pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_EXECUTE_ACK *pRecvMsg = (MSG_SA_SERVER_EXECUTE_ACK*)pMsg;
|
|
|
|
// 패치를 실행시킨 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "[SERVER_EXECUTE_ACK] Can't find ServerStart-User!" );
|
|
return;
|
|
}
|
|
|
|
// 서버시작 결과를 알린다.
|
|
MSG_SM_SERVER_EXECUTE_ACK AckMsg;
|
|
AckMsg.m_byResult = pRecvMsg->m_byResult;
|
|
memcpy( &AckMsg.m_ServerInfo, &pRecvMsg->m_ServerInfo, sizeof(SERVER_INFO) );
|
|
pUser->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
|
|
//패치 시작을 전 유저에게 알려서 패치 시작시 다른 작업을 못하게 한다.
|
|
|
|
MSGOUT( "[SERVER_EXECUTE_ACK] Result : %d, World : %d, Channel : %d, ServerType : %d, ServerNum %d "
|
|
, AckMsg.m_byResult, pRecvMsg->m_ServerInfo.m_byWorld, pRecvMsg->m_ServerInfo.m_byChannel
|
|
, pRecvMsg->m_ServerInfo.m_byServerType, pRecvMsg->m_ServerInfo.m_byServerNum );
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_SA_SERVER_FORCE_DISCONNECT_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_FORCE_DISCONNECT_ACK *pRecvMsg = (MSG_SA_SERVER_FORCE_DISCONNECT_ACK*)pMsg;
|
|
|
|
// 패치를 실행시킨 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "[Handler_SA::OnHandler_SA_SERVER_FORCE_DISCONNECT_ACK] Can't find ServerStart-User!" );
|
|
return;
|
|
}
|
|
|
|
// 서버 강제종료 결과를 알린다.
|
|
MSG_SM_SERVER_FORCE_DISCONNECT_ACK Ack;
|
|
Ack.m_byResult = pRecvMsg->m_byResult;
|
|
Ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
pUser->SendPacket( &Ack, sizeof(Ack) );
|
|
}
|
|
|
|
// 패치 시작 결과
|
|
VOID Handler_SA::OnHandler_SA_PATCH_EXECUTE_ACK( ServerSession *pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_PATCH_EXECUTE_ACK *pRecvMsg = (MSG_SA_PATCH_EXECUTE_ACK*)pMsg;
|
|
|
|
UnitServer* pSunServer = WorldManager::Instance()->FindSunServer( pRecvMsg->m_ServerInfo.m_byWorld );
|
|
if( !pSession )
|
|
{
|
|
MSGOUT( "[패치시작결과] %d월드의 SunServer 정보를 찾을수 없습니다.", pRecvMsg->m_ServerInfo.m_byWorld );
|
|
return;
|
|
}
|
|
|
|
if( pSunServer->GetServerStatus() != SERVER_STATUS_PATCHING )
|
|
{
|
|
MSGOUT( "[패치시작결과] %d월드가 패치중이 아닌데, 패치결과가 왔다.", pRecvMsg->m_ServerInfo.m_byWorld );
|
|
return;
|
|
}
|
|
|
|
// 패치를 실행시킨 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "[패치시작결과] 패치를 실행한 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
//해당월드의 모든 서버의 상태를 패치중으로 고친다.
|
|
// UnitServer* pSunServer = WorldManager::Instance()->FindSunServer( pRecvMsg->m_ServerInfo.m_byWorld );
|
|
pSunServer->SetServerStatus( SERVER_STATUS_PATCHING );
|
|
|
|
MSG_SM_PATCH_EXECUTE_ACK AckMsg;
|
|
AckMsg.m_byResult = pRecvMsg->m_byResult;
|
|
memcpy( &AckMsg.m_ServerInfo, &pRecvMsg->m_ServerInfo, sizeof(SERVER_INFO) );
|
|
pUser->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
|
|
MSGOUT( "[PATCH_EXECUTE_ACK] Result : %d, World : %d, Channel : %d, ServerType : %d, ServerNum %d "
|
|
, pRecvMsg->m_byResult, pRecvMsg->m_ServerInfo.m_byWorld, pRecvMsg->m_ServerInfo.m_byChannel
|
|
, pRecvMsg->m_ServerInfo.m_byServerType, pRecvMsg->m_ServerInfo.m_byServerNum );
|
|
}
|
|
|
|
// 패치 완료 결과
|
|
// 이 패킷이 오면, 무조건 서버상태를 오프라인으로 바꾼다.
|
|
VOID Handler_SA::OnHandler_SA_PATCH_RESULT_NTF( ServerSession *pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_PATCH_RESULT_NTF *pRecvMsg = (MSG_SA_PATCH_RESULT_NTF*)pMsg;
|
|
|
|
// Manager로 현재 결과를 보낸다.
|
|
MSG_SM_PATCH_RESULT_NTF msg;
|
|
msg.patch_result_.patch_result_type_ = pRecvMsg->m_dwResult;
|
|
msg.patch_result_.solar_server_type_ = pRecvMsg->m_byNum;
|
|
ZeroMemory( &msg.m_ServerPatchInfo, sizeof(SERVER_PATCH_INFO) );
|
|
memcpy( &msg.m_ServerPatchInfo.m_PatchVer, &pRecvMsg->m_PatchVer, sizeof(PATCH_VERSION) );
|
|
|
|
|
|
// AgentKey와 ServerType으로 해당서버를 찾는다.
|
|
UnitServer *pSunServer = WorldManager::Instance()->FindUnitServer( pSession->GetServerKey(), pRecvMsg->m_byServerType );
|
|
if( pSunServer )
|
|
{
|
|
if( pSunServer->GetServerType() != SUN_SERVER && pSunServer->GetServerType() != SOLARAUTH_SERVER )
|
|
{
|
|
MSGOUT("패치결과가 SUN_SERVER가 아닌 이상한 값이 넘어왔다. SERVER_TYPE = %d", pSunServer->GetServerType() );
|
|
}
|
|
|
|
// 해당 SunServer가 속한 월드의 모든 서버상태를 Offline으로 바꾼다. ==> Offline이 아니라 당연히 Offline 상태이어야 한다.
|
|
World* pWorld = WorldManager::Instance()->FindWorld( pSunServer->GetWorld() );
|
|
pWorld->SetServerStatus( SERVER_STATUS_OFFLINE );
|
|
|
|
//현재 패치결과가 날라온 서버가 존재한다면... 해당 서버의 정보를 보낼 메세지에 저장한다.
|
|
pSunServer->GetServerInfo().GetServerInfo( &msg.m_ServerPatchInfo );
|
|
}
|
|
else //현재 패치결과에 해당하는 서버가 존재하지 않는다면..
|
|
{
|
|
MSGOUT("AgentKey[%d] ServerType[%d] Can't Find ServerInfo! \n", pSession->GetServerKey(), pRecvMsg->m_byServerType );
|
|
msg.m_ServerPatchInfo.m_byServerType = pRecvMsg->m_byServerType;
|
|
}
|
|
|
|
// 패치를 실행시킨 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "[PATCH_RESULT_NTF] Can't find Patch-User! \n" );
|
|
return;
|
|
}
|
|
|
|
int nRet = pUser->SendPacket( &msg, sizeof(msg) );
|
|
}
|
|
|
|
|
|
// 공지사항
|
|
VOID Handler_SA::OnHandler_SA_SERVER_NOTICE_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_NOTICE_ACK *pRecvMsg = (MSG_SA_SERVER_NOTICE_ACK*)pMsg;
|
|
|
|
// 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "공지를 정보를 요청한 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
MSG_SM_SERVER_NOTICE_ACK AckMsg;
|
|
AckMsg.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
AckMsg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
strcpy( AckMsg.m_szNotice, pRecvMsg->m_szNotice );
|
|
|
|
pUser->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_SA_SERVER_SEND_NOTICE_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_SEND_NOTICE_ACK *pRecvMsg = (MSG_SA_SERVER_SEND_NOTICE_ACK*)pMsg;
|
|
|
|
// 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "공지를 보낸 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
MSG_SM_SERVER_SEND_NOTICE_ACK AckMsg;
|
|
AckMsg.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
AckMsg.m_bFlag = pRecvMsg->m_bFlag;
|
|
AckMsg.m_bConnectAgentServer = TRUE;
|
|
|
|
pUser->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
}
|
|
|
|
|
|
VOID Handler_SA::OnHandler_SA_CHECK_LOGFILE_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_CHECK_LOGFILE_ACK *pRecvMsg = (MSG_SA_CHECK_LOGFILE_ACK*)pMsg;
|
|
|
|
// 패치를 실행시킨 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "[로그보기결과] 로그보기를 실행한 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
MSG_SM_CHECK_LOGFILE_ACK AckMsg;
|
|
AckMsg.m_byResult = pRecvMsg->m_byResult;
|
|
AckMsg.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
memcpy( &AckMsg.m_szLogFile, &pRecvMsg->m_szLogFile, MAX_FILE_BUFFER_SIZE );
|
|
AckMsg.m_wFileSize = pRecvMsg->m_wFileSize;
|
|
AckMsg.m_NumAllLogPage = pRecvMsg->m_NumAllLogPage;
|
|
|
|
pUser->SendPacket( &AckMsg, AckMsg.GetSize() );
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_SA_CHECK_GAMEPROCESS_NTF( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_CHECK_GAMEPROCESS_NTF* pRecvMsg = (MSG_SA_CHECK_GAMEPROCESS_NTF*)pMsg;
|
|
AgentServerSession* pAgentSession = (AgentServerSession*)pSession;
|
|
|
|
//에이전트 키와 서버타입으로, 현재 서버의 정보를 얻는다.
|
|
UnitServer* pUnitServer = WorldManager::Instance()->FindUnitServer( pAgentSession->GetServerKey(), pRecvMsg->m_GameStatus.m_ServerType );
|
|
if( !pUnitServer )
|
|
{
|
|
//그런 서버 존재하지 않음.
|
|
return;
|
|
}
|
|
|
|
//현재 서버의 상태와 같은 상태이면 보내지 않는다.
|
|
if( pUnitServer->GetServerStatus() == pRecvMsg->m_GameStatus.m_Status ) //같은 서버
|
|
return;
|
|
|
|
//현재 서버가 패치중이면 보내지 않는다.
|
|
if( pUnitServer->GetServerStatus() == SERVER_STATUS_PATCHING )
|
|
return;
|
|
|
|
//여기로 오는 메세지는 서버가 켜져 있다, 아니면 꺼져있다.. 2가지 상태이다.
|
|
if( SERVER_STATUS_LIVE_PROCESS == pRecvMsg->m_GameStatus.m_Status ) //켜져있으면
|
|
{
|
|
//1. 현재 서버의 상태가 Online인데, 라이브 명령이면 무시한다.
|
|
if( SERVER_STATUS_ONLINE == pUnitServer->GetServerStatus() )
|
|
return;
|
|
}
|
|
|
|
pUnitServer->SetServerStatus( pRecvMsg->m_GameStatus.m_Status );
|
|
// MSG_SM_CHECK_GAMEPROCESS_NTF msg;
|
|
// ServerInfo& rServerInfo = pUnitServer->GetServerInfo();
|
|
// rServerInfo.GetServerInfo( &msg.m_ServerInfo );
|
|
// UserManager::Instance()->SendPacketAll( &msg, sizeof(msg) );
|
|
}
|
|
|
|
|
|
VOID Handler_SA::OnHandler_SA_SERVER_BACKUP_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_BACKUP_ACK* pRecvMsg = (MSG_SA_SERVER_BACKUP_ACK*)pMsg;
|
|
|
|
// 패치를 실행시킨 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "[백업결과] 백업을 실행한 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
MSG_SM_SERVER_BACKUP_ACK ack;
|
|
ack.m_byResult = pRecvMsg->m_byResult;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
|
|
pUser->SendPacket( &ack, sizeof(ack) );
|
|
}
|
|
|
|
|
|
VOID Handler_SA::OnHandler_SA_SERVER_RESTORE_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_RESTORE_ACK* pRecvMsg = (MSG_SA_SERVER_RESTORE_ACK*)pMsg;
|
|
|
|
// 패치를 실행시킨 유저를 찾는다.
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey );
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "[백업결과] 백업을 실행한 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
MSG_SM_SERVER_RESTORE_ACK ack;
|
|
ack.m_byResult = pRecvMsg->m_byResult;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
|
|
pUser->SendPacket( &ack, sizeof(ack) );
|
|
}
|
|
|
|
#ifdef __20080312__SOLARAUTH_SERVER_PATCH
|
|
VOID Handler_SA::OnHandler_SA_SOLARSCRIPT_BACKUP_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SOLARSCRIPT_BACKUP_ACK* pRecvMsg = (MSG_SA_SOLARSCRIPT_BACKUP_ACK *)pMsg;
|
|
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey);
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "스크립트 백업을 실행한 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
MSG_SM_SERVER_SOLARSCRIPT_BACKUP_ACK ack;
|
|
ack.m_byResult = pRecvMsg->m_byResult;
|
|
ack.m_FolderInfo = pRecvMsg->m_ScriptFolder;
|
|
|
|
pUser->SendPacket( &ack, sizeof(ack) );
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_SA_SOLARSCRIPT_RESTORE_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SOLARSCRIPT_RESTORE_ACK* pRecvMsg = (MSG_SA_SOLARSCRIPT_RESTORE_ACK *)pMsg;
|
|
|
|
MSG_SM_SERVER_SOLARSCRIPT_RESTORE_ACK ack;
|
|
ack.m_byResult = pRecvMsg->m_byResult;
|
|
ack.m_FolderInfo = pRecvMsg->m_ScriptFolder;
|
|
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey);
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "스크립트 복원을 실행한 유저를 찾을 수 없습니다." );
|
|
ack.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL;
|
|
}
|
|
|
|
pUser->SendPacket( &ack, sizeof( ack));
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_SA_SOLARSCRIPT_EXECUTE_ACK( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SOLARSCRIPT_EXECUTE_ACK* pRecvMsg = (MSG_SA_SOLARSCRIPT_EXECUTE_ACK *)pMsg;
|
|
|
|
User *pUser = (User*)UserManager::Instance()->GetUser( pRecvMsg->m_dwUserKey);
|
|
if( !pUser )
|
|
{
|
|
MSGOUT( "스크립트 패치를 실행한 유저를 찾을 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
MSG_SM_PATCH_SOLARSCRIPT_EXECUTE_ACK ack;
|
|
ack.m_byResult = pRecvMsg->m_byResult;
|
|
ack.m_FolderInfo = pRecvMsg->m_ScriptFolder;
|
|
|
|
pUser->SendPacket( &ack, sizeof( ack));
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef _NA_006543_20130318_HEARTBEAT
|
|
|
|
VOID Handler_SA::OnHandler_SA_CHECK_HEARTBEAT_NTF( ServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
//UpdateServer에서 사용
|
|
//DISPMSG("Recv Heartbeat\n");
|
|
static_cast<AgentServerSession*>(pSession)->CheckHeatbeatRecv();
|
|
}
|
|
#endif
|