⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.cpp

📁 wowmodelview魔兽世界的模型查看工具。下了看看吧
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (mpq_b->filepos > archivesize || mpq_b->csize > archivesize) {			if ((mpq_a->flags & LIBMPQ_FLAG_PROTECTED) == 0) {				return LIBMPQ_EFILE_FORMAT;			}		}		mpq_b->filepos += mpq_a->mpqpos;	}	return LIBMPQ_TOOLS_SUCCESS;}int libmpq_file_read_block(mpq_archive *mpq_a, mpq_file *mpq_f, unsigned int blockpos, char *buffer, unsigned int blockbytes) {	unsigned char *tempbuf = NULL;			/* Buffer for reading compressed data from the file */	unsigned int readpos;				/* Reading position from the file */	unsigned int toread = 0;			/* Number of bytes to read */	unsigned int blocknum;				/* Block number (needed for decrypt) */	unsigned int bytesread = 0;			/* Total number of bytes read */	unsigned int nblocks;				/* Number of blocks to load */	unsigned int i;	/* Test parameters. Block position and block size must be block-aligned, block size nonzero */	if ((blockpos & (mpq_a->blocksize - 1)) || blockbytes == 0) {		return 0;	}	/* Check the end of file */	if ((blockpos + blockbytes) > mpq_f->mpq_b->fsize) {		blockbytes = mpq_f->mpq_b->fsize - blockpos;	}	blocknum = blockpos   / mpq_a->blocksize;	nblocks  = blockbytes / mpq_a->blocksize;	if (blockbytes % mpq_a->blocksize) {		nblocks++;	}	/* If file has variable block positions, we have to load them */	if ((mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) && mpq_f->blockposloaded == FALSE) {		unsigned int nread;		if (mpq_f->mpq_b->filepos != mpq_a->filepos) {			lseek(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET);		}		/* Read block positions from begin of file. */		nread = (mpq_f->nblocks + 1) * sizeof(int);		nread = read(mpq_a->fd, mpq_f->blockpos, nread);		/*		 *  If the archive is protected some way, perform additional check		 *  Sometimes, the file appears not to be encrypted, but it is.		 */		if (mpq_f->blockpos[0] != nread) {			mpq_f->mpq_b->flags |= LIBMPQ_FILE_ENCRYPTED;		}		/* Decrypt loaded block positions if necessary */		if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) {			/* If we don't know the file seed, try to find it. */			if (mpq_f->seed == 0) {				mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread);			}			/* If we don't know the file seed, sorry but we cannot extract the file. */			if (mpq_f->seed == 0) {				return 0;			}			/* Decrypt block positions */			libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1);			/*			 *  Check if the block positions are correctly decrypted			 *  I don't know why, but sometimes it will result invalid			 *  block positions on some files.			 */			if (mpq_f->blockpos[0] != nread) {				/* Try once again to detect file seed and decrypt the blocks */				lseek(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET);				nread = read(mpq_a->fd, mpq_f->blockpos, (mpq_f->nblocks + 1) * sizeof(int));				mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread);				libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1);				/* Check if the block positions are correctly decrypted. */				if (mpq_f->blockpos[0] != nread) {					return 0;				}			}		}		/* Update mpq_f's variables */		mpq_f->blockposloaded = TRUE;		mpq_a->filepos        = mpq_f->mpq_b->filepos + nread;	}	/* Get file position and number of bytes to read */	readpos = blockpos;	toread  = blockbytes;	if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {		readpos = mpq_f->blockpos[blocknum];		toread  = mpq_f->blockpos[blocknum + nblocks] - readpos;	}	readpos += mpq_f->mpq_b->filepos;	/* Get work buffer for store read data */	if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {		if ((tempbuf = (unsigned char*)malloc(toread)) == NULL) {			/* Hmmm... We should add a better error handling here :) */			return 0;		}	}	/* Set file pointer, if necessary. */	if (mpq_a->filepos != readpos) {		mpq_a->filepos = lseek(mpq_a->fd, readpos, SEEK_SET);	}	/* 15018F87 - Read all requested blocks. */	bytesread = read(mpq_a->fd, tempbuf, toread);	mpq_a->filepos = readpos + bytesread;	/* Block processing part. */	unsigned int blockstart = 0;			/* Index of block start in work buffer. */	unsigned int blocksize  = min(blockbytes, mpq_a->blocksize);	unsigned int index      = blocknum;		/* Current block index. */	bytesread = 0;					/* Clear read byte counter */	/* Walk through all blocks. */	for (i = 0; i < nblocks; i++, index++) {		int outlength = mpq_a->blocksize;		/* Get current block length */		if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {			blocksize = mpq_f->blockpos[index + 1] - mpq_f->blockpos[index];		}		/* If block is encrypted, we have to decrypt it. */		if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) {			if (mpq_f->seed == 0) {				return 0;			}			libmpq_decrypt_block(mpq_a, (unsigned int *)&tempbuf[blockstart], blocksize, mpq_f->seed + index);		}		/*		 *  If the block is really compressed, recompress it.		 *  WARNING: Some block may not be compressed, it can		 *  only be determined by comparing uncompressed and		 *  compressed size!		 */		if (blocksize < blockbytes) {			/* Is the file compressed with PKWARE Data Compression Library? */			if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) {				libmpq_pkzip_decompress(buffer, &outlength, (char*)&tempbuf[blockstart], blocksize);			}			/*			 *  Is it a file compressed by Blizzard's multiple compression ?			 *  Note that Storm.dll v 1.0.9 distributed with Warcraft III			 *  passes the full path name of the opened archive as the new			 *  last parameter.			 */			if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) {				libmpq_multi_decompress(buffer, &outlength, (char*)&tempbuf[blockstart], blocksize);			}			bytesread += outlength;			buffer    += outlength;		} else {			memcpy(buffer, tempbuf, blocksize);			bytesread += blocksize;			buffer    += blocksize;		}		blockstart += blocksize;	}	/* Delete input buffer, if necessary. */	if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {		free(tempbuf);	}	return bytesread;}int libmpq_file_read_file(mpq_archive *mpq_a, mpq_file *mpq_f, unsigned int filepos, char *buffer, unsigned int toread) {	unsigned int bytesread = 0;			/* Number of bytes read from the file */	unsigned int blockpos;				/* Position in the file aligned to the whole blocks */	unsigned int loaded = 0;	/* File position is greater or equal to file size? */	if (filepos >= mpq_f->mpq_b->fsize) {		return 0;	}	/* If to few bytes in the file remaining, cut them */	if ((mpq_f->mpq_b->fsize - filepos) < toread) {		toread = (mpq_f->mpq_b->fsize - filepos);	}	/* Block position in the file */	blockpos = filepos & ~(mpq_a->blocksize - 1);	/*	 *  Load the first block, if noncomplete. It may be loaded in the cache buffer.	 *  We have to check if this block is loaded. If not, load it.	 */	if ((filepos % mpq_a->blocksize) != 0) {		/* Number of bytes remaining in the buffer */		unsigned int tocopy;		unsigned int loaded = mpq_a->blocksize;		/* Check if data are loaded in the cache */		if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) {   			/* Load one MPQ block into archive buffer */			loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char*)mpq_a->blockbuf, mpq_a->blocksize);			if (loaded == 0) {				return 0;			}			/* Save lastly accessed file and block position for later use */			mpq_f->accessed = TRUE;			mpq_a->blockpos = blockpos;			mpq_a->bufpos   = filepos % mpq_a->blocksize;		}		tocopy = loaded - mpq_a->bufpos;		if (tocopy > toread) {			tocopy = toread;		}		/* Copy data from block buffer into target buffer */		memcpy(buffer, mpq_a->blockbuf + mpq_a->bufpos, tocopy);		/* Update pointers */		toread        -= tocopy;		bytesread     += tocopy;		buffer        += tocopy;		blockpos      += mpq_a->blocksize;		mpq_a->bufpos += tocopy;		/* If all, return. */		if (toread == 0) {			return bytesread;		}	}	/* Load the whole ("middle") blocks only if there are more or equal one block */	if (toread > mpq_a->blocksize) {		unsigned int blockbytes = toread & ~(mpq_a->blocksize - 1);		loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, buffer, blockbytes);		if (loaded == 0) {			return 0;		}		/* Update pointers */		toread    -= loaded;		bytesread += loaded;		buffer    += loaded;		blockpos  += loaded;		/* If all, return. */		if (toread == 0) {			return bytesread;		}	}	/* Load the terminating block */	if (toread > 0) {		unsigned int tocopy = mpq_a->blocksize;		/* Check if data are loaded in the cache */		if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) {			/* Load one MPQ block into archive buffer */			tocopy = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char*)mpq_a->blockbuf, mpq_a->blocksize);			if (tocopy == 0) {				return 0;			}			/* Save lastly accessed file and block position for later use */			mpq_f->accessed = TRUE;			mpq_a->blockpos = blockpos;		}		mpq_a->bufpos  = 0;		/* Check number of bytes read */		if (tocopy > toread) {			tocopy = toread;		}		memcpy(buffer, mpq_a->blockbuf, tocopy);		bytesread     += tocopy;		mpq_a->bufpos  = tocopy;	}	/* Return what we've read */	return bytesread;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -