aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/DLC
diff options
context:
space:
mode:
authordaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
committerdaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
commitb691c43c44ff180d10e7d4a9afc83b98551ff586 (patch)
tree3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/Common/DLC
parentdef8cb415354ac390b7e89052a50605285f1aca9 (diff)
Initial commit
Diffstat (limited to 'Minecraft.Client/Common/DLC')
-rw-r--r--Minecraft.Client/Common/DLC/DLCAudioFile.cpp216
-rw-r--r--Minecraft.Client/Common/DLC/DLCAudioFile.h54
-rw-r--r--Minecraft.Client/Common/DLC/DLCCapeFile.cpp12
-rw-r--r--Minecraft.Client/Common/DLC/DLCCapeFile.h10
-rw-r--r--Minecraft.Client/Common/DLC/DLCColourTableFile.cpp26
-rw-r--r--Minecraft.Client/Common/DLC/DLCColourTableFile.h18
-rw-r--r--Minecraft.Client/Common/DLC/DLCFile.cpp26
-rw-r--r--Minecraft.Client/Common/DLC/DLCFile.h25
-rw-r--r--Minecraft.Client/Common/DLC/DLCGameRules.h10
-rw-r--r--Minecraft.Client/Common/DLC/DLCGameRulesFile.cpp21
-rw-r--r--Minecraft.Client/Common/DLC/DLCGameRulesFile.h15
-rw-r--r--Minecraft.Client/Common/DLC/DLCGameRulesHeader.cpp92
-rw-r--r--Minecraft.Client/Common/DLC/DLCGameRulesHeader.h42
-rw-r--r--Minecraft.Client/Common/DLC/DLCLocalisationFile.cpp14
-rw-r--r--Minecraft.Client/Common/DLC/DLCLocalisationFile.h18
-rw-r--r--Minecraft.Client/Common/DLC/DLCManager.cpp671
-rw-r--r--Minecraft.Client/Common/DLC/DLCManager.h99
-rw-r--r--Minecraft.Client/Common/DLC/DLCPack.cpp410
-rw-r--r--Minecraft.Client/Common/DLC/DLCPack.h93
-rw-r--r--Minecraft.Client/Common/DLC/DLCSkinFile.cpp212
-rw-r--r--Minecraft.Client/Common/DLC/DLCSkinFile.h29
-rw-r--r--Minecraft.Client/Common/DLC/DLCTextureFile.cpp59
-rw-r--r--Minecraft.Client/Common/DLC/DLCTextureFile.h24
-rw-r--r--Minecraft.Client/Common/DLC/DLCUIDataFile.cpp32
-rw-r--r--Minecraft.Client/Common/DLC/DLCUIDataFile.h20
25 files changed, 2248 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/DLC/DLCAudioFile.cpp b/Minecraft.Client/Common/DLC/DLCAudioFile.cpp
new file mode 100644
index 00000000..49ba52cd
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCAudioFile.cpp
@@ -0,0 +1,216 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCAudioFile.h"
+#if defined _XBOX || defined _WINDOWS64
+#include "..\..\Xbox\XML\ATGXmlParser.h"
+#include "..\..\Xbox\XML\xmlFilesCallback.h"
+#endif
+
+DLCAudioFile::DLCAudioFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_Audio,path)
+{
+ m_pbData = NULL;
+ m_dwBytes = 0;
+}
+
+void DLCAudioFile::addData(PBYTE pbData, DWORD dwBytes)
+{
+ m_pbData = pbData;
+ m_dwBytes = dwBytes;
+
+ processDLCDataFile(pbData,dwBytes);
+}
+
+PBYTE DLCAudioFile::getData(DWORD &dwBytes)
+{
+ dwBytes = m_dwBytes;
+ return m_pbData;
+}
+
+WCHAR *DLCAudioFile::wchTypeNamesA[]=
+{
+ L"CUENAME",
+ L"CREDIT",
+};
+
+DLCAudioFile::EAudioParameterType DLCAudioFile::getParameterType(const wstring &paramName)
+{
+ EAudioParameterType type = e_AudioParamType_Invalid;
+
+ for(DWORD i = 0; i < e_AudioParamType_Max; ++i)
+ {
+ if(paramName.compare(wchTypeNamesA[i]) == 0)
+ {
+ type = (EAudioParameterType)i;
+ break;
+ }
+ }
+
+ return type;
+}
+
+void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype, const wstring &value)
+{
+ switch(ptype)
+ {
+
+ case e_AudioParamType_Credit: // If this parameter exists, then mark this as free
+ //add it to the DLC credits list
+
+ // we'll need to justify this text since we don't have a lot of room for lines of credits
+ {
+ // don't look for duplicate in the music credits
+
+ //if(app.AlreadySeenCreditText(value)) break;
+
+ int maximumChars = 55;
+
+ bool bIsSDMode=!RenderManager.IsHiDef() && !RenderManager.IsWidescreen();
+
+ if(bIsSDMode)
+ {
+ maximumChars = 45;
+ }
+
+ switch(XGetLanguage())
+ {
+ case XC_LANGUAGE_JAPANESE:
+ case XC_LANGUAGE_TCHINESE:
+ case XC_LANGUAGE_KOREAN:
+ maximumChars = 35;
+ break;
+ }
+ wstring creditValue = value;
+ while (creditValue.length() > maximumChars)
+ {
+ unsigned int i = 1;
+ while (i < creditValue.length() && (i + 1) <= maximumChars)
+ {
+ i++;
+ }
+ int iLast=(int)creditValue.find_last_of(L" ",i);
+ switch(XGetLanguage())
+ {
+ case XC_LANGUAGE_JAPANESE:
+ case XC_LANGUAGE_TCHINESE:
+ case XC_LANGUAGE_KOREAN:
+ iLast = maximumChars;
+ break;
+ default:
+ iLast=(int)creditValue.find_last_of(L" ",i);
+ break;
+ }
+
+ // if a space was found, include the space on this line
+ if(iLast!=i)
+ {
+ iLast++;
+ }
+
+ app.AddCreditText((creditValue.substr(0, iLast)).c_str());
+ creditValue = creditValue.substr(iLast);
+ }
+ app.AddCreditText(creditValue.c_str());
+
+ }
+ break;
+ case e_AudioParamType_Cuename:
+ m_parameters[type].push_back(value);
+ //m_parameters[(int)type] = value;
+ break;
+ }
+}
+
+bool DLCAudioFile::processDLCDataFile(PBYTE pbData, DWORD dwLength)
+{
+ unordered_map<int, EAudioParameterType> parameterMapping;
+ unsigned int uiCurrentByte=0;
+
+ // File format defined in the AudioPacker
+ // File format: Version 1
+
+ unsigned int uiVersion=*(unsigned int *)pbData;
+ uiCurrentByte+=sizeof(int);
+
+ if(uiVersion < CURRENT_AUDIO_VERSION_NUM)
+ {
+ if(pbData!=NULL) delete [] pbData;
+ app.DebugPrintf("DLC version of %d is too old to be read\n", uiVersion);
+ return false;
+ }
+
+ unsigned int uiParameterTypeCount=*(unsigned int *)&pbData[uiCurrentByte];
+ uiCurrentByte+=sizeof(int);
+ C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
+
+ for(unsigned int i=0;i<uiParameterTypeCount;i++)
+ {
+ // Map DLC strings to application strings, then store the DLC index mapping to application index
+ wstring parameterName((WCHAR *)pParams->wchData);
+ EAudioParameterType type = getParameterType(parameterName);
+ if( type != e_AudioParamType_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++)
+ {
+ EAudioType type = (EAudioType)pFile->dwType;
+ // Params
+ unsigned int uiParameterCount=*(unsigned int *)pbTemp;
+ pbTemp+=sizeof(int);
+ pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
+ for(unsigned int j=0;j<uiParameterCount;j++)
+ {
+ //EAudioParameterType paramType = e_AudioParamType_Invalid;
+
+ AUTO_VAR(it, parameterMapping.find( pParams->dwType ));
+
+ if(it != parameterMapping.end() )
+ {
+ addParameter(type,(EAudioParameterType)pParams->dwType,(WCHAR *)pParams->wchData);
+ }
+ pbTemp+=sizeof(C4JStorage::DLC_FILE_PARAM)+(sizeof(WCHAR)*pParams->dwWchCount);
+ pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
+ }
+ // 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];
+
+ }
+
+ return true;
+}
+
+int DLCAudioFile::GetCountofType(DLCAudioFile::EAudioType eType)
+{
+ return m_parameters[eType].size();
+}
+
+
+wstring &DLCAudioFile::GetSoundName(int iIndex)
+{
+ int iWorldType=e_AudioType_Overworld;
+ while(iIndex>=m_parameters[iWorldType].size())
+ {
+ iIndex-=m_parameters[iWorldType].size();
+ iWorldType++;
+ }
+ return m_parameters[iWorldType].at(iIndex);
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCAudioFile.h b/Minecraft.Client/Common/DLC/DLCAudioFile.h
new file mode 100644
index 00000000..728512d7
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCAudioFile.h
@@ -0,0 +1,54 @@
+#pragma once
+#include "DLCFile.h"
+
+class DLCAudioFile : public DLCFile
+{
+
+public:
+
+ // If you add to the Enum,then you need to add the array of type names
+ // These are the names used in the XML for the parameters
+ enum EAudioType
+ {
+ e_AudioType_Invalid = -1,
+
+ e_AudioType_Overworld = 0,
+ e_AudioType_Nether,
+ e_AudioType_End,
+
+ e_AudioType_Max,
+ };
+ enum EAudioParameterType
+ {
+ e_AudioParamType_Invalid = -1,
+
+ e_AudioParamType_Cuename = 0,
+ e_AudioParamType_Credit,
+
+ e_AudioParamType_Max,
+
+ };
+ static WCHAR *wchTypeNamesA[e_AudioParamType_Max];
+
+ DLCAudioFile(const wstring &path);
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+ virtual PBYTE getData(DWORD &dwBytes);
+
+ bool processDLCDataFile(PBYTE pbData, DWORD dwLength);
+ int GetCountofType(DLCAudioFile::EAudioType ptype);
+ wstring &GetSoundName(int iIndex);
+
+private:
+ using DLCFile::addParameter;
+
+ PBYTE m_pbData;
+ DWORD m_dwBytes;
+ static const int CURRENT_AUDIO_VERSION_NUM=1;
+ //unordered_map<int, wstring> m_parameters;
+ vector<wstring> m_parameters[e_AudioType_Max];
+
+ // use the EAudioType to order these
+ void addParameter(DLCAudioFile::EAudioType type, DLCAudioFile::EAudioParameterType ptype, const wstring &value);
+ DLCAudioFile::EAudioParameterType getParameterType(const wstring &paramName);
+};
diff --git a/Minecraft.Client/Common/DLC/DLCCapeFile.cpp b/Minecraft.Client/Common/DLC/DLCCapeFile.cpp
new file mode 100644
index 00000000..29a50ad4
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCCapeFile.cpp
@@ -0,0 +1,12 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCCapeFile.h"
+
+DLCCapeFile::DLCCapeFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_Cape,path)
+{
+}
+
+void DLCCapeFile::addData(PBYTE pbData, DWORD dwBytes)
+{
+ app.AddMemoryTextureFile(m_path,pbData,dwBytes);
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCCapeFile.h b/Minecraft.Client/Common/DLC/DLCCapeFile.h
new file mode 100644
index 00000000..8373d340
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCCapeFile.h
@@ -0,0 +1,10 @@
+#pragma once
+#include "DLCFile.h"
+
+class DLCCapeFile : public DLCFile
+{
+public:
+ DLCCapeFile(const wstring &path);
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCColourTableFile.cpp b/Minecraft.Client/Common/DLC/DLCColourTableFile.cpp
new file mode 100644
index 00000000..ec800dac
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCColourTableFile.cpp
@@ -0,0 +1,26 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCColourTableFile.h"
+#include "..\..\Minecraft.h"
+#include "..\..\TexturePackRepository.h"
+#include "..\..\TexturePack.h"
+
+DLCColourTableFile::DLCColourTableFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_ColourTable,path)
+{
+ m_colourTable = NULL;
+}
+
+DLCColourTableFile::~DLCColourTableFile()
+{
+ if(m_colourTable != NULL)
+ {
+ app.DebugPrintf("Deleting DLCColourTableFile data\n");
+ delete m_colourTable;
+ }
+}
+
+void DLCColourTableFile::addData(PBYTE pbData, DWORD dwBytes)
+{
+ ColourTable *defaultColourTable = Minecraft::GetInstance()->skins->getDefault()->getColourTable();
+ m_colourTable = new ColourTable(defaultColourTable, pbData, dwBytes);
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCColourTableFile.h b/Minecraft.Client/Common/DLC/DLCColourTableFile.h
new file mode 100644
index 00000000..84269739
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCColourTableFile.h
@@ -0,0 +1,18 @@
+#pragma once
+#include "DLCFile.h"
+
+class ColourTable;
+
+class DLCColourTableFile : public DLCFile
+{
+private:
+ ColourTable *m_colourTable;
+
+public:
+ DLCColourTableFile(const wstring &path);
+ ~DLCColourTableFile();
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+
+ ColourTable *getColourTable() { return m_colourTable; }
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCFile.cpp b/Minecraft.Client/Common/DLC/DLCFile.cpp
new file mode 100644
index 00000000..e7bbace0
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCFile.cpp
@@ -0,0 +1,26 @@
+#include "stdafx.h"
+#include "DLCFile.h"
+
+DLCFile::DLCFile(DLCManager::EDLCType type, const wstring &path)
+{
+ m_type = type;
+ m_path = path;
+
+ // store the id
+ bool dlcSkin = path.substr(0,3).compare(L"dlc") == 0;
+
+ if(dlcSkin)
+ {
+ wstring skinValue = path.substr(7,path.size());
+ skinValue = skinValue.substr(0,skinValue.find_first_of(L'.'));
+ std::wstringstream ss;
+ ss << std::dec << skinValue.c_str();
+ ss >> m_dwSkinId;
+ m_dwSkinId = MAKE_SKIN_BITMASK(true, m_dwSkinId);
+
+ }
+ else
+ {
+ m_dwSkinId=0;
+ }
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCFile.h b/Minecraft.Client/Common/DLC/DLCFile.h
new file mode 100644
index 00000000..3a40dbc7
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCFile.h
@@ -0,0 +1,25 @@
+#pragma once
+#include "DLCManager.h"
+
+class DLCFile
+{
+protected:
+ DLCManager::EDLCType m_type;
+ wstring m_path;
+ DWORD m_dwSkinId;
+
+public:
+ DLCFile(DLCManager::EDLCType type, const wstring &path);
+ virtual ~DLCFile() {}
+
+ DLCManager::EDLCType getType() { return m_type; }
+ wstring getPath() { return m_path; }
+ DWORD getSkinID() { return m_dwSkinId; }
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes) {}
+ virtual PBYTE getData(DWORD &dwBytes) { dwBytes = 0; return NULL; }
+ virtual void addParameter(DLCManager::EDLCParameterType type, const wstring &value) {}
+
+ virtual wstring getParameterAsString(DLCManager::EDLCParameterType type) { return L""; }
+ virtual bool getParameterAsBool(DLCManager::EDLCParameterType type) { return false;}
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCGameRules.h b/Minecraft.Client/Common/DLC/DLCGameRules.h
new file mode 100644
index 00000000..9d3bbaad
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCGameRules.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "DLCFile.h"
+#include "..\GameRules\LevelGenerationOptions.h"
+
+class DLCGameRules : public DLCFile
+{
+public:
+ DLCGameRules(DLCManager::EDLCType type, const wstring &path) : DLCFile(type,path) {}
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCGameRulesFile.cpp b/Minecraft.Client/Common/DLC/DLCGameRulesFile.cpp
new file mode 100644
index 00000000..8ca520d6
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCGameRulesFile.cpp
@@ -0,0 +1,21 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCGameRulesFile.h"
+
+DLCGameRulesFile::DLCGameRulesFile(const wstring &path) : DLCGameRules(DLCManager::e_DLCType_GameRules,path)
+{
+ m_pbData = NULL;
+ m_dwBytes = 0;
+}
+
+void DLCGameRulesFile::addData(PBYTE pbData, DWORD dwBytes)
+{
+ m_pbData = pbData;
+ m_dwBytes = dwBytes;
+}
+
+PBYTE DLCGameRulesFile::getData(DWORD &dwBytes)
+{
+ dwBytes = m_dwBytes;
+ return m_pbData;
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCGameRulesFile.h b/Minecraft.Client/Common/DLC/DLCGameRulesFile.h
new file mode 100644
index 00000000..e6456d73
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCGameRulesFile.h
@@ -0,0 +1,15 @@
+#pragma once
+#include "DLCGameRules.h"
+
+class DLCGameRulesFile : public DLCGameRules
+{
+private:
+ PBYTE m_pbData;
+ DWORD m_dwBytes;
+
+public:
+ DLCGameRulesFile(const wstring &path);
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+ virtual PBYTE getData(DWORD &dwBytes);
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCGameRulesHeader.cpp b/Minecraft.Client/Common/DLC/DLCGameRulesHeader.cpp
new file mode 100644
index 00000000..39b85219
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCGameRulesHeader.cpp
@@ -0,0 +1,92 @@
+#include "stdafx.h"
+
+#include <string>
+
+#include "..\..\..\Minecraft.World\File.h"
+#include "..\..\..\Minecraft.World\StringHelpers.h"
+#include "..\..\..\Minecraft.World\InputOutputStream.h"
+
+#include "DLCManager.h"
+#include "DLCGameRulesHeader.h"
+
+DLCGameRulesHeader::DLCGameRulesHeader(const wstring &path) : DLCGameRules(DLCManager::e_DLCType_GameRulesHeader,path)
+{
+ m_pbData = NULL;
+ m_dwBytes = 0;
+
+ m_hasData = false;
+
+ m_grfPath = path.substr(0, path.length() - 4) + L".grf";
+
+ lgo = NULL;
+}
+
+void DLCGameRulesHeader::addData(PBYTE pbData, DWORD dwBytes)
+{
+ m_pbData = pbData;
+ m_dwBytes = dwBytes;
+
+
+#if 0
+ byteArray data(m_pbData, m_dwBytes);
+ ByteArrayInputStream bais(data);
+ DataInputStream dis(&bais);
+
+ // Init values.
+ int version_number;
+ byte compression_type;
+ wstring texturepackid;
+
+ // Read Datastream.
+ version_number = dis.readInt();
+ compression_type = dis.readByte();
+ m_defaultSaveName = dis.readUTF();
+ m_displayName = dis.readUTF();
+ texturepackid = dis.readUTF();
+ m_grfPath = dis.readUTF();
+
+ // Debug printout.
+ app.DebugPrintf (
+ "DLCGameRulesHeader::readHeader:\n"
+ "\tversion_number = '%d',\n"
+ "\tcompression_type = '%d',\n"
+ "\tdefault_savename = '%s',\n"
+ "\tdisplayname = '%s',\n"
+ "\ttexturepackid = '%s',\n"
+ "\tgrf_path = '%s',\n",
+
+ version_number, compression_type,
+
+ wstringtofilename(m_defaultSaveName),
+ wstringtofilename(m_displayName),
+ wstringtofilename(texturepackid),
+ wstringtofilename(m_grfPath)
+ );
+
+ // Texture Pack.
+ m_requiredTexturePackId = _fromString<long>(texturepackid);
+ m_bRequiresTexturePack = m_requiredTexturePackId > 0;
+
+ dis.close();
+ bais.close();
+ bais.reset();
+#endif
+}
+
+PBYTE DLCGameRulesHeader::getData(DWORD &dwBytes)
+{
+ dwBytes = m_dwBytes;
+ return m_pbData;
+}
+
+void DLCGameRulesHeader::setGrfData(PBYTE fData, DWORD fSize, StringTable *st)
+{
+ if (!m_hasData)
+ {
+ m_hasData = true;
+
+ //app.m_gameRules.loadGameRules(lgo, fData, fSize);
+
+ app.m_gameRules.readRuleFile(lgo, fData, fSize, st);
+ }
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCGameRulesHeader.h b/Minecraft.Client/Common/DLC/DLCGameRulesHeader.h
new file mode 100644
index 00000000..4521ae11
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCGameRulesHeader.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "DLCGameRules.h"
+#include "..\GameRules\LevelGenerationOptions.h"
+
+class DLCGameRulesHeader : public DLCGameRules, public JustGrSource
+{
+private:
+
+ // GR-Header
+ PBYTE m_pbData;
+ DWORD m_dwBytes;
+
+ bool m_hasData;
+
+public:
+ virtual bool requiresTexturePack() {return m_bRequiresTexturePack;}
+ virtual UINT getRequiredTexturePackId() {return m_requiredTexturePackId;}
+ virtual wstring getDefaultSaveName() {return m_defaultSaveName;}
+ virtual LPCWSTR getWorldName() {return m_worldName.c_str();}
+ virtual LPCWSTR getDisplayName() {return m_displayName.c_str();}
+ virtual wstring getGrfPath() {return L"GameRules.grf";}
+
+ virtual void setRequiresTexturePack(bool x) {m_bRequiresTexturePack = x;}
+ virtual void setRequiredTexturePackId(UINT x) {m_requiredTexturePackId = x;}
+ virtual void setDefaultSaveName(const wstring &x) {m_defaultSaveName = x;}
+ virtual void setWorldName(const wstring & x) {m_worldName = x;}
+ virtual void setDisplayName(const wstring & x) {m_displayName = x;}
+ virtual void setGrfPath(const wstring & x) {m_grfPath = x;}
+
+ LevelGenerationOptions *lgo;
+
+public:
+ DLCGameRulesHeader(const wstring &path);
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+ virtual PBYTE getData(DWORD &dwBytes);
+
+ void setGrfData(PBYTE fData, DWORD fSize, StringTable *);
+
+ virtual bool ready() { return m_hasData; }
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCLocalisationFile.cpp b/Minecraft.Client/Common/DLC/DLCLocalisationFile.cpp
new file mode 100644
index 00000000..358a93e5
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCLocalisationFile.cpp
@@ -0,0 +1,14 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCLocalisationFile.h"
+#include "..\..\StringTable.h"
+
+DLCLocalisationFile::DLCLocalisationFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_LocalisationData,path)
+{
+ m_strings = NULL;
+}
+
+void DLCLocalisationFile::addData(PBYTE pbData, DWORD dwBytes)
+{
+ m_strings = new StringTable(pbData, dwBytes);
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCLocalisationFile.h b/Minecraft.Client/Common/DLC/DLCLocalisationFile.h
new file mode 100644
index 00000000..083e60d8
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCLocalisationFile.h
@@ -0,0 +1,18 @@
+#pragma once
+#include "DLCFile.h"
+
+class StringTable;
+
+class DLCLocalisationFile : public DLCFile
+{
+private:
+ StringTable *m_strings;
+
+public:
+ DLCLocalisationFile(const wstring &path);
+ DLCLocalisationFile(PBYTE pbData, DWORD dwBytes); // when we load in a texture pack details file from TMS++
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+
+ StringTable *getStringTable() { return m_strings; }
+}; \ No newline at end of file
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
diff --git a/Minecraft.Client/Common/DLC/DLCManager.h b/Minecraft.Client/Common/DLC/DLCManager.h
new file mode 100644
index 00000000..55a62312
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCManager.h
@@ -0,0 +1,99 @@
+#pragma once
+using namespace std;
+#include <vector>
+class DLCPack;
+class DLCSkinFile;
+
+class DLCManager
+{
+public:
+ enum EDLCType
+ {
+ e_DLCType_Skin = 0,
+ e_DLCType_Cape,
+ e_DLCType_Texture,
+ e_DLCType_UIData,
+ e_DLCType_PackConfig,
+ e_DLCType_TexturePack,
+ e_DLCType_LocalisationData,
+ e_DLCType_GameRules,
+ e_DLCType_Audio,
+ e_DLCType_ColourTable,
+ e_DLCType_GameRulesHeader,
+
+ e_DLCType_Max,
+ e_DLCType_All,
+ };
+
+ // If you add to the Enum,then you need to add the array of type names
+ // These are the names used in the XML for the parameters
+ enum EDLCParameterType
+ {
+ e_DLCParamType_Invalid = -1,
+
+ e_DLCParamType_DisplayName = 0,
+ e_DLCParamType_ThemeName,
+ e_DLCParamType_Free, // identify free skins
+ e_DLCParamType_Credit, // legal credits for DLC
+ e_DLCParamType_Cape,
+ e_DLCParamType_Box,
+ e_DLCParamType_Anim,
+ e_DLCParamType_PackId,
+ e_DLCParamType_NetherParticleColour,
+ e_DLCParamType_EnchantmentTextColour,
+ e_DLCParamType_EnchantmentTextFocusColour,
+ e_DLCParamType_DataPath,
+ e_DLCParamType_PackVersion,
+
+ e_DLCParamType_Max,
+
+ };
+ static WCHAR *wchTypeNamesA[e_DLCParamType_Max];
+
+private:
+ vector<DLCPack *> m_packs;
+ //bool m_bNeedsUpdated;
+ bool m_bNeedsCorruptCheck;
+ DWORD m_dwUnnamedCorruptDLCCount;
+public:
+ DLCManager();
+ ~DLCManager();
+
+ static EDLCParameterType getParameterType(const wstring &paramName);
+
+ DWORD getPackCount(EDLCType type = e_DLCType_All);
+
+ //bool NeedsUpdated() { return m_bNeedsUpdated; }
+ //void SetNeedsUpdated(bool val) { m_bNeedsUpdated = val; }
+
+ bool NeedsCorruptCheck() { return m_bNeedsCorruptCheck; }
+ void SetNeedsCorruptCheck(bool val) { m_bNeedsCorruptCheck = val; }
+
+ void resetUnnamedCorruptCount() { m_dwUnnamedCorruptDLCCount = 0; }
+ void incrementUnnamedCorruptCount() { ++m_dwUnnamedCorruptDLCCount; }
+
+ void addPack(DLCPack *pack);
+ void removePack(DLCPack *pack);
+
+ DLCPack *getPack(const wstring &name);
+#ifdef _XBOX_ONE
+ DLCPack *DLCManager::getPackFromProductID(const wstring &productID);
+#endif
+ DLCPack *getPack(DWORD index, EDLCType type = e_DLCType_All);
+ DWORD getPackIndex(DLCPack *pack, bool &found, EDLCType type = e_DLCType_All);
+ DLCSkinFile *getSkinFile(const wstring &path); // Will hunt all packs of type skin to find the right skinfile
+
+ DLCPack *getPackContainingSkin(const wstring &path);
+ DWORD getPackIndexContainingSkin(const wstring &path, bool &found);
+
+ DWORD checkForCorruptDLCAndAlert(bool showMessage = true);
+
+ bool readDLCDataFile(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack, bool fromArchive = false);
+ bool readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DLCPack *pack, bool fromArchive = false);
+ DWORD retrievePackIDFromDLCDataFile(const string &path, DLCPack *pack);
+
+private:
+ bool processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwLength, DLCPack *pack);
+
+ DWORD retrievePackID(PBYTE pbData, DWORD dwLength, DLCPack *pack);
+};
diff --git a/Minecraft.Client/Common/DLC/DLCPack.cpp b/Minecraft.Client/Common/DLC/DLCPack.cpp
new file mode 100644
index 00000000..23a2e44a
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCPack.cpp
@@ -0,0 +1,410 @@
+#include "stdafx.h"
+#include "DLCPack.h"
+#include "DLCSkinFile.h"
+#include "DLCCapeFile.h"
+#include "DLCTextureFile.h"
+#include "DLCUIDataFile.h"
+#include "DLCLocalisationFile.h"
+#include "DLCGameRulesFile.h"
+#include "DLCGameRulesHeader.h"
+#include "DLCAudioFile.h"
+#include "DLCColourTableFile.h"
+#include "..\..\..\Minecraft.World\StringHelpers.h"
+
+DLCPack::DLCPack(const wstring &name,DWORD dwLicenseMask)
+{
+ m_dataPath = L"";
+ m_packName = name;
+ m_dwLicenseMask=dwLicenseMask;
+#ifdef _XBOX_ONE
+ m_wsProductId = L"";
+#else
+ m_ullFullOfferId = 0LL;
+#endif
+ m_isCorrupt = false;
+ m_packId = 0;
+ m_packVersion = 0;
+ m_parentPack = NULL;
+ m_dlcMountIndex = -1;
+#ifdef _XBOX
+ m_dlcDeviceID = XCONTENTDEVICE_ANY;
+#endif
+
+ // This pointer is for all the data used for this pack, so deleting it invalidates ALL of it's children.
+ m_data = NULL;
+}
+
+#ifdef _XBOX_ONE
+DLCPack::DLCPack(const wstring &name,const wstring &productID,DWORD dwLicenseMask)
+{
+ m_dataPath = L"";
+ m_packName = name;
+ m_dwLicenseMask=dwLicenseMask;
+ m_wsProductId = productID;
+ m_isCorrupt = false;
+ m_packId = 0;
+ m_packVersion = 0;
+ m_parentPack = NULL;
+ m_dlcMountIndex = -1;
+
+ // This pointer is for all the data used for this pack, so deleting it invalidates ALL of it's children.
+ m_data = NULL;
+}
+#endif
+
+DLCPack::~DLCPack()
+{
+ for(AUTO_VAR(it, m_childPacks.begin()); it != m_childPacks.end(); ++it)
+ {
+ delete *it;
+ }
+
+ for(unsigned int i = 0; i < DLCManager::e_DLCType_Max; ++i)
+ {
+ for(AUTO_VAR(it,m_files[i].begin()); it != m_files[i].end(); ++it)
+ {
+ delete *it;
+ }
+ }
+
+ // This pointer is for all the data used for this pack, so deleting it invalidates ALL of it's children.
+ if(m_data)
+ {
+#ifndef _CONTENT_PACKAGE
+ wprintf(L"Deleting data for DLC pack %ls\n", m_packName.c_str());
+#endif
+ // For the same reason, don't delete data pointer for any child pack as it just points to a region within the parent pack that has already been freed
+ if( m_parentPack == NULL )
+ {
+ delete [] m_data;
+ }
+ }
+}
+
+DWORD DLCPack::GetDLCMountIndex()
+{
+ if(m_parentPack != NULL)
+ {
+ return m_parentPack->GetDLCMountIndex();
+ }
+ return m_dlcMountIndex;
+}
+
+XCONTENTDEVICEID DLCPack::GetDLCDeviceID()
+{
+ if(m_parentPack != NULL )
+ {
+ return m_parentPack->GetDLCDeviceID();
+ }
+ return m_dlcDeviceID;
+}
+
+void DLCPack::addChildPack(DLCPack *childPack)
+{
+ int packId = childPack->GetPackId();
+#ifndef _CONTENT_PACKAGE
+ if(packId < 0 || packId > 15)
+ {
+ __debugbreak();
+ }
+#endif
+ childPack->SetPackId( (packId<<24) | m_packId );
+ m_childPacks.push_back(childPack);
+ childPack->setParentPack(this);
+ childPack->m_packName = m_packName + childPack->getName();
+}
+
+void DLCPack::setParentPack(DLCPack *parentPack)
+{
+ m_parentPack = parentPack;
+}
+
+void DLCPack::addParameter(DLCManager::EDLCParameterType type, const wstring &value)
+{
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_PackId:
+ {
+ DWORD packId = 0;
+
+ std::wstringstream ss;
+ // 4J Stu - numbered using decimal to make it easier for artists/people to number manually
+ ss << std::dec << value.c_str();
+ ss >> packId;
+
+ SetPackId(packId);
+ }
+ break;
+ case DLCManager::e_DLCParamType_PackVersion:
+ {
+ DWORD version = 0;
+
+ std::wstringstream ss;
+ // 4J Stu - numbered using decimal to make it easier for artists/people to number manually
+ ss << std::dec << value.c_str();
+ ss >> version;
+
+ SetPackVersion(version);
+ }
+ break;
+ case DLCManager::e_DLCParamType_DisplayName:
+ m_packName = value;
+ break;
+ case DLCManager::e_DLCParamType_DataPath:
+ m_dataPath = value;
+ break;
+ default:
+ m_parameters[(int)type] = value;
+ break;
+ }
+}
+
+bool DLCPack::getParameterAsUInt(DLCManager::EDLCParameterType type, unsigned int &param)
+{
+ AUTO_VAR(it,m_parameters.find((int)type));
+ if(it != m_parameters.end())
+ {
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_NetherParticleColour:
+ case DLCManager::e_DLCParamType_EnchantmentTextColour:
+ case DLCManager::e_DLCParamType_EnchantmentTextFocusColour:
+ {
+ std::wstringstream ss;
+ ss << std::hex << it->second.c_str();
+ ss >> param;
+ }
+ break;
+ default:
+ param = _fromString<unsigned int>(it->second);
+ }
+ return true;
+ }
+ return false;
+}
+
+DLCFile *DLCPack::addFile(DLCManager::EDLCType type, const wstring &path)
+{
+ DLCFile *newFile = NULL;
+
+ switch(type)
+ {
+ case DLCManager::e_DLCType_Skin:
+ {
+ std::vector<std::wstring> splitPath = stringSplit(path,L'/');
+ wstring strippedPath = splitPath.back();
+
+ newFile = new DLCSkinFile(strippedPath);
+
+ // check to see if we can get the full offer id using this skin name
+#ifdef _XBOX_ONE
+ app.GetDLCFullOfferIDForSkinID(strippedPath,m_wsProductId);
+#else
+ ULONGLONG ullVal=0LL;
+
+ if(app.GetDLCFullOfferIDForSkinID(strippedPath,&ullVal))
+ {
+ m_ullFullOfferId=ullVal;
+ }
+#endif
+ }
+ break;
+ case DLCManager::e_DLCType_Cape:
+ {
+ std::vector<std::wstring> splitPath = stringSplit(path,L'/');
+ wstring strippedPath = splitPath.back();
+ newFile = new DLCCapeFile(strippedPath);
+ }
+ break;
+ case DLCManager::e_DLCType_Texture:
+ newFile = new DLCTextureFile(path);
+ break;
+ case DLCManager::e_DLCType_UIData:
+ newFile = new DLCUIDataFile(path);
+ break;
+ case DLCManager::e_DLCType_LocalisationData:
+ newFile = new DLCLocalisationFile(path);
+ break;
+ case DLCManager::e_DLCType_GameRules:
+ newFile = new DLCGameRulesFile(path);
+ break;
+ case DLCManager::e_DLCType_Audio:
+ newFile = new DLCAudioFile(path);
+ break;
+ case DLCManager::e_DLCType_ColourTable:
+ newFile = new DLCColourTableFile(path);
+ break;
+ case DLCManager::e_DLCType_GameRulesHeader:
+ newFile = new DLCGameRulesHeader(path);
+ break;
+ };
+
+ if( newFile != NULL )
+ {
+ m_files[newFile->getType()].push_back(newFile);
+ }
+
+ return newFile;
+}
+
+// MGH - added this comp func, as the embedded func in find_if was confusing the PS3 compiler
+static const wstring *g_pathCmpString = NULL;
+static bool pathCmp(DLCFile *val)
+{
+ return (g_pathCmpString->compare(val->getPath()) == 0);
+}
+
+bool DLCPack::doesPackContainFile(DLCManager::EDLCType type, const wstring &path)
+{
+ bool hasFile = false;
+ if(type == DLCManager::e_DLCType_All)
+ {
+ for(DLCManager::EDLCType currentType = (DLCManager::EDLCType)0; currentType < DLCManager::e_DLCType_Max; currentType = (DLCManager::EDLCType)(currentType + 1))
+ {
+ hasFile = doesPackContainFile(currentType,path);
+ if(hasFile) break;
+ }
+ }
+ else
+ {
+ g_pathCmpString = &path;
+ AUTO_VAR(it, find_if( m_files[type].begin(), m_files[type].end(), pathCmp ));
+ hasFile = it != m_files[type].end();
+ if(!hasFile && m_parentPack )
+ {
+ hasFile = m_parentPack->doesPackContainFile(type,path);
+ }
+ }
+ return hasFile;
+}
+
+DLCFile *DLCPack::getFile(DLCManager::EDLCType type, DWORD index)
+{
+ DLCFile *file = NULL;
+ if(type == DLCManager::e_DLCType_All)
+ {
+ for(DLCManager::EDLCType currentType = (DLCManager::EDLCType)0; currentType < DLCManager::e_DLCType_Max; currentType = (DLCManager::EDLCType)(currentType + 1))
+ {
+ file = getFile(currentType,index);
+ if(file != NULL) break;
+ }
+ }
+ else
+ {
+ if(m_files[type].size() > index) file = m_files[type][index];
+ if(!file && m_parentPack)
+ {
+ file = m_parentPack->getFile(type,index);
+ }
+ }
+ return file;
+}
+
+DLCFile *DLCPack::getFile(DLCManager::EDLCType type, const wstring &path)
+{
+ DLCFile *file = NULL;
+ if(type == DLCManager::e_DLCType_All)
+ {
+ for(DLCManager::EDLCType currentType = (DLCManager::EDLCType)0; currentType < DLCManager::e_DLCType_Max; currentType = (DLCManager::EDLCType)(currentType + 1))
+ {
+ file = getFile(currentType,path);
+ if(file != NULL) break;
+ }
+ }
+ else
+ {
+ g_pathCmpString = &path;
+ AUTO_VAR(it, find_if( m_files[type].begin(), m_files[type].end(), pathCmp ));
+
+ if(it == m_files[type].end())
+ {
+ // Not found
+ file = NULL;
+ }
+ else
+ {
+ file = *it;
+ }
+ if(!file && m_parentPack)
+ {
+ file = m_parentPack->getFile(type,path);
+ }
+ }
+ return file;
+}
+
+DWORD DLCPack::getDLCItemsCount(DLCManager::EDLCType type /*= DLCManager::e_DLCType_All*/)
+{
+ DWORD count = 0;
+
+ switch(type)
+ {
+ case DLCManager::e_DLCType_All:
+ for(int i = 0; i < DLCManager::e_DLCType_Max; ++i)
+ {
+ count += getDLCItemsCount((DLCManager::EDLCType)i);
+ }
+ break;
+ default:
+ count = (DWORD)m_files[(int)type].size();
+ break;
+ };
+ return count;
+};
+
+DWORD DLCPack::getFileIndexAt(DLCManager::EDLCType type, const wstring &path, bool &found)
+{
+ if(type == DLCManager::e_DLCType_All)
+ {
+ app.DebugPrintf("Unimplemented\n");
+#ifndef __CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return 0;
+ }
+
+ DWORD foundIndex = 0;
+ found = false;
+ DWORD index = 0;
+ for(AUTO_VAR(it, m_files[type].begin()); it != m_files[type].end(); ++it)
+ {
+ if(path.compare((*it)->getPath()) == 0)
+ {
+ foundIndex = index;
+ found = true;
+ break;
+ }
+ ++index;
+ }
+
+ return foundIndex;
+}
+
+bool DLCPack::hasPurchasedFile(DLCManager::EDLCType type, const wstring &path)
+{
+ if(type == DLCManager::e_DLCType_All)
+ {
+ app.DebugPrintf("Unimplemented\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return false;
+ }
+#ifndef _CONTENT_PACKAGE
+ if( app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_UnlockAllDLC) )
+ {
+ return true;
+ }
+ else
+#endif
+ if ( m_dwLicenseMask == 0 )
+ {
+ //not purchased.
+ return false;
+ }
+ else
+ {
+ //purchased
+ return true;
+ }
+}
diff --git a/Minecraft.Client/Common/DLC/DLCPack.h b/Minecraft.Client/Common/DLC/DLCPack.h
new file mode 100644
index 00000000..856744c2
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCPack.h
@@ -0,0 +1,93 @@
+#pragma once
+using namespace std;
+#include "DLCManager.h"
+
+class DLCFile;
+class DLCSkinFile;
+
+class DLCPack
+{
+private:
+ vector<DLCFile *> m_files[DLCManager::e_DLCType_Max];
+ vector<DLCPack *> m_childPacks;
+ DLCPack *m_parentPack;
+
+ unordered_map<int, wstring> m_parameters;
+
+ wstring m_packName;
+ wstring m_dataPath;
+ DWORD m_dwLicenseMask;
+ int m_dlcMountIndex;
+ XCONTENTDEVICEID m_dlcDeviceID;
+#ifdef _XBOX_ONE
+ wstring m_wsProductId;
+#else
+ ULONGLONG m_ullFullOfferId;
+#endif
+ bool m_isCorrupt;
+ DWORD m_packId;
+ DWORD m_packVersion;
+
+ PBYTE m_data; // This pointer is for all the data used for this pack, so deleting it invalidates ALL of it's children.
+public:
+
+ DLCPack(const wstring &name,DWORD dwLicenseMask);
+#ifdef _XBOX_ONE
+ DLCPack(const wstring &name,const wstring &productID,DWORD dwLicenseMask);
+#endif
+ ~DLCPack();
+
+ wstring getFullDataPath() { return m_dataPath; }
+
+ void SetDataPointer(PBYTE pbData) { m_data = pbData; }
+
+ bool IsCorrupt() { return m_isCorrupt; }
+ void SetIsCorrupt(bool val) { m_isCorrupt = val; }
+
+ void SetPackId(DWORD id) { m_packId = id; }
+ DWORD GetPackId() { return m_packId; }
+
+ void SetPackVersion(DWORD version) { m_packVersion = version; }
+ DWORD GetPackVersion() { return m_packVersion; }
+
+ DLCPack * GetParentPack() { return m_parentPack; }
+ DWORD GetParentPackId() { return m_parentPack->m_packId; }
+
+ void SetDLCMountIndex(DWORD id) { m_dlcMountIndex = id; }
+ DWORD GetDLCMountIndex();
+ void SetDLCDeviceID(XCONTENTDEVICEID deviceId) { m_dlcDeviceID = deviceId; }
+ XCONTENTDEVICEID GetDLCDeviceID();
+
+ void addChildPack(DLCPack *childPack);
+ void setParentPack(DLCPack *parentPack);
+
+ void addParameter(DLCManager::EDLCParameterType type, const wstring &value);
+ bool getParameterAsUInt(DLCManager::EDLCParameterType type, unsigned int &param);
+
+ void updateLicenseMask( DWORD dwLicenseMask ) { m_dwLicenseMask = dwLicenseMask; }
+ DWORD getLicenseMask( ) { return m_dwLicenseMask; }
+
+ wstring getName() { return m_packName; }
+#ifdef _XBOX_ONE
+ wstring getPurchaseOfferId() { return m_wsProductId; }
+#else
+ ULONGLONG getPurchaseOfferId() { return m_ullFullOfferId; }
+#endif
+
+ DLCFile *addFile(DLCManager::EDLCType type, const wstring &path);
+ DLCFile *getFile(DLCManager::EDLCType type, DWORD index);
+ DLCFile *getFile(DLCManager::EDLCType type, const wstring &path);
+
+ DWORD getDLCItemsCount(DLCManager::EDLCType type = DLCManager::e_DLCType_All);
+ DWORD getFileIndexAt(DLCManager::EDLCType type, const wstring &path, bool &found);
+ bool doesPackContainFile(DLCManager::EDLCType type, const wstring &path);
+ DWORD GetPackID() {return m_packId;}
+
+ DWORD getSkinCount() { return getDLCItemsCount(DLCManager::e_DLCType_Skin); }
+ DWORD getSkinIndexAt(const wstring &path, bool &found) { return getFileIndexAt(DLCManager::e_DLCType_Skin, path, found); }
+ DLCSkinFile *getSkinFile(const wstring &path) { return (DLCSkinFile *)getFile(DLCManager::e_DLCType_Skin, path); }
+ DLCSkinFile *getSkinFile(DWORD index) { return (DLCSkinFile *)getFile(DLCManager::e_DLCType_Skin, index); }
+ bool doesPackContainSkin(const wstring &path) { return doesPackContainFile(DLCManager::e_DLCType_Skin, path); }
+
+ bool hasPurchasedFile(DLCManager::EDLCType type, const wstring &path);
+};
diff --git a/Minecraft.Client/Common/DLC/DLCSkinFile.cpp b/Minecraft.Client/Common/DLC/DLCSkinFile.cpp
new file mode 100644
index 00000000..f3768a34
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCSkinFile.cpp
@@ -0,0 +1,212 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCSkinFile.h"
+#include "..\..\ModelPart.h"
+#include "..\..\EntityRenderer.h"
+#include "..\..\EntityRenderDispatcher.h"
+#include "..\..\..\Minecraft.World\Player.h"
+#include "..\..\..\Minecraft.World\StringHelpers.h"
+
+DLCSkinFile::DLCSkinFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_Skin,path)
+{
+ m_displayName = L"";
+ m_themeName = L"";
+ m_cape = L"";
+ m_bIsFree = false;
+ m_uiAnimOverrideBitmask=0L;
+}
+
+void DLCSkinFile::addData(PBYTE pbData, DWORD dwBytes)
+{
+ app.AddMemoryTextureFile(m_path,pbData,dwBytes);
+}
+
+void DLCSkinFile::addParameter(DLCManager::EDLCParameterType type, const wstring &value)
+{
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_DisplayName:
+ {
+ // 4J Stu - In skin pack 2, the name for Zap is mis-spelt with two p's as Zapp
+ // dlcskin00000109.png
+ if( m_path.compare(L"dlcskin00000109.png") == 0)
+ {
+ m_displayName = L"Zap";
+ }
+ else
+ {
+ m_displayName = value;
+ }
+ }
+ break;
+ case DLCManager::e_DLCParamType_ThemeName:
+ m_themeName = value;
+ break;
+ case DLCManager::e_DLCParamType_Free: // If this parameter exists, then mark this as free
+ m_bIsFree = true;
+ break;
+ case DLCManager::e_DLCParamType_Credit: // If this parameter exists, then mark this as free
+ //add it to the DLC credits list
+
+ // we'll need to justify this text since we don't have a lot of room for lines of credits
+ {
+ if(app.AlreadySeenCreditText(value)) break;
+ // first add a blank string for spacing
+ app.AddCreditText(L"");
+
+ int maximumChars = 55;
+
+ bool bIsSDMode=!RenderManager.IsHiDef() && !RenderManager.IsWidescreen();
+
+ if(bIsSDMode)
+ {
+ maximumChars = 45;
+ }
+
+ switch(XGetLanguage())
+ {
+ case XC_LANGUAGE_JAPANESE:
+ case XC_LANGUAGE_TCHINESE:
+ case XC_LANGUAGE_KOREAN:
+ maximumChars = 35;
+ break;
+ }
+ wstring creditValue = value;
+ while (creditValue.length() > maximumChars)
+ {
+ unsigned int i = 1;
+ while (i < creditValue.length() && (i + 1) <= maximumChars)
+ {
+ i++;
+ }
+ int iLast=(int)creditValue.find_last_of(L" ",i);
+ switch(XGetLanguage())
+ {
+ case XC_LANGUAGE_JAPANESE:
+ case XC_LANGUAGE_TCHINESE:
+ case XC_LANGUAGE_KOREAN:
+ iLast = maximumChars;
+ break;
+ default:
+ iLast=(int)creditValue.find_last_of(L" ",i);
+ break;
+ }
+
+ // if a space was found, include the space on this line
+ if(iLast!=i)
+ {
+ iLast++;
+ }
+
+ app.AddCreditText((creditValue.substr(0, iLast)).c_str());
+ creditValue = creditValue.substr(iLast);
+ }
+ app.AddCreditText(creditValue.c_str());
+
+ }
+ break;
+ case DLCManager::e_DLCParamType_Cape:
+ m_cape = value;
+ break;
+ case DLCManager::e_DLCParamType_Box:
+ {
+ WCHAR wchBodyPart[10];
+ SKIN_BOX *pSkinBox = new SKIN_BOX;
+ ZeroMemory(pSkinBox,sizeof(SKIN_BOX));
+
+#ifdef __PS3__
+ // 4J Stu - The Xbox version used swscanf_s which isn't available in GCC.
+ swscanf(value.c_str(), L"%10ls%f%f%f%f%f%f%f%f", wchBodyPart,
+#else
+ swscanf_s(value.c_str(), L"%9ls%f%f%f%f%f%f%f%f", wchBodyPart,10,
+#endif
+ &pSkinBox->fX,
+ &pSkinBox->fY,
+ &pSkinBox->fZ,
+ &pSkinBox->fW,
+ &pSkinBox->fH,
+ &pSkinBox->fD,
+ &pSkinBox->fU,
+ &pSkinBox->fV);
+
+ if(wcscmp(wchBodyPart,L"HEAD")==0)
+ {
+ pSkinBox->ePart=eBodyPart_Head;
+ }
+ else if(wcscmp(wchBodyPart,L"BODY")==0)
+ {
+ pSkinBox->ePart=eBodyPart_Body;
+ }
+ else if(wcscmp(wchBodyPart,L"ARM0")==0)
+ {
+ pSkinBox->ePart=eBodyPart_Arm0;
+ }
+ else if(wcscmp(wchBodyPart,L"ARM1")==0)
+ {
+ pSkinBox->ePart=eBodyPart_Arm1;
+ }
+ else if(wcscmp(wchBodyPart,L"LEG0")==0)
+ {
+ pSkinBox->ePart=eBodyPart_Leg0;
+ }
+ else if(wcscmp(wchBodyPart,L"LEG1")==0)
+ {
+ pSkinBox->ePart=eBodyPart_Leg1;
+ }
+
+ // add this to the skin's vector of parts
+ m_AdditionalBoxes.push_back(pSkinBox);
+ }
+ break;
+ case DLCManager::e_DLCParamType_Anim:
+#ifdef __PS3__
+ // 4J Stu - The Xbox version used swscanf_s which isn't available in GCC.
+ swscanf(value.c_str(), L"%X", &m_uiAnimOverrideBitmask);
+#else
+ swscanf_s(value.c_str(), L"%X", &m_uiAnimOverrideBitmask,sizeof(unsigned int));
+#endif
+ DWORD skinId = app.getSkinIdFromPath(m_path);
+ app.SetAnimOverrideBitmask(skinId, m_uiAnimOverrideBitmask);
+ break;
+ }
+}
+
+// vector<ModelPart *> *DLCSkinFile::getAdditionalModelParts()
+// {
+// return &m_AdditionalModelParts;
+// }
+
+int DLCSkinFile::getAdditionalBoxesCount()
+{
+ return (int)m_AdditionalBoxes.size();
+}
+vector<SKIN_BOX *> *DLCSkinFile::getAdditionalBoxes()
+{
+ return &m_AdditionalBoxes;
+}
+
+wstring DLCSkinFile::getParameterAsString(DLCManager::EDLCParameterType type)
+{
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_DisplayName:
+ return m_displayName;
+ case DLCManager::e_DLCParamType_ThemeName:
+ return m_themeName;
+ case DLCManager::e_DLCParamType_Cape:
+ return m_cape;
+ default:
+ return L"";
+ }
+}
+
+bool DLCSkinFile::getParameterAsBool(DLCManager::EDLCParameterType type)
+{
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_Free:
+ return m_bIsFree;
+ default:
+ return false;
+ }
+}
diff --git a/Minecraft.Client/Common/DLC/DLCSkinFile.h b/Minecraft.Client/Common/DLC/DLCSkinFile.h
new file mode 100644
index 00000000..c8dcf0e9
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCSkinFile.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "DLCFile.h"
+#include "..\..\..\Minecraft.Client\HumanoidModel.h"
+
+class DLCSkinFile : public DLCFile
+{
+
+private:
+ wstring m_displayName;
+ wstring m_themeName;
+ wstring m_cape;
+ unsigned int m_uiAnimOverrideBitmask;
+ bool m_bIsFree;
+ vector<SKIN_BOX *> m_AdditionalBoxes;
+
+public:
+
+ DLCSkinFile(const wstring &path);
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+ virtual void addParameter(DLCManager::EDLCParameterType type, const wstring &value);
+
+ virtual wstring getParameterAsString(DLCManager::EDLCParameterType type);
+ virtual bool getParameterAsBool(DLCManager::EDLCParameterType type);
+ vector<SKIN_BOX *> *getAdditionalBoxes();
+ int getAdditionalBoxesCount();
+ unsigned int getAnimOverrideBitmask() { return m_uiAnimOverrideBitmask;}
+ bool isFree() {return m_bIsFree;}
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCTextureFile.cpp b/Minecraft.Client/Common/DLC/DLCTextureFile.cpp
new file mode 100644
index 00000000..cf99465a
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCTextureFile.cpp
@@ -0,0 +1,59 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCTextureFile.h"
+
+DLCTextureFile::DLCTextureFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_Texture,path)
+{
+ m_bIsAnim = false;
+ m_animString = L"";
+
+ m_pbData = NULL;
+ m_dwBytes = 0;
+}
+
+void DLCTextureFile::addData(PBYTE pbData, DWORD dwBytes)
+{
+ //app.AddMemoryTextureFile(m_path,pbData,dwBytes);
+ m_pbData = pbData;
+ m_dwBytes = dwBytes;
+}
+
+PBYTE DLCTextureFile::getData(DWORD &dwBytes)
+{
+ dwBytes = m_dwBytes;
+ return m_pbData;
+}
+
+void DLCTextureFile::addParameter(DLCManager::EDLCParameterType type, const wstring &value)
+{
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_Anim:
+ m_animString = value;
+ m_bIsAnim = true;
+
+ break;
+ }
+}
+
+wstring DLCTextureFile::getParameterAsString(DLCManager::EDLCParameterType type)
+{
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_Anim:
+ return m_animString;
+ default:
+ return L"";
+ }
+}
+
+bool DLCTextureFile::getParameterAsBool(DLCManager::EDLCParameterType type)
+{
+ switch(type)
+ {
+ case DLCManager::e_DLCParamType_Anim:
+ return m_bIsAnim;
+ default:
+ return false;
+ }
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCTextureFile.h b/Minecraft.Client/Common/DLC/DLCTextureFile.h
new file mode 100644
index 00000000..bc791686
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCTextureFile.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "DLCFile.h"
+
+class DLCTextureFile : public DLCFile
+{
+
+private:
+ bool m_bIsAnim;
+ wstring m_animString;
+
+ PBYTE m_pbData;
+ DWORD m_dwBytes;
+
+public:
+ DLCTextureFile(const wstring &path);
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes);
+ virtual PBYTE getData(DWORD &dwBytes);
+
+ virtual void addParameter(DLCManager::EDLCParameterType type, const wstring &value);
+
+ virtual wstring getParameterAsString(DLCManager::EDLCParameterType type);
+ virtual bool getParameterAsBool(DLCManager::EDLCParameterType type);
+}; \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCUIDataFile.cpp b/Minecraft.Client/Common/DLC/DLCUIDataFile.cpp
new file mode 100644
index 00000000..a2a56bca
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCUIDataFile.cpp
@@ -0,0 +1,32 @@
+#include "stdafx.h"
+#include "DLCManager.h"
+#include "DLCUIDataFile.h"
+
+DLCUIDataFile::DLCUIDataFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_UIData,path)
+{
+ m_pbData = NULL;
+ m_dwBytes = 0;
+ m_canDeleteData = false;
+}
+
+DLCUIDataFile::~DLCUIDataFile()
+{
+ if(m_canDeleteData && m_pbData != NULL)
+ {
+ app.DebugPrintf("Deleting DLCUIDataFile data\n");
+ delete [] m_pbData;
+ }
+}
+
+void DLCUIDataFile::addData(PBYTE pbData, DWORD dwBytes,bool canDeleteData)
+{
+ m_pbData = pbData;
+ m_dwBytes = dwBytes;
+ m_canDeleteData = canDeleteData;
+}
+
+PBYTE DLCUIDataFile::getData(DWORD &dwBytes)
+{
+ dwBytes = m_dwBytes;
+ return m_pbData;
+} \ No newline at end of file
diff --git a/Minecraft.Client/Common/DLC/DLCUIDataFile.h b/Minecraft.Client/Common/DLC/DLCUIDataFile.h
new file mode 100644
index 00000000..105ad0df
--- /dev/null
+++ b/Minecraft.Client/Common/DLC/DLCUIDataFile.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "DLCFile.h"
+
+class DLCUIDataFile : public DLCFile
+{
+private:
+ PBYTE m_pbData;
+ DWORD m_dwBytes;
+ bool m_canDeleteData;
+
+public:
+ DLCUIDataFile(const wstring &path);
+ ~DLCUIDataFile();
+
+ using DLCFile::addData;
+ using DLCFile::addParameter;
+
+ virtual void addData(PBYTE pbData, DWORD dwBytes,bool canDeleteData = false);
+ virtual PBYTE getData(DWORD &dwBytes);
+};