Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
15 kB · 546 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547#include "stdafx.h"#include "compression.h"#if defined __ORBIS__ || defined __PS3__ || defined _DURANGO || defined _WIN64#include "..\Minecraft.Client\Common\zlib\zlib.h"#endif
#if defined __PSVITA__#include "..\Minecraft.Client\PSVita\PSVitaExtras\zlib.h"#elif defined __PS3__#include "..\Minecraft.Client\PS3\PS3Extras\EdgeZLib.h"#endif //__PS3__
DWORD Compression::tlsIdx = 0;Compression::ThreadStorage *Compression::tlsDefault = NULL;
Compression::ThreadStorage::ThreadStorage(){ compression = new Compression();}
Compression::ThreadStorage::~ThreadStorage(){ delete compression;}
void Compression::CreateNewThreadStorage(){ ThreadStorage *tls = new ThreadStorage(); if(tlsDefault == NULL ) { tlsIdx = TlsAlloc(); tlsDefault = tls; } TlsSetValue(tlsIdx, tls);}
void Compression::UseDefaultThreadStorage(){ TlsSetValue(tlsIdx, tlsDefault);}
void Compression::ReleaseThreadStorage(){ ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx); if( tls == tlsDefault ) return;
delete tls;}
Compression *Compression::getCompression(){ ThreadStorage *tls = (ThreadStorage *)TlsGetValue(tlsIdx); return tls->compression;}
HRESULT Compression::CompressLZXRLE(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize){ EnterCriticalSection(&rleCompressLock); //static unsigned char rleBuf[1024*100];
unsigned char *pucIn = (unsigned char *)pSource; unsigned char *pucEnd = pucIn + SrcSize; unsigned char *pucOut = (unsigned char *)rleCompressBuf;
// Compress with RLE first: // 0 - 254 - encodes a single byte // 255 followed by 0, 1, 2 - encodes a 1, 2, or 3 255s // 255 followed by 3-255, followed by a byte - encodes a run of n + 1 bytes PIXBeginNamedEvent(0,"RLE compression"); do { unsigned char thisOne = *pucIn++;
unsigned int count = 1; while( ( pucIn != pucEnd ) && ( *pucIn == thisOne ) && ( count < 256 ) ) { pucIn++; count++; }
if( count <= 3 ) { if( thisOne == 255 ) { *pucOut++ = 255; *pucOut++ = count - 1; } else { for( unsigned int i = 0; i < count ; i++ ) { *pucOut++ = thisOne; } } } else { *pucOut++ = 255; *pucOut++ = count - 1; *pucOut++ = thisOne; } } while (pucIn != pucEnd); unsigned int rleSize = (unsigned int)(pucOut - rleCompressBuf); PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Secondary compression"); Compress(pDestination, pDestSize, rleCompressBuf, rleSize); PIXEndNamedEvent(); LeaveCriticalSection(&rleCompressLock);// printf("Compressed from %d to %d to %d\n",SrcSize,rleSize,*pDestSize);
return S_OK;}
HRESULT Compression::CompressRLE(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize){ EnterCriticalSection(&rleCompressLock); //static unsigned char rleBuf[1024*100];
unsigned char *pucIn = (unsigned char *)pSource; unsigned char *pucEnd = pucIn + SrcSize; unsigned char *pucOut = (unsigned char *)rleCompressBuf;
// Compress with RLE first: // 0 - 254 - encodes a single byte // 255 followed by 0, 1, 2 - encodes a 1, 2, or 3 255s // 255 followed by 3-255, followed by a byte - encodes a run of n + 1 bytes PIXBeginNamedEvent(0,"RLE compression"); do { unsigned char thisOne = *pucIn++;
unsigned int count = 1; while( ( pucIn != pucEnd ) && ( *pucIn == thisOne ) && ( count < 256 ) ) { pucIn++; count++; }
if( count <= 3 ) { if( thisOne == 255 ) { *pucOut++ = 255; *pucOut++ = count - 1; } else { for( unsigned int i = 0; i < count ; i++ ) { *pucOut++ = thisOne; } } } else { *pucOut++ = 255; *pucOut++ = count - 1; *pucOut++ = thisOne; } } while (pucIn != pucEnd); unsigned int rleSize = (unsigned int)(pucOut - rleCompressBuf); PIXEndNamedEvent(); LeaveCriticalSection(&rleCompressLock);
// Return if (rleSize <= *pDestSize) { *pDestSize = rleSize; memcpy(pDestination, rleCompressBuf, *pDestSize); } else {#ifndef _CONTENT_PACKAGE assert(false);#endif }
return S_OK;}
HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize){ EnterCriticalSection(&rleDecompressLock); // 4J Stu - Fix for #13676 - Crash: Crash while attempting to load a world after updating TU // Some saves can have chunks that decompress into very large sizes, so I have doubled the size of this buffer // Ideally we should be able to dynamically allocate the buffer if it's going to be too big, as most chunks // only use 5% of this buffer
// 4J Stu - Changed this again to dynamically allocate a buffer if it's going to be too big unsigned char *pucIn = NULL;
//const unsigned int staticRleSize = 1024*200; //static unsigned char rleBuf[staticRleSize]; unsigned int rleSize = staticRleSize; unsigned char *dynamicRleBuf = NULL;
if(*pDestSize > rleSize) { rleSize = *pDestSize; dynamicRleBuf = new unsigned char[rleSize]; Decompress(dynamicRleBuf, &rleSize, pSource, SrcSize); pucIn = (unsigned char *)dynamicRleBuf; } else { Decompress(rleDecompressBuf, &rleSize, pSource, SrcSize); pucIn = (unsigned char *)rleDecompressBuf; }
//unsigned char *pucIn = (unsigned char *)rleDecompressBuf; unsigned char *pucEnd = pucIn + rleSize; unsigned char *pucOut = (unsigned char *)pDestination;
while( pucIn != pucEnd ) { unsigned char thisOne = *pucIn++; if( thisOne == 255 ) { unsigned int count = *pucIn++; if( count < 3 ) { count++; for( unsigned int i = 0; i < count; i++ ) { *pucOut++ = 255; } } else { count++; unsigned char data = *pucIn++; for( unsigned int i = 0; i < count; i++ ) { *pucOut++ = data; } } } else { *pucOut++ = thisOne; } } *pDestSize = (unsigned int)(pucOut - (unsigned char *)pDestination);
// printf("Decompressed from %d to %d to %d\n",SrcSize,rleSize,*pDestSize);
if(dynamicRleBuf != NULL) delete [] dynamicRleBuf;
LeaveCriticalSection(&rleDecompressLock); return S_OK;}
HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize){ EnterCriticalSection(&rleDecompressLock); //unsigned char *pucIn = (unsigned char *)rleDecompressBuf; unsigned char *pucIn = (unsigned char *)pSource; unsigned char *pucEnd = pucIn + SrcSize; unsigned char *pucOut = (unsigned char *)pDestination;
while( pucIn != pucEnd ) { unsigned char thisOne = *pucIn++; if( thisOne == 255 ) { unsigned int count = *pucIn++; if( count < 3 ) { count++; for( unsigned int i = 0; i < count; i++ ) { *pucOut++ = 255; } } else { count++; unsigned char data = *pucIn++; for( unsigned int i = 0; i < count; i++ ) { *pucOut++ = data; } } } else { *pucOut++ = thisOne; } } *pDestSize = (unsigned int)(pucOut - (unsigned char *)pDestination);
LeaveCriticalSection(&rleDecompressLock); return S_OK;}
HRESULT Compression::Compress(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize){ // Using zlib for x64 compression - 360 is using native 360 compression and PS3 a stubbed non-compressing version of this#if defined __ORBIS__ || defined _DURANGO || defined _WIN64 || defined __PSVITA__ SIZE_T destSize = (SIZE_T)(*pDestSize); int res = ::compress((Bytef *)pDestination, (uLongf *)&destSize, (Bytef *)pSource, SrcSize); *pDestSize = (unsigned int)destSize; return ( ( res == Z_OK ) ? S_OK : -1 );#elif defined __PS3__ uint32_t destSize = (uint32_t)(*pDestSize); bool res = EdgeZLib::Compress(pDestination, &destSize, pSource, SrcSize); *pDestSize = (unsigned int)destSize; return ( ( res ) ? S_OK : -1 );#else SIZE_T destSize = (SIZE_T)(*pDestSize); HRESULT res = XMemCompress(compressionContext, pDestination, &destSize, pSource, SrcSize); *pDestSize = (unsigned int)destSize; return res;#endif}
HRESULT Compression::Decompress(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize){
if(m_decompressType != m_localDecompressType) // check if we're decompressing data from a different platform { // only used for loading a save from a different platform (Sony cloud storage cross play) return DecompressWithType(pDestination, pDestSize, pSource, SrcSize); }
// Using zlib for x64 compression - 360 is using native 360 compression and PS3 a stubbed non-compressing version of this#if defined __ORBIS__ || defined _DURANGO || defined _WIN64 || defined __PSVITA__ SIZE_T destSize = (SIZE_T)(*pDestSize); int res = ::uncompress((Bytef *)pDestination, (uLongf *)&destSize, (Bytef *)pSource, SrcSize); *pDestSize = (unsigned int)destSize; return ( ( res == Z_OK ) ? S_OK : -1 );#elif defined __PS3__ uint32_t destSize = (uint32_t)(*pDestSize); bool res = EdgeZLib::Decompress(pDestination, &destSize, pSource, SrcSize); *pDestSize = (unsigned int)destSize; return ( ( res ) ? S_OK : -1 );#else SIZE_T destSize = (SIZE_T)(*pDestSize); HRESULT res = XMemDecompress(decompressionContext, pDestination, (SIZE_T *)&destSize, pSource, SrcSize); *pDestSize = (unsigned int)destSize; return res;#endif}
// MGH - same as VirtualDecompress in PSVitaStubs, but for use on other platforms (so no virtual mem stuff)#ifndef _XBOXVOID Compression::VitaVirtualDecompress(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize) // (LPVOID buf, SIZE_T dwSize, LPVOID dst){ uint8_t *pSrc = (uint8_t *)pSource; int Offset = 0; int Page = 0; int Index = 0; uint8_t* Data = (uint8_t*)pDestination; while( Index != SrcSize ) { // is this a normal value if( pSrc[Index] ) { // just copy it across Data[Offset] = pSrc[Index]; Offset += 1; } else { // how many zeros do we have Index += 1; int Count = pSrc[Index]; // to do : this should really be a sequence of memsets for( int i = 0;i < Count;i += 1 ) { Data[Offset] = 0; Offset += 1; } } Index += 1; } *pDestSize = Offset;}#endif
HRESULT Compression::DecompressWithType(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize){ switch(m_decompressType) { case eCompressionType_RLE: // 4J-JEV, RLE is just that; don't want to break here though. case eCompressionType_None: memcpy(pDestination,pSource,SrcSize); *pDestSize = SrcSize; return S_OK; case eCompressionType_LZXRLE: {#if (defined _XBOX || defined _DURANGO || defined _WIN64) SIZE_T destSize = (SIZE_T)(*pDestSize); HRESULT res = XMemDecompress(decompressionContext, pDestination, (SIZE_T *)&destSize, pSource, SrcSize); *pDestSize = (unsigned int)destSize; return res;#else assert(0);#endif } break; case eCompressionType_ZLIBRLE:#if (defined __ORBIS__ || defined __PS3__ || defined _DURANGO || defined _WIN64) if (pDestination != NULL) return ::uncompress((PBYTE)pDestination, (unsigned long *) pDestSize, (PBYTE) pSource, SrcSize); // Decompress else break; // Cannot decompress when destination is NULL#else assert(0); break;#endif case eCompressionType_PS3ZLIB:#if (defined __ORBIS__ || defined __PSVITA__ || defined _DURANGO || defined _WIN64) // Note that we're missing the normal zlib header and footer so we'll use inflate to // decompress the payload and skip all the CRC checking, etc if (pDestination != NULL) { // Read big-endian srcize from array PBYTE pbDestSize = (PBYTE) pDestSize; PBYTE pbSource = (PBYTE) pSource; for (int i = 3; i >= 0; i--) { pbDestSize[3-i] = pbSource[i]; }
byteArray uncompr = byteArray(*pDestSize);
// Build decompression stream z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.next_out = uncompr.data; strm.avail_out = uncompr.length; // Skip those first 4 bytes strm.next_in = (PBYTE) pSource + 4; strm.avail_in = SrcSize - 4;
int hr = inflateInit2(&strm, -15);
// Run inflate() on input until end of stream do { hr = inflate(&strm, Z_NO_FLUSH);
// Check switch (hr) { case Z_NEED_DICT: case Z_DATA_ERROR: case Z_MEM_ERROR: case Z_STREAM_ERROR: (void)inflateEnd(&strm); assert(false); } } while (hr != Z_STREAM_END);
inflateEnd(&strm); // MGH - added, to clean up zlib, was causing a leak on Vita when dowloading a PS3 save
// Copy the uncompressed data to the destination memcpy(pDestination, uncompr.data, uncompr.length); *pDestSize = uncompr.length;
// Delete uncompressed data delete uncompr.data; return S_OK; } else break; // Cannot decompress when destination is NULL#else assert(0);#endif }
assert(false); return -1;}
Compression::Compression(){ // Using zlib for x64 compression - 360 is using native 360 compression and PS3 a stubbed non-compressing version of this#if !(defined __ORBIS__ || defined __PS3__) // The default parameters for compression context allocated about 6.5MB, reducing the partition size here from the default 512KB to 128KB // brings this down to about 3MB XMEMCODEC_PARAMETERS_LZX params; params.Flags = 0; params.WindowSize = 128 * 1024; params.CompressionPartitionSize = 128 * 1024;
XMemCreateCompressionContext(XMEMCODEC_LZX,¶ms,0,&compressionContext); XMemCreateDecompressionContext(XMEMCODEC_LZX,¶ms,0,&decompressionContext);#endif
#if defined _XBOX m_localDecompressType = eCompressionType_LZXRLE;#elif defined __PS3__ m_localDecompressType = eCompressionType_PS3ZLIB;#else m_localDecompressType = eCompressionType_ZLIBRLE;#endif m_decompressType = m_localDecompressType;
InitializeCriticalSection(&rleCompressLock); InitializeCriticalSection(&rleDecompressLock);}
Compression::~Compression(){#if !(defined __ORBIS__ || defined __PS3__ || defined __PSVITA__)
XMemDestroyCompressionContext(compressionContext); XMemDestroyDecompressionContext(decompressionContext);#endif DeleteCriticalSection(&rleCompressLock); DeleteCriticalSection(&rleDecompressLock);}
void Compression::SetDecompressionType(ESavePlatform platform){ switch(platform) { case SAVE_FILE_PLATFORM_X360: Compression::getCompression()->SetDecompressionType(Compression::eCompressionType_LZXRLE); break; case SAVE_FILE_PLATFORM_PS3: Compression::getCompression()->SetDecompressionType(Compression::eCompressionType_PS3ZLIB); break; case SAVE_FILE_PLATFORM_XBONE: case SAVE_FILE_PLATFORM_PS4: case SAVE_FILE_PLATFORM_PSVITA: case SAVE_FILE_PLATFORM_WIN64: Compression::getCompression()->SetDecompressionType(Compression::eCompressionType_ZLIBRLE); break; default: assert(0); break; }}
/*Compression gCompression;*/