812 lines
24 KiB
C++
812 lines
24 KiB
C++
#include "StdAfx.h"
|
|
#include ".\handler_sa.h"
|
|
#include "SunUpdateAgent.h"
|
|
#include "UpdateServerSession.h"
|
|
#include <PacketStruct_SA.h>
|
|
#include <Constant.h>
|
|
#include "AgentInfoParser.h"
|
|
#include <string>
|
|
#include <io.h>
|
|
#include <WZTime.h>
|
|
#include "FileUtil.h"
|
|
#ifdef _NA_006662_20130423_SVNPATCH
|
|
#include <PacketStruct_AT.h>
|
|
#endif //_NA_006662_20130423_SVNPATCH
|
|
|
|
Handler_SA::Handler_SA(void)
|
|
{
|
|
}
|
|
|
|
Handler_SA::~Handler_SA(void)
|
|
{
|
|
}
|
|
|
|
// 서버 인증
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_AUTH_ACK( UpdateServerSession *pSession, MSG_BASE *pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_AUTH_ACK *pRecvMsg = (MSG_SA_SERVER_AUTH_ACK*)pMsg;
|
|
if( !pRecvMsg ) return;
|
|
|
|
if( pRecvMsg->m_byResult == RC_AGENT_AUTH_SUCCESS )
|
|
MSGOUT("Auth Success, AgentKey = %u", pRecvMsg->m_dwAgentKey );
|
|
else
|
|
MSGOUT("Auth Fail, AgentKey = %u", pRecvMsg->m_dwAgentKey );
|
|
|
|
SunUpdateAgent::Instance()->SetAgentKey( pRecvMsg->m_dwAgentKey );
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_TYPE_ACK( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_TYPE_ACK *pRecvMsg = (MSG_SA_SERVER_TYPE_ACK*)pMsg;
|
|
|
|
if( pRecvMsg )
|
|
{
|
|
MSG_SA_SERVER_AUTH_SYN msg;
|
|
pSession->SendPacket( &msg, sizeof(msg) );
|
|
}
|
|
|
|
}
|
|
|
|
// 서버 시작
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_EXECUTE_SYN( UpdateServerSession *pSession, MSG_BASE *pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_EXECUTE_SYN *pRecvMsg = (MSG_SA_SERVER_EXECUTE_SYN*)pMsg;
|
|
|
|
MSG_SA_SERVER_EXECUTE_ACK AckMsg;
|
|
AckMsg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
memcpy( &AckMsg.m_ServerInfo, &pRecvMsg->m_ServerInfo, sizeof(SERVER_INFO) );
|
|
|
|
// 해당서버의 경로를 찾는다.
|
|
std::string strPath;
|
|
if( !AgentInfoParser::Instance()->GetGameServerPath( pRecvMsg->m_ServerInfo.m_byServerType, strPath ) )
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_EXECUTE_FAIL_NOT_FIND_PATH;
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
return;
|
|
}
|
|
|
|
PROCESS_INFORMATION pi;
|
|
STARTUPINFO si = {0, };
|
|
si.cb = sizeof(si);
|
|
|
|
std::string directory_path = strPath.substr(0, strPath.rfind('\\'));
|
|
|
|
// 서버를 실행시킨다.
|
|
if( _access( strPath.c_str(), 0 ) != -1 ) //파일이 존재하면
|
|
{
|
|
#ifdef __20080312__SOLARAUTH_SERVER_PATCH
|
|
if( CreateProcess( strPath.c_str(), NULL,
|
|
NULL, NULL, TRUE,
|
|
CREATE_NEW_CONSOLE,
|
|
NULL, directory_path.c_str(),
|
|
&si, &pi) )
|
|
{
|
|
MSGOUT( "서버실행 성공: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_EXECUTE_SUCCESS;
|
|
}
|
|
#else
|
|
if( WinExec( strPath.c_str(), SW_SHOW ) > 31 ) //성공하면
|
|
{
|
|
MSGOUT( "서버실행 성공: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_EXECUTE_SUCCESS;
|
|
}
|
|
#endif //__20080312__SOLARAUTH_SERVER_PATCH
|
|
else
|
|
{
|
|
MSGOUT( "서버실행 실패: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_EXECUTE_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MSGOUT( "서버실행 실패(파일이 없습니다): %s" , strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_EXECUTE_FAIL_FILE_NOT_EXITE;
|
|
}
|
|
|
|
// 서버시작 결과를 알린다.
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
}
|
|
|
|
#ifdef _NA_006662_20130423_SVNPATCH
|
|
// 패치 실행
|
|
VOID Handler_SA::OnHandler_MSG_SA_PATCH_EXECUTE_SYN( UpdateServerSession *pSession, MSG_BASE *pMsg, int nSize )
|
|
{
|
|
DWORD patch_style = AgentInfoParser::Instance()->GetPatchStyle();
|
|
if (patch_style == AgentInfoParser::ePATCH_STYLE::PATCHSTYLE_FTP)
|
|
{
|
|
//기존의 FTP방식으로 처리
|
|
_ProcessPatchUsingUpdateTool(pSession, pMsg, nSize);
|
|
}
|
|
else if(patch_style == AgentInfoParser::ePATCH_STYLE::PATCHSTYLE_SVN)
|
|
{
|
|
//SVN으로 스크립트를 관리하는 경우
|
|
_ProcessPatchUsingBatchFile(pSession, pMsg, nSize);
|
|
}
|
|
}
|
|
#endif //_NA_006662_20130423_SVNPATCH
|
|
|
|
VOID Handler_SA::OnHandler_MSG_SA_CHECK_LOGFILE_SYN( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_CHECK_LOGFILE_SYN* pRecvMsg = (MSG_SA_CHECK_LOGFILE_SYN*)pMsg;
|
|
|
|
MSGOUT( "로그확인 요청. Type = %d", pRecvMsg->m_ServerInfo.m_byServerType );
|
|
|
|
std::string strFile, strLog;
|
|
TCHAR szTime[MAX_PATH];
|
|
WZTime::GetTime( 2, szTime, MAX_PATH );
|
|
|
|
if (pRecvMsg->m_ServerInfo.m_byServerType < ACCOUNT_DBPROXY)
|
|
strFile = AgentInfoParser::Instance()->GetAuthSystemLogViewPath();
|
|
else
|
|
strFile = AgentInfoParser::Instance()->GetLogViewPath();
|
|
|
|
if( pRecvMsg->m_ServerInfo.m_byServerType == AUTH_SERVER )
|
|
strFile += "\\AuthServer__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == AUTH_AGENT_SERVER )
|
|
strFile += "\\AuthAgent__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == LOGIN_FRONT_SERVER )
|
|
strFile += "\\LoginFront__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == ACCOUNT_DBPROXY )
|
|
strFile += "\\AccountDBProxy__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == MASTER_SERVER )
|
|
strFile += "\\Master__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == GAME_DBPROXY )
|
|
strFile += "\\DBProxy__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == WORLD_SERVER )
|
|
strFile += "\\World__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == FIELD_SERVER )
|
|
strFile += "\\Field__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == BATTLE_SERVER )
|
|
strFile += "\\Battle__Date_";
|
|
else if( pRecvMsg->m_ServerInfo.m_byServerType == AGENT_SERVER )
|
|
strFile += "\\Agent__Date_";
|
|
else
|
|
{
|
|
MSGOUT( "지원되지 않는 서버타입의 로그를 요청하였습니다. Type = %d", pRecvMsg->m_ServerInfo.m_byServerType );
|
|
}
|
|
|
|
strFile += szTime;
|
|
strFile += ".wzl";
|
|
|
|
MSG_SA_CHECK_LOGFILE_ACK ack;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
//ack.m_NumAllLogPage = 100;
|
|
ZeroMemory( ack.m_szLogFile, MAX_FILE_BUFFER_SIZE );
|
|
|
|
if( _access( strFile.c_str(), 0 ) != -1 ) //파일이 존재하면.
|
|
{
|
|
ack.m_byResult = RC_CHECK_LOGFILE_SUCCESS;
|
|
|
|
FILE* pFile = fopen( strFile.c_str(), "r" );
|
|
if( !pFile )
|
|
{
|
|
fclose( pFile );
|
|
return;
|
|
}
|
|
|
|
char szFile[MAX_FILE_BUFFER_SIZE];
|
|
BYTE bySize = 0;
|
|
DWORD dwFileSize = 0;
|
|
WORD numRead = 0;
|
|
|
|
fseek( pFile, 0, SEEK_END );
|
|
dwFileSize = ftell( pFile );
|
|
|
|
//파일의 총 페이지 수를 구한다.
|
|
ack.m_NumAllLogPage = (dwFileSize / MAX_FILE_BUFFER_SIZE);
|
|
if( !( dwFileSize%MAX_FILE_BUFFER_SIZE ) )
|
|
ack.m_NumAllLogPage--;//0페이지부터 시작, 나머지 페이지 없기 때문
|
|
|
|
//유저가 요청하는 해당 페이지의 파일을 읽는다.
|
|
fseek( pFile, MAX_FILE_BUFFER_SIZE*pRecvMsg->m_CntLogPage, SEEK_SET);
|
|
numRead = fread( szFile, sizeof(char), MAX_FILE_BUFFER_SIZE, pFile );
|
|
|
|
strncpy( ack.m_szLogFile, szFile, numRead );
|
|
ack.m_szLogFile[numRead-1] = 0;
|
|
ack.m_wFileSize = numRead;
|
|
/*
|
|
while( !feof(pFile) )
|
|
{
|
|
ZeroMemory( szFile, 200 );
|
|
fgets( szFile, 200 - 1, pFile );
|
|
strLog += szFile;
|
|
}
|
|
|
|
if( strLog.size() >= MAX_FILE_BUFFER_SIZE )
|
|
{
|
|
//뒤에서부터 MAX_FILE_BUFFER_SIZE만큰 뒤부터 보낸다.
|
|
std::string strLogEx = strLog.substr( strLog.size() - MAX_FILE_BUFFER_SIZE );
|
|
strncpy( ack.m_szLogFile, strLogEx.c_str(), MAX_FILE_BUFFER_SIZE );
|
|
ack.m_szLogFile[MAX_FILE_BUFFER_SIZE-1] = 0;
|
|
ack.m_wFileSize = MAX_FILE_BUFFER_SIZE;
|
|
}
|
|
else
|
|
{
|
|
//전체를 보낸다.
|
|
strncpy( ack.m_szLogFile, strLog.c_str(), MAX_FILE_BUFFER_SIZE );
|
|
ack.m_szLogFile[strLog.size()-1] = 0;
|
|
ack.m_wFileSize = (WORD)strLog.size();
|
|
}
|
|
*/
|
|
fclose( pFile );
|
|
}
|
|
else
|
|
{
|
|
ack.m_byResult = RC_CHECK_LOGFILE_NOT_FOUND;
|
|
ack.m_wFileSize = 0;
|
|
}
|
|
|
|
pSession->SendPacket( &ack, ack.GetSize() );
|
|
}
|
|
|
|
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_FORCE_DISCONNECT_SYN( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_FORCE_DISCONNECT_SYN* pRecvMsg = (MSG_SA_SERVER_FORCE_DISCONNECT_SYN*)pMsg;
|
|
|
|
std::string strProcess;
|
|
AgentInfoParser::Instance()->GetGameProcessName( pRecvMsg->m_ServerInfo.m_byServerType, strProcess );
|
|
|
|
DWORD dwPreGameServerProcID = 0;
|
|
|
|
DWORD dwProID = 0;
|
|
BOOL bRet = CheckLiveProcess( (TCHAR*)strProcess.c_str(), dwProID, dwPreGameServerProcID );
|
|
|
|
MSG_SA_SERVER_FORCE_DISCONNECT_ACK Ack;
|
|
Ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
Ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
|
|
if( dwProID ) //존재하면.. 현재 실제 실행되고 있는 프로세서이다.
|
|
{
|
|
if( ServerForceShutDown( dwProID ) )
|
|
{
|
|
MSGOUT("강제서버종료 성공: Name = %s", strProcess.c_str() );
|
|
Ack.m_byResult = RC_SERVER_FORCE_DISCONNECT_SUCCESS;
|
|
|
|
// cmd.exe 창 종료시키기.. "cmd.exe" ==> 프로세스 명
|
|
BYTE byCount = 0;
|
|
while( byCount < 10 )
|
|
{
|
|
DWORD dwCmdID = 0;
|
|
BOOL bRet = CheckLiveProcess( "cmd.exe", dwCmdID, 0 );
|
|
if( dwCmdID )
|
|
ServerForceShutDown( dwCmdID );
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MSGOUT("강제서버종료 실패: Name = %s", strProcess.c_str() );
|
|
Ack.m_byResult = RC_SERVER_FORCE_DISCONNECT_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MSGOUT("강제서버종료 실패: 현재 %s 서버가 실행중이지 않습니다.", strProcess.c_str() );
|
|
Ack.m_byResult = RC_SERVER_FORCE_DISCONNECT_FAIL_SERVER_OFFLINE;
|
|
}
|
|
|
|
pSession->SendPacket( &Ack, sizeof(Ack) );
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_BACKUP_SYN( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_BACKUP_SYN* pRecvMsg = (MSG_SA_SERVER_BACKUP_SYN*)pMsg;
|
|
|
|
std::string strDataFolder, strBackupFolder, strOriginal;
|
|
|
|
MSG_SA_SERVER_BACKUP_ACK ack;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
if( pRecvMsg->m_ServerInfo.m_byServerType != SUN_SERVER )
|
|
{
|
|
ack.m_byResult = RC_SERVER_BACKUP_FAIL;
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
strOriginal = AgentInfoParser::Instance()->GetBasicServerPath();
|
|
strOriginal += "\\SunServer\\";
|
|
strDataFolder = strOriginal;
|
|
strDataFolder += "data";
|
|
strBackupFolder = strOriginal;
|
|
strBackupFolder += "backup";
|
|
}
|
|
|
|
if( !FileUtil::CopyFoler( strDataFolder.c_str(), strBackupFolder.c_str() ) )
|
|
ack.m_byResult = RC_SERVER_BACKUP_FAIL;
|
|
else
|
|
ack.m_byResult = RC_SERVER_BACKUP_SUCCESS;
|
|
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
}
|
|
|
|
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_RESTORE_SYN( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_RESTORE_SYN* pRecvMsg = (MSG_SA_SERVER_RESTORE_SYN*)pMsg;
|
|
|
|
MSG_SA_SERVER_RESTORE_ACK ack;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
|
|
std::string strDataFolder, strBackupFolder, strOriginal;
|
|
|
|
if( pRecvMsg->m_ServerInfo.m_byServerType != SUN_SERVER )
|
|
{
|
|
ack.m_byResult = RC_SERVER_BACKUP_FAIL;
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
strOriginal = AgentInfoParser::Instance()->GetBasicServerPath();
|
|
strOriginal += "\\SunServer\\";
|
|
strDataFolder = strOriginal;
|
|
strBackupFolder = strOriginal;
|
|
strBackupFolder += "backup\\data";
|
|
}
|
|
|
|
if( !FileUtil::CopyFoler( strBackupFolder.c_str(), strDataFolder.c_str() ) )
|
|
ack.m_byResult = RC_SERVER_RESTORE_FAIL;
|
|
else
|
|
ack.m_byResult = RC_SERVER_RESTORE_SUCCESS;
|
|
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
}
|
|
|
|
// 공지사항
|
|
// 2012.2.22 김진휘
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_NOTICE_SYN( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_NOTICE_SYN* pRecvMsg = (MSG_SA_SERVER_NOTICE_SYN*)pMsg;
|
|
|
|
if (pRecvMsg->m_ServerInfo.m_byServerType != WORLD_SERVER) return;
|
|
|
|
std::string strPath = AgentInfoParser::Instance()->GetNoticePath();
|
|
strPath += "\\Notice.txt";
|
|
|
|
char szNotice[MAX_NOTICE_LEN+1];
|
|
ZeroMemory( szNotice, sizeof(szNotice) );
|
|
|
|
FILE *fp = fopen( strPath.c_str(), "rt");
|
|
if( !fp )
|
|
{
|
|
// 공지사항 파일 찾기 실패
|
|
FILE *wfp = fopen( strPath.c_str(), "wt" );
|
|
char szbuffer[MAX_NOTICE_LEN] = "서버 패치를 위해 10초 후 채널서버를 강제 종료하겠습니다. 안전한 곳으로 이동하여 종료해 주십시오.";
|
|
fwrite( szbuffer, sizeof(char), sizeof(szbuffer) , wfp );
|
|
memcpy( szNotice, szbuffer, sizeof(szbuffer) );
|
|
fclose( wfp );
|
|
}
|
|
else
|
|
{
|
|
fread( szNotice, sizeof(char), MAX_NOTICE_LEN, fp );
|
|
fclose( fp );
|
|
}
|
|
|
|
MSG_SA_SERVER_NOTICE_ACK Ackmsg;
|
|
Ackmsg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
Ackmsg.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
strcpy( Ackmsg.m_szNotice, szNotice );
|
|
|
|
pSession->SendPacket( &Ackmsg, sizeof(Ackmsg) );
|
|
}
|
|
|
|
VOID Handler_SA::OnHandler_MSG_SA_SERVER_SEND_NOTICE_SYN( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SERVER_SEND_NOTICE_SYN* pRecvMsg = (MSG_SA_SERVER_SEND_NOTICE_SYN*)pMsg;
|
|
|
|
if( pRecvMsg->m_ServerInfo.m_byServerType != WORLD_SERVER ) return;
|
|
|
|
std::string strPath = AgentInfoParser::Instance()->GetNoticePath();
|
|
strPath += "\\Notice.txt";
|
|
|
|
FILE *fp = fopen( strPath.c_str(), "wt");
|
|
|
|
if( fp )
|
|
{
|
|
fwrite( pRecvMsg->m_szNotice, sizeof(char), strlen(pRecvMsg->m_szNotice), fp );
|
|
fclose( fp );
|
|
}
|
|
|
|
MSG_SA_SERVER_SEND_NOTICE_ACK Ackmsg;
|
|
Ackmsg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
Ackmsg.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
|
|
// WorldServer.exe 찾기..///////////////////////////////////////////////////////////////////////
|
|
std::string strWorldServer;
|
|
AgentInfoParser::Instance()->GetGameProcessName( WORLD_SERVER, strWorldServer );
|
|
|
|
DWORD dwPreGameServerProcID = 0;
|
|
DWORD dwID = 0;
|
|
BOOL bRet = CheckLiveProcess( (TCHAR*)strWorldServer.c_str(), dwID, dwPreGameServerProcID);
|
|
|
|
// Local에서 WorldServer.exe가 없을 때..
|
|
if( !bRet )
|
|
{
|
|
Ackmsg.m_bFlag = FALSE;
|
|
pSession->SendPacket( &Ackmsg, sizeof(Ackmsg) );
|
|
return;
|
|
}
|
|
|
|
CallbackInfo st_Callback;
|
|
|
|
st_Callback.m_dwPID = dwID;
|
|
st_Callback.m_hWnd = NULL;
|
|
|
|
EnumWindows(EnumProc, (LPARAM)&st_Callback);
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// WorldServer.exe의 핸들값을 찾았다면..
|
|
if( st_Callback.m_hWnd )
|
|
{
|
|
::PostMessage( st_Callback.m_hWnd, WM_CHAR, 'n', (LPARAM)1 );
|
|
Ackmsg.m_bFlag = TRUE;
|
|
}
|
|
|
|
pSession->SendPacket( &Ackmsg, sizeof(Ackmsg) );
|
|
|
|
}
|
|
|
|
#ifdef __20080312__SOLARAUTH_SERVER_PATCH
|
|
|
|
//
|
|
// default_path\data.encrypted.data -> default_path\backup\data.encrypted.China
|
|
//
|
|
VOID
|
|
Handler_SA::OnHandler_MSG_SA_SOLARSCRIPT_BACKUP_SYN(
|
|
UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SOLARSCRIPT_BACKUP_SYN *pRecvMsg = (MSG_SA_SOLARSCRIPT_BACKUP_SYN *)pMsg;
|
|
|
|
MSG_SA_SOLARSCRIPT_BACKUP_ACK ack;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
ack.m_ScriptFolder = pRecvMsg->m_ScriptFolder;
|
|
|
|
std::string strDefault( AgentInfoParser::Instance()->GetSCFolderPath())
|
|
, strToFolder
|
|
, strFromFolder;
|
|
|
|
if( pRecvMsg->m_ServerInfo.m_byServerType != SOLARAUTH_SERVER )
|
|
{
|
|
ack.m_byResult = RC_SERVER_SCFOLDER_BACKUP_FAIL;
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
strToFolder = strDefault + "\\backup\\";
|
|
strFromFolder = strDefault + "\\" + pRecvMsg->m_ScriptFolder.m_szName ;
|
|
}
|
|
|
|
if( !FileUtil::CopyFoler( strFromFolder.c_str(), strToFolder.c_str() ) )
|
|
ack.m_byResult = RC_SERVER_SCFOLDER_BACKUP_FILECOPY_FAIL;
|
|
else
|
|
ack.m_byResult = RC_SERVER_SCFOLDER_BACKUP_SUCCESS;
|
|
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
}
|
|
|
|
//
|
|
// default_patch\backup\data.encrypted.China - > default_path\data.encrypted.data
|
|
//
|
|
VOID
|
|
Handler_SA::OnHandler_MSG_SA_SOLARSCRIPT_RESTORE_SYN(
|
|
UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SOLARSCRIPT_RESTORE_SYN *pRecvMsg = (MSG_SA_SOLARSCRIPT_RESTORE_SYN *)pMsg;
|
|
|
|
MSG_SA_SOLARSCRIPT_RESTORE_ACK ack;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
ack.m_ScriptFolder = pRecvMsg->m_ScriptFolder;
|
|
|
|
std::string strDefault( AgentInfoParser::Instance()->GetSCFolderPath())
|
|
, strToFolder
|
|
, strFromFolder;
|
|
|
|
if( pRecvMsg->m_ServerInfo.m_byServerType != SOLARAUTH_SERVER )
|
|
{
|
|
ack.m_byResult = RC_SERVER_SCFOLDER_RESTORE_FAIL;
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
strToFolder = strDefault;
|
|
strFromFolder = strDefault + "\\backup\\" + pRecvMsg->m_ScriptFolder.m_szName ;
|
|
}
|
|
|
|
if( !FileUtil::CopyFoler( strFromFolder.c_str(), strToFolder.c_str() ) )
|
|
ack.m_byResult = RC_SERVER_SCFOLDER_RESTORE_FAIL;
|
|
else
|
|
ack.m_byResult = RC_SERVER_SCFOLDER_RESTORE_SUCCESS;
|
|
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &ack, sizeof(ack) );
|
|
}
|
|
|
|
//
|
|
// execute AutoPatchTool
|
|
//
|
|
VOID Handler_SA::OnHandler_MSG_SA_SOLARSCRIPT_EXECUTE_SYN(
|
|
UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
MSG_SA_SOLARSCRIPT_EXECUTE_SYN *pRecvMsg = (MSG_SA_SOLARSCRIPT_EXECUTE_SYN *)pMsg;
|
|
|
|
MSG_SA_SOLARSCRIPT_EXECUTE_ACK ack;
|
|
ack.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
ack.m_ServerInfo = pRecvMsg->m_ServerInfo;
|
|
ack.m_ScriptFolder = pRecvMsg->m_ScriptFolder;
|
|
|
|
DWORD dwProcID = 0;
|
|
if( CheckLiveProcess( "SunAutoUpdateTool.exe", dwProcID) ||
|
|
CheckLiveProcess( "SunAutoUpdateTool_d.exe", dwProcID) )
|
|
{
|
|
ack.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_RUNNING;
|
|
MSGOUT( "업데이트툴이 실행중입니다." );
|
|
pSession->SendPacket( &ack, sizeof(ack) );
|
|
return;
|
|
}
|
|
|
|
// 툴 실행.
|
|
TCHAR pszPath[MAX_PATH];
|
|
std::string strPath = AgentInfoParser::Instance()->GetToolPath();
|
|
_snprintf( pszPath, MAX_PATH, "%s <RTTA> <%d> <%d> <%d> <%d>", strPath.c_str(),
|
|
0, 0, pRecvMsg->m_ServerInfo.m_byServerType, pRecvMsg->m_dwUserKey );
|
|
|
|
if( _access( strPath.c_str(), 0 ) != -1 )
|
|
{
|
|
if( WinExec( pszPath, SW_SHOW ) > 31 )
|
|
{
|
|
ack.m_byResult = RC_SERVER_PATCH_EXECUTE_SUCCESS;
|
|
MSGOUT( "업데이트툴 실행 성공" );
|
|
}
|
|
else
|
|
{
|
|
ack.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL;
|
|
MSGOUT( "업데이트툴 실행 실패. 경로 = %s", pszPath );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ack.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_NOT_EXIST;
|
|
MSGOUT( "업데이트툴이 존재하지 않습니다. 경로 = %s", pszPath );
|
|
}
|
|
|
|
pSession->SendPacket( &ack, sizeof(ack));
|
|
}
|
|
#endif
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef _NA_006543_20130318_HEARTBEAT
|
|
VOID Handler_SA::OnHandler_MSG_SA_CHECK_HEARTBEAT_ACK( UpdateServerSession* pSession, MSG_BASE* pMsg, int nSize )
|
|
{
|
|
//Update Agent에서 사용
|
|
MSG_SA_CHECK_HEARTBEAT msg;
|
|
|
|
pSession->SendPacket(&msg, sizeof(msg));
|
|
|
|
//DISPMSG("Recv/Send Heartbeat\n");
|
|
}
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#ifdef _NA_006662_20130423_SVNPATCH
|
|
VOID Handler_SA::_ProcessPatchUsingUpdateTool(UpdateServerSession *pSession, MSG_BASE *pMsg, int nSize)
|
|
{
|
|
MSG_SA_PATCH_EXECUTE_SYN *pRecvMsg = (MSG_SA_PATCH_EXECUTE_SYN*)pMsg;
|
|
|
|
MSG_SA_PATCH_EXECUTE_ACK AckMsg;
|
|
AckMsg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
memcpy( &AckMsg.m_ServerInfo, &pRecvMsg->m_ServerInfo, sizeof(SERVER_INFO) );
|
|
|
|
DWORD dwProcID = 0;
|
|
//패치툴이 살아 있으면..
|
|
if( CheckLiveProcess( "SunAutoUpdateTool.exe", dwProcID ) || CheckLiveProcess( "SunAutoUpdateTool_d.exe", dwProcID ) )
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_RUNNING;
|
|
MSGOUT( "업데이트툴이 실행중입니다." );
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
return;
|
|
}
|
|
|
|
// 업데이트 툴을 실행시킨다.
|
|
TCHAR pszPath[MAX_PATH];
|
|
std::string strPath = AgentInfoParser::Instance()->GetToolPath();
|
|
|
|
_snprintf( pszPath, MAX_PATH,
|
|
"%s <RTTA> <%d> <%d> <%d> <%d>",
|
|
strPath.c_str(),
|
|
pRecvMsg->m_ServerInfo.m_byWorld,
|
|
pRecvMsg->m_ServerInfo.m_byChannel,
|
|
pRecvMsg->m_ServerInfo.m_byServerType,
|
|
pRecvMsg->m_dwUserKey );
|
|
|
|
if( _access( strPath.c_str(), 0 ) != -1 ) //파일이 존재하면..
|
|
{
|
|
#ifdef __20080312__SOLARAUTH_SERVER_PATCH
|
|
PROCESS_INFORMATION pi;
|
|
STARTUPINFO si = {0, };
|
|
si.cb = sizeof(si);
|
|
|
|
std::string directory_path = strPath.substr(0, strPath.rfind('\\'));
|
|
|
|
if( CreateProcess( NULL, pszPath,
|
|
NULL, NULL, TRUE,
|
|
CREATE_NEW_CONSOLE,
|
|
NULL, directory_path.c_str(),
|
|
&si, &pi) )
|
|
{
|
|
MSGOUT( "서버실행 성공: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_SUCCESS;
|
|
}
|
|
#else
|
|
if( WinExec( strPath.c_str(), SW_SHOW ) > 31 ) //성공하면
|
|
{
|
|
MSGOUT( "서버실행 성공: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_SUCCESS;
|
|
}
|
|
#endif //__20080312__SOLARAUTH_SERVER_PATCH
|
|
else
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL;
|
|
MSGOUT( "업데이트툴 실행 실패. 경로 = %s", pszPath );
|
|
}
|
|
}
|
|
else //파일이 존재하지 않으면..
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_NOT_EXIST;
|
|
MSGOUT( "업데이트툴이 존재하지 않습니다. 경로 = %s", pszPath );
|
|
}
|
|
|
|
//패치 시작결과에 대해 알린다.
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
}
|
|
//----------------------------------------------------------------------------------------------------------
|
|
VOID Handler_SA::_ProcessPatchUsingBatchFile(UpdateServerSession *pSession, MSG_BASE *pMsg, int nSize)
|
|
{
|
|
MSG_SA_PATCH_EXECUTE_SYN *pRecvMsg = (MSG_SA_PATCH_EXECUTE_SYN*)pMsg;
|
|
|
|
MSG_SA_PATCH_EXECUTE_ACK AckMsg;
|
|
AckMsg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
memcpy( &AckMsg.m_ServerInfo, &pRecvMsg->m_ServerInfo, sizeof(SERVER_INFO) );
|
|
|
|
DWORD dwProcID = 0;
|
|
//패치툴이 살아 있으면..
|
|
if( CheckLiveProcess( "py.exe", dwProcID ) )
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_RUNNING;
|
|
MSGOUT( "업데이트툴이 실행중입니다." );
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
return;
|
|
}
|
|
|
|
// 배치파일을 실행시킨다.
|
|
TCHAR pszPath[MAX_PATH];
|
|
std::string strPath = AgentInfoParser::Instance()->GetToolPath();
|
|
|
|
_snprintf( pszPath, MAX_PATH,
|
|
"%s <RTTA> <%d> <%d> <%d> <%d>",
|
|
strPath.c_str(),
|
|
pRecvMsg->m_ServerInfo.m_byWorld,
|
|
pRecvMsg->m_ServerInfo.m_byChannel,
|
|
pRecvMsg->m_ServerInfo.m_byServerType,
|
|
pRecvMsg->m_dwUserKey );
|
|
|
|
if( _access( strPath.c_str(), 0 ) != -1 ) //파일이 존재하면..
|
|
{
|
|
if(ShellExecute(NULL,"open", strPath.c_str(), NULL, NULL, SW_SHOW))
|
|
{
|
|
MSGOUT( "bat파일 실행 성공: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_SUCCESS;
|
|
|
|
SunUpdateAgent::Instance()->SetPatchingSVNmode(TRUE);
|
|
SunUpdateAgent::Instance()->SetPatchingUserKey(pRecvMsg->m_dwUserKey);
|
|
}
|
|
else
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL;
|
|
MSGOUT( "bat파일 실행 실패. 경로 = %s", pszPath );
|
|
}
|
|
}
|
|
else //파일이 존재하지 않으면..
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_NOT_EXIST;
|
|
MSGOUT( "batfile이 존재하지 않습니다. 경로 = %s", pszPath );
|
|
}
|
|
|
|
//패치 시작결과에 대해 알린다.
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
|
|
#ifdef _NA_006662_20130423_SVNPATCH
|
|
#else
|
|
MSG_SA_PATCH_RESULT_NTF msg;
|
|
msg.m_dwResult = MSG_MO_RTTG_PATCHRESULT_ANS::ERROR_PATCHSUCCESS;
|
|
msg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
msg.m_byNum = 0;
|
|
msg.m_byServerType = SUN_SERVER;
|
|
msg.m_PatchVer.m_byVer1 = 0;
|
|
msg.m_PatchVer.m_byVer2 = 0;
|
|
msg.m_PatchVer.m_byVer3 = 0;
|
|
|
|
SunUpdateAgent::Instance()->SendToUpdateServer( &msg, sizeof(msg) );
|
|
#endif //_NA_006662_20130423_SVNPATCH
|
|
}
|
|
#else //_NA_006662_20130423_SVNPATCH----------------------------------------------------------------------
|
|
// 패치 실행
|
|
VOID Handler_SA::OnHandler_MSG_SA_PATCH_EXECUTE_SYN( UpdateServerSession *pSession, MSG_BASE *pMsg, int nSize )
|
|
{
|
|
MSG_SA_PATCH_EXECUTE_SYN *pRecvMsg = (MSG_SA_PATCH_EXECUTE_SYN*)pMsg;
|
|
|
|
MSG_SA_PATCH_EXECUTE_ACK AckMsg;
|
|
AckMsg.m_dwUserKey = pRecvMsg->m_dwUserKey;
|
|
memcpy( &AckMsg.m_ServerInfo, &pRecvMsg->m_ServerInfo, sizeof(SERVER_INFO) );
|
|
|
|
DWORD dwProcID = 0;
|
|
//패치툴이 살아 있으면..
|
|
if( CheckLiveProcess( "SunAutoUpdateTool.exe", dwProcID ) || CheckLiveProcess( "SunAutoUpdateTool_d.exe", dwProcID ) )
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_RUNNING;
|
|
MSGOUT( "업데이트툴이 실행중입니다." );
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
return;
|
|
}
|
|
|
|
// 업데이트 툴을 실행시킨다.
|
|
TCHAR pszPath[MAX_PATH];
|
|
std::string strPath = AgentInfoParser::Instance()->GetToolPath();
|
|
|
|
_snprintf( pszPath, MAX_PATH,
|
|
"%s <RTTA> <%d> <%d> <%d> <%d>",
|
|
strPath.c_str(),
|
|
pRecvMsg->m_ServerInfo.m_byWorld,
|
|
pRecvMsg->m_ServerInfo.m_byChannel,
|
|
pRecvMsg->m_ServerInfo.m_byServerType,
|
|
pRecvMsg->m_dwUserKey );
|
|
|
|
if( _access( strPath.c_str(), 0 ) != -1 ) //파일이 존재하면..
|
|
{
|
|
#ifdef __20080312__SOLARAUTH_SERVER_PATCH
|
|
PROCESS_INFORMATION pi;
|
|
STARTUPINFO si = {0, };
|
|
si.cb = sizeof(si);
|
|
|
|
std::string directory_path = strPath.substr(0, strPath.rfind('\\'));
|
|
|
|
if( CreateProcess( NULL, pszPath,
|
|
NULL, NULL, TRUE,
|
|
CREATE_NEW_CONSOLE,
|
|
NULL, directory_path.c_str(),
|
|
&si, &pi) )
|
|
{
|
|
MSGOUT( "서버실행 성공: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_SUCCESS;
|
|
}
|
|
#else
|
|
if( WinExec( strPath.c_str(), SW_SHOW ) > 31 ) //성공하면
|
|
{
|
|
MSGOUT( "서버실행 성공: %s", strPath.c_str() );
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_SUCCESS;
|
|
}
|
|
#endif //__20080312__SOLARAUTH_SERVER_PATCH
|
|
else
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL;
|
|
MSGOUT( "업데이트툴 실행 실패. 경로 = %s", pszPath );
|
|
}
|
|
}
|
|
else //파일이 존재하지 않으면..
|
|
{
|
|
AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATETOOL_NOT_EXIST;
|
|
MSGOUT( "업데이트툴이 존재하지 않습니다. 경로 = %s", pszPath );
|
|
}
|
|
|
|
//패치 시작결과에 대해 알린다.
|
|
pSession->SendPacket( &AckMsg, sizeof(AckMsg) );
|
|
}
|
|
#endif //_NA_006662_20130423_SVNPATCH
|