Initial commit: ROW Client source code
Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
750
Tools/PatchSFX/PatchSFXDlg.cpp
Normal file
750
Tools/PatchSFX/PatchSFXDlg.cpp
Normal file
@@ -0,0 +1,750 @@
|
||||
// PatchSFXDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "PatchSFX.h"
|
||||
#include "PatchSFXDlg.h"
|
||||
|
||||
#include "ZipArchive.h"
|
||||
#include "ZipStorage.h"
|
||||
|
||||
#include "atlenc.h"
|
||||
#include <process.h>
|
||||
#include ".\patchsfxdlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
|
||||
// CPatchSFXDlg dialog
|
||||
|
||||
UINT IID_PROGRESS_EXTRACT_SFXFILES = 1;
|
||||
UINT PROGRESS_UPDATE_TIME = 200;
|
||||
|
||||
void GetCurrentFolderName(CString& szCurrentFolderName)
|
||||
{
|
||||
TCHAR szFullPathName[MAX_PATH * 2];
|
||||
GetModuleFileName(NULL, szFullPathName, MAX_PATH * 2 - 1);
|
||||
szFullPathName[MAX_PATH * 2 - 1] = 0;
|
||||
|
||||
TCHAR szDrive[MAX_PATH];
|
||||
TCHAR szDirectory[MAX_PATH];
|
||||
|
||||
_tsplitpath(szFullPathName, szDrive, szDirectory, 0, 0);
|
||||
szCurrentFolderName.Format("%s%s", szDrive, szDirectory);
|
||||
}
|
||||
|
||||
CPatchSFXDlg::CPatchSFXDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CPatchSFXDlg::IDD, pParent)
|
||||
, m_szFileProgress(_T("0/0"))
|
||||
, m_szPatchFileName(_T(""))
|
||||
, m_szInstalledPathKey(_T(""))
|
||||
, m_szRegKeyValue(_T(""))
|
||||
, m_dwTotalFileSize(0LL)
|
||||
, m_dwMinver(0L)
|
||||
, m_dwMaxver(0L)
|
||||
, m_nTotalFileNum(0)
|
||||
, m_hExtractThread(0)
|
||||
, m_nExtractThreadID(0)
|
||||
, m_szCurrentExtract(_T(""))
|
||||
{
|
||||
m_SharedData.InitSharedData();
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
DDX_Control(pDX, IDC_EXTRACT_POS, m_edExtractPos);
|
||||
DDX_Control(pDX, IDC_EXTRACT_PROGRESS, m_prgExtract);
|
||||
DDX_Control(pDX, IDC_BTN_PATCH_NOW, m_btnPatchNow);
|
||||
DDX_Control(pDX, IDC_BTN_PATCH_LIST, m_btnPatchAdvanced);
|
||||
DDX_Control(pDX, IDC_CONSOLE, m_edLog);
|
||||
DDX_Text(pDX, IDC_PROGRESS_FILE, m_szFileProgress);
|
||||
DDX_Text(pDX, IDC_CURRENT_EXTRACT, m_szCurrentExtract);
|
||||
DDX_Control(pDX, IDC_BTN_EXTRACT_TO, m_btnExtractPos);
|
||||
DDX_Control(pDX, IDC_PATCH_DONE, m_btnPatchDone);
|
||||
DDX_Control(pDX, IDCANCEL, m_btnPatchCancel);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CPatchSFXDlg, CDialog)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_TIMER()
|
||||
ON_WM_CLOSE()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
|
||||
ON_BN_CLICKED(IDC_BTN_EXTRACT_TO, OnBnClickedBtnExtractTo)
|
||||
ON_BN_CLICKED(IDC_BTN_PATCH_NOW, OnBnClickedBtnPatchNow)
|
||||
ON_BN_CLICKED(IDC_BTN_PATCH_LIST, OnBnClickedBtnPatchList)
|
||||
|
||||
ON_BN_CLICKED(IDC_PATCH_DONE, OnBnClickedPatchDone)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
// CPatchSFXDlg message handlers
|
||||
|
||||
BOOL CPatchSFXDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// Set the icon for this dialog. The framework does this automatically
|
||||
// when the application's main window is not a dialog
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
|
||||
m_edLog.SetLimitText(UINT_MAX);
|
||||
|
||||
// <20>ڱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD>.
|
||||
|
||||
CZipArchive zipFile;
|
||||
CString szError;
|
||||
|
||||
TCHAR szBuff[MAX_PATH * 2];
|
||||
if (!GetModuleFileName(NULL, szBuff, MAX_PATH * 2))
|
||||
{
|
||||
szError.Format(_T("Unable to find patch file : code(%d)"), GetLastError());
|
||||
MessageBox(szError, _T("Patch error"), MB_OK | MB_ICONERROR);
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
szBuff[MAX_PATH * 2 - 1] = (TCHAR)0;
|
||||
m_szPatchFileName.SetString(szBuff);
|
||||
}
|
||||
|
||||
TRY
|
||||
{
|
||||
zipFile.Open(m_szPatchFileName, CZipArchive::zipOpenReadOnly);
|
||||
CZipString szComment = zipFile.GetGlobalComment();
|
||||
m_nTotalFileNum = zipFile.GetCount(true);
|
||||
zipFile.Close();
|
||||
|
||||
int nDecodeBufferLen = Base64DecodeGetRequiredLength(szComment.GetLength());
|
||||
int nDecodedDataLen = nDecodeBufferLen;
|
||||
LPBYTE lpData = (LPBYTE) malloc(sizeof(BYTE) * nDecodeBufferLen);
|
||||
|
||||
if (!Base64Decode(szComment.GetString(), szComment.GetLength(), lpData, &nDecodedDataLen))
|
||||
{
|
||||
free(lpData);
|
||||
|
||||
szError.Format(_T("Unable to decode patch header : code(%d)"), GetLastError());
|
||||
MessageBox(szError, _T("Patch error"), MB_OK | MB_ICONERROR);
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMemFile srcData(lpData, nDecodeBufferLen);
|
||||
|
||||
srcData.Read(&m_dwTotalFileSize, sizeof(m_dwTotalFileSize));
|
||||
srcData.Read(&m_dwMinver, sizeof(m_dwMinver));
|
||||
srcData.Read(&m_dwMaxver, sizeof(m_dwMaxver));
|
||||
|
||||
int nInstalledPathLen = 0;
|
||||
int nValueNameLen = 0;
|
||||
|
||||
TCHAR szInstalledPathKey[MAX_PATH];
|
||||
TCHAR szRegKeyValue[MAX_PATH];
|
||||
|
||||
srcData.Read(&nInstalledPathLen, sizeof(nInstalledPathLen));
|
||||
srcData.Read(&nValueNameLen, sizeof(nValueNameLen));
|
||||
|
||||
srcData.Read(szInstalledPathKey, sizeof(TCHAR) * nInstalledPathLen);
|
||||
m_szInstalledPathKey.SetString(szInstalledPathKey, nInstalledPathLen);
|
||||
|
||||
srcData.Read(szRegKeyValue, sizeof(TCHAR) * nValueNameLen);
|
||||
m_szRegKeyValue.SetString(szRegKeyValue, nValueNameLen);
|
||||
}
|
||||
}
|
||||
CATCH_ALL(e)
|
||||
{
|
||||
DWORD dwError = GetLastError();
|
||||
|
||||
if (e->IsKindOf(RUNTIME_CLASS(CZipException)))
|
||||
{
|
||||
szError.Format(_T("Read Patch Header From Archive Error : code(%d)"), dwError);
|
||||
}
|
||||
else
|
||||
{
|
||||
szError.Format(_T("Invalid Patch Header : code(%d)"), dwError);
|
||||
}
|
||||
|
||||
MessageBox(szError, _T("Patch error"), MB_OK | MB_ICONERROR);
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
END_CATCH_ALL;
|
||||
|
||||
|
||||
CRegKey regKey;
|
||||
TCHAR szInstalledBuffer[MAX_PATH * 2];
|
||||
ULONG nBufferSize = MAX_PATH * 2 - 1;
|
||||
|
||||
if (ERROR_SUCCESS == regKey.Open(HKEY_LOCAL_MACHINE, m_szInstalledPathKey, KEY_READ) &&
|
||||
ERROR_SUCCESS == regKey.QueryStringValue(m_szRegKeyValue, szInstalledBuffer, &nBufferSize))
|
||||
{
|
||||
szInstalledBuffer[MAX_PATH * 2 - 1] = (TCHAR)0;
|
||||
|
||||
CString szInstalledPath(szInstalledBuffer);
|
||||
szInstalledPath.Trim();
|
||||
|
||||
int nLength = szInstalledPath.GetLength();
|
||||
if (1 < nLength && szInstalledPath.GetString()[nLength - 1] != _T('\\'))
|
||||
{
|
||||
szInstalledPath.Append(_T("\\"));
|
||||
}
|
||||
|
||||
m_edExtractPos.SetWindowText(szInstalledPath);
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
|
||||
CString szWindowTitle;
|
||||
/*
|
||||
if (m_dwMaxver < 1000)
|
||||
{
|
||||
szWindowTitle.Format(_T("RYL Part1 Patch (version %d to %d)"),
|
||||
m_dwMinver + 100, m_dwMaxver + 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
szWindowTitle.Format(_T("RYL Part2 Patch (version %d to %d)"),
|
||||
m_dwMinver, m_dwMaxver);
|
||||
}
|
||||
*/
|
||||
szWindowTitle.Format(_T("Return of Warrior Patch (version %d to %d)"),
|
||||
m_dwMinver, m_dwMaxver);
|
||||
|
||||
SetWindowText(szWindowTitle);
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
}
|
||||
|
||||
// If you add a minimize button to your dialog, you will need the code below
|
||||
// to draw the icon. For MFC applications using the document/view model,
|
||||
// this is automatically done for you by the framework.
|
||||
|
||||
void CPatchSFXDlg::OnPaint()
|
||||
{
|
||||
if (IsIconic())
|
||||
{
|
||||
CPaintDC dc(this); // device context for painting
|
||||
|
||||
SendMessage(WM_ICONERASEBKGND,
|
||||
reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
|
||||
|
||||
// Center icon in client rectangle
|
||||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
||||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
int x = (rect.Width() - cxIcon + 1) / 2;
|
||||
int y = (rect.Height() - cyIcon + 1) / 2;
|
||||
|
||||
// Draw the icon
|
||||
dc.DrawIcon(x, y, m_hIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnPaint();
|
||||
}
|
||||
}
|
||||
|
||||
// The system calls this function to obtain the cursor to display while the user drags
|
||||
// the minimized window.
|
||||
HCURSOR CPatchSFXDlg::OnQueryDragIcon()
|
||||
{
|
||||
return static_cast<HCURSOR>(m_hIcon);
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::OnBnClickedBtnExtractTo()
|
||||
{
|
||||
CString szFolderName;
|
||||
|
||||
BROWSEINFO brInfo;
|
||||
memset(&brInfo, 0, sizeof(BROWSEINFO));
|
||||
|
||||
TCHAR szTemp[MAX_PATH * 2];
|
||||
|
||||
brInfo.hwndOwner = GetSafeHwnd();
|
||||
brInfo.pidlRoot = NULL;
|
||||
brInfo.pszDisplayName = szTemp;
|
||||
brInfo.lpszTitle = _T("Select patch extract folder");
|
||||
brInfo.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
|
||||
|
||||
LPITEMIDLIST lpItemIDList = SHBrowseForFolder(&brInfo);
|
||||
if (NULL != lpItemIDList && SHGetPathFromIDList(lpItemIDList, szTemp))
|
||||
{
|
||||
szTemp[MAX_PATH * 2 - 1] = (TCHAR)0;
|
||||
szFolderName.SetString(szTemp);
|
||||
szFolderName.Trim();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̹Ƿ<CCB9>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD> <20>ش<EFBFBD>.
|
||||
int nLength = szFolderName.GetLength();
|
||||
if (1 < nLength && _T('\\') != szFolderName.GetString()[nLength - 1])
|
||||
{
|
||||
szFolderName.Append(_T("\\"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!szFolderName.IsEmpty())
|
||||
{
|
||||
m_edExtractPos.SetWindowText(szFolderName);
|
||||
|
||||
m_btnPatchDone.ShowWindow(SW_HIDE);
|
||||
m_btnPatchNow.ShowWindow(SW_SHOW);
|
||||
m_btnPatchCancel.ShowWindow(SW_SHOW);
|
||||
|
||||
UpdateData(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct ExtractWorkerData
|
||||
{
|
||||
CPatchSFXDlg* m_lpDlg;
|
||||
CString m_szExtractPos;
|
||||
DWORD m_dwMinver;
|
||||
DWORD m_dwMaxver;
|
||||
};
|
||||
|
||||
|
||||
unsigned __stdcall CPatchSFXDlg::ExtractWorker(void *pArg)
|
||||
{
|
||||
ExtractWorkerData* lpWorkerData =
|
||||
reinterpret_cast<ExtractWorkerData*>(pArg);
|
||||
|
||||
CPatchSFXDlg* lpDlg = lpWorkerData->m_lpDlg;
|
||||
|
||||
SharedData sharedData;
|
||||
|
||||
TCHAR szFileName[MAX_PATH * 2];
|
||||
GetModuleFileName(NULL, szFileName, MAX_PATH * 2);
|
||||
szFileName[MAX_PATH * 2 - 1] = 0;
|
||||
|
||||
CZipArchive zipFile;
|
||||
CZipFileHeader fhInfo;
|
||||
|
||||
CString szError;
|
||||
|
||||
const int MAX_ERROR_LEN = 256;
|
||||
TCHAR szErrorMsg[MAX_ERROR_LEN];
|
||||
|
||||
bool bFailedExtract = false;
|
||||
|
||||
TRY
|
||||
{
|
||||
zipFile.Open(szFileName, CZipArchive::zipOpenReadOnly);
|
||||
int nTotalFileNum = zipFile.GetCount();
|
||||
zipFile.SetRootPath(lpWorkerData->m_szExtractPos);
|
||||
|
||||
for (; !sharedData.m_bStopWorkerThread && sharedData.m_nCurrentFiles < nTotalFileNum;
|
||||
++sharedData.m_nCurrentFiles)
|
||||
{
|
||||
if (!zipFile.GetFileInfo(fhInfo, sharedData.m_nCurrentFiles))
|
||||
{
|
||||
szError.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
|
||||
szError.AppendFormat(_T("Get fileinfo failed : index(%d)"),
|
||||
sharedData.m_nCurrentFiles);
|
||||
|
||||
sharedData.m_ProgressList.AddTail(szError);
|
||||
|
||||
bFailedExtract = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sharedData.m_szCurrentExtract.SetString(
|
||||
zipFile.PredictExtractedFileName(fhInfo.GetFileName(),
|
||||
lpWorkerData->m_szExtractPos, true));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ӽ<EFBFBD><D3BC><EFBFBD> Normal<61><6C>
|
||||
SetFileAttributes(sharedData.m_szCurrentExtract,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE);
|
||||
|
||||
lpDlg->UpdateProgress(sharedData);
|
||||
|
||||
if (!zipFile.ExtractFile(sharedData.m_nCurrentFiles, lpWorkerData->m_szExtractPos))
|
||||
{
|
||||
szError.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
|
||||
szError.AppendFormat(_T("Extract file failed! : %s%s"),
|
||||
lpWorkerData->m_szExtractPos, fhInfo.GetFileName());
|
||||
|
||||
sharedData.m_ProgressList.AddTail(szError);
|
||||
|
||||
bFailedExtract = true;
|
||||
}
|
||||
|
||||
sharedData.m_nCurrentDataSize += fhInfo.m_uUncomprSize;
|
||||
}
|
||||
|
||||
lpDlg->UpdateProgress(sharedData);
|
||||
}
|
||||
|
||||
szError.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
|
||||
|
||||
if (sharedData.m_bStopWorkerThread)
|
||||
{
|
||||
szError.AppendFormat(_T("Canceled extract patch."));
|
||||
}
|
||||
else if (bFailedExtract)
|
||||
{
|
||||
szError.AppendFormat(_T("Failed to extract patch."));
|
||||
}
|
||||
else
|
||||
{
|
||||
CString szVersionInfoFileName;
|
||||
CString szCurrentVersion;
|
||||
|
||||
szVersionInfoFileName.Format(_T("%sVersionInfo.dat"),
|
||||
lpWorkerData->m_szExtractPos);
|
||||
|
||||
szCurrentVersion.Format(_T("%d"), lpWorkerData->m_dwMaxver);
|
||||
|
||||
CStdioFile file;
|
||||
if (!file.Open(szVersionInfoFileName,
|
||||
CFile::modeCreate | CFile::modeWrite | CFile::typeText))
|
||||
{
|
||||
szError.AppendFormat(_T("Failed to write version info!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
file.WriteString(szCurrentVersion);
|
||||
szError.AppendFormat(_T("Patch Complete! : %s"), lpWorkerData->m_szExtractPos);
|
||||
}
|
||||
}
|
||||
|
||||
sharedData.m_ProgressList.AddTail(szError);
|
||||
zipFile.Close();
|
||||
}
|
||||
CATCH_ALL(e)
|
||||
{
|
||||
e->GetErrorMessage(szErrorMsg, MAX_ERROR_LEN - 1);
|
||||
szErrorMsg[MAX_ERROR_LEN - 1] = 0;
|
||||
|
||||
if (e->IsKindOf(RUNTIME_CLASS(CZipException)))
|
||||
{
|
||||
szError.Format(_T("Extract failed : zipArchive error! (%s)"), szErrorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
szError.Format(_T("Extract failed : unknown error! (%s)"), szErrorMsg);
|
||||
}
|
||||
|
||||
sharedData.m_ProgressList.AddTail(szError);
|
||||
}
|
||||
END_CATCH_ALL;
|
||||
|
||||
delete lpWorkerData;
|
||||
lpDlg->UpdateProgress(sharedData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::UpdateProgress(SharedData& sharedData)
|
||||
{
|
||||
m_csProgress.Lock();
|
||||
|
||||
sharedData.m_bStopWorkerThread = m_SharedData.m_bStopWorkerThread;
|
||||
|
||||
m_SharedData.m_nCurrentFiles = sharedData.m_nCurrentFiles;
|
||||
m_SharedData.m_nCurrentDataSize = sharedData.m_nCurrentDataSize;
|
||||
m_SharedData.m_szCurrentExtract = sharedData.m_szCurrentExtract;
|
||||
|
||||
m_SharedData.m_ProgressList.AddTail(&sharedData.m_ProgressList);
|
||||
|
||||
m_csProgress.Unlock();
|
||||
|
||||
sharedData.m_ProgressList.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
afx_msg void CPatchSFXDlg::OnTimer(UINT_PTR nIDEvent)
|
||||
{
|
||||
if (nIDEvent == IID_PROGRESS_EXTRACT_SFXFILES)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>尡 <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
|
||||
int nLower = 0;
|
||||
int nUpper = 0;
|
||||
m_prgExtract.GetRange(nLower, nUpper);
|
||||
|
||||
int nCurrentPos = m_prgExtract.GetPos();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD>
|
||||
m_csProgress.Lock();
|
||||
|
||||
if (nUpper != static_cast<int>(m_dwTotalFileSize))
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲ<EFBFBD><D9B2><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
m_prgExtract.SetRange32(0, static_cast<int>(m_dwTotalFileSize));
|
||||
}
|
||||
|
||||
if (nCurrentPos != m_SharedData.m_nCurrentDataSize)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD>
|
||||
m_prgExtract.SetPos(m_SharedData.m_nCurrentDataSize);
|
||||
}
|
||||
|
||||
m_szCurrentExtract.SetString(m_SharedData.m_szCurrentExtract);
|
||||
|
||||
m_szFileProgress.Format(_T("%d/%d"),
|
||||
m_SharedData.m_nCurrentFiles, m_nTotalFileNum);
|
||||
|
||||
// <20>α<EFBFBD> <20><EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> ȭ<>鿡 <20>Ѹ<EFBFBD><D1B8><EFBFBD>.
|
||||
POSITION pos = m_SharedData.m_ProgressList.GetHeadPosition();
|
||||
while(0 != pos) { m_edLog.AddLine(m_SharedData.m_ProgressList.GetNext(pos)); }
|
||||
m_SharedData.m_ProgressList.RemoveAll();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
m_csProgress.Unlock();
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hExtractThread, 0))
|
||||
{
|
||||
StopWorker();
|
||||
|
||||
if (!m_PatchFolderList.IsEmpty())
|
||||
{
|
||||
m_edExtractPos.SetWindowText(m_PatchFolderList.RemoveHead());
|
||||
UpdateData(FALSE);
|
||||
|
||||
// <20><>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><>ġ<EFBFBD><C4A1> <20>Ѵ<EFBFBD>..
|
||||
PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BTN_PATCH_NOW, BN_CLICKED));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_btnPatchDone.ShowWindow(SW_SHOW);
|
||||
m_btnPatchNow.ShowWindow(SW_HIDE);
|
||||
m_btnPatchCancel.ShowWindow(SW_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CPatchSFXDlg::CheckExtractPosVersion()
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> VersionInfo.dat<61><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ֳ<EFBFBD> <20><><EFBFBD>캻 <20>ڿ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ּҹ<D6BC><D2B9><EFBFBD> / <20>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ɴ<EFBFBD>.
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD≯<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><> <20><><EFBFBD><EFBFBD><EEBABB>.
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
CString szError;
|
||||
CString szVersion;
|
||||
CString szExtractPos;
|
||||
CString szVersionInfoFileName;
|
||||
|
||||
m_edExtractPos.GetWindowText(szExtractPos);
|
||||
szVersionInfoFileName.Format(_T("%sVersionInfo.dat"), szExtractPos);
|
||||
|
||||
CStdioFile file;
|
||||
if (file.Open(szVersionInfoFileName, CFile::modeRead | CFile::typeText))
|
||||
{
|
||||
file.ReadString(szVersion);
|
||||
|
||||
DWORD dwVersion = _ttol(szVersion);
|
||||
|
||||
if (dwVersion < m_dwMinver)
|
||||
{
|
||||
MessageBox(_T("Current version is too low, try other patch first"),
|
||||
_T("Patch error"), MB_OK | MB_ICONERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (m_dwMaxver < dwVersion &&
|
||||
IDNO == MessageBox(_T("Current version is higher than this patch version. Overwrite it?"),
|
||||
_T("Question"), MB_YESNO | MB_ICONEXCLAMATION))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::OnBnClickedBtnPatchNow()
|
||||
{
|
||||
// TODO: <20><><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20>˸<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>ڵ带 <20>߰<EFBFBD><DFB0>մϴ<D5B4>.
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
CString szError;
|
||||
CString szPatchFolder;
|
||||
bool bFailedAndCleanup = true;
|
||||
|
||||
ExtractWorkerData* lpWorkerData = new ExtractWorkerData;
|
||||
|
||||
if (0 != lpWorkerData)
|
||||
{
|
||||
m_edExtractPos.GetWindowText(szPatchFolder);
|
||||
|
||||
lpWorkerData->m_lpDlg = this;
|
||||
lpWorkerData->m_dwMinver = m_dwMinver;
|
||||
lpWorkerData->m_dwMaxver = m_dwMaxver;
|
||||
lpWorkerData->m_szExtractPos.SetString(szPatchFolder);
|
||||
|
||||
if (0 != m_hExtractThread)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>尡 <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> <20><>ư<EFBFBD><C6B0> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>þ<EFBFBD><C3BE>ݽô<DDBD>.
|
||||
}
|
||||
else if (lpWorkerData->m_szExtractPos.IsEmpty())
|
||||
{
|
||||
MessageBox(_T("Invalid Extract Position. Please set extract position"),
|
||||
_T("Patch Error"), MB_OK | MB_ICONERROR);
|
||||
PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BTN_EXTRACT_TO, BN_CLICKED));
|
||||
}
|
||||
else if (CheckExtractPosVersion())
|
||||
{
|
||||
m_hExtractThread = reinterpret_cast<HANDLE>(
|
||||
_beginthreadex(0, 0, ExtractWorker, lpWorkerData, 0, &m_nExtractThreadID));
|
||||
|
||||
if (0 == m_hExtractThread)
|
||||
{
|
||||
szError.Format(_T("Create extract thread failed : code(%d)"), GetLastError());
|
||||
MessageBox(szError, _T("Patch Error"), MB_OK | MB_ICONERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
bFailedAndCleanup = false;
|
||||
|
||||
// ȭ<><C8AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> Ÿ<≯Ӹ<CCB8> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
SetTimer(IID_PROGRESS_EXTRACT_SFXFILES, PROGRESS_UPDATE_TIME, NULL);
|
||||
|
||||
// <20><>ġ <20><>ư<EFBFBD><C6B0> <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
m_btnPatchNow.EnableWindow(FALSE);
|
||||
m_btnPatchAdvanced.EnableWindow(FALSE);
|
||||
m_btnExtractPos.EnableWindow(FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bFailedAndCleanup)
|
||||
{
|
||||
delete lpWorkerData;
|
||||
}
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::StopWorker()
|
||||
{
|
||||
if (0 != m_hExtractThread)
|
||||
{
|
||||
m_csProgress.Lock();
|
||||
m_SharedData.m_bStopWorkerThread = TRUE;
|
||||
m_csProgress.Unlock();
|
||||
|
||||
WaitForSingleObject(m_hExtractThread, INFINITE);
|
||||
|
||||
KillTimer(IID_PROGRESS_EXTRACT_SFXFILES);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>尡 <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD>.
|
||||
CloseHandle(m_hExtractThread);
|
||||
m_hExtractThread = 0;
|
||||
m_nExtractThreadID = 0;
|
||||
m_SharedData.InitSharedData();
|
||||
|
||||
m_btnPatchNow.EnableWindow(TRUE);
|
||||
m_btnPatchAdvanced.EnableWindow(TRUE);
|
||||
m_btnExtractPos.EnableWindow(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::OnClose()
|
||||
{
|
||||
// TODO: <20><><EFBFBD> <20><EFBFBD><DEBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>ڵ带 <20>߰<EFBFBD> <20><>/<2F>Ǵ<EFBFBD> <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD> ȣ<><C8A3><EFBFBD>մϴ<D5B4>.
|
||||
m_PatchFolderList.RemoveAll();
|
||||
|
||||
StopWorker();
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::OnBnClickedBtnPatchList()
|
||||
{
|
||||
// TODO: <20><><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20>˸<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>ڵ带 <20>߰<EFBFBD><DFB0>մϴ<D5B4>.
|
||||
|
||||
// <20><>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<>Ƽ<EFBFBD> <20>д´<D0B4>.
|
||||
// <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>д´<D0B4>.
|
||||
|
||||
// ù<><C3B9>° <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
// <20><>ġ <20><>ư<EFBFBD><C6B0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
|
||||
CString szLog;
|
||||
CString szPatchFolder;
|
||||
CString szFolderListFile;
|
||||
GetCurrentFolderName(szFolderListFile);
|
||||
|
||||
szFolderListFile.AppendFormat(_T("PatchFolders.ini"));
|
||||
|
||||
CStdioFile folderList;
|
||||
|
||||
if (folderList.Open(szFolderListFile,
|
||||
CFile::modeCreate | CFile::modeNoTruncate | CFile::modeRead | CFile::shareDenyNone | CFile::typeText))
|
||||
{
|
||||
while(folderList.ReadString(szPatchFolder))
|
||||
{
|
||||
szPatchFolder.Trim();
|
||||
szPatchFolder.Replace(_T('/'), _T('\\'));
|
||||
|
||||
int nLength = szPatchFolder.GetLength();
|
||||
if (1 < nLength && szPatchFolder.GetString()[nLength - 1] != _T('\\'))
|
||||
{
|
||||
szPatchFolder.Append(_T("\\"));
|
||||
}
|
||||
|
||||
if (INVALID_FILE_ATTRIBUTES != GetFileAttributes(szPatchFolder))
|
||||
{
|
||||
m_PatchFolderList.AddTail(szPatchFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
szLog.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
|
||||
szLog.AppendFormat(_T("Invalid folder %s : Please write existing folder"),
|
||||
szPatchFolder);
|
||||
|
||||
m_edLog.AddLine(szLog);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_PatchFolderList.IsEmpty())
|
||||
{
|
||||
POSITION pos = m_PatchFolderList.GetHeadPosition();
|
||||
|
||||
while (0 != pos)
|
||||
{
|
||||
CString& szReadyPatchFolder = m_PatchFolderList.GetNext(pos);
|
||||
|
||||
szLog.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
|
||||
szLog.AppendFormat(_T("Ready to patch %s folder now!"), szReadyPatchFolder);
|
||||
|
||||
m_edLog.AddLine(szLog);
|
||||
}
|
||||
|
||||
m_btnPatchDone.ShowWindow(SW_HIDE);
|
||||
m_btnPatchNow.ShowWindow(SW_SHOW);
|
||||
m_btnPatchCancel.ShowWindow(SW_SHOW);
|
||||
|
||||
m_edExtractPos.SetWindowText(m_PatchFolderList.RemoveHead());
|
||||
UpdateData(FALSE);
|
||||
|
||||
// <20><>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><>ġ<EFBFBD><C4A1> <20>Ѵ<EFBFBD>..
|
||||
PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BTN_PATCH_NOW, BN_CLICKED));
|
||||
}
|
||||
else
|
||||
{
|
||||
szLog.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
|
||||
szLog.AppendFormat(_T("There is no folder list in %s file\nPlease edit contents"),
|
||||
szFolderListFile);
|
||||
MessageBox(szLog, "Patch Error", MB_OK | MB_ICONEXCLAMATION);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szLog.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
|
||||
szLog.AppendFormat(_T("Open %s file failed\nPlease edit contents"), szFolderListFile);
|
||||
MessageBox(szLog, "Patch Error", MB_OK | MB_ICONEXCLAMATION);
|
||||
}
|
||||
}
|
||||
|
||||
void CPatchSFXDlg::OnBnClickedPatchDone()
|
||||
{
|
||||
// TODO: <20><><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20>˸<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>ڵ带 <20>߰<EFBFBD><DFB0>մϴ<D5B4>.
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
Reference in New Issue
Block a user