#include "stdafx.h" #include "NxFileSystemTool.h" #include "NxFileSystemToolDlg.h" #include "NewFolderDlg.h" #include "ExportBrowseFolder.h" #include "WorkDialog.h" #include "BuildDivisionPacking.h" #include "BuildDivisionPackingCapacity.h" #include "LogWnd.h" #include "SundriesFunc.h" #include "SHFolderDialog.h" #include #ifdef _DEBUG #define new DEBUG_NEW #endif #pragma warning(disable:4311) // 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다. class CAboutDlg : public CDialog { public: CAboutDlg(); // 대화 상자 데이터 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원 // 구현 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CNxFileSystemToolDlg 대화 상자 CNxFileSystemToolDlg::CNxFileSystemToolDlg(CWnd* pParent /*=NULL*/) : CDialog(CNxFileSystemToolDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_iOverwriteType = -1; } void CNxFileSystemToolDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_FILE_LIST, m_FileList); DDX_Control(pDX, IDC_NAVI , m_Edit); } BEGIN_MESSAGE_MAP(CNxFileSystemToolDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_WM_SIZE() ON_COMMAND(ID_LOADSYSTEM, OnLoadsystem) ON_COMMAND(ID_NEWSYSTEM, OnNewsystem) ON_COMMAND(ID_FILESYSTEM_CLOSE, OnFilesystemClose) ON_COMMAND(ID_INSERT_FILE, OnInsertFile) ON_MESSAGE(WM_COMPLETE_MSG, OnCompleteMsg) ON_MESSAGE(WM_COMPLETE_OPTIMIZE, OnComplete_Optimize) ON_MESSAGE(WM_COMPLETE_EXPORT, OnComplete_Export) ON_COMMAND(ID_NEW_FOLDER, OnNewFolder) ON_COMMAND(ID_REMOVE, OnRemove) ON_NOTIFY(NM_DBLCLK, IDC_FILE_LIST, OnNMDblclkFileList) ON_NOTIFY(LVN_ENDLABELEDIT, IDC_FILE_LIST, OnLvnEndlabeleditFileList) ON_COMMAND(ID_IPAC_EXIT, OnIpacExit) ON_COMMAND(ID_OPTIMIZE, OnOptimize) ON_COMMAND(ID_RENAME, OnRename) ON_COMMAND(ID_EXPORT, OnExport) ON_COMMAND(ID_ABOUT, OnAbout) ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) ON_COMMAND(ID_MENU_DIV_PACKING, &CNxFileSystemToolDlg::OnMenuDivPacking) ON_COMMAND(ID_MENU_DIV_PACKING_CAPACITY, &CNxFileSystemToolDlg::OnMenuDivPackingCapacity) ON_COMMAND(ID_PATCH, &CNxFileSystemToolDlg::OnPatch) ON_MESSAGE(WM_COMPLETE_PATCH, OnCompletePatch) ON_COMMAND(ID_COMPARE, &CNxFileSystemToolDlg::OnCompare) ON_COMMAND(ID_INSERT_FOLDER, &CNxFileSystemToolDlg::OnInsertFolder) END_MESSAGE_MAP() // CNxFileSystemToolDlg 메시지 처리기 BOOL CNxFileSystemToolDlg::OnInitDialog() { CDialog::OnInitDialog(); // 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다. // IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는 // 프레임워크가 이 작업을 자동으로 수행합니다. SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다. SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다. // TODO: 여기에 추가 초기화 작업을 추가합니다. m_FileList.DragAcceptFiles(); m_FileList.SetExtendedStyle(LVS_EX_FULLROWSELECT); RECT Rect; m_FileList.GetWindowRect(&Rect); const int COLUMN_WIDTH_GAB = 4; const int SIZECOLUMN_WIDTH = 300; const int SIZECOLUMN_WIDTH2 = 80; m_FileList.InsertColumn(0,_T("이름"),LVCFMT_LEFT,SIZECOLUMN_WIDTH); m_FileList.InsertColumn(1,_T("크기"),LVCFMT_LEFT,SIZECOLUMN_WIDTH2); m_FileList.InsertColumn(2,_T("원본크기"),LVCFMT_LEFT,SIZECOLUMN_WIDTH2); m_FileList.InsertColumn(3,_T("설명"),LVCFMT_LEFT,SIZECOLUMN_WIDTH); m_ImageList.Create(IDB_FILE_LIST_ICON,16,2,RGB(0,255,0)); m_FileList.SetImageList(&m_ImageList,LVSIL_SMALL); m_bWorking = false; // 작업중인지 아닌지.. 초기화 m_FileList.SetFocus(); // LogWnd::CreateLog(); return TRUE; // 컨트롤에 대한 포커스를 설정하지 않을 경우 TRUE를 반환합니다. } void CNxFileSystemToolDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면 // 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는 // 프레임워크에서 이 작업을 자동으로 수행합니다. void CNxFileSystemToolDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(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 CNxFileSystemToolDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } BOOL CNxFileSystemToolDlg::PreTranslateMessage(MSG* pMsg) { switch(pMsg->wParam) { case VK_ESCAPE: pMsg->wParam=NULL; // ESC 는 무시한다. break; case VK_RETURN: pMsg->wParam=NULL; // 엔터도 무시한다. break; } switch(pMsg->message) { case WM_DROPFILES: if(pMsg->hwnd == m_FileList.GetSafeHwnd()) DropFile((HDROP)pMsg->wParam); break; case WM_KEYDOWN: if(pMsg->hwnd == m_FileList.GetSafeHwnd() && pMsg->wParam == VK_DELETE) OnRemove(); break; } return CDialog::PreTranslateMessage(pMsg); } void CNxFileSystemToolDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); const int SIZECOLUMN_WIDTH = 300; const int SIZECOLUMN_WIDTH2 = 60; CRect rt; // TODO: 여기에 메시지 처리기 코드를 추가합니다. if (m_FileList.GetSafeHwnd() != NULL ) { m_FileList.SetWindowPos(NULL,10,35,cx-22,cy-48,SWP_NOZORDER); //Client 영역의 크기를 구한다. m_FileList.GetClientRect(&rt); } } static int CALLBACK FileListItemSortFunc(LPARAM lParam1,LPARAM lParam2,LPARAM /*lParamSort*/) { SNxFileInfo* pFH1 = (SNxFileInfo*)lParam1; SNxFileInfo* pFH2 = (SNxFileInfo*)lParam2; CString strItem1; if(pFH1->nFileType == NFS_DIR) { strItem1.Format(_T("!%s"),pFH1->szFileName); } else { strItem1 = pFH1->szFileName; } CString strItem2; if(pFH2->nFileType == NFS_DIR) { strItem2.Format(_T("!%s"),pFH2->szFileName); } else { strItem2 = pFH2->szFileName; } return _tcscmp(strItem1,strItem2); } void CNxFileSystemToolDlg::UpdateFileList() { m_FileList.DeleteAllItems(); int i; CString strFileSize; CString OriFileSize; std::vector< SPackingFileInfo * > vecFileInfo; std::vector< std::string > vecDirList; g_FileSystem.GetFileInfoListCurDir( vecFileInfo ); g_FileSystem.GetDirListCurDir( vecDirList ); m_vecFileInfo.resize( vecFileInfo.size() + vecDirList.size() ); for( i = 0; i < ( int )vecFileInfo.size(); i++ ) { _GetFullFileName( m_vecFileInfo[ i ].szFileName, _countof(m_vecFileInfo[ i ].szFileName), vecFileInfo[ i ]->szFileName ); m_vecFileInfo[ i ].dwCompressSize = vecFileInfo[ i ]->dwCompressSize; m_vecFileInfo[ i ].dwOriginalSize = vecFileInfo[ i ]->dwOriginalSize; m_vecFileInfo[ i ].nFileType = NFS_FILE; } for( i = 0; i < ( int )vecDirList.size(); i++ ) { strcpy_s( m_vecFileInfo[ vecFileInfo.size() + i ].szFileName, _MAX_PATH, vecDirList[ i ].c_str() ); m_vecFileInfo[ vecFileInfo.size() + i ].nFileType = NFS_DIR; } for( i = 0; i < ( int )m_vecFileInfo.size(); i++ ) { m_FileList.InsertItem( i, m_vecFileInfo[ i ].szFileName, 1 ); m_FileList.SetItemData( i, ( DWORD )( &m_vecFileInfo[ i ] ) ); if( m_vecFileInfo[ i ].nFileType == NFS_FILE ) { strFileSize.Format(_T("%dKB"),( m_vecFileInfo[ i ].dwCompressSize + 999 ) / 1000 ); m_FileList.SetItemText(i,1,LPCTSTR(strFileSize)); OriFileSize.Format(_T("%dKB"),( m_vecFileInfo[ i ].dwOriginalSize + 999 ) / 1000 ); m_FileList.SetItemText(i,2,LPCTSTR(OriFileSize)); } } m_FileList.SortItems(FileListItemSortFunc,NULL); this->SetDlgItemText(IDC_NAVI,g_FileSystem.GetCurDir()); } void CNxFileSystemToolDlg::OnLoadsystem() { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return ; } CFileDialog Dlg(TRUE,_T(".pak"),NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("파일(*.pak)|*.pak||"),NULL); if(Dlg.DoModal() == IDCANCEL) return; if(!g_FileSystem.OpenFileSystem(LPCTSTR(Dlg.GetPathName()))) { // 파일 시스템 쓰기로 안열리면 읽기로라도 연다.. if( !g_FileSystem.OpenFileSystem(LPCTSTR(Dlg.GetPathName()), true )) { AfxMessageBox(_T("파일시스템을 열지 못하였거나 잘못된 파일 입니다.")); return; } } m_strPath = Dlg.GetPathName(); UpdateFileList(); } void CNxFileSystemToolDlg::OnNewsystem() { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return ; } CFileDialog Dlg(FALSE,_T(".Nfs"),_T("NewSystem.pak"),OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("파일(*.pak)|*.pak||"),NULL); if(Dlg.DoModal() == IDCANCEL) return; if(!g_FileSystem.NewFileSystem(LPCTSTR(Dlg.GetPathName()))) { AfxMessageBox(_T("새로운 파일시스템 생성에 실패 하였습니다.")); return; } if(!g_FileSystem.OpenFileSystem(LPCTSTR(Dlg.GetPathName()))) { AfxMessageBox(_T("새파일 시스템을 생성하였지만 로드하지 못하였습니다.")); return; } m_strPath = Dlg.GetPathName(); UpdateFileList(); } void CNxFileSystemToolDlg::OnFilesystemClose() { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return ; } // TODO: 여기에 명령 처리기 코드를 추가합니다. g_FileSystem.CloseFileSystem(); m_strPath.Empty(); UpdateFileList(); } BOOL CNxFileSystemToolDlg::DestroyWindow() { // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다. SAFE_DELETE (g_pAddThread); return CDialog::DestroyWindow(); } LRESULT CNxFileSystemToolDlg::OnCompleteMsg(WPARAM wParam, LPARAM lParam) { SAFE_DELETE (g_pAddThread); m_bWorking = false; ::PostMessage(g_pWorking->GetSafeHwnd(),WM_DESTROY,0,0); SAFE_DELETE(g_pWorking); UpdateFileList(); return TRUE; } void CNxFileSystemToolDlg::OnInsertFile() { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return; } // TODO: 여기에 명령 처리기 코드를 추가합니다. if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.")); return; } CFileDialog Dlg(TRUE); if(Dlg.DoModal() == IDCANCEL) return; TCHAR strName[_MAX_FNAME]; g_FileSystem.GetNameOnly(strName,Dlg.GetPathName().GetBuffer()); /* if(g_FileSystem.CheckNameExist(strName)) { if(AfxMessageBox(_T("동일한 이름의 파일이 이미 존재합니다.\n\n모든 파일을 새로운 파일로 덮어쓰시려면 '예' 를\n\n모든 기존의 파일을 보존하시려면 '아니오' 를 눌러주십시오! "),MB_YESNO) == IDNO) return; g_FileSystem.Remove(strName); }*/ // 안내 박스.. 띄우기.. DrawWorking(); AddFileInfo add; add.FileName = LPCTSTR( Dlg.GetPathName() ); add.FilePath = g_FileSystem.GetCurDir(); g_AddFileList.push_back(add); // 파일 추가 쓰레스 시작! g_pAddThread = new CFileImportThread(this->GetSafeHwnd()); g_pAddThread->Start(); m_bWorking = true; } void CNxFileSystemToolDlg::OnInsertFolder() { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return; } // TODO: 여기에 명령 처리기 코드를 추가합니다. if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.")); return; } CString strSelectedPath; if( !CSHFolderDialog::BrowseForFolder( strSelectedPath, _T("Choose a Folder:"), m_hWnd, 0, 0, NULL ) == IDOK ) { return; } SearchFolderAndAddFile( strSelectedPath.GetBuffer() ); // 안내 박스.. 띄우기.. DrawWorking(); // 파일 추가 쓰레스 시작! g_pAddThread = new CFileImportThread(this->GetSafeHwnd()); g_pAddThread->Start(); m_bWorking = true; } void CNxFileSystemToolDlg::SearchFolderAndAddFile( const char *szFolderName ) { char acCommonBuffer[1024]; sprintf(acCommonBuffer, szFolderName); strcat(acCommonBuffer, "/*.*"); HANDLE hSearchFile; WIN32_FIND_DATA wfd; BOOL bResult = TRUE; // 폴더안에 있는 파일을 찾아 순회한다. hSearchFile = FindFirstFile(acCommonBuffer, &wfd); if (hSearchFile == INVALID_HANDLE_VALUE) return; std::string strSubFolder; std::string::size_type szLength; if( m_strRootFolder.length() == 0 ) { std::string strTemp = szFolderName; szLength = strTemp.rfind( "\\" ); strTemp.erase( szLength ); m_strRootFolder = strTemp; } std::string strFolderName = szFolderName; strFolderName.erase( 0, m_strRootFolder.length() ); strSubFolder = strFolderName + "\\"; // 뭔가 찾았다면, while (bResult) { // 파일 순서는 항상 영어이름 순이다. 폴더와 파일 구분 없다. if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // 모든 폴더에는 항상 . 과 .. 폴더가 있다. 이건 그냥 넘기고, 다른 폴더라면, if (wfd.cFileName[0] != '.') { // 재귀호출로 처리한다. sprintf(acCommonBuffer, "%s\\%s", szFolderName, wfd.cFileName); SearchFolderAndAddFile(acCommonBuffer); } } else { if (_stricmp(wfd.cFileName, "Thumbs.db")) { // 파일명 조합 sprintf(acCommonBuffer, "%s\\%s", szFolderName, wfd.cFileName); // 파일 크기가 0이 아닌 경우에만 추가한다. 파일크기 0은 의미없는 파일이다. HANDLE hFile = CreateFile(acCommonBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (GetFileSize(hFile, NULL) != 0) { AddFileInfo add; add.FileName = acCommonBuffer; add.FilePath = strSubFolder; g_AddFileList.push_back(add); } CloseHandle(hFile); } } bResult = FindNextFile(hSearchFile, &wfd); } FindClose(hSearchFile); } void CNxFileSystemToolDlg::OnNewFolder() { // TODO: 여기에 명령 처리기 코드를 추가합니다. if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return; } if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.")); return; } CNewFolderDlg Dlg; if(Dlg.DoModal() == IDCANCEL) return; if(Dlg.m_strFolderName.IsEmpty()) return; // g_FileSystem.AddDirWithChange(LPCTSTR(Dlg.m_strFolderName)); UpdateFileList(); } void CNxFileSystemToolDlg::OnRemove() { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return; } if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.")); return; } if(!m_FileList.GetSelectedCount()) return; if(AfxMessageBox(_T("선택된 파일 혹은 폴더를 삭제하시겠습니까?"), MB_YESNO) == IDYES) { CStringArray strRemove; POSITION Pos = m_FileList.GetFirstSelectedItemPosition(); while(Pos) { int iItem = m_FileList.GetNextSelectedItem(Pos); SNxFileInfo* NxFileInfo = (SNxFileInfo*)m_FileList.GetItemData(iItem); strRemove.Add(NxFileInfo->szFileName); } for(int i=0;iiItem >= 0) { SNxFileInfo *pFH = ( SNxFileInfo * )m_FileList.GetItemData(pNMItemActivate->iItem); if( pFH->nFileType == NFS_DIR) { g_FileSystem.ChangeDir(pFH->szFileName); UpdateFileList(); } } *pResult = 0; } void CNxFileSystemToolDlg::OnLvnEndlabeleditFileList(NMHDR *pNMHDR, LRESULT *pResult) { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return; } NMLVDISPINFO *pDispInfo = reinterpret_cast(pNMHDR); if(!pDispInfo->item.pszText) return; SNxFileInfo *pFH = ( SNxFileInfo * )m_FileList.GetItemData(pDispInfo->item.iItem); if(!g_FileSystem.Rename(pFH->szFileName,pDispInfo->item.pszText)) { AfxMessageBox(_T("선택된 파일 혹은 폴더의 이름을 변경할수 없습니다!")); return; } m_FileList.SetItemText(pDispInfo->item.iItem,0,pDispInfo->item.pszText); *pResult = 0; } void CNxFileSystemToolDlg::DropFile(HDROP hDrop) { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return; } g_AddFileList.clear(); if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.")); return; } if ( AfxMessageBox(_T("드래그한 파일및 폴더를 파일시스템에 저장하시겠습니까?") , MB_YESNO) == IDNO ) return; // 안내 박스.. 띄우기.. DrawWorking(); /* UINT DragQueryFile( HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch ); iFile의 값이 0xFFFFFFFF일 경우에는 리턴값으로 몇 개의 파일이 드롭되었는지를 정수형으로 반환 또, iFile값이 0과 드롭된 전체 파일수사이의 값이고, lpszFile이 NULL인 경우에는 null을 포함하지 않는 필요한 캐릭터 크기를 리턴 hDrop : 드롭파일 지시자 iFile : 파일 쿼리에 대한 인덱스를 나타내며, 이 값에 의해 필요한 쿼리가 변합니다. lpszFile : 패스명을 받아드릴 버퍼(스트링형) cch : 버퍼의 크기 */ int iCount = DragQueryFile(hDrop,0xFFFFFFFF,NULL,0); // 파일의 갯수를 구한다. TCHAR strPath[_MAX_PATH]; for(int i=0;iGetSafeHwnd()); g_pAddThread->Start(); m_bWorking = true; } BOOL CNxFileSystemToolDlg::DropFolder(const TCHAR* strPath) { if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return FALSE; } char *pFindPtr = strstr( ( char * )strPath, ".svn" ); if( pFindPtr ) { if( _stricmp( pFindPtr, ".svn" ) == 0 ) { return FALSE; } } TCHAR strOldPath[_MAX_PATH]; GetCurrentDirectory(_MAX_PATH,strOldPath); // 현재 이 프로그램이 실행중인 디렉토리를 알아낸다. SetCurrentDirectory(strPath); // 드롭할 폴더로 이동.?? TCHAR strName[_MAX_FNAME]; g_FileSystem.GetNameOnly(strName,strPath); /* if(!g_FileSystem.CheckNameExist(strName)) { g_FileSystem.AddDir(strName); }*/ if(!g_FileSystem.ChangeDir(strName)) return FALSE; CFileFind FileFind; if(FileFind.FindFile()) { for(BOOL bNext=TRUE;bNext;) { bNext = FileFind.FindNextFile(); CString strP = FileFind.GetFilePath(); CString strN = FileFind.GetFileName(); if(strN == "." || strN == "..") continue; if(FileFind.IsDirectory()) { DropFolder(LPCTSTR(strP)); } else { /* if(g_FileSystem.CheckNameExist(strN)) { if(m_iOverwriteType < 0) m_iOverwriteType = AfxMessageBox(_T("동일한 이름의 파일이 이미 존재합니다.\n\n모든 파일을 새로운 파일로 덮어쓰시려면 '예' 를\n\n모든 기존의 파일을 보존하시려면 '아니오' 를 눌러주십시오!"),MB_YESNO); if(m_iOverwriteType == IDNO) continue; g_FileSystem.Remove(strN); }*/ // 파일 추가.. AddFileInfo add; add.FileName = strP; add.FilePath = g_FileSystem.GetCurDir(); g_AddFileList.push_back(add); } } } FileFind.Close(); g_FileSystem.ChangeDir(_T("..")); SetCurrentDirectory(strOldPath); return TRUE; } void CNxFileSystemToolDlg::OnIpacExit() { // TODO: 여기에 명령 처리기 코드를 추가합니다. if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.\n\n조금만 기다려주시면 안될까요..? \n\n흑흑...")); return; } PostQuitMessage(0); } void CNxFileSystemToolDlg::OnOptimize() { // TODO: 여기에 명령 처리기 코드를 추가합니다. if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.\n\n조금만 기다려주시면 안될까요..? \n\n흑흑...")); return; } if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.")); return; } // 안내 박스.. 띄우기.. DrawWorking(); // 파일 추가 쓰레스 시작! g_pOptimizeThread = new COptimizeThread(this->GetSafeHwnd() , m_strPath); //OptimizeThread->Start(); g_pOptimizeThread->Run(); m_bWorking = true; } LRESULT CNxFileSystemToolDlg::OnComplete_Optimize(WPARAM wParam, LPARAM lParam) { SAFE_DELETE (g_pOptimizeThread); g_FileSystem.ChangeDir(_T("/")); m_bWorking = false; ::PostMessage(g_pWorking->GetSafeHwnd(),WM_DESTROY,0,0); SAFE_DELETE(g_pWorking); AfxMessageBox(_T("최적화 작업을 성공했습니다.\n\n오래기달렷슈~")); UpdateFileList(); return TRUE; } LRESULT CNxFileSystemToolDlg::OnComplete_Export(WPARAM wParam, LPARAM lParam) { SAFE_DELETE (g_pExportThread); ::PostMessage(g_pWorking->GetSafeHwnd(),WM_DESTROY,0,0); SAFE_DELETE(g_pWorking); AfxMessageBox(_T("파일 추출 작업이 완료 되었습니다.")); UpdateFileList(); m_bWorking = false; return TRUE; } void CNxFileSystemToolDlg::OnRename() { ; } using namespace std; typedef list CValueFileHandleList; typedef list::iterator CValueFileHandleList_It; void CNxFileSystemToolDlg::OnExport() { // TODO: 여기에 명령 처리기 코드를 추가합니다. if ( m_bWorking ) { AfxMessageBox(_T("아직 작업이 진행중입니다.")); return; } if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.")); return; } if(!m_FileList.GetSelectedCount()) return; if ( AfxMessageBox(_T("선택된 파일 혹은 폴더를 외부로 추출하시겠습니까?"), MB_YESNO) == IDNO) return; TCHAR strOldPath[_MAX_PATH]= { 0 , }; // GetCurrentDirectory(_MAX_PATH,strOldPath); // 현재 디렉토리를 알아낸다. if ( ExportBrowseFolder(GetSafeHwnd(),strOldPath) == FALSE ) return; CString CurPath; CString ExportPath; CurPath = strOldPath; ExportPath = CurPath + _T("\\Exports"); // 선택한 경로 + Exports 폴더 만들기 CreateDirectory(ExportPath,NULL); // 익스포트 할 폴더로 이동 SetCurrentDirectory(ExportPath); // 안내 박스.. 띄우기.. DrawWorking(); g_ExportList.clear(); POSITION Pos = m_FileList.GetFirstSelectedItemPosition(); CValueFileHandleList OriginalValue; while(Pos) { int iItem = m_FileList.GetNextSelectedItem(Pos); SNxFileInfo *pFH = ( SNxFileInfo * )m_FileList.GetItemData(iItem); if( *(pFH->szFileName) == _T('.') ) continue; SNxFileInfo FH = *pFH; // Value Copy OriginalValue.push_back(FH); } CValueFileHandleList_It tempit=OriginalValue.begin(); for(tempit ; tempit!=OriginalValue.end() ; ++tempit ) { SNxFileInfo FH = (SNxFileInfo)(*tempit); ExportInfo add; add.FileType = FH.nFileType; add.Name = FH.szFileName; add.FilePath = g_FileSystem.GetCurDir(); g_ExportList.push_back(add); if ( FH.nFileType == NFS_DIR ) { tstring name = FH.szFileName; FolderExport(name); g_FileSystem.ChangeDir(_T("..")); } } // 파일 로그를 남겨 보아요~ ExportInfoList_It Export_It = g_ExportList.begin(); //@Log.LogInfo(L"###### 타입 0 번이면 폴더 1번이면 파일 ######"); for (Export_It ; Export_It != g_ExportList.end() ; ++Export_It ) { tstring name = (*Export_It).Name; tstring FilePath = (*Export_It).FilePath; int FileType = (*Export_It).FileType; //@Log.LogInfo(L"이름:[%s] , 경로:[%s] , 파일타입: [%d] ",name.c_str(),FilePath.c_str(),FileType); } // 목록을 다 뽑았으니 쓰레드를 시작해볼까!! g_pExportThread = new CFileExportThread(this->GetSafeHwnd() , ExportPath); g_pExportThread->Start(); m_bWorking = true; OriginalValue.clear(); } void CNxFileSystemToolDlg::FolderExport(tstring FolderName) { if ( g_FileSystem.ChangeDir(FolderName.c_str()) == FALSE) { return; } std::vector< SPackingFileInfo * > vecFileInfo; std::vector< std::string > vecDirList; g_FileSystem.GetDirListCurDir( vecDirList ); g_FileSystem.GetFileInfoListCurDir( vecFileInfo ); int i; for( i = 0; i < ( int )vecFileInfo.size(); i++ ) { if( vecFileInfo[ i ]->dwCompressSize > 0 ) { ExportInfo add; add.FileType = NFS_FILE; add.Name = vecFileInfo[ i ]->szFileName; add.FilePath = g_FileSystem.GetCurDir(); g_ExportList.push_back(add); } } for( i = 0; i < ( int )vecDirList.size(); i++ ) { if( _stricmp( vecDirList[ i ].c_str(), "." ) == 0 ) { continue; } if( _stricmp( vecDirList[ i ].c_str(), ".." ) == 0 ) { continue; } FolderExport( vecDirList[ i ].c_str() ); } g_FileSystem.ChangeDir( ".." ); } void CNxFileSystemToolDlg::OnAbout() { // TODO: 여기에 명령 처리기 코드를 추가합니다. CAboutDlg dlgAbout; dlgAbout.DoModal(); } void CNxFileSystemToolDlg::OnBnClickedButton1() { // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다. CString Path; this->GetDlgItemText(IDC_NAVI,Path); if( g_FileSystem.ChangeDir((LPTSTR)(LPCTSTR)Path) ) { UpdateFileList(); } } void CNxFileSystemToolDlg::OnMenuDivPacking() { // TODO: Add your command handler code here BuildDivisionPacking dlg; dlg.DoModal(); } void CNxFileSystemToolDlg::OnMenuDivPackingCapacity() { // TODO: Add your command handler code here BuildDivisionPackingCapacity dlg; dlg.DoModal(); } void CNxFileSystemToolDlg::OnPatch() { // TODO: Add your command handler code here if(!m_FileList.GetItemCount()) { AfxMessageBox(_T("파일시스템이 생성되어 있지 않습니다.\n원본패킹파일을 로드해주세요.")); return; } CFileDialog Dlg(TRUE,_T(".pak"),NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("파일(*.pak)|*.pak||"),NULL); if(Dlg.DoModal() == IDCANCEL) return; DrawWorking(); // 파일 패치 쓰레드 시작! g_pPatchThread = new PatchThread(this->GetSafeHwnd(), std::string(LPCTSTR(Dlg.GetPathName()))); g_pPatchThread->Start(); m_bWorking = true; } LRESULT CNxFileSystemToolDlg::OnCompletePatch(WPARAM wParam, LPARAM lParam) { m_bWorking = false; SAFE_DELETE(g_pPatchThread); //AfxMessageBox(_T("패치 완료!!")); if ( g_pWorking ) { ::PostMessage(g_pWorking->GetSafeHwnd(),WM_DESTROY,0,0); SAFE_DELETE(g_pWorking); } g_FileSystem.ChangeDir(_T("/")); UpdateFileList(); return 0; } void CNxFileSystemToolDlg::OnCompare() { char szFileList[ 10000 ]; TCHAR szFilter[] = _T( "DragonNest Packing File (*.pak)|*.pak|All Files (*.*)|*.*||" ); CFileDialog FileDlg( TRUE, _T("pak"), _T("*.pak"), OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_ENABLESIZING , szFilter, this ); memset( szFileList, 0, 10000 ); FileDlg.GetOFN().lpstrFile = szFileList; FileDlg.GetOFN().nMaxFile = 10000; FileDlg.m_ofn.lpstrTitle = "Open Source File"; if( FileDlg.DoModal() != IDOK ) { return; } std::vector< std::string > vecSour, vecDest; POSITION Pos = FileDlg.GetStartPosition(); while( Pos ) { CString szFileName = FileDlg.GetNextPathName( Pos ); vecSour.push_back( szFileName.GetBuffer() ); } FileDlg.m_ofn.lpstrTitle = "Open Destination File"; if( FileDlg.DoModal() != IDOK ) { return; } Pos = FileDlg.GetStartPosition(); while( Pos ) { CString szFileName = FileDlg.GetNextPathName( Pos ); vecDest.push_back( szFileName.GetBuffer() ); } std::vector< SPackingFileInfo > vecSourFileInfo, vecDestFileInfo; int i, j; for( i = 0; i < ( int )vecSour.size(); i++ ) { CEtPackingFile FileSystem; if( !FileSystem.OpenFileSystem( vecSour[ i ].c_str(), true ) ) { continue; } int nFileCount = FileSystem.GetFileCount(); for( j = 0; j < nFileCount; j++ ) { SPackingFileInfo *pFileInfo = FileSystem.GetFileInfo( j ); if( pFileInfo->dwCompressSize == 0 ) { continue; } vecSourFileInfo.push_back( *pFileInfo ); } FileSystem.CloseFileSystem(); } for( i = 0; i < ( int )vecDest.size(); i++ ) { CEtPackingFile FileSystem; if( !FileSystem.OpenFileSystem( vecDest[ i ].c_str(), true ) ) { continue; } int nFileCount = FileSystem.GetFileCount(); for( j = 0; j < nFileCount; j++ ) { SPackingFileInfo *pFileInfo = FileSystem.GetFileInfo( j ); if( pFileInfo->dwCompressSize == 0 ) { continue; } vecDestFileInfo.push_back( *pFileInfo ); } FileSystem.CloseFileSystem(); } std::vector< char > vecCheckField; std::vector< SPackingFileInfo > vecSourExist, vecDestExist, vecDiff; vecCheckField.resize( vecDestFileInfo.size() ); memset( &vecCheckField[ 0 ], 0, vecCheckField.size() ); for( i = 0; i < ( int )vecSourFileInfo.size(); i++ ) { for( j = 0; j < ( int )vecDestFileInfo.size(); j++ ) { if( _stricmp( vecSourFileInfo[ i ].szFileName, vecDestFileInfo[ j ].szFileName ) == 0 ) { vecCheckField[ j ] = 1; if( vecSourFileInfo[ i ].dwChecksum != vecDestFileInfo[ j ].dwChecksum ) { vecDiff.push_back( vecSourFileInfo[ i ] ); } break; } } if( j == ( int )vecDestFileInfo.size() ) { vecSourExist.push_back( vecSourFileInfo[ i ] ); } } for( i = 0; i < ( int )vecCheckField.size(); i++ ) { if( vecCheckField[ i ] == 0 ) { vecDestExist.push_back( vecDestFileInfo[ i ] ); } } if( vecDestExist.size() + vecSourExist.size() + vecDiff.size() == 0 ) { MessageBox( "File Is Identical" ); return; } MessageBox( "File Is Different" ); return; }