From 66343a5ba1f13ee614cae7ee5cb3798c742e802a Mon Sep 17 00:00:00 2001 From: Soggy_Pancake <54160598+Soggy-Pancake@users.noreply.github.com> Date: Sat, 21 Mar 2026 22:21:17 -0700 Subject: [PATCH] Implement folderTexturePack --- Minecraft.Client/FolderTexturePack.cpp | 153 ++++++++++++++++++++++--- Minecraft.Client/FolderTexturePack.h | 13 ++- 2 files changed, 148 insertions(+), 18 deletions(-) diff --git a/Minecraft.Client/FolderTexturePack.cpp b/Minecraft.Client/FolderTexturePack.cpp index 05feca66..d11f47ce 100644 --- a/Minecraft.Client/FolderTexturePack.cpp +++ b/Minecraft.Client/FolderTexturePack.cpp @@ -1,35 +1,119 @@ #include "stdafx.h" #include "FolderTexturePack.h" +#include "TexturePackRepository.h" +#include "..\Minecraft.World\StringHelpers.h" FolderTexturePack::FolderTexturePack(DWORD id, const wstring &name, File *folder, TexturePack *fallback) : AbstractTexturePack(id, folder, name, fallback) { // 4J Stu - These calls need to be in the most derived version of the class + cacheFiles(*folder, folder->getPath().length() + 1); + loadColourTable(); loadIcon(); loadName(); loadDescription(); + checkTexSize(); bUILoaded = false; } -InputStream *FolderTexturePack::getResourceImplementation(const wstring &name) //throws IOException +DLCPack* FolderTexturePack::getDLCPack() { -#if 0 - final File file = new File(this.file, name.substring(1)); - if (!file.exists()) { - throw new FileNotFoundException(name); + return NULL; +} + +void FolderTexturePack::loadName() { + texname = file->getName(); +} + +void FolderTexturePack::loadIcon() +{ + if (hasFile(L"pack.png") && _iconData.empty()) + { + app.DebugPrintf("Found pack.png in folder, loading as icon\n"); + File iconFile(file->getPath() + L"\\pack.png"); + FileInputStream is(iconFile); + + _iconData.resize(iconFile.length()); + byteArray arr(iconFile.length()); + is.read(arr, 0, _iconData.size()); + memcpy(_iconData.data(), arr.data, _iconData.size()); + delete arr.data; + + if (!_iconData.empty()) { + iconImage = new BufferedImage(_iconData.data(), _iconData.size()); + m_iconData = _iconData.data(); + m_iconSize = _iconData.size(); + } + else + app.DebugPrintf("Failed to load pack.png from folder\n"); + } +} + +void FolderTexturePack::loadDescription() +{ + desc1 = L""; + desc2 = L""; +} + +bool FolderTexturePack::hasData() +{ + return _cachedFiles.find(L"pack.mcmeta") != _cachedFiles.end(); +} + +bool FolderTexturePack::isLoadingData() +{ + return false; +} + +void FolderTexturePack::cacheFiles(File &dir, int folderLen) +{ + int i = 0; + for (auto file : *dir.listFiles()) { + if (i++ < 2) continue; // skip `.` and `..` + if (file->isDirectory()) { + cacheFiles(*file, folderLen); + } else { + _cachedFiles[file->getPath().substr(folderLen)] = file->getPath().substr(folderLen); + _cachedFiles[file->getName()] = file->getPath().substr(folderLen); + } + } +} + +wstring FolderTexturePack::getAnimationString(const wstring& textureName, const wstring& path, bool allowFallback) { + // copy paste of base class method, except I return null and check for existence in getResource + + std::wstring result = L""; + InputStream* fileStream = getResource(L"\\" + path + textureName + L".txt", true); + + if (fileStream) { + InputStreamReader isr(fileStream); + BufferedReader br(&isr); + + wstring line = br.readLine(); + while (!line.empty()) + { + line = trimString(line); + if (line.length() > 0) + { + result.append(L","); + result.append(line); + } + line = br.readLine(); + } + delete fileStream; } - return new BufferedInputStream(new FileInputStream(file)); -#endif + return result; +} - wstring wDrive = L""; +InputStream *FolderTexturePack::getResourceImplementation(const wstring &name) //throws IOException +{ // Make the content package point to to the UPDATE: drive is needed -#ifdef _XBOX - wDrive=L"GAME:\\DummyTexturePack\\res"; -#else - wDrive = L"Common\\DummyTexturePack\\res"; -#endif - InputStream *resource = InputStream::getResourceAsStream(wDrive + name); + std::wstring wDrive = this->file->getPath(); + if (!hasFile(name)) + return nullptr; + + InputStream *resource = InputStream::getResourceAsStream(name); //InputStream *stream = DefaultTexturePack::class->getResourceAsStream(name); //if (stream == nullptr) //{ @@ -40,11 +124,46 @@ InputStream *FolderTexturePack::getResourceImplementation(const wstring &name) / return resource; } +BufferedImage* FolderTexturePack::getImageResource(const wstring& file, bool filenameHasExtension, bool bTitleUpdateTexture, const wstring& drive) { + app.DebugPrintf("FolderPack: image - %ls\n", file.c_str()); + + if (file == L"terrain.png" && terrainAtlas.get() != nullptr) + return terrainAtlas.release(); + + if (file == L"items.png" && itemAtlas.get() != nullptr) + return itemAtlas.release(); + + std::wstring f = file; + auto it = AbstractTexturePack::INDEXED_TO_JAVA_MAP.find(L"res/" + file); + if (it != INDEXED_TO_JAVA_MAP.end()) { + f = L"assets/minecraft/textures/" + it->second; + } + + f = replaceAll(f, L"/", L"\\"); + if (hasFile(f)) { + f = _cachedFiles[f]; + + File img(this->file->getPath() + L"\\" + f); + FileInputStream is(img); + + byteArray arr(img.length()); + is.read(arr, 0, img.length()); + return new BufferedImage(arr.data, arr.length); + } + + app.DebugPrintf("FolderPack: failed to find %ls fetching from default\n", f.c_str()); + + TexturePackRepository* repo = Minecraft::GetInstance()->skins; + return repo->getDefault()->getImageResource(file, filenameHasExtension, bTitleUpdateTexture); +} + bool FolderTexturePack::hasFile(const wstring &name) { - File file = File( getPath() + name); - return file.exists() && file.isFile(); - //return true; + std::wstring f = name; + if (f.find(L"/") != f.npos) + for (int i = 0; i < f.length(); i++) + f[i] == L'/' ? f[i] = L'\\' : 0; // putting zero there just works ig + return _cachedFiles.find(f) != _cachedFiles.end(); } bool FolderTexturePack::isTerrainUpdateCompatible() diff --git a/Minecraft.Client/FolderTexturePack.h b/Minecraft.Client/FolderTexturePack.h index 4327698d..8b38eca0 100644 --- a/Minecraft.Client/FolderTexturePack.h +++ b/Minecraft.Client/FolderTexturePack.h @@ -6,19 +6,30 @@ class FolderTexturePack : public AbstractTexturePack { private: bool bUILoaded; + unordered_map _cachedFiles; + vector _iconData; + void cacheFiles(File& dir, int folderLen); public: FolderTexturePack(DWORD id, const wstring &name, File *folder, TexturePack *fallback); + DLCPack* getDLCPack(); + void loadIcon(); + void loadDescription(); + bool hasData(); + bool isLoadingData(); + wstring getAnimationString(const wstring& textureName, const wstring& path, bool allowFallback); protected: //@Override InputStream *getResourceImplementation(const wstring &name); //throws IOException + void loadName(); public: //@Override bool hasFile(const wstring &name); bool isTerrainUpdateCompatible(); - + BufferedImage* getImageResource(const wstring& File, bool filenameHasExtension = false, bool bTitleUpdateTexture = false, const wstring& drive = L""); + // 4J Added virtual wstring getPath(bool bTitleUpdateTexture = false, const char *pchBDPatchFilename=nullptr); virtual void loadUI();