bool ExtractFile( char const* mpq_name, std::string const& filename ) { for(ArchiveSet::const_reverse_iterator i=gOpenArchives.rbegin(); i!=gOpenArchives.rend();++i) { HANDLE fileHandle; if (!SFileOpenFileEx(*i, mpq_name, SFILE_OPEN_PATCHED_FILE, &fileHandle)) continue; if (SFileGetFileSize(fileHandle, NULL) == 0) // some files removed in next updates and its reported size 0 { SFileCloseFile(fileHandle); return true; } SFileCloseFile(fileHandle); if (!SFileExtractFile(*i, mpq_name, filename.c_str(), SFILE_OPEN_PATCHED_FILE)) { printf("Can't extract file: %s\n", mpq_name); return false; } return true; } printf("Extracting file not found: %s\n", filename.c_str()); return false; }
bool OpenNewestFile(char const* filename, HANDLE* fileHandlerPtr) { for(ArchiveSet::const_reverse_iterator i=gOpenArchives.rbegin(); i!=gOpenArchives.rend();++i) { // always prefer get updated file version if (SFileOpenFileEx(*i, filename, SFILE_OPEN_PATCHED_FILE, fileHandlerPtr)) return true; } return false; }
MPQFile::MPQFile(const char* filename): eof(false), buffer(0), pointer(0), size(0) { for(ArchiveSet::reverse_iterator i=gOpenArchives.rbegin(); i!=gOpenArchives.rend();++i) { mpq_archive &mpq_a = (*i)->mpq_a; mpq_hash hash = (*i)->GetHashEntry(filename); uint32 blockindex = hash.blockindex; if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) { continue; //file not found } int fileno = blockindex; //int fileno = libmpq_file_number(&mpq_a, filename); //if(fileno == LIBMPQ_EFILE_NOT_FOUND) // continue; // Found! size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, fileno); // 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 char[size]; //libmpq_file_getdata int result = libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer); return; } eof = true; buffer = 0; }