aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/DLC/DLCManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client/Common/DLC/DLCManager.cpp')
-rw-r--r--Minecraft.Client/Common/DLC/DLCManager.cpp671
1 files changed, 671 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/DLC/DLCManager.cpp b/Minecraft.Client/Common/DLC/DLCManager.cpp
new file mode 100644
index 00000000..123e4266
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCManager.cpp
@@ -0,0 +1,671 @@
+#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 &paramName)
+{
+ 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;
+ }
+}
+
+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_ONE
+DLCPack *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.RequestMessageBox( IDS_CORRUPT_DLC_TITLE, IDS_CORRUPT_DLC, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable(),wchFormat);
+
+ }
+ else
+ {
+ C4JStorage::EMessageResult result = ui.RequestMessageBox( IDS_CORRUPT_DLC_TITLE, IDS_CORRUPT_DLC_MULTIPLE, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
+ }
+ }
+
+ 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;
+} \ No newline at end of file