the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 215 lines 4.5 kB view raw
1#include "stdafx.h" 2 3#include "..\Minecraft.World\StringHelpers.h" 4#include "..\Minecraft.World\compression.h" 5 6#include "ArchiveFile.h" 7 8void ArchiveFile::_readHeader(DataInputStream *dis) 9{ 10 int numberOfFiles = dis->readInt(); 11 12 for (int i = 0; i < numberOfFiles; i++) 13 { 14 MetaData *meta = new MetaData(); 15 meta->filename = dis->readUTF(); 16 meta->ptr = dis->readInt(); 17 meta->filesize = dis->readInt(); 18 19 // Filenames preceeded by an asterisk have been compressed. 20 if (meta->filename[0] == '*') 21 { 22 meta->filename = meta->filename.substr(1); 23 meta->isCompressed = true; 24 } 25 else meta->isCompressed = false; 26 27 m_index.insert( pair<wstring,PMetaData>(meta->filename,meta) ); 28 } 29} 30 31ArchiveFile::ArchiveFile(File file) 32{ 33 m_cachedData = NULL; 34 m_sourcefile = file; 35 app.DebugPrintf("Loading archive file...\n"); 36#ifndef _CONTENT_PACKAGE 37 char buf[256]; 38 wcstombs(buf, file.getPath().c_str(), 256); 39 app.DebugPrintf("archive file - %s\n",buf); 40#endif 41 42 if(!file.exists()) 43 { 44 app.DebugPrintf("Failed to load archive file!\n");//,file.getPath()); 45 app.FatalLoadError(); 46 } 47 48 FileInputStream fis(file); 49 50#if defined _XBOX_ONE || defined __ORBIS__ || defined _WINDOWS64 51 byteArray readArray(file.length()); 52 fis.read(readArray,0,file.length()); 53 54 ByteArrayInputStream bais(readArray); 55 DataInputStream dis(&bais); 56 57 m_cachedData = readArray.data; 58#else 59 DataInputStream dis(&fis); 60#endif 61 62 _readHeader(&dis); 63 64 dis.close(); 65 fis.close(); 66#if defined _XBOX_ONE || defined __ORBIS__ || defined _WINDOWS64 67 bais.reset(); 68#endif 69 app.DebugPrintf("Finished loading archive file\n"); 70} 71 72ArchiveFile::~ArchiveFile() 73{ 74 delete m_cachedData; 75} 76 77vector<wstring> *ArchiveFile::getFileList() 78{ 79 vector<wstring> *out = new vector<wstring>(); 80 81 for ( AUTO_VAR(it, m_index.begin()); 82 it != m_index.end(); 83 it++ ) 84 85 out->push_back( it->first ); 86 87 return out; 88} 89 90bool ArchiveFile::hasFile(const wstring &filename) 91{ 92 return m_index.find(filename) != m_index.end(); 93} 94 95int ArchiveFile::getFileSize(const wstring &filename) 96{ 97 return hasFile(filename) ? m_index.at(filename)->filesize : -1; 98} 99 100byteArray ArchiveFile::getFile(const wstring &filename) 101{ 102 byteArray out; 103 AUTO_VAR(it,m_index.find(filename)); 104 105 if(it == m_index.end()) 106 { 107 app.DebugPrintf("Couldn't find file in archive\n"); 108 app.DebugPrintf("Failed to find file '%ls' in archive\n", filename.c_str()); 109#ifndef _CONTENT_PACKAGE 110 __debugbreak(); 111#endif 112 app.FatalLoadError(); 113 } 114 else 115 { 116 PMetaData data = it->second; 117 118#if defined _XBOX_ONE || defined __ORBIS__ || defined _WINDOWS64 119 out = byteArray(data->filesize ); 120 121 memcpy( out.data, m_cachedData + data->ptr, data->filesize ); 122#else 123 124#ifdef _UNICODE 125 HANDLE hfile = CreateFile( m_sourcefile.getPath().c_str(), 126 GENERIC_READ, 127 0, 128 NULL, 129 OPEN_EXISTING, 130 FILE_ATTRIBUTE_NORMAL, 131 NULL 132 ); 133#else 134 app.DebugPrintf("Createfile archive\n"); 135 HANDLE hfile = CreateFile( wstringtofilename(m_sourcefile.getPath()), 136 GENERIC_READ, 137 0, 138 NULL, 139 OPEN_EXISTING, 140 FILE_ATTRIBUTE_NORMAL, 141 NULL 142 ); 143#endif 144 145 if (hfile != INVALID_HANDLE_VALUE) 146 { 147 app.DebugPrintf("hfile ok\n"); 148 DWORD ok = SetFilePointer( hfile, 149 data->ptr, 150 NULL, 151 FILE_BEGIN 152 ); 153 154 if (ok != INVALID_SET_FILE_POINTER) 155 { 156 PBYTE pbData = new BYTE[ data->filesize ]; 157 158 DWORD bytesRead = -1; 159 BOOL bSuccess = ReadFile( hfile, 160 (LPVOID) pbData, 161 data->filesize, 162 &bytesRead, 163 NULL 164 ); 165 166 if(bSuccess==FALSE) 167 { 168 app.FatalLoadError(); 169 } 170 assert(bytesRead == data->filesize); 171 out = byteArray(pbData, data->filesize); 172 } 173 else 174 { 175 app.FatalLoadError(); 176 } 177 178 CloseHandle(hfile); 179 } 180 else 181 { 182 app.DebugPrintf("bad hfile\n"); 183 app.FatalLoadError(); 184 } 185#endif 186 187 // Compressed filenames are preceeded with an asterisk. 188 if ( data->isCompressed && out.data != NULL ) 189 { 190 /* 4J-JEV: 191 * If a compressed file is accessed before compression object is 192 * initialized it will crash here (Compression::getCompression). 193 */ 194 ///4 279 553 556 195 196 ByteArrayInputStream bais(out); 197 DataInputStream dis(&bais); 198 unsigned int decompressedSize = dis.readInt(); 199 dis.close(); 200 201 PBYTE uncompressedBuffer = new BYTE[decompressedSize]; 202 Compression::getCompression()->Decompress(uncompressedBuffer, &decompressedSize, out.data+4, out.length-4); 203 204 delete [] out.data; 205 206 out.data = uncompressedBuffer; 207 out.length = decompressedSize; 208 } 209 210 assert(out.data != NULL); // THERE IS NO FILE WITH THIS NAME! 211 212 } 213 214 return out; 215}