void MPQArchive::close() { libmpq_archive_close(&mpq_a); for(ArchiveSet::iterator it=gOpenArchives.begin(); it!=gOpenArchives.end();++it) { mpq_archive &mpq_b = **it; if (&mpq_b == &mpq_a) { gOpenArchives.erase(it); //delete (*it); return; } } }
MPQArchive::MPQArchive(wxString filename) : ok(false) { wxLogMessage(wxT("Opening %s %s"), filename.Mid(gamePath.Len()).c_str(), isPartialMPQ(filename) ? "(Partial)" : ""); g_modelViewer->SetStatusText(wxT("Initiating "+filename+wxT(" Archive"))); #ifndef _MINGW if (!SFileOpenArchive(filename.fn_str(), 0, MPQ_OPEN_FORCE_MPQ_V1|MPQ_OPEN_READ_ONLY, &mpq_a )) { #else if (!SFileOpenArchive(filename.char_str(), 0, MPQ_OPEN_FORCE_MPQ_V1|MPQ_OPEN_READ_ONLY, &mpq_a )) { #endif int nError = GetLastError(); wxLogMessage(wxT("Error opening archive %s, error #: 0x%X"), filename.Mid(gamePath.Len()).c_str(), nError); return; } // do patch, but skip cache\ directory if (!(filename.BeforeLast(SLASH).Lower().Contains(wxT("cache")) && filename.AfterLast(SLASH).Lower().StartsWith(wxT("patch"))) && !isPartialMPQ(filename)) { // skip the PTCH files atrchives // do patch for(ssize_t j=mpqArchives.GetCount()-1; j>=0; j--) { if (!mpqArchives[j].AfterLast(SLASH).StartsWith(wxT("wow-update-"))) continue; if (mpqArchives[j].AfterLast(SLASH).Len() == strlen("wow-update-xxxxx.mpq")) { #ifndef _MINGW SFileOpenPatchArchive(mpq_a, mpqArchives[j].fn_str(), "base", 0); SFileOpenPatchArchive(mpq_a, mpqArchives[j].fn_str(), langName.fn_str(), 0); #else SFileOpenPatchArchive(mpq_a, mpqArchives[j].char_str(), "base", 0); SFileOpenPatchArchive(mpq_a, mpqArchives[j].char_str(), langName.char_str(), 0); #endif // too many for ptr client, just comment it // wxLogMessage(wxT("Appending base & %s patch %s"), langName.c_str(), mpqArchives[j].Mid(gamePath.Len()).c_str()); } else if (mpqArchives[j].BeforeLast(SLASH) == filename.BeforeLast(SLASH)) { // same directory only #ifndef _MINGW SFileOpenPatchArchive(mpq_a, mpqArchives[j].fn_str(), "", 0); #else SFileOpenPatchArchive(mpq_a, mpqArchives[j].char_str(), "", 0); #endif // wxLogMessage(wxT("Appending patch %s"), mpqArchives[j].Mid(gamePath.Len()).c_str()); } } } ok = true; gOpenArchives.push_back( make_pair( filename, &mpq_a ) ); } MPQArchive::~MPQArchive() { /* for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i) { mpq_archive &mpq_a = **i; free(mpq_a.header); } */ //gOpenArchives.erase(gOpenArchives.begin(), gOpenArchives.end()); } bool MPQArchive::isPartialMPQ(wxString filename) { if (filename.AfterLast(SLASH).StartsWith(wxT("wow-update-"))) return true; return false; } void MPQArchive::close() { if (ok == false) return; SFileCloseArchive(mpq_a); for(ArchiveSet::iterator it=gOpenArchives.begin(); it!=gOpenArchives.end();++it) { HANDLE &mpq_b = *it->second; if (&mpq_b == &mpq_a) { gOpenArchives.erase(it); //delete (*it); return; } } } bool MPQFile::isPartialMPQ(wxString filename) { if (filename.AfterLast(SLASH).StartsWith(wxT("wow-update-"))) return true; return false; } void MPQFile::openFile(wxString filename) { eof = false; buffer = 0; pointer = 0; size = 0; if( useLocalFiles ) { wxString fn1 = wxGetCwd()+SLASH+wxT("Import")+SLASH; wxString fn2 = fn1; wxString fn3 = gamePath; fn1.Append(filename); fn2.Append(filename.AfterLast(SLASH)); fn3.Append(filename); wxString fns[] = { fn1, fn2, fn3 }; for(size_t i=0; i<WXSIZEOF(fns); i++) { wxString fn = fns[i]; if (wxFile::Exists(fn)) { // success wxFile file; // if successfully opened if (file.Open(fn, wxFile::read)) { size = file.Length(); if (size > 0) { buffer = new unsigned char[size]; // if successfully read data if (file.Read(buffer, size) > 0) { eof = false; file.Close(); return; } else { wxDELETEA(buffer); eof = true; size = 0; } } file.Close(); } } } } // zhCN alternate file mode if (bAlternate && !filename.Lower().StartsWith(wxT("alternate"))) { wxString alterName = wxT("alternate")+SLASH+filename; for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end(); ++i) { HANDLE &mpq_a = *i->second; HANDLE fh; #ifndef _MINGW if( !SFileOpenFileEx( mpq_a, alterName.fn_str(), SFILE_OPEN_PATCHED_FILE, &fh ) ) #else if( !SFileOpenFileEx( mpq_a, alterName.char_str(), SFILE_OPEN_PATCHED_FILE, &fh ) ) #endif continue; // Found! DWORD filesize = SFileGetFileSize( fh ); size = filesize; // HACK: in patch.mpq some files don't want to open and give 1 for filesize if (size<=1) { eof = true; buffer = 0; return; } buffer = new unsigned char[size]; SFileReadFile( fh, buffer, (DWORD)size ); SFileCloseFile( fh ); return; } } for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end(); ++i) { HANDLE &mpq_a = *i->second; HANDLE fh; #ifndef _MINGW if( !SFileOpenFileEx( mpq_a, filename.fn_str(), SFILE_OPEN_PATCHED_FILE, &fh ) ) #else if( !SFileOpenFileEx( mpq_a, filename.char_str(), SFILE_OPEN_PATCHED_FILE, &fh ) ) #endif continue; // Found! DWORD filesize = SFileGetFileSize( fh ); size = filesize; // HACK: in patch.mpq some files don't want to open and give 1 for filesize if (size<=1) { eof = true; buffer = 0; return; } buffer = new unsigned char[size]; SFileReadFile( fh, buffer, (DWORD)size ); SFileCloseFile( fh ); return; } eof = true; buffer = 0; }