DragonNest/Client/DnLauncher2/Torrent/Source/TorrentTest/TorrentTestDlg.cpp
2024-12-19 09:48:26 +08:00

398 lines
11 KiB
C++

// TorrentTestDlg.cpp : 구현 파일
//
#include "stdafx.h"
#include "TorrentTest.h"
#include "TorrentTestDlg.h"
#include "WLibTorrent.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CTorrentTestDlg 대화 상자
CTorrentTestDlg::CTorrentTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTorrentTestDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTorrentTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CTorrentTestDlg, CDialog)
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CTorrentTestDlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_BUTTON1, &CTorrentTestDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CTorrentTestDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CTorrentTestDlg::OnBnClickedButton3)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CTorrentTestDlg 메시지 처리기
void CTorrentTestDlg::OnDestroy()
{
m_vecPeers.clear();
}
BOOL CTorrentTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
// 프레임워크가 이 작업을 자동으로 수행합니다.
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.
// TODO: 여기에 추가 초기화 작업을 추가합니다.
CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem( IDC_LIST2 );
if( pListCtrl )
{
pListCtrl->InsertColumn( 0, L"IP", LVCFMT_CENTER, 140 );
pListCtrl->InsertColumn( 1, L"Port", LVCFMT_CENTER, 80 );
pListCtrl->InsertColumn( 2, L"Seed", LVCFMT_CENTER, 60 );
pListCtrl->InsertColumn( 3, L"Upload", LVCFMT_CENTER, 100 );
pListCtrl->InsertColumn( 4, L"Download", LVCFMT_CENTER, 100 );
}
return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
// 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
// 프레임워크에서 이 작업을 자동으로 수행합니다.
void CTorrentTestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
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;
// 아이콘을 그립니다.
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
// 이 함수를 호출합니다.
HCURSOR CTorrentTestDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CTorrentTestDlg::OnBnClickedOk()
{
CString strFilter = L"Torrent Files (*.torrent)|*.torrent||";
CFileDialog dlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, strFilter );
if( IDOK == dlg.DoModal() )
{
m_strTorrentName = dlg.GetPathName();
}
if( m_strTorrentName.GetLength() == 0 )
return;
if( WLibTorrent::GetInstance()->InitSession( L"test" ) )
{
if( WLibTorrent::GetInstance()->AddTorrent( m_strTorrentName.GetBuffer( 0 ), m_strSavePath.GetBuffer( 0 ) ) )
{
MessageBox( L"Success AddTorrent" );
}
}
GetDlgItem( IDC_STATIC_NAME )->SetWindowText( m_strTorrentName );
CProgressCtrl* pProgressBar = (CProgressCtrl*)GetDlgItem( IDC_PROGRESS1 );
if( pProgressBar )
pProgressBar->SetRange( 1,100 );
SetTimer( PROGRESS_TIMER, 100, NULL ); // TimerID = 1000; TimerTick = 100ms
}
void CTorrentTestDlg::OnTimer( UINT_PTR nIDEvent )
{
if( nIDEvent == PROGRESS_TIMER )
{
float fPercent = 0.0f;
torrent_status TorrentStatus;
libtorrent::torrent_handle* pTorrentHandle = WLibTorrent::GetInstance()->GetTorrentHandle( m_strTorrentName.GetBuffer(0) );
if( pTorrentHandle )
{
TorrentStatus = pTorrentHandle->status();
fPercent = TorrentStatus.progress_ppm / 10000.f;
CString strState;
switch( TorrentStatus.state )
{
case torrent_status::queued_for_checking:
strState = L"queued_for_checking";
break;
case torrent_status::checking_files:
strState = L"checking_files";
break;
case torrent_status::downloading_metadata:
strState = L"downloading_metadata";
break;
case torrent_status::downloading:
strState = L"downloading";
break;
case torrent_status::finished:
strState = L"finished";
break;
case torrent_status::seeding:
strState = L"seeding";
break;
case torrent_status::allocating:
strState = L"allocating";
break;
case torrent_status::checking_resume_data:
strState = L"checking_resume_data";
break;
}
GetDlgItem( IDC_STATIC_STATE )->SetWindowText( strState );
}
int nPercent = static_cast<int>( fPercent );
if( nPercent > 100 )
nPercent = 100;
CProgressCtrl* pProgressBar = (CProgressCtrl*)GetDlgItem( IDC_PROGRESS1 );
if( pProgressBar )
pProgressBar->SetPos( nPercent );
CString strPercent;
strPercent.Format( L"%.2f%%", fPercent );
GetDlgItem( IDC_STATIC_PERCENT )->SetWindowText( strPercent );
if( TorrentStatus.state != torrent_status::queued_for_checking && TorrentStatus.state != torrent_status::checking_files )
{
CString strDownloadInfo;
CString strDownloadRate;
CString strConnectionInfo;
strDownloadInfo.Format( L"Total Download : %s | Total Upload : %s", AddSuffix( TorrentStatus.total_download ), AddSuffix( TorrentStatus.total_upload ) );
strDownloadRate.Format( L"Download Rate : %s | Upload Rate : %s", AddSuffix( TorrentStatus.download_rate, "/s" ), AddSuffix( TorrentStatus.upload_rate, "/s" ) );
strConnectionInfo.Format( L"Peers : %d | Seeds : %d", TorrentStatus.num_peers, TorrentStatus.num_seeds );
GetDlgItem( IDC_STATIC_DOWNLOAD )->SetWindowText( strDownloadInfo );
GetDlgItem( IDC_STATIC_DOWNLOAD_RATE )->SetWindowText( strDownloadRate );
GetDlgItem( IDC_STATIC_CONNECTION )->SetWindowText( strConnectionInfo );
}
// Set Peers, Seeds Info
std::vector<peer_info> peers;
if( TorrentStatus.state != torrent_status::seeding )
{
pTorrentHandle->get_peer_info( peers );
}
if( CheckPeers( peers ) ) // Update Peers
{
CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem( IDC_LIST2 );
pListCtrl->DeleteAllItems();
CString strIP;
CString strPort;
if( pListCtrl && !m_vecPeers.empty() )
{
int nIndex = 0;
for( std::vector<peer_info>::const_iterator i = m_vecPeers.begin(); i != m_vecPeers.end(); ++i )
{
if( i->flags & (peer_info::handshake | peer_info::connecting | peer_info::queued) )
continue;
boost::system::error_code ec;
wchar_t wChar[250];
MultiByteToWideChar( CP_ACP, 0, i->ip.address().to_string( ec ).c_str(), -1, wChar, 250 );
strIP.Format( L"%-22s", wChar );
strPort.Format( L"%-5d", i->ip.port() );
pListCtrl->InsertItem( nIndex, strIP );
pListCtrl->SetItemText( nIndex, 1, strPort );
if( i->flags & peer_info::seed )
pListCtrl->SetItemText( nIndex, 2, L"Seed" );
pListCtrl->SetItemText( nIndex, 3, AddSuffix( i->up_speed, "/s" ) );
pListCtrl->SetItemText( nIndex, 4, AddSuffix( i->down_speed, "/s" ) );
nIndex++;
/* snprintf(str, sizeof(str)
, "%s%s (%s|%s) %s%s (%s|%s) %s%3d (%3d) %3d %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c %c%c%c%c%c%c "
, esc("32"), add_suffix(i->down_speed, "/s").c_str()
, add_suffix(i->total_download).c_str(), add_suffix(i->download_rate_peak, "/s").c_str()
, esc("31"), add_suffix(i->up_speed, "/s").c_str(), add_suffix(i->total_upload).c_str()
, add_suffix(i->upload_rate_peak, "/s").c_str(), esc("0")
*/
}
}
}
peers.clear();
// if( nPercent == 100 )
// KillTimer( PROGRESS_TIMER );
}
}
bool CTorrentTestDlg::CheckPeers( std::vector<peer_info>& peers )
{
if( m_vecPeers.size() != peers.size() )
{
m_vecPeers = peers;
return true;
}
bool bSamePeers = true;
for( std::vector<peer_info>::const_iterator i = m_vecPeers.begin(); i != m_vecPeers.end(); ++i )
{
bool bFindIP = false;
for( std::vector<peer_info>::const_iterator i2 = peers.begin(); i2 != peers.end(); ++i2 )
{
if( i->ip.address() == i2->ip.address() )
{
bFindIP = true;
break;
}
}
if( !bFindIP )
{
bSamePeers = false;
break;
}
}
if( !bSamePeers )
{
m_vecPeers = peers;
return true;
}
return false;
}
CString CTorrentTestDlg::AddSuffix( float val, char const* suffix )
{
CString strAddSuffix;
WCHAR* chrPrefix[] = { L"kB", L"MB", L"GB", L"TB"};
const int nNumPrefix = sizeof(chrPrefix) / sizeof(WCHAR*);
for( int i=0; i<nNumPrefix; ++i )
{
val /= 1000.f;
if( std::fabs(val) < 1000.f )
{
strAddSuffix.Format( L"%.2f", val );
strAddSuffix += chrPrefix[i];
if( suffix ) strAddSuffix += suffix;
break;
}
}
return strAddSuffix;
}
void CTorrentTestDlg::OnBnClickedButton1()
{
CString strFileName;
CString strMakeFileName;
CString strFilter = L"Make Files (*.*)|*.*||";
CFileDialog dlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, strFilter );
if( IDOK == dlg.DoModal() )
{
strFileName = dlg.GetPathName();
}
if( strFileName.GetLength() == 0 )
return;
std::vector<std::wstring> vecWstrWebSeeds;
std::vector<std::wstring> vecWstrTrackers;
strMakeFileName = strFileName + L".torrent";
// vecWstrTrackers.push_back( L"http://172.24.32.20:6881/announce" );
bool bMake = WLibTorrent::GetInstance()->MakeTorrent( strFileName, vecWstrWebSeeds, vecWstrTrackers, strMakeFileName, L"Test" );
// std::wstring strTestWebSeed = L"http://dn-nexon14.ktics.co.kr/ReleaseBuild/Patch/00000352/Patch00000352.pak";
// vecWstrWebSeeds.push_back( strTestWebSeed );
// bool bMake = WLibTorrent::GetInstance()->MakeTorrent( L"C:\\libtorrent\\Example\\TorrentTest\\Patch00000352.pak", vecWstrWebSeeds, vecWstrTrackers,
// L"C:\\libtorrent\\Example\\TorrentTest\\Patch00000352.pak.torrent", L"Test" );
}
void CTorrentTestDlg::OnBnClickedButton2()
{
ITEMIDLIST* pildBrowse;
TCHAR pszPathname[MAX_PATH];
BROWSEINFO bInfo;
memset( &bInfo, 0, sizeof( bInfo ) );
bInfo.hwndOwner = GetSafeHwnd();
bInfo.pidlRoot = NULL;
bInfo.pszDisplayName = pszPathname;
bInfo.lpszTitle = _T("디렉토리를 선택하세요");
bInfo.ulFlags = BIF_RETURNONLYFSDIRS;
bInfo.lpfn = NULL;
bInfo.lParam = (LPARAM)(LPCTSTR)"C:\\";
bInfo.lParam = (LPARAM)NULL;
pildBrowse = ::SHBrowseForFolder(&bInfo);
if( pildBrowse )
{
SHGetPathFromIDList( pildBrowse, pszPathname );
std::vector<std::wstring> vecWstrWebSeeds;
std::vector<std::wstring> vecWstrTrackers;
CString strMakeFileName;
CString strFileName = pszPathname;
strMakeFileName = strFileName + L".torrent";
bool bMake = WLibTorrent::GetInstance()->MakeTorrent( strFileName, vecWstrWebSeeds, vecWstrTrackers, strMakeFileName, L"Test" );
}
}
void CTorrentTestDlg::OnBnClickedButton3()
{
ITEMIDLIST* pildBrowse;
TCHAR pszPathname[MAX_PATH];
BROWSEINFO bInfo;
memset( &bInfo, 0, sizeof( bInfo ) );
bInfo.hwndOwner = GetSafeHwnd();
bInfo.pidlRoot = NULL;
bInfo.pszDisplayName = pszPathname;
bInfo.lpszTitle = _T("디렉토리를 선택하세요");
bInfo.ulFlags = BIF_RETURNONLYFSDIRS;
bInfo.lpfn = NULL;
bInfo.lParam = (LPARAM)(LPCTSTR)"C:\\";
bInfo.lParam = (LPARAM)NULL;
pildBrowse = ::SHBrowseForFolder(&bInfo);
if( pildBrowse )
{
SHGetPathFromIDList( pildBrowse, pszPathname );
m_strSavePath = pszPathname;
GetDlgItem( IDC_STATIC_PATH )->SetWindowText( m_strSavePath );
}
}