植物大战僵尸pak修改

19 篇文章 0 订阅
7 篇文章 0 订阅

植物大战僵尸pak修改

pvz.h

#pragma once
extern "C"
{
#include<stdio.h>
}
#include<iostream>
struct fileinf
{
	fileinf();
	char *filename;
	int filelength,refilelength;
	bool Reset;
	char filenamelength;
	char *loadpath;
	void setLoadpath(char *loadpath);
	fileinf*next;
};
int getlast(const char *t);
void makeRelatedpath(char *file, char *savepath, char *out);
fileinf*findinf(fileinf*head,const char*name);
class pvz
{
private:
	char inumber[9];
	bool freed;
public:
	FILE *pak;
	bool hasmore;
	long datastart;
	pvz(char*);
	~pvz();
	void getnextfileinf(FILE *, fileinf *);
	void release();
	void getallfileinf(fileinf *head,FILE *outpath);
	void Export(fileinf *head, FILE *savepath,FILE *tmppath);
	static void decodefile(const char *path);
};

pvz.cpp

#include"pvz.h"
#include<direct.h>
#include <io.h>
#pragma warning(disable:4996)
int getlast(const char *t)
{
	int len = strlen(t);
	for (int i = len - 1; i >= 0; i--)
		if (t[i] == '\\')
			return i;
	return 0;
}
void makeRelatedpath(char *file, char *savepath, char *out)
{
	int len = strlen(savepath);
	int ed = strlen(file);
	memset(out, 0, 256);
	strcpy(out, savepath);
	int j = len;
	for (int i = 0; i < ed; i++)
	{
		out[j++] = file[i];
		if (file[i] == '\\')
			if (access(out, 0) == -1)
				mkdir(out);
	}
}
fileinf*findinf(fileinf*head,const char*name)
{
	fileinf*t = head;
	while (1)
	{
		if (t == NULL)break;
		if (!strcmp(t->filename, name))return t;
		t = t->next;
	}
	return NULL;
}
pvz::pvz(char*pakfile)
{
	this->freed = false;
	this->hasmore = true;
	this->pak = fopen(pakfile, "rb");
	fread(this->inumber, 1, 9, this->pak);
	if (this->inumber[0] != 0xC0 && this->inumber[0] ^ 0xF7 == 0xC0
		&& this->inumber[1] != 0x4A && this->inumber[1] ^ 0xF7 == 0x4A
		&& this->inumber[2] != 0xC0 && this->inumber[2] ^ 0xF7 == 0xC0
		&& this->inumber[3] != 0xBA && this->inumber[3] ^ 0xF7 == 0xC0)
	{
		fseek(this->pak, 0, 0);
		printf("开始文件异或运算\n");
		FILE *tp = fopen("temp.tmp", "wb");
		char t[1024];
		int len = 0;
		while ((len = fread(t, 1, 1024, this->pak)))
		{
			for (int i = 0; i < len; i++)
				t[i] ^= 0xF7;
			fwrite(t, 1, len, tp);
		}
		fclose(this->pak);
		fclose(tp);
		puts("文件已输出");
		this->pak = fopen("temp.tmp", "rb");
		fseek(this->pak, 9, 0);
	}
}

void pvz::decodefile(const char * path)
{
	FILE *fp = fopen(path, "rb");
	FILE *tp = fopen("temp.tmp", "wb");
	char t[1024];
	int len = 0;
	while ((len = fread(t, 1, 1024, fp)))
	{
		for (int i = 0; i < len; i++)
			t[i] ^= 0xF7;
		fwrite(t, 1, len, tp);
	}
	fclose(fp);
	fclose(tp);
	remove(path);
	rename("temp.tmp", path);
}

pvz::~pvz()
{
	if(!this->freed)
	fclose(this->pak);
}

void pvz::getnextfileinf(FILE *fp, fileinf *head)
{
	char len;
	fread(&len, 1, 1, this->pak);
	head->filenamelength = len;
	int rellen = (unsigned char)len;
	char *t = new char[rellen +1];//读取文件名
	memset(t, 0, rellen + 1);
	t[rellen] = 0;
	fread(t, 1, rellen, this->pak);
	int datalen;
	fread(&datalen, 1, 4, this->pak);
	head->filelength = datalen;
	if (fp != NULL)
	{
		char temp[8];
		fread(temp, 1, 8, this->pak);
	}
	else
	fseek(this->pak,8, SEEK_CUR);
	fread(&len, 1, 1, this->pak);
	this->hasmore = (len == 0x0);
	head->filename = t;
}

void pvz::release()
{
	if (!this->freed)
	{
		this->freed = true;
		fclose(this->pak);
	}
}

void pvz::getallfileinf(fileinf * head, FILE *outpath)
{
	fileinf *tmp = head;
	while (1)
	{
		this->getnextfileinf(outpath,tmp);
		//tmp->filelength = this->filelength;
		if (!this->hasmore)break;
		tmp->next = new fileinf();
		tmp = tmp->next;
		tmp->next = NULL;
	}
	this->datastart = ftell(this->pak);
}

void pvz::Export(fileinf * head, FILE * savepath, FILE *tmppath)
{
	fwrite(this->inumber, 1, 8, savepath);
	fileinf*r = head;
	char t[8];
	char flag[2],readbuffer[1024];
	flag[0] = 0x0;
	flag[1] = 0x80;
	printf("输出头部信息中...\n");
	while (true)
	{
		if (r == NULL)
		{
			fwrite(&flag[1], 1, 1, savepath);
			break;
		}
		else fwrite(&flag[0], 1, 1, savepath);
		fwrite(&r->filenamelength, 1, 1, savepath);
		fwrite(r->filename, 1, (int)(unsigned char)r->filenamelength, savepath);
		if(r->Reset)
			fwrite(&r->refilelength, sizeof(int), 1, savepath);
		else
			fwrite(&r->filelength, sizeof(int), 1, savepath);
		fread(t, 1, 8, tmppath);
		fwrite(t, 1, 8, savepath);
		r = r->next;
	}
	printf("输出完成,开始更改\n");
	fseek(this->pak, this->datastart, 0);
	int s, k;
	r = head;
	while (true)
	{
		if (r == NULL)
			break;
		if (r->Reset)
		{
			fseek(this->pak, r->filelength, 1);
			printf("已经将%s插入至pak文件\n",r->loadpath);
			FILE *tmp = fopen(r->loadpath, "rb");
			s = r->refilelength % 1024;
			k = r->refilelength / 1024;
			for (int i = 0; i < k; i++)
			{
				fread(readbuffer, 1, 1024, tmp);
				fwrite(readbuffer, 1, 1024, savepath);
			}
			fread(readbuffer, 1, s, tmp);
			fwrite(readbuffer, 1, s, savepath);
			fclose(tmp);
		}
		else
		{
			s = r->filelength % 1024;
			k = r->filelength / 1024;
			for (int i = 0; i < k; i++)
			{
				fread(readbuffer, 1, 1024, this->pak);
				fwrite(readbuffer, 1, 1024, savepath);
			}
			fread(readbuffer, 1, s, this->pak);
			fwrite(readbuffer, 1, s, savepath);
		}
		r = r->next;
	}
	puts("数据信息已修改完成!\n开始追加尾部信息...");
	int len = 0;
	while ((len = fread(readbuffer, 1, 1024, this->pak)))
	{
		fwrite(readbuffer, 1, 1024, savepath);
	}
	puts("尾部信息追加结束,文件修改完成!");
}

fileinf::fileinf()
{
	this->Reset = false;
}

void fileinf::setLoadpath(char * loadpath)
{
	this->Reset = true;
	this->loadpath = loadpath;
	FILE *fp = fopen(loadpath, "rb");
	fseek(fp, 0, 2);
	this->refilelength = (int)ftell(fp);
	fclose(fp);
}

main.cpp

#include"pvz.h"
#include<iostream>
#include<direct.h>
#pragma warning(disable:4996)
using namespace std;
void ex()
{
	pvz p("E:\\desktop\\1.pak");
	fileinf *h = new fileinf();
	p.getallfileinf(h, NULL);
	fileinf *t = h;
	char *tmpdir = "tmp\\";
	mkdir(tmpdir);
	char path[256], read[1024];
	while (1)
	{
		if (t == NULL)break;
		makeRelatedpath(t->filename, tmpdir, path);
		int s = t->filelength % 1024;
		int k = t->filelength / 1024;
		FILE *fp = fopen(path, "wb");
		for (int i = 0; i<k; i++)
		{

			fread(read, 1, 1024, p.pak);
			fwrite(read, 1, 1024, fp);
		}
		fread(read, 1, s, p.pak);
		fwrite(read, 1, s, fp);
		fclose(fp);
		t = t->next;
	}
}
#define NUM 14
void main()
{
	char *stpath = "E:\\Visual Studio 2015\\Projects\\植物大战僵尸\\植物大战僵尸\\tmp\\";
	char refile[NUM][256]={
		"reanim\\Zombie_head.png",
		"reanim\\Zombie_imp_jaw.png"
		,"reanim\\Zombie_jaw.png",
		"particles\\ZombieHead.png"
		,"sounds\\awooga.ogg"
		,"ad\\loading.jpg"
		,"reanim\\Cornpult_butter.png"
		,"reanim\\Cornpult_butter_splat.png"
		,"images\\brain.png"
		,"images\\Credits_BigBrain_.png"
		,"images\\Credits_BigBrain.jpg"
		,"reanim\\ZombiesWon.jpg"
		,"reanim\\ZombiesWon_.png"
		,"reanim\\Credits_nozombies.jpg"
	};//需要修改的文件在这里提出
	pvz p("E:\\desktop\\1.pak");
	fileinf *inf = new fileinf();
	FILE *tmpfile_ = fopen("ttt.txt", "wb");
	p.getallfileinf(inf,tmpfile_);
	fclose(tmpfile_);
	printf("寻找中...\n");
	char *path;
	for (int i = 0; i < NUM; i++)
	{
		path = new char[256];
		memset(path, 0, 256);
		strcpy(path, stpath);
		strcat(path, refile[i]);
		fileinf *f = findinf(inf, refile[i]);
		if (f != NULL)
		{
			printf(path);
			printf("已被找到!");
			f->setLoadpath(path);
			printf("文件长度%d\n", f->refilelength);
		}
	}
	FILE *fp = fopen("G:\\植物大战僵尸年度版\\main.pak", "wb");
	tmpfile_= fopen("ttt.txt", "rb");
	p.Export(inf, fp, tmpfile_);
	cout << "导出完成";
	fclose(fp);
	fclose(tmpfile_);
	p.release();
	puts("开始文件异或运算");
	pvz::decodefile("G:\\植物大战僵尸年度版\\main.pak");
	puts("已输出");
	cout << "程序结束!";
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值