dlc fixes

This commit is contained in:
Fireblade
2026-05-11 21:16:28 -04:00
parent 0c944cb713
commit d32e62027c
6 changed files with 339 additions and 73 deletions
+157 -1
View File
@@ -4,9 +4,56 @@
#include "DLCPack.h"
#include "DLCFile.h"
#include "../../../Minecraft.World/StringHelpers.h"
#include "../../../Minecraft.World/File.h"
#include "../../Minecraft.h"
#include "../../TexturePackRepository.h"
#include "Common/UI/UI.h"
#include "lce_filesystem/FolderFile.h"
static bool hasPckFolderFallback(const wstring &path, wstring &folderPath)
{
wstring lowerPath = toLower(path);
const wstring pckSuffix = L".pck";
if(lowerPath.size() <= pckSuffix.size())
{
return false;
}
if(lowerPath.compare(lowerPath.size() - pckSuffix.size(), pckSuffix.size(), pckSuffix) != 0)
{
return false;
}
if(!(lowerPath.find(L"x16Data.pck") != wstring::npos
|| lowerPath.find(L"x32Data.pck") != wstring::npos))
{
return false;
}
folderPath = path.substr(0, path.size() - pckSuffix.size());
return true;
}
static DLCManager::EDLCType getFolderFileType(const wstring &path)
{
wstring lowerPath = toLower(path);
if(lowerPath == L"colours.col" || lowerPath.rfind(L"/colours.col") != wstring::npos)
{
return DLCManager::e_DLCType_ColourTable;
}
if(lowerPath.rfind(L"/languages.loc") != wstring::npos || lowerPath.rfind(L".loc") != wstring::npos)
{
return DLCManager::e_DLCType_LocalisationData;
}
if(lowerPath.rfind(L".xzp") != wstring::npos)
{
return DLCManager::e_DLCType_UIData;
}
if(lowerPath.rfind(L".grf") != wstring::npos)
{
return DLCManager::e_DLCType_GameRulesHeader;
}
return DLCManager::e_DLCType_Texture;
}
const WCHAR *DLCManager::wchTypeNamesA[]=
{
@@ -328,13 +375,47 @@ bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DL
}
else if (fromArchive) return false;
wstring finalPathW = wPath;
#ifdef _WINDOWS64
string finalPath = StorageManager.GetMountedPath(path.c_str());
if(finalPath.size() == 0) finalPath = path;
HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
finalPathW = convStringToWstring(finalPath);
#elif defined(_DURANGO)
wstring finalPath = StorageManager.GetMountedPath(wPath.c_str());
if(finalPath.size() == 0) finalPath = wPath;
finalPathW = finalPath;
#endif
if(!fromArchive)
{
wstring folderPath;
if(hasPckFolderFallback(finalPathW, folderPath))
{
wstring resolvedFolderPath = folderPath;
#ifdef _WINDOWS64
const char *folderPathA = wstringtofilename(folderPath);
string mountedFolderPath = StorageManager.GetMountedPath(folderPathA);
if(mountedFolderPath.size() > 0)
{
resolvedFolderPath = convStringToWstring(mountedFolderPath);
}
#elif defined(_DURANGO)
wstring mountedFolderPath = StorageManager.GetMountedPath(folderPath.c_str());
if(mountedFolderPath.size() > 0)
{
resolvedFolderPath = mountedFolderPath;
}
#endif
if(readDLCDataFolder(dwFilesProcessed, resolvedFolderPath, pack))
{
return true;
}
}
}
#ifdef _WINDOWS64
HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
#elif defined(_DURANGO)
HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
#else
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
@@ -371,6 +452,81 @@ bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DL
return processDLCDataFile(dwFilesProcessed, pbData, bytesRead, pack);
}
bool DLCManager::readDLCDataFolder(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack)
{
File folder(path);
if(!folder.exists() || !folder.isDirectory())
{
return false;
}
FolderFile folderFile(path);
vector<wstring> *fileList = folderFile.getFileList();
if(fileList == nullptr || fileList->empty())
{
delete fileList;
return false;
}
struct FolderEntry
{
wstring rawPath;
wstring normalizedPath;
int size;
};
vector<FolderEntry> entries;
entries.reserve(fileList->size());
unsigned int totalBytes = 0;
for(const auto &rawPath : *fileList)
{
wstring normalized = replaceAll(rawPath, L"\\", L"/");
if(normalized.empty() || normalized == L"0")
{
continue;
}
int size = folderFile.getFileSize(rawPath);
if(size <= 0)
{
continue;
}
entries.push_back({ rawPath, normalized, size });
totalBytes += static_cast<unsigned int>(size);
}
delete fileList;
if(entries.empty() || totalBytes == 0)
{
return false;
}
PBYTE dataBuffer = new BYTE[totalBytes];
pack->SetDataPointer(dataBuffer);
unsigned int offset = 0;
for(const auto &entry : entries)
{
byteArray data = folderFile.getFile(entry.rawPath);
if(data.data == nullptr || data.length == 0)
{
continue;
}
DLCManager::EDLCType type = getFolderFileType(entry.normalizedPath);
DLCFile *dlcFile = pack->addFile(type, entry.normalizedPath);
if(dlcFile != nullptr)
{
memcpy(dataBuffer + offset, data.data, data.length);
dlcFile->addData(dataBuffer + offset, data.length);
offset += data.length;
++dwFilesProcessed;
}
delete [] data.data;
}
return dwFilesProcessed > 0;
}
bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwLength, DLCPack *pack)
{
unordered_map<int, EDLCParameterType> parameterMapping;
+1
View File
@@ -93,6 +93,7 @@ public:
bool readDLCDataFile(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack, bool fromArchive = false);
bool readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DLCPack *pack, bool fromArchive = false);
bool readDLCDataFolder(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack);
DWORD retrievePackIDFromDLCDataFile(const string &path, DLCPack *pack);
static unsigned short SwapInt16(unsigned short value) {
@@ -988,6 +988,13 @@ int CGameNetworkManager::RunNetworkGameThreadProc( void* lpParameter )
int CGameNetworkManager::ServerThreadProc( void* lpParameter )
{
int64_t seed = 0;
Compression::UseDefaultThreadStorage();
if (Compression::getCompression() == nullptr)
{
Compression::CreateNewThreadStorage();
}
if (lpParameter != nullptr)
{
NetworkGameInitData *param = static_cast<NetworkGameInitData *>(lpParameter);
@@ -1027,6 +1034,7 @@ int CGameNetworkManager::ServerThreadProc( void* lpParameter )
AABB::ReleaseThreadStorage();
Vec3::ReleaseThreadStorage();
IntCache::ReleaseThreadStorage();
Compression::ReleaseThreadStorage();
Level::destroyLightingCache();
if(lpParameter != nullptr) delete lpParameter;