1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS
#ifndef MPQ_H
#define MPQ_H
#include "libmpq/mpq.h"
#include <string.h>
#include <ctype.h>
#include <vector>
#include <iostream>
#include <deque>
using namespace std;
typedef unsigned int uint32;
class MPQArchive
{
public:
mpq_archive mpq_a;
MPQArchive(const char* filename);
void close();
uint32 HashString(const char* Input, uint32 Offset) {
uint32 seed1 = 0x7fed7fed;
uint32 seed2 = 0xeeeeeeee;
for (uint32 i = 0; i < strlen(Input); i++) {
uint32 val = toupper(Input[i]);
seed1 = mpq_a.buf[Offset + val] ^ (seed1 + seed2);
seed2 = val + seed1 + seed2 + (seed2 << 5) + 3;
}
return seed1;
}
mpq_hash GetHashEntry(const char* Filename) {
uint32 index = HashString(Filename, 0);
index &= mpq_a.header->hashtablesize - 1;
uint32 name1 = HashString(Filename, 0x100);
uint32 name2 = HashString(Filename, 0x200);
for(uint32 i = index; i < mpq_a.header->hashtablesize; ++i) {
mpq_hash hash = mpq_a.hashtable[i];
if (hash.name1 == name1 && hash.name2 == name2) return hash;
}
mpq_hash nullhash;
nullhash.blockindex = 0xFFFFFFFF;
return nullhash;
}
void GetFileListTo(vector<string>& filelist) {
mpq_hash hash = GetHashEntry("(listfile)");
uint32 blockindex = hash.blockindex;
if ((blockindex == 0xFFFFFFFF) || (blockindex == 0))
return;
uint32 size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, blockindex);
char *buffer = new char[size];
libmpq_file_getdata(&mpq_a, hash, blockindex, (unsigned char*)buffer);
char seps[] = "\n";
char *token;
token = strtok( buffer, seps );
uint32 counter = 0;
while ((token != NULL) && (counter < size)) {
//cout << token << endl;
token[strlen(token) - 1] = 0;
string s = token;
filelist.push_back(s);
counter += strlen(token) + 2;
token = strtok(NULL, seps);
}
delete[] buffer;
}
};
typedef std::deque<MPQArchive*> ArchiveSet;
class MPQFile
{
//MPQHANDLE handle;
bool eof;
char *buffer;
size_t pointer,size;
// disable copying
MPQFile(const MPQFile &f) {}
void operator=(const MPQFile &f) {}
public:
MPQFile(const char* filename); // filenames are not case sensitive
~MPQFile() { close(); }
size_t read(void* dest, size_t bytes);
size_t getSize() { return size; }
size_t getPos() { return pointer; }
char* getBuffer() { return buffer; }
char* getPointer() { return buffer + pointer; }
bool isEof() { return eof; }
void seek(int offset);
void seekRelative(int offset);
void close();
};
inline void flipcc(char *fcc)
{
char t;
t=fcc[0];
fcc[0]=fcc[3];
fcc[3]=t;
t=fcc[1];
fcc[1]=fcc[2];
fcc[2]=t;
}
#endif
|