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

📄 mpq.cpp

📁 魔兽解压DBC的一些功能代码,专门用来分解魔兽客户端所使用的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		case LIBMPQ_FILE_TYPE_CHAR:
			for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) {
				sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i);
				if (strncmp(tempfile, (char *)file, strlen((char *)file)) == 0) {

					/* if file found break */
					found = 1;
					break;
				}
			}

			/* if a file was found return 0 */
			if (found == 1) {
				return LIBMPQ_TOOLS_SUCCESS;
			} else {
				return LIBMPQ_EFILE_NOT_FOUND;
			}
		default:
			return LIBMPQ_TOOLS_SUCCESS;
	}
}

/*
 *  This function extracts a file from a MPQ archive
 *  by the given number.
 */
int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename) {
	int blockindex = number; //-1;
	int fd = 0;
	int i = 0;
	char buffer[0x1000];
	//char tempfile[PATH_MAX];
	unsigned int transferred = 1;
	mpq_file *mpq_f = NULL;
	mpq_block *mpq_b = NULL;
	mpq_hash *mpq_h = NULL;

/*	if (number < 1 || number > mpq_a->header->blocktablesize) {
		return LIBMPQ_EINV_RANGE;
	}*/
/*
	sprintf(tempfile, libmpq_file_name(mpq_a, number));
*/
	/* check if mpq_f->filename could be written here. */
	fd = _open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
	if (fd == LIBMPQ_EFILE) {
		return LIBMPQ_EFILE;
	}

	/* search for correct hashtable */
	/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
		if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
			blockindex = (mpq_a->hashtable[i]).blockindex;
			mpq_h = &(mpq_a->hashtable[i]);
			break;
		}
	}*/

	/* check if file was found */
	if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
		return LIBMPQ_EFILE_NOT_FOUND;
	}

	/* check if sizes are correct */
	mpq_b = mpq_a->blocktable + blockindex;
	if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
		return LIBMPQ_EFILE_CORRUPT;
	}

	/* check if file exists */
	if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
		return LIBMPQ_EFILE_NOT_FOUND;
	}

	/* allocate memory for file structure */
	mpq_f = (mpq_file *)malloc(sizeof(mpq_file));
	if (!mpq_f) {
		return LIBMPQ_EALLOCMEM;
	}

	/* initialize file structure */
	memset(mpq_f, 0, sizeof(mpq_file));
	mpq_f->fd             = fd;
	mpq_f->mpq_b          = mpq_b;
	mpq_f->nblocks        = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
	mpq_f->mpq_h          = mpq_h;
	mpq_f->accessed       = FALSE;
	mpq_f->blockposloaded = FALSE;
	sprintf((char *)mpq_f->filename, filename);

	/* allocate buffers for decompression. */
	if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {

		/*
		 *  Allocate buffer for block positions. At the begin of file are stored
		 *  unsigned ints holding positions of each block relative from begin of
		 *  file in the archive.
		 */
		if ((mpq_f->blockpos = (unsigned int *)malloc(sizeof(int) * mpq_f->nblocks + 1)) == NULL) {
			return LIBMPQ_EALLOCMEM;
		}
	}

	while (transferred > 0) {
		transferred = libmpq_file_read_file(mpq_a, mpq_f, mpq_f->filepos, buffer, sizeof(buffer));
		if (transferred == 0) {
			break;
		} else {
			mpq_f->accessed  = TRUE;
			mpq_f->filepos  += transferred;
		}

		transferred = _write(mpq_f->fd, buffer, transferred);
		if (transferred == 0) {
			break;
		}
	}

	_close(fd);

	/* freeing the file structure */
	free(mpq_f);
	return LIBMPQ_TOOLS_SUCCESS;
}

/*
 *  This function tries to get the filenames for the hashes. It uses
 *  an internal listfile database and gets the correct listfile from
 *  some specific archive informations.
 */

int libmpq_listfile_open(mpq_archive *mpq_a, char file[PATH_MAX]) {
	FILE *fp;
	//char **filelist;
	int i = 0;
	//int fl_count;
	//int fl_size;
	int fl_count_fb;
	int fl_size_fb;
	int result = LIBMPQ_TOOLS_SUCCESS;
	struct stat statbuf;

	/* get file status */
	if (stat(file, &statbuf) < 0) {
		result = LIBMPQ_CONF_EFILE_NOT_FOUND;
	}

	/* check if file is a filename or directory */
	/*if (S_ISDIR(statbuf.st_mode)) {

		// allocate memory for the file list
		filelist = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
		fl_count = 0;
		fl_size = LIBMPQ_CONF_FL_INCREMENT;

		// check if it is a valid listfile
		if (libmpq_detect_listfile_rec(file, &filelist, &fl_count, &fl_size)) {
			filelist == NULL;
		}

		filelist[fl_count] = NULL;

		// return if no listfile was found
		if (filelist == NULL) {
			result = LIBMPQ_CONF_EFILE_NOT_FOUND;
		}

		for (i = 0; filelist[i]; i++) {
			if ((fp = fopen(filelist[i], "r")) != NULL ) {
				result = libmpq_read_listfile(mpq_a, fp);
				fclose(fp);
			}
		}

		// freeing the listfile struct
		libmpq_free_listfile(filelist);
	}*/

	/* if file is a regular file use it */
	//if (S_ISREG(statbuf.st_mode)) {

		/* if specific listfile was forced. */
		if ((fp = fopen(file, "r")) != NULL ) {
			result = libmpq_read_listfile(mpq_a, fp);
			fclose(fp);
		} else {
			result = LIBMPQ_CONF_EFILE_OPEN;
		}
	//}

	/* if error occured we need to create a fallback filelist. */
	if (mpq_a->mpq_l->mpq_files == NULL) {

		/* allocate memory for the file list */
		mpq_a->mpq_l->mpq_files = (unsigned char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
		fl_count_fb = 0;
		fl_size_fb = LIBMPQ_CONF_FL_INCREMENT;

		for (i = 0; i < libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES); i++) {

			/* set the next filelist entry to a copy of the file */
			mpq_a->mpq_l->mpq_files[fl_count_fb++] = (unsigned char *)_strdup("file%06lu.xxx");

			/* increase the array size */
			if (fl_count_fb == fl_size_fb) {
				mpq_a->mpq_l->mpq_files = (unsigned char **)realloc(mpq_a->mpq_l->mpq_files, (fl_size_fb + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *));
				fl_size_fb += LIBMPQ_CONF_FL_INCREMENT;
			}
		}
		mpq_a->mpq_l->mpq_files[fl_count_fb] = NULL;

		/* if no error occurs and no listfile was assigned, we think there was no matching listfile. */
		if (result == 0) {
			result = LIBMPQ_CONF_EFILE_NOT_FOUND;
		}
	}

	return result;
}

/*
 *  This function frees the allocated memory for the listfile.
 */
int libmpq_listfile_close(mpq_archive *mpq_a) {
	int i = 0;

	/* safety check if we really have a filelist. */
	if (mpq_a->mpq_l->mpq_files != NULL) {
		/* freeing the filelist */
		while (mpq_a->mpq_l->mpq_files[i]) {
			free(mpq_a->mpq_l->mpq_files[i++]);
		}
		free(mpq_a->mpq_l->mpq_files);
	}
    return 0;
}

int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest) {
	int blockindex = number; //-1;
	int i = 0;
	mpq_file *mpq_f = NULL;
	mpq_block *mpq_b = NULL;
	int success = 0;

	/*if (number < 1 || number > mpq_a->header->blocktablesize) {
		return LIBMPQ_EINV_RANGE;
	}*/

	/* search for correct hashtable */
	/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
		if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
			blockindex = (mpq_a->hashtable[i]).blockindex;
			mpq_h = &(mpq_a->hashtable[i]);
			break;
		}
	}*/

	/* check if file was found */
	if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
		return LIBMPQ_EFILE_NOT_FOUND;
	}

	/* check if sizes are correct */
	mpq_b = mpq_a->blocktable + blockindex;
	if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
		return LIBMPQ_EFILE_CORRUPT;
	}

	/* check if file exists */
	if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
		return LIBMPQ_EFILE_NOT_FOUND;
	}

	/* allocate memory for file structure */
	mpq_f = (mpq_file*)malloc(sizeof(mpq_file));
	if (!mpq_f) {
		return LIBMPQ_EALLOCMEM;
	}

	/* initialize file structure */
	memset(mpq_f, 0, sizeof(mpq_file));
	mpq_f->mpq_b          = mpq_b;
	mpq_f->nblocks        = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
	mpq_f->mpq_h          = &mpq_h;
	mpq_f->accessed       = FALSE;
	mpq_f->blockposloaded = FALSE;

	/* allocate buffers for decompression. */
	if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {

		/*
		 *  Allocate buffer for block positions. At the begin of file are stored
		 *  unsigned ints holding positions of each block relative from begin of
		 *  file in the archive.
		 */
		if ((mpq_f->blockpos = (unsigned int*)malloc(sizeof(int) * (mpq_f->nblocks + 1))) == NULL) {
			return LIBMPQ_EALLOCMEM;
		}
	}

    if(libmpq_file_read_file(mpq_a, mpq_f, 0, (char*)dest, mpq_b->fsize) == mpq_b->fsize)
        success = 1;

    if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
        // Free buffer for block positions
		
	       free(mpq_f->blockpos);
	}
	/* freeing the file structure */
	free(mpq_f);
	return success?LIBMPQ_TOOLS_SUCCESS:LIBMPQ_EFILE_CORRUPT;
}

⌨️ 快捷键说明

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