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.
19 kB · 693 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693#include "stdafx.h"#include <algorithm>#include "DLCManager.h"#include "DLCPack.h"#include "DLCFile.h"#include "..\..\..\Minecraft.World\StringHelpers.h"#include "..\..\Minecraft.h"#include "..\..\TexturePackRepository.h"
WCHAR *DLCManager::wchTypeNamesA[]={ L"DISPLAYNAME", L"THEMENAME", L"FREE", L"CREDIT", L"CAPEPATH", L"BOX", L"ANIM", L"PACKID", L"NETHERPARTICLECOLOUR", L"ENCHANTTEXTCOLOUR", L"ENCHANTTEXTFOCUSCOLOUR", L"DATAPATH", L"PACKVERSION",};
DLCManager::DLCManager(){ //m_bNeedsUpdated = true; m_bNeedsCorruptCheck = true;}
DLCManager::~DLCManager(){ for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *pack = *it; delete pack; }}
DLCManager::EDLCParameterType DLCManager::getParameterType(const wstring ¶mName){ EDLCParameterType type = e_DLCParamType_Invalid;
for(DWORD i = 0; i < e_DLCParamType_Max; ++i) { if(paramName.compare(wchTypeNamesA[i]) == 0) { type = (EDLCParameterType)i; break; } }
return type;}
DWORD DLCManager::getPackCount(EDLCType type /*= e_DLCType_All*/){ DWORD packCount = 0; if( type != e_DLCType_All ) { for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *pack = *it; if( pack->getDLCItemsCount(type) > 0 ) { ++packCount; } } } else { packCount = (DWORD)m_packs.size(); } return packCount;}
void DLCManager::addPack(DLCPack *pack){ m_packs.push_back(pack);}
void DLCManager::removePack(DLCPack *pack){ if(pack != NULL) { AUTO_VAR(it, find(m_packs.begin(),m_packs.end(),pack)); if(it != m_packs.end() ) m_packs.erase(it); delete pack; }}
void DLCManager::removeAllPacks(void){ for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *pack = (DLCPack *)*it; delete pack; }
m_packs.clear();}
void DLCManager::LanguageChanged(void){ for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *pack = (DLCPack *)*it; // update the language pack->UpdateLanguage(); }
}
DLCPack *DLCManager::getPack(const wstring &name){ DLCPack *pack = NULL; //DWORD currentIndex = 0; DLCPack *currentPack = NULL; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { currentPack = *it; wstring wsName=currentPack->getName();
if(wsName.compare(name) == 0) { pack = currentPack; break; } } return pack;}
#ifdef _XBOX_ONEDLCPack *DLCManager::getPackFromProductID(const wstring &productID){ DLCPack *pack = NULL; //DWORD currentIndex = 0; DLCPack *currentPack = NULL; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { currentPack = *it; wstring wsName=currentPack->getPurchaseOfferId();
if(wsName.compare(productID) == 0) { pack = currentPack; break; } } return pack;}#endif
DLCPack *DLCManager::getPack(DWORD index, EDLCType type /*= e_DLCType_All*/){ DLCPack *pack = NULL; if( type != e_DLCType_All ) { DWORD currentIndex = 0; DLCPack *currentPack = NULL; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { currentPack = *it; if(currentPack->getDLCItemsCount(type)>0) { if(currentIndex == index) { pack = currentPack; break; } ++currentIndex; } } } else { if(index >= m_packs.size()) { app.DebugPrintf("DLCManager: Trying to access a DLC pack beyond the range of valid packs\n"); __debugbreak(); } pack = m_packs[index]; }
return pack;}
DWORD DLCManager::getPackIndex(DLCPack *pack, bool &found, EDLCType type /*= e_DLCType_All*/){ DWORD foundIndex = 0; found = false; if(pack == NULL) { app.DebugPrintf("DLCManager: Attempting to find the index for a NULL pack\n"); //__debugbreak(); return foundIndex; } if( type != e_DLCType_All ) { DWORD index = 0; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *thisPack = *it; if(thisPack->getDLCItemsCount(type)>0) { if(thisPack == pack) { found = true; foundIndex = index; break; } ++index; } } } else { DWORD index = 0; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *thisPack = *it; if(thisPack == pack) { found = true; foundIndex = index; break; } ++index; } } return foundIndex;}
DWORD DLCManager::getPackIndexContainingSkin(const wstring &path, bool &found){ DWORD foundIndex = 0; found = false; DWORD index = 0; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *pack = *it; if(pack->getDLCItemsCount(e_DLCType_Skin)>0) { if(pack->doesPackContainSkin(path)) { foundIndex = index; found = true; break; } ++index; } } return foundIndex;}
DLCPack *DLCManager::getPackContainingSkin(const wstring &path){ DLCPack *foundPack = NULL; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *pack = *it; if(pack->getDLCItemsCount(e_DLCType_Skin)>0) { if(pack->doesPackContainSkin(path)) { foundPack = pack; break; } } } return foundPack;}
DLCSkinFile *DLCManager::getSkinFile(const wstring &path){ DLCSkinFile *foundSkinfile = NULL; for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { DLCPack *pack = *it; foundSkinfile=pack->getSkinFile(path); if(foundSkinfile!=NULL) { break; } } return foundSkinfile;}
DWORD DLCManager::checkForCorruptDLCAndAlert(bool showMessage /*= true*/){ DWORD corruptDLCCount = m_dwUnnamedCorruptDLCCount; DLCPack *pack = NULL; DLCPack *firstCorruptPack = NULL;
for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) { pack = *it; if( pack->IsCorrupt() ) { ++corruptDLCCount; if(firstCorruptPack == NULL) firstCorruptPack = pack; } }
if(corruptDLCCount > 0 && showMessage) { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; if(corruptDLCCount == 1 && firstCorruptPack != NULL) { // pass in the pack format string WCHAR wchFormat[132]; swprintf(wchFormat, 132, L"%ls\n\n%%ls", firstCorruptPack->getName().c_str());
C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_CORRUPT_DLC_TITLE, IDS_CORRUPT_DLC, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL,wchFormat);
} else { C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_CORRUPT_DLC_TITLE, IDS_CORRUPT_DLC_MULTIPLE, uiIDA,1,ProfileManager.GetPrimaryPad()); } }
SetNeedsCorruptCheck(false);
return corruptDLCCount;}
bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack, bool fromArchive){ return readDLCDataFile( dwFilesProcessed, wstringtofilename(path), pack, fromArchive);}
bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DLCPack *pack, bool fromArchive){ wstring wPath = convStringToWstring(path); if (fromArchive && app.getArchiveFileSize(wPath) >= 0) { byteArray bytes = app.getArchiveFile(wPath); return processDLCDataFile(dwFilesProcessed, bytes.data, bytes.length, pack); } else if (fromArchive) return false;
#ifdef _WINDOWS64 string finalPath = StorageManager.GetMountedPath(path.c_str()); if(finalPath.size() == 0) finalPath = path; HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);#elif defined(_DURANGO) wstring finalPath = StorageManager.GetMountedPath(wPath.c_str()); if(finalPath.size() == 0) finalPath = wPath; HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);#else HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);#endif if( file == INVALID_HANDLE_VALUE ) { DWORD error = GetLastError(); app.DebugPrintf("Failed to open DLC data file with error code %d (%x)\n", error, error); if( dwFilesProcessed == 0 ) removePack(pack); assert(false); return false; }
DWORD bytesRead,dwFileSize = GetFileSize(file,NULL); PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; BOOL bSuccess = ReadFile(file,pbData,dwFileSize,&bytesRead,NULL); if(bSuccess==FALSE) { // need to treat the file as corrupt, and flag it, so can't call fatal error //app.FatalLoadError(); } else { CloseHandle(file); } if(bSuccess==FALSE) { // Corrupt or some other error. In any case treat as corrupt app.DebugPrintf("Failed to read %s from DLC content package\n", path.c_str()); pack->SetIsCorrupt( true ); SetNeedsCorruptCheck(true); return false; } return processDLCDataFile(dwFilesProcessed, pbData, bytesRead, pack);}
bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwLength, DLCPack *pack){ unordered_map<int, DLCManager::EDLCParameterType> parameterMapping; unsigned int uiCurrentByte=0;
// File format defined in the DLC_Creator // File format: Version 2 // unsigned long, version number // unsigned long, t = number of parameter types // t * DLC_FILE_PARAM structs mapping strings to id's // unsigned long, n = number of files // n * DLC_FILE_DETAILS describing each file in the pack // n * files of the form // // unsigned long, p = number of parameters // // p * DLC_FILE_PARAM describing each parameter for this file // // ulFileSize bytes of data blob of the file added unsigned int uiVersion=*(unsigned int *)pbData; uiCurrentByte+=sizeof(int);
if(uiVersion < CURRENT_DLC_VERSION_NUM) { if(pbData!=NULL) delete [] pbData; app.DebugPrintf("DLC version of %d is too old to be read\n", uiVersion); return false; } pack->SetDataPointer(pbData); unsigned int uiParameterCount=*(unsigned int *)&pbData[uiCurrentByte]; uiCurrentByte+=sizeof(int); C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; //DWORD dwwchCount=0; for(unsigned int i=0;i<uiParameterCount;i++) { // Map DLC strings to application strings, then store the DLC index mapping to application index wstring parameterName((WCHAR *)pParams->wchData); DLCManager::EDLCParameterType type = DLCManager::getParameterType(parameterName); if( type != DLCManager::e_DLCParamType_Invalid ) { parameterMapping[pParams->dwType] = type; } uiCurrentByte+= sizeof(C4JStorage::DLC_FILE_PARAM)+(pParams->dwWchCount*sizeof(WCHAR)); pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; } //ulCurrentByte+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM);
unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte]; uiCurrentByte+=sizeof(int); C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
DWORD dwTemp=uiCurrentByte; for(unsigned int i=0;i<uiFileCount;i++) { dwTemp+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR); pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[dwTemp]; } PBYTE pbTemp=((PBYTE )pFile);//+ sizeof(C4JStorage::DLC_FILE_DETAILS)*ulFileCount; pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
for(unsigned int i=0;i<uiFileCount;i++) { DLCManager::EDLCType type = (DLCManager::EDLCType)pFile->dwType;
DLCFile *dlcFile = NULL; DLCPack *dlcTexturePack = NULL;
if(type == e_DLCType_TexturePack) { dlcTexturePack = new DLCPack(pack->getName(), pack->getLicenseMask()); } else if(type != e_DLCType_PackConfig) { dlcFile = pack->addFile(type,(WCHAR *)pFile->wchFile); }
// Params uiParameterCount=*(unsigned int *)pbTemp; pbTemp+=sizeof(int); pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; for(unsigned int j=0;j<uiParameterCount;j++) { //DLCManager::EDLCParameterType paramType = DLCManager::e_DLCParamType_Invalid;
AUTO_VAR(it, parameterMapping.find( pParams->dwType ));
if(it != parameterMapping.end() ) { if(type == e_DLCType_PackConfig) { pack->addParameter(it->second,(WCHAR *)pParams->wchData); } else { if(dlcFile != NULL) dlcFile->addParameter(it->second,(WCHAR *)pParams->wchData); else if(dlcTexturePack != NULL) dlcTexturePack->addParameter(it->second, (WCHAR *)pParams->wchData); } } pbTemp+=sizeof(C4JStorage::DLC_FILE_PARAM)+(sizeof(WCHAR)*pParams->dwWchCount); pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; } //pbTemp+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM);
if(dlcTexturePack != NULL) { DWORD texturePackFilesProcessed = 0; bool validPack = processDLCDataFile(texturePackFilesProcessed,pbTemp,pFile->uiFileSize,dlcTexturePack); pack->SetDataPointer(NULL); // If it's a child pack, it doesn't own the data if(!validPack || texturePackFilesProcessed == 0) { delete dlcTexturePack; dlcTexturePack = NULL; } else { pack->addChildPack(dlcTexturePack);
if(dlcTexturePack->getDLCItemsCount(DLCManager::e_DLCType_Texture) > 0) { Minecraft::GetInstance()->skins->addTexturePackFromDLC(dlcTexturePack, dlcTexturePack->GetPackId() ); } } ++dwFilesProcessed; } else if(dlcFile != NULL) { // Data dlcFile->addData(pbTemp,pFile->uiFileSize);
// TODO - 4J Stu Remove the need for this vSkinNames vector, or manage it differently switch(pFile->dwType) { case DLCManager::e_DLCType_Skin: app.vSkinNames.push_back((WCHAR *)pFile->wchFile); break; }
++dwFilesProcessed; }
// Move the pointer to the start of the next files data; pbTemp+=pFile->uiFileSize; uiCurrentByte+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR);
pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; }
if( pack->getDLCItemsCount(DLCManager::e_DLCType_GameRules) > 0 || pack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader) > 0) { app.m_gameRules.loadGameRules(pack); }
if(pack->getDLCItemsCount(DLCManager::e_DLCType_Audio) > 0) { //app.m_Audio.loadAudioDetails(pack); } // TODO Should be able to delete this data, but we can't yet due to how it is added to the Memory textures (MEM_file)
return true;}
DWORD DLCManager::retrievePackIDFromDLCDataFile(const string &path, DLCPack *pack){ DWORD packId = 0; wstring wPath = convStringToWstring(path);
#ifdef _WINDOWS64 string finalPath = StorageManager.GetMountedPath(path.c_str()); if(finalPath.size() == 0) finalPath = path; HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);#elif defined(_DURANGO) wstring finalPath = StorageManager.GetMountedPath(wPath.c_str()); if(finalPath.size() == 0) finalPath = wPath; HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);#else HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);#endif if( file == INVALID_HANDLE_VALUE ) { return 0; }
DWORD bytesRead,dwFileSize = GetFileSize(file,NULL); PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; BOOL bSuccess = ReadFile(file,pbData,dwFileSize,&bytesRead,NULL); if(bSuccess==FALSE) { // need to treat the file as corrupt, and flag it, so can't call fatal error //app.FatalLoadError(); } else { CloseHandle(file); } if(bSuccess==FALSE) { // Corrupt or some other error. In any case treat as corrupt app.DebugPrintf("Failed to read %s from DLC content package\n", path.c_str()); delete [] pbData; return 0; } packId=retrievePackID(pbData, bytesRead, pack); delete [] pbData;
return packId;}
DWORD DLCManager::retrievePackID(PBYTE pbData, DWORD dwLength, DLCPack *pack){ DWORD packId=0; bool bPackIDSet=false; unordered_map<int, DLCManager::EDLCParameterType> parameterMapping; unsigned int uiCurrentByte=0;
// File format defined in the DLC_Creator // File format: Version 2 // unsigned long, version number // unsigned long, t = number of parameter types // t * DLC_FILE_PARAM structs mapping strings to id's // unsigned long, n = number of files // n * DLC_FILE_DETAILS describing each file in the pack // n * files of the form // // unsigned long, p = number of parameters // // p * DLC_FILE_PARAM describing each parameter for this file // // ulFileSize bytes of data blob of the file added unsigned int uiVersion=*(unsigned int *)pbData; uiCurrentByte+=sizeof(int);
if(uiVersion < CURRENT_DLC_VERSION_NUM) { app.DebugPrintf("DLC version of %d is too old to be read\n", uiVersion); return 0; } pack->SetDataPointer(pbData); unsigned int uiParameterCount=*(unsigned int *)&pbData[uiCurrentByte]; uiCurrentByte+=sizeof(int); C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; for(unsigned int i=0;i<uiParameterCount;i++) { // Map DLC strings to application strings, then store the DLC index mapping to application index wstring parameterName((WCHAR *)pParams->wchData); DLCManager::EDLCParameterType type = DLCManager::getParameterType(parameterName); if( type != DLCManager::e_DLCParamType_Invalid ) { parameterMapping[pParams->dwType] = type; } uiCurrentByte+= sizeof(C4JStorage::DLC_FILE_PARAM)+(pParams->dwWchCount*sizeof(WCHAR)); pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; }
unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte]; uiCurrentByte+=sizeof(int); C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
DWORD dwTemp=uiCurrentByte; for(unsigned int i=0;i<uiFileCount;i++) { dwTemp+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR); pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[dwTemp]; } PBYTE pbTemp=((PBYTE )pFile); pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
for(unsigned int i=0;i<uiFileCount;i++) { DLCManager::EDLCType type = (DLCManager::EDLCType)pFile->dwType;
// Params uiParameterCount=*(unsigned int *)pbTemp; pbTemp+=sizeof(int); pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; for(unsigned int j=0;j<uiParameterCount;j++) { AUTO_VAR(it, parameterMapping.find( pParams->dwType ));
if(it != parameterMapping.end() ) { if(type==e_DLCType_PackConfig) { if(it->second==e_DLCParamType_PackId) { wstring wsTemp=(WCHAR *)pParams->wchData; std::wstringstream ss; // 4J Stu - numbered using decimal to make it easier for artists/people to number manually ss << std::dec << wsTemp.c_str(); ss >> packId; bPackIDSet=true; break; } } } pbTemp+=sizeof(C4JStorage::DLC_FILE_PARAM)+(sizeof(WCHAR)*pParams->dwWchCount); pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; }
if(bPackIDSet) break; // Move the pointer to the start of the next files data; pbTemp+=pFile->uiFileSize; uiCurrentByte+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR);
pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; }
parameterMapping.clear(); return packId;}