植物大战僵尸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 << "程序结束!";
}