Files
2022-10-26 12:25:11 +08:00

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