first commit

This commit is contained in:
murdle
2026-03-01 02:38:58 +02:00
commit 19250b9db4
19111 changed files with 4358159 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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; }
};

View File

@@ -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;
}
}

View File

@@ -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;}
};

View File

@@ -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) {}
};

View File

@@ -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;
}

View File

@@ -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);
};

View File

@@ -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);
}
}

View File

@@ -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; }
};

View File

@@ -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);
}

View File

@@ -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; }
};

View File

@@ -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;
}

View File

@@ -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);
};

View File

@@ -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;
}
}

View File

@@ -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);
};

View File

@@ -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;
}
}

View File

@@ -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;}
};

View File

@@ -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;
}
}

View File

@@ -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);
};

View File

@@ -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;
}

View File

@@ -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);
};