Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void NLS::WZ::File(Node n) {
- string filename = Path+n.data->name+".wz";
- ifstream *file = new ifstream(filename, ios::in|ios::binary);
- if (!file->is_open()) {
- C("ERROR") << "Failed to load " << filename << endl;
- return;
- //throw(273);
- }
- string ident(4, '\0');
- file->read(const_cast<char*>(ident.c_str()), 4);
- if (ident != "PKG1") {
- C("ERROR") << "Invalid ident header for " << filename << endl;
- return;
- }
- uint64_t fileSize = Read<uint64_t>(file);
- uint32_t fileStart = Read<uint32_t>(file);
- string copyright;
- *file >> copyright;
- file->seekg(fileStart);
- auto ReadOffset = [](ifstream* file, uint32_t fileStart) -> uint32_t {
- uint32_t p = file->tellg();
- p = (p-fileStart)^0xFFFFFFFF;
- p *= VersionHash;
- p -= OffsetKey;
- p = (p<<(p&0x1F))|(p>>(32-p&0x1F));
- uint32_t more = Read<uint32_t>(file);
- p ^= more;
- p += fileStart*2;
- return p;
- };
- if (!Version) {
- EncVersion = Read<int16_t>(file);
- int32_t count = ReadCInt(file);
- uint32_t c = 0;
- for (int k = 0; k < count; k++) {
- uint8_t type = Read<uint8_t>(file);
- if (type == 3) {
- ReadEncFast(file);
- ReadCInt(file);
- ReadCInt(file);
- Read<uint32_t>(file);
- continue;
- } else if (type == 4) {
- ReadEncFast(file);
- ReadCInt(file);
- ReadCInt(file);
- c = file->tellg();
- break;
- } else {
- C("ERROR") << "Malformed WZ structure" << endl;
- throw(273);
- }
- }
- if (c == 0) {
- C("ERROR") << "Unable to find a top level .img for hash verification" << endl;
- }
- bool success = false;
- for (uint8_t j = 0; j < 2 and !success; j++) {
- WZKey = WZKeys[j];
- for (Version = 0; Version < 256; Version++) {
- string s = tostring(Version);
- VersionHash = 0;
- for (int i = 0; i < s.size(); i++) {
- VersionHash = 32*VersionHash+s[i]+1;
- }
- uint32_t result = 0xFF^(VersionHash>>24)^(VersionHash<<8>>24)^(VersionHash<<16>>24)^(VersionHash<<24>>24);
- if (result == EncVersion) {
- file->clear();
- file->seekg(c);
- uint32_t offset = ReadOffset(file, fileStart);
- if (offset > fileSize) {
- continue;
- }
- file->seekg(offset);
- uint8_t a = Read<uint8_t>(file);
- if(a != 0x73) {
- continue;
- }
- string ss = ReadEncString(file);
- if (ss != "Property") {
- continue;
- }
- C("WZ") << "Detected WZ version: " << Version << endl;
- success = true;
- break;
- }
- }
- }
- if (!success) {
- C("ERROR") << "Unable to determine WZ version" << endl;
- throw(273);
- }
- file->seekg(fileStart+2);
- } else {
- int16_t eversion = Read<int16_t>(file);
- if (eversion != EncVersion) {
- C("ERROR") << "Version of WZ file does not match existing files" << endl;
- }
- }
- set <sf::Thread*> threads;
- function <void(Node n)> Directory = [&](Node n) {
- int32_t count = ReadCInt(file);
- if (count == 0) {
- sf::Thread* t = new sf::Thread([](Node n){File(n);}, n);
- t->Launch();
- threads.insert(t);
- return;
- }
- set<pair<string, uint32_t>> dirs;
- for (int i = 0; i < count; i++) {
- string name;
- uint8_t type = Read<uint8_t>(file);
- if (type == 1) {
- file->seekg(10, ios::cur);
- continue;
- } else if (type == 2) {
- int32_t s = Read<int32_t>(file);
- uint32_t p = file->tellg();
- file->seekg(fileStart+s);
- type = Read<uint8_t>(file);
- name = ReadEncString(file);
- file->seekg(p);
- } else if (type == 3) {
- name = ReadEncString(file);
- } else if (type == 4) {
- name = ReadEncString(file);
- } else {
- C("ERROR") << "Wat?" << endl;
- throw(273);
- }
- int32_t fsize = ReadCInt(file);
- int32_t checksum = ReadCInt(file);
- uint32_t offset = ReadOffset(file, fileStart);
- if (type == 3) {
- dirs.insert(pair<string, uint32_t>(name, offset));
- } else if (type == 4) {
- name.erase(name.size()-4);
- new Image(file, n.g(name), offset);
- } else {
- C("ERROR") << "Wat?" << endl;
- throw(273);
- }
- }
- for (auto it = dirs.begin(); it != dirs.end(); it++) {
- file->seekg(it->second);
- Directory(n.g(it->first));
- }
- };
- Directory(n);
- for (auto it = threads.begin(); it != threads.end(); it++) {
- (*it)->Wait();
- delete *it;
- }
- }
Add Comment
Please, Sign In to add comment