From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.Client/Common/DLC/DLCAudioFile.cpp | 216 +++++++ Minecraft.Client/Common/DLC/DLCAudioFile.h | 54 ++ Minecraft.Client/Common/DLC/DLCCapeFile.cpp | 12 + Minecraft.Client/Common/DLC/DLCCapeFile.h | 10 + Minecraft.Client/Common/DLC/DLCColourTableFile.cpp | 26 + Minecraft.Client/Common/DLC/DLCColourTableFile.h | 18 + Minecraft.Client/Common/DLC/DLCFile.cpp | 26 + Minecraft.Client/Common/DLC/DLCFile.h | 25 + Minecraft.Client/Common/DLC/DLCGameRules.h | 10 + Minecraft.Client/Common/DLC/DLCGameRulesFile.cpp | 21 + Minecraft.Client/Common/DLC/DLCGameRulesFile.h | 15 + Minecraft.Client/Common/DLC/DLCGameRulesHeader.cpp | 92 +++ Minecraft.Client/Common/DLC/DLCGameRulesHeader.h | 42 ++ .../Common/DLC/DLCLocalisationFile.cpp | 14 + Minecraft.Client/Common/DLC/DLCLocalisationFile.h | 18 + Minecraft.Client/Common/DLC/DLCManager.cpp | 671 +++++++++++++++++++++ Minecraft.Client/Common/DLC/DLCManager.h | 99 +++ Minecraft.Client/Common/DLC/DLCPack.cpp | 410 +++++++++++++ Minecraft.Client/Common/DLC/DLCPack.h | 93 +++ Minecraft.Client/Common/DLC/DLCSkinFile.cpp | 212 +++++++ Minecraft.Client/Common/DLC/DLCSkinFile.h | 29 + Minecraft.Client/Common/DLC/DLCTextureFile.cpp | 59 ++ Minecraft.Client/Common/DLC/DLCTextureFile.h | 24 + Minecraft.Client/Common/DLC/DLCUIDataFile.cpp | 32 + Minecraft.Client/Common/DLC/DLCUIDataFile.h | 20 + 25 files changed, 2248 insertions(+) create mode 100644 Minecraft.Client/Common/DLC/DLCAudioFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCAudioFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCCapeFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCCapeFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCColourTableFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCColourTableFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCGameRules.h create mode 100644 Minecraft.Client/Common/DLC/DLCGameRulesFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCGameRulesFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCGameRulesHeader.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCGameRulesHeader.h create mode 100644 Minecraft.Client/Common/DLC/DLCLocalisationFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCLocalisationFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCManager.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCManager.h create mode 100644 Minecraft.Client/Common/DLC/DLCPack.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCPack.h create mode 100644 Minecraft.Client/Common/DLC/DLCSkinFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCSkinFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCTextureFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCTextureFile.h create mode 100644 Minecraft.Client/Common/DLC/DLCUIDataFile.cpp create mode 100644 Minecraft.Client/Common/DLC/DLCUIDataFile.h (limited to 'Minecraft.Client/Common/DLC') 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 ¶mName) +{ + 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 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;iwchData); + 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;idwWchCount*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;idwType; + // Params + unsigned int uiParameterCount=*(unsigned int *)pbTemp; + pbTemp+=sizeof(int); + pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; + for(unsigned int j=0;jdwType )); + + 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 m_parameters; + vector 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 ¶mName); +}; 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 + +#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(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 +#include "DLCManager.h" +#include "DLCPack.h" +#include "DLCFile.h" +#include "..\..\..\Minecraft.World\StringHelpers.h" +#include "..\..\Minecraft.h" +#include "..\..\TexturePackRepository.h" + +WCHAR *DLCManager::wchTypeNamesA[]= +{ + L"DISPLAYNAME", + L"THEMENAME", + L"FREE", + L"CREDIT", + L"CAPEPATH", + L"BOX", + L"ANIM", + L"PACKID", + L"NETHERPARTICLECOLOUR", + L"ENCHANTTEXTCOLOUR", + L"ENCHANTTEXTFOCUSCOLOUR", + L"DATAPATH", + L"PACKVERSION", +}; + +DLCManager::DLCManager() +{ + //m_bNeedsUpdated = true; + m_bNeedsCorruptCheck = true; +} + +DLCManager::~DLCManager() +{ + for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) + { + DLCPack *pack = *it; + delete pack; + } +} + +DLCManager::EDLCParameterType DLCManager::getParameterType(const wstring ¶mName) +{ + EDLCParameterType type = e_DLCParamType_Invalid; + + for(DWORD i = 0; i < e_DLCParamType_Max; ++i) + { + if(paramName.compare(wchTypeNamesA[i]) == 0) + { + type = (EDLCParameterType)i; + break; + } + } + + return type; +} + +DWORD DLCManager::getPackCount(EDLCType type /*= e_DLCType_All*/) +{ + DWORD packCount = 0; + if( type != e_DLCType_All ) + { + for(AUTO_VAR(it, m_packs.begin()); it != m_packs.end(); ++it) + { + DLCPack *pack = *it; + if( pack->getDLCItemsCount(type) > 0 ) + { + ++packCount; + } + } + } + else + { + packCount = (DWORD)m_packs.size(); + } + return packCount; +} + +void DLCManager::addPack(DLCPack *pack) +{ + m_packs.push_back(pack); +} + +void DLCManager::removePack(DLCPack *pack) +{ + if(pack != NULL) + { + AUTO_VAR(it, find(m_packs.begin(),m_packs.end(),pack)); + if(it != m_packs.end() ) m_packs.erase(it); + delete pack; + } +} + +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 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;iwchData); + 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;idwWchCount*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;idwType; + + 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;jdwType )); + + 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 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;iwchData); + 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;idwWchCount*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;idwType; + + // Params + uiParameterCount=*(unsigned int *)pbTemp; + pbTemp+=sizeof(int); + pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; + for(unsigned int j=0;jdwType )); + + 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 +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 m_packs; + //bool m_bNeedsUpdated; + bool m_bNeedsCorruptCheck; + DWORD m_dwUnnamedCorruptDLCCount; +public: + DLCManager(); + ~DLCManager(); + + static EDLCParameterType getParameterType(const wstring ¶mName); + + 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 ¶m) +{ + 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(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 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 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< m_files[DLCManager::e_DLCType_Max]; + vector m_childPacks; + DLCPack *m_parentPack; + + unordered_map 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 ¶m); + + 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 *DLCSkinFile::getAdditionalModelParts() +// { +// return &m_AdditionalModelParts; +// } + +int DLCSkinFile::getAdditionalBoxesCount() +{ + return (int)m_AdditionalBoxes.size(); +} +vector *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 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 *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); +}; -- cgit v1.2.3