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>
447 lines
13 KiB
C++
447 lines
13 KiB
C++
// SettingOptionPage.cpp : 구현 파일입니다.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "PatchMaker.h"
|
|
#include "SettingOptionPage.h"
|
|
|
|
#include "UtilityFunc.h"
|
|
#include "PMSettingConstant.h"
|
|
#include ".\settingoptionpage.h"
|
|
|
|
// CSettingOptionPage 대화 상자입니다.
|
|
|
|
IMPLEMENT_DYNAMIC(CSettingOptionPage, CPropertyPage)
|
|
CSettingOptionPage::CSettingOptionPage(CPMSetting& pmSetting, CPropertySheet& ownerSheet)
|
|
: CPropertyPage(CSettingOptionPage::IDD)
|
|
, m_dwManualPatchMinVer(100)
|
|
, m_OwnerSheet(ownerSheet)
|
|
, m_pmSettingOption(pmSetting)
|
|
{
|
|
|
|
}
|
|
|
|
CSettingOptionPage::~CSettingOptionPage()
|
|
{
|
|
|
|
}
|
|
|
|
void CSettingOptionPage::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CPropertyPage::DoDataExchange(pDX);
|
|
|
|
DDX_Control(pDX, IDC_CB_OPT_PATCH_TYPE, m_cbPatchType);
|
|
DDX_Control(pDX, IDC_ED_OPT_OLD_PKG, m_edOldPkgPos);
|
|
DDX_Control(pDX, IDC_ED_OPT_NEW_CLIENT, m_edNewClientPos);
|
|
DDX_Control(pDX, IDC_ED_OPT_NEW_PKG, m_edNewPkgPos);
|
|
DDX_Control(pDX, IDC_ED_OPT_MAX_PKG, m_edMaxPkgSize);
|
|
DDX_Control(pDX, IDC_CB_OPT_OLD_PKG_POS, m_cbPkgPos);
|
|
DDX_Control(pDX, IDC_ED_OPT_FTP_ADDR, m_edFTPAddr);
|
|
DDX_Control(pDX, IDC_ED_OPT_FTP_PORT, m_edFTPPort);
|
|
DDX_Control(pDX, IDC_CK_OPT_FTP_PASSIVE, m_bFTPPassive);
|
|
DDX_Control(pDX, IDC_ED_OPT_MANUAL_PATCH_FILE, m_edManualPatchFolder);
|
|
DDX_Control(pDX, IDC_ED_OPT_MANUAL_SFX_FILE, m_edManualPatchSFXFile);
|
|
DDX_Control(pDX, IDC_ED_OPT_MANUAL_MIN_VER, m_edManualPatchMinVer);
|
|
|
|
DDX_Text(pDX, IDC_ED_OPT_MANUAL_MIN_VER, m_dwManualPatchMinVer);
|
|
DDV_MinMaxUInt(pDX, m_dwManualPatchMinVer, 100, 10000);
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CSettingOptionPage, CPropertyPage)
|
|
|
|
ON_BN_CLICKED(IDC_BTN_OPT_OLD_PKG, OnBnClickedBtnOptOldPkg)
|
|
ON_BN_CLICKED(IDC_BTN_OPT_NEW_CLIENT, OnBnClickedBtnOptNewClient)
|
|
ON_BN_CLICKED(IDC_BTN_OPT_NEW_PKG, OnBnClickedBtnOptNewPkg)
|
|
ON_BN_CLICKED(IDC_BTN_OPT_MANUAL_PATCH_FILE, OnBnClickedBtnOptManualPatchFile)
|
|
ON_BN_CLICKED(IDC_BTN_OPT_MANUAL_SFX_FILE, OnBnClickedBtnOptManualSfxFile)
|
|
ON_BN_CLICKED(ID_SAVE_SETUP, OnBnClickedSaveSetup)
|
|
ON_BN_CLICKED(ID_LOAD_SETUP, OnBnClickedLoadSetup)
|
|
|
|
ON_REGISTERED_MESSAGE(PMConst::AP_SETTING_ENABLE, OnEnableAutoPatchOption)
|
|
ON_REGISTERED_MESSAGE(PMConst::AP_SETTING_DISABLE, OnDisableAutoPatchOption)
|
|
ON_REGISTERED_MESSAGE(PMConst::MP_SETTING_ENABLE, OnEnableManualPatchOption)
|
|
ON_REGISTERED_MESSAGE(PMConst::MP_SETTING_DISABLE, OnDisableManualPatchOption)
|
|
|
|
ON_CBN_SELCHANGE(IDC_CB_OPT_OLD_PKG_POS, OnCbnSelchangeCbOptOldPkgPos)
|
|
ON_WM_DESTROY()
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
// CSettingOptionPage 메시지 처리기입니다.
|
|
|
|
inline int AddCBString(CComboBox& combo, CString& tempString, int nIndex, UINT nID)
|
|
{
|
|
tempString.LoadString(nID);
|
|
return combo.InsertString(nIndex, tempString);
|
|
}
|
|
|
|
BOOL CSettingOptionPage::OnInitDialog()
|
|
{
|
|
CPropertyPage::OnInitDialog();
|
|
|
|
// TODO: 여기에 추가 초기화 작업을 추가합니다.
|
|
CString szTmp;
|
|
|
|
m_cbPatchType.InsertString(0, PMConst::PatchType_Part1);
|
|
m_cbPatchType.InsertString(1, PMConst::PatchType_BattleLohan);
|
|
m_cbPatchType.InsertString(2, PMConst::PatchType_Part2);
|
|
m_cbPatchType.InsertString(3, PMConst::PatchType_Part2Test);
|
|
m_cbPatchType.InsertString(4, PMConst::PatchType_Part2Malay);
|
|
|
|
AddCBString(m_cbPkgPos, szTmp, 0, IDS_CB_FTP);
|
|
AddCBString(m_cbPkgPos, szTmp, 1, IDS_CB_LOCAL);
|
|
|
|
OnCbnSelchangeCbOptOldPkgPos();
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// 예외: OCX 속성 페이지는 FALSE를 반환해야 합니다.
|
|
}
|
|
|
|
void CSettingOptionPage::OnBnClickedBtnOptOldPkg()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
PMUtil::BrowseForFolder(GetSafeHwnd(),
|
|
_T("예전 패키지가 있는 폴더를 선택해주세요"), m_edOldPkgPos);
|
|
}
|
|
|
|
void CSettingOptionPage::OnBnClickedBtnOptNewClient()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
PMUtil::BrowseForFolder(GetSafeHwnd(),
|
|
_T("깨끗한 클라이언트 파일이 있는 폴더를 선택해주세요"), m_edNewClientPos);
|
|
}
|
|
|
|
void CSettingOptionPage::OnBnClickedBtnOptNewPkg()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
PMUtil::BrowseForFolder(GetSafeHwnd(),
|
|
_T("새 패키지 파일이 저장될 루트 폴더를 선택해주세요"), m_edNewPkgPos);
|
|
}
|
|
|
|
void CSettingOptionPage::OnBnClickedBtnOptManualPatchFile()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
PMUtil::BrowseForFolder(GetSafeHwnd(),
|
|
_T("수동 패치 파일이 위치한 폴더를 선택해주세요"), m_edManualPatchFolder);
|
|
}
|
|
|
|
void CSettingOptionPage::OnBnClickedBtnOptManualSfxFile()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
CString szFileName;
|
|
if (PMUtil::BrowseForExisingFile(this->GetSafeHwnd(),
|
|
_T("수동 패치 SFX파일을 선택해주세요"), "SFX File\0*.exe", szFileName))
|
|
{
|
|
m_edManualPatchSFXFile.SetWindowText(szFileName);
|
|
}
|
|
}
|
|
|
|
|
|
void CSettingOptionPage::OnBnClickedSaveSetup()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
|
|
UpdateSetupData(TRUE);
|
|
|
|
if (!m_pmSettingOption.SaveSetting())
|
|
{
|
|
MessageBox(_T("셋업 파일을 저장하기 위해서 여는 데 실패했습니다"),
|
|
_T("파일 열기 오류"), MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
}
|
|
|
|
void CSettingOptionPage::OnBnClickedLoadSetup()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
if (m_pmSettingOption.LoadSetting())
|
|
{
|
|
UpdateSetupData(FALSE);
|
|
OnCbnSelchangeCbOptOldPkgPos();
|
|
}
|
|
else
|
|
{
|
|
MessageBox(_T("셋업 파일을 불러오기 위해서 여는 데 실패했습니다"),
|
|
_T("파일 열기 오류"), MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
}
|
|
|
|
void SetCBSel(CComboBox& cb, CString& szValue, int nDefaultSel = 0)
|
|
{
|
|
CString szCBValue;
|
|
int nMaxCount = cb.GetCount();
|
|
for (int nCount = 0; nCount < nMaxCount; ++nCount)
|
|
{
|
|
cb.GetLBText(nCount, szCBValue);
|
|
|
|
if (0 == szValue.CompareNoCase(szCBValue))
|
|
{
|
|
cb.SetCurSel(nCount);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (nCount == nMaxCount)
|
|
{
|
|
// 찾아봐서 맞는 문자열이 없으면 기본값으로 선택
|
|
cb.SetCurSel(nDefaultSel);
|
|
}
|
|
}
|
|
|
|
|
|
void CSettingOptionPage::UpdateSetupData(bool bSaveAndValidate)
|
|
{
|
|
CString szValue;
|
|
|
|
struct KeyValuePair
|
|
{
|
|
LPCTSTR m_szKey;
|
|
CEdit& m_edValue;
|
|
};
|
|
|
|
KeyValuePair keyValueData[] =
|
|
{
|
|
{ PMConst::AP_OldPkg, m_edOldPkgPos },
|
|
{ PMConst::AP_NewClient, m_edNewClientPos },
|
|
{ PMConst::AP_NewPkg, m_edNewPkgPos },
|
|
{ PMConst::AP_MaxPkg, m_edMaxPkgSize },
|
|
{ PMConst::AP_FTPAddr, m_edFTPAddr },
|
|
{ PMConst::AP_FTPPort, m_edFTPPort },
|
|
{ PMConst::MP_Folder, m_edManualPatchFolder },
|
|
{ PMConst::MP_SFXFile, m_edManualPatchSFXFile }
|
|
};
|
|
|
|
const int nMaxData = sizeof(keyValueData) / sizeof(KeyValuePair);
|
|
|
|
if (!bSaveAndValidate)
|
|
{
|
|
// 셋업 맵의 데이터를 컨트롤로 저장한다.
|
|
for (int nCount = 0; nCount < nMaxData; ++nCount)
|
|
{
|
|
m_pmSettingOption.GetSettingData(keyValueData[nCount].m_szKey, szValue);
|
|
keyValueData[nCount].m_edValue.SetWindowText(szValue);
|
|
}
|
|
|
|
m_pmSettingOption.GetSettingData(PMConst::PatchType, szValue);
|
|
SetCBSel(m_cbPatchType, szValue);
|
|
|
|
m_pmSettingOption.GetSettingData(PMConst::AP_PkgPosType, szValue);
|
|
SetCBSel(m_cbPkgPos, szValue);
|
|
|
|
m_pmSettingOption.GetSettingData(PMConst::AP_FTPPassive, szValue);
|
|
m_bFTPPassive.SetCheck(0 == szValue.CompareNoCase(_T("TRUE")) ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
m_pmSettingOption.GetSettingData(PMConst::MP_MinVer, szValue);
|
|
long nVersion = atol(szValue);
|
|
if (nVersion < 100) { nVersion = 100; }
|
|
m_dwManualPatchMinVer = nVersion;
|
|
|
|
// 컨트롤 데이터를 화면에 반영한다.
|
|
UpdateData(FALSE);
|
|
}
|
|
else
|
|
{
|
|
// 화면 데이터를 컨트롤에 읽어온다.
|
|
UpdateData(TRUE);
|
|
|
|
// 컨트롤의 데이터를 셋업 맵에 저장한다.
|
|
for (int nCount = 0; nCount < nMaxData; ++nCount)
|
|
{
|
|
keyValueData[nCount].m_edValue.GetWindowText(szValue);
|
|
m_pmSettingOption.SetSettingData(keyValueData[nCount].m_szKey, szValue);
|
|
}
|
|
|
|
int nCurSel = m_cbPatchType.GetCurSel();
|
|
if (CB_ERR != nCurSel)
|
|
{
|
|
m_cbPatchType.GetLBText(nCurSel, szValue);
|
|
m_pmSettingOption.SetSettingData(PMConst::PatchType, szValue);
|
|
}
|
|
|
|
nCurSel = m_cbPkgPos.GetCurSel();
|
|
if (CB_ERR != nCurSel)
|
|
{
|
|
m_cbPkgPos.GetLBText(nCurSel, szValue);
|
|
m_pmSettingOption.SetSettingData(PMConst::AP_PkgPosType, szValue);
|
|
}
|
|
|
|
m_pmSettingOption.SetSettingData(PMConst::AP_FTPPassive,
|
|
BST_CHECKED == m_bFTPPassive.GetCheck() ? _T("TRUE") : _T("FALSE"));
|
|
|
|
szValue.Format("%u", m_dwManualPatchMinVer);
|
|
m_pmSettingOption.SetSettingData(PMConst::MP_MinVer, szValue);
|
|
}
|
|
}
|
|
|
|
bool CSettingOptionPage::IsEmptyOption()
|
|
{
|
|
if (CB_ERR == m_cbPatchType.GetCurSel() ||
|
|
0 == m_edOldPkgPos.GetWindowTextLength() ||
|
|
0 == m_edNewClientPos.GetWindowTextLength() ||
|
|
0 == m_edNewPkgPos.GetWindowTextLength() ||
|
|
0 == m_edMaxPkgSize.GetWindowTextLength() ||
|
|
CB_ERR == m_cbPkgPos.GetCurSel() ||
|
|
0 == m_edManualPatchFolder.GetWindowTextLength() ||
|
|
0 == m_edManualPatchSFXFile.GetWindowTextLength() ||
|
|
m_dwManualPatchMinVer < 100 ||
|
|
10000 < m_dwManualPatchMinVer)
|
|
{
|
|
// 빈 항목이 있으면 실패!
|
|
return true;
|
|
}
|
|
|
|
CString szPkgPos, szFTPPos((LPCTSTR)IDS_CB_FTP);
|
|
m_cbPkgPos.GetLBText(m_cbPkgPos.GetCurSel(), szPkgPos);
|
|
|
|
if (0 == szPkgPos.CompareNoCase(szFTPPos) &&
|
|
(0 == m_edFTPAddr.GetWindowTextLength() ||
|
|
0 == m_edFTPPort.GetWindowTextLength()))
|
|
{
|
|
// FTP를 선택했는데, 주소나 Port가 없으면 실패!
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
BOOL CSettingOptionPage::OnKillActive()
|
|
{
|
|
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
|
|
|
|
if (this == m_OwnerSheet.GetActivePage())
|
|
{
|
|
// 페이지를 옮기면 자동으로 저장됨
|
|
SendMessage(WM_COMMAND, MAKEWPARAM(ID_SAVE_SETUP, BN_CLICKED));
|
|
|
|
if (IsEmptyOption())
|
|
{
|
|
MessageBox(_T("기록하지 않은 설정이 있습니다. 남은 설정을 모두 입력해 주십시오"),
|
|
_T("옵션 설정"), MB_OK | MB_ICONEXCLAMATION);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return CPropertyPage::OnKillActive();
|
|
}
|
|
|
|
BOOL CSettingOptionPage::OnSetActive()
|
|
{
|
|
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
|
|
SendMessage(WM_COMMAND, MAKEWPARAM(ID_LOAD_SETUP, BN_CLICKED));
|
|
return CPropertyPage::OnSetActive();
|
|
}
|
|
|
|
|
|
afx_msg LRESULT CSettingOptionPage::OnEnableAutoPatchOption(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SetAutoPatchOption(true);
|
|
return 0;
|
|
}
|
|
|
|
afx_msg LRESULT CSettingOptionPage::OnDisableAutoPatchOption(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SetAutoPatchOption(false);
|
|
return 0;
|
|
}
|
|
|
|
afx_msg LRESULT CSettingOptionPage::OnEnableManualPatchOption(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SetManualPatchOption(true);
|
|
return 0;
|
|
}
|
|
|
|
afx_msg LRESULT CSettingOptionPage::OnDisableManualPatchOption(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SetManualPatchOption(false);
|
|
return 0;
|
|
}
|
|
|
|
void CSettingOptionPage::SetAutoPatchOption(bool bEnable)
|
|
{
|
|
UINT nDisableID[] =
|
|
{
|
|
IDC_BTN_OPT_OLD_PKG,
|
|
IDC_BTN_OPT_NEW_CLIENT,
|
|
IDC_BTN_OPT_NEW_PKG,
|
|
};
|
|
|
|
PMUtil::EnableDlgItems(*this, nDisableID,
|
|
sizeof(nDisableID)/sizeof(UINT), bEnable);
|
|
|
|
if (bEnable && !theApp.IsManualPatchOperate())
|
|
{
|
|
// 수동패치가 작동 안할때만 Enable
|
|
m_cbPatchType.EnableWindow(TRUE);
|
|
}
|
|
else
|
|
{
|
|
m_cbPatchType.EnableWindow(FALSE);
|
|
}
|
|
|
|
m_cbPkgPos.EnableWindow(bEnable);
|
|
m_bFTPPassive.EnableWindow(bEnable);
|
|
|
|
m_edOldPkgPos.SetReadOnly(!bEnable);
|
|
m_edMaxPkgSize.SetReadOnly(!bEnable);
|
|
|
|
m_edFTPAddr.SetReadOnly(!bEnable);
|
|
m_edFTPPort.SetReadOnly(!bEnable);
|
|
}
|
|
|
|
void CSettingOptionPage::SetManualPatchOption(bool bEnable)
|
|
{
|
|
UINT nDisableID[] =
|
|
{
|
|
IDC_BTN_OPT_MANUAL_PATCH_FILE,
|
|
IDC_BTN_OPT_MANUAL_SFX_FILE
|
|
};
|
|
|
|
PMUtil::EnableDlgItems(*this, nDisableID,
|
|
sizeof(nDisableID)/sizeof(UINT), bEnable);
|
|
|
|
if (bEnable && !theApp.IsAutoPatchOperate())
|
|
{
|
|
// 자동패치가 작동 안할때만 Enable
|
|
m_cbPatchType.EnableWindow(TRUE);
|
|
}
|
|
else
|
|
{
|
|
m_cbPatchType.EnableWindow(FALSE);
|
|
}
|
|
|
|
m_edManualPatchMinVer.SetReadOnly(!bEnable);
|
|
}
|
|
|
|
void CSettingOptionPage::OnCbnSelchangeCbOptOldPkgPos()
|
|
{
|
|
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
|
|
|
BOOL bEnableFTP = FALSE;
|
|
|
|
int nCurSel = m_cbPkgPos.GetCurSel();
|
|
if (CB_ERR != nCurSel)
|
|
{
|
|
CString szFTP((LPCTSTR)IDS_CB_FTP);
|
|
CString szCurrentSel;
|
|
m_cbPkgPos.GetLBText(nCurSel, szCurrentSel);
|
|
|
|
if (0 == szCurrentSel.CompareNoCase(szFTP))
|
|
{
|
|
bEnableFTP = TRUE;
|
|
}
|
|
}
|
|
|
|
m_edFTPAddr.EnableWindow(bEnableFTP);
|
|
m_edFTPPort.EnableWindow(bEnableFTP);
|
|
m_bFTPPassive.EnableWindow(bEnableFTP);
|
|
|
|
m_edOldPkgPos.SetReadOnly(!bEnableFTP);
|
|
}
|
|
|
|
|
|
void CSettingOptionPage::OnDestroy()
|
|
{
|
|
SendMessage(WM_COMMAND, MAKEWPARAM(ID_SAVE_SETUP, BN_CLICKED));
|
|
CPropertyPage::OnDestroy();
|
|
}
|