diff options
| author | Sestain <35299377+sestain@users.noreply.github.com> | 2026-03-27 21:59:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-27 15:59:35 -0400 |
| commit | 3c1166c45e3be1dc44f0ea83accb0408a24b2751 (patch) | |
| tree | 5f40c11210b43c95dae4d6726dd0cc44f555345e /Minecraft.Client | |
| parent | 0d4874dea5ce5cfd31a67f6b1d5e38c271a4308b (diff) | |
Added support for Big-Endian DLCs (#1291)
* Added support for Big-Endian DLCs
* Remove unused variable
* Remove the things made for other PR
Diffstat (limited to 'Minecraft.Client')
| -rw-r--r-- | Minecraft.Client/Common/DLC/DLCManager.cpp | 43 | ||||
| -rw-r--r-- | Minecraft.Client/Common/DLC/DLCManager.h | 24 |
2 files changed, 58 insertions, 9 deletions
diff --git a/Minecraft.Client/Common/DLC/DLCManager.cpp b/Minecraft.Client/Common/DLC/DLCManager.cpp index 931b0e1d..88a7756e 100644 --- a/Minecraft.Client/Common/DLC/DLCManager.cpp +++ b/Minecraft.Client/Common/DLC/DLCManager.cpp @@ -387,22 +387,34 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD // // 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; + unsigned int uiVersion=readUInt32(pbData, false); uiCurrentByte+=sizeof(int); - if(uiVersion < CURRENT_DLC_VERSION_NUM) - { - if(pbData!=nullptr) delete [] pbData; - app.DebugPrintf("DLC version of %d is too old to be read\n", uiVersion); + bool bSwapEndian = false; + unsigned int uiVersionSwapped = SwapInt32(uiVersion); + if (uiVersion >= 0 && uiVersion <= CURRENT_DLC_VERSION_NUM) { + bSwapEndian = false; + } else if (uiVersionSwapped >= 0 && uiVersionSwapped <= CURRENT_DLC_VERSION_NUM) { + bSwapEndian = true; + } else { + if(pbData!=nullptr) delete [] pbData; + app.DebugPrintf("Unknown DLC version of %d\n", uiVersion); return false; } pack->SetDataPointer(pbData); - unsigned int uiParameterCount=*(unsigned int *)&pbData[uiCurrentByte]; + unsigned int uiParameterCount=readUInt32(&pbData[uiCurrentByte], bSwapEndian); 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++) { + pParams->dwType = bSwapEndian ? SwapInt32(pParams->dwType) : pParams->dwType; + pParams->dwWchCount = bSwapEndian ? SwapInt32(pParams->dwWchCount) : pParams->dwWchCount; + char16_t* wchData = reinterpret_cast<char16_t*>(pParams->wchData); + if (bSwapEndian) { + SwapUTF16Bytes(wchData, pParams->dwWchCount); + } + // Map DLC strings to application strings, then store the DLC index mapping to application index wstring parameterName(static_cast<WCHAR *>(pParams->wchData)); EDLCParameterType type = getParameterType(parameterName); @@ -414,14 +426,14 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; } //ulCurrentByte+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM); - - unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte]; + unsigned int uiFileCount=readUInt32(&pbData[uiCurrentByte], bSwapEndian); 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++) { + pFile->dwWchCount = bSwapEndian ? SwapInt32(pFile->dwWchCount) : pFile->dwWchCount; dwTemp+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR); pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[dwTemp]; } @@ -430,6 +442,13 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD for(unsigned int i=0;i<uiFileCount;i++) { + pFile->dwType = bSwapEndian ? SwapInt32(pFile->dwType) : pFile->dwType; + pFile->uiFileSize = bSwapEndian ? SwapInt32(pFile->uiFileSize) : pFile->uiFileSize; + char16_t* wchFile = reinterpret_cast<char16_t*>(pFile->wchFile); + if (bSwapEndian) { + SwapUTF16Bytes(wchFile, pFile->dwWchCount); + } + EDLCType type = static_cast<EDLCType>(pFile->dwType); DLCFile *dlcFile = nullptr; @@ -445,12 +464,18 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD } // Params - uiParameterCount=*(unsigned int *)pbTemp; + uiParameterCount=readUInt32(pbTemp, bSwapEndian); pbTemp+=sizeof(int); pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; for(unsigned int j=0;j<uiParameterCount;j++) { //DLCManager::EDLCParameterType paramType = DLCManager::e_DLCParamType_Invalid; + pParams->dwType = bSwapEndian ? SwapInt32(pParams->dwType) : pParams->dwType; + pParams->dwWchCount = bSwapEndian ? SwapInt32(pParams->dwWchCount) : pParams->dwWchCount; + char16_t* wchData = reinterpret_cast<char16_t*>(pParams->wchData); + if (bSwapEndian) { + SwapUTF16Bytes(wchData, pParams->dwWchCount); + } auto it = parameterMapping.find(pParams->dwType); diff --git a/Minecraft.Client/Common/DLC/DLCManager.h b/Minecraft.Client/Common/DLC/DLCManager.h index d4dd2508..7191ab0b 100644 --- a/Minecraft.Client/Common/DLC/DLCManager.h +++ b/Minecraft.Client/Common/DLC/DLCManager.h @@ -94,6 +94,30 @@ public: bool readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DLCPack *pack, bool fromArchive = false); DWORD retrievePackIDFromDLCDataFile(const string &path, DLCPack *pack); + static unsigned short SwapInt16(unsigned short value) { + return (value >> 8) | (value << 8); + } + + static unsigned int SwapInt32(unsigned int value) { + return ((value & 0xFF) << 24) | + ((value & 0xFF00) << 8) | + ((value & 0xFF0000) >> 8) | + ((value & 0xFF000000) >> 24); + } + + static void SwapUTF16Bytes(char16_t* buffer, size_t count) { + for (size_t i = 0; i < count; ++i) { + char16_t& c = buffer[i]; + c = (c >> 8) | (c << 8); + } + } + + static unsigned int readUInt32(unsigned char* ptr, bool endian) { + unsigned int val = *(unsigned int*)ptr; + if (endian) val = SwapInt32(val); + return val; + } + private: bool processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwLength, DLCPack *pack); |
