From 8b202ba5f132bc2aee4c39d52467f76af6fd88fb Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Thu, 9 Apr 2026 21:11:41 +1000 Subject: [PATCH] refactor: extract ISkinAssetData so minecraft/ stops including DLCSkinFile.h --- targets/app/common/AppGameServices.cpp | 3 +- targets/app/common/AppGameServices.h | 3 +- targets/app/common/DLC/DLCSkinFile.h | 29 ++++++++++++------- targets/minecraft/IGameServices.h | 4 +-- .../client/multiplayer/ClientConnection.cpp | 12 ++++---- .../minecraft/client/skins/ISkinAssetData.h | 26 +++++++++++++++++ .../packet/TextureAndGeometryPacket.cpp | 11 +++---- .../network/packet/TextureAndGeometryPacket.h | 4 +-- .../server/network/PlayerConnection.cpp | 20 ++++++------- .../minecraft/world/entity/player/Player.cpp | 28 +++++++++--------- 10 files changed, 89 insertions(+), 51 deletions(-) create mode 100644 targets/minecraft/client/skins/ISkinAssetData.h diff --git a/targets/app/common/AppGameServices.cpp b/targets/app/common/AppGameServices.cpp index 74ce03d03..560fab883 100644 --- a/targets/app/common/AppGameServices.cpp +++ b/targets/app/common/AppGameServices.cpp @@ -1,5 +1,6 @@ #include "app/common/AppGameServices.h" +#include "app/common/DLC/DLCSkinFile.h" #include "app/common/Game.h" #include "java/Class.h" // eINSTANCEOF #include "platform/game/game.h" @@ -386,7 +387,7 @@ void AppGameServices::debugPrintf(const char* msg) { // -- DLC -- -DLCSkinFile* AppGameServices::getDLCSkinFile(const std::string& name) { +ISkinAssetData* AppGameServices::getSkinAssetData(const std::string& name) { return game_.m_dlcManager.getSkinFile(name); } bool AppGameServices::dlcNeedsCorruptCheck() { diff --git a/targets/app/common/AppGameServices.h b/targets/app/common/AppGameServices.h index 6e2e4d9bf..0cfb98a17 100644 --- a/targets/app/common/AppGameServices.h +++ b/targets/app/common/AppGameServices.h @@ -4,6 +4,7 @@ class Game; class IMenuService; +class ISkinAssetData; class AppGameServices : public IGameServices { public: @@ -150,7 +151,7 @@ public: void debugPrintf(const char* msg) override; // -- DLC -- - DLCSkinFile* getDLCSkinFile(const std::string& name) override; + ISkinAssetData* getSkinAssetData(const std::string& name) override; bool dlcNeedsCorruptCheck() override; unsigned int dlcCheckForCorrupt(bool showMessage) override; bool dlcReadDataFile(unsigned int& filesProcessed, const std::string& path, diff --git a/targets/app/common/DLC/DLCSkinFile.h b/targets/app/common/DLC/DLCSkinFile.h index fbcc7c2ef..81b3fdfde 100644 --- a/targets/app/common/DLC/DLCSkinFile.h +++ b/targets/app/common/DLC/DLCSkinFile.h @@ -8,8 +8,9 @@ #include "app/common/DLC/DLCManager.h" #include "minecraft/client/model/HumanoidModel.h" #include "minecraft/client/model/SkinBox.h" +#include "minecraft/client/skins/ISkinAssetData.h" -class DLCSkinFile : public DLCFile { +class DLCSkinFile : public DLCFile, public ISkinAssetData { private: std::string m_displayName; std::string m_themeName; @@ -21,15 +22,23 @@ private: public: DLCSkinFile(const std::string& path); - virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes); - virtual void addParameter(DLCManager::EDLCParameterType type, - const std::string& value); + void addData(std::uint8_t* pbData, std::uint32_t dataBytes) override; + void addParameter(DLCManager::EDLCParameterType type, + const std::string& value) override; + + std::string getParameterAsString( + DLCManager::EDLCParameterType type) override; + bool getParameterAsBool(DLCManager::EDLCParameterType type) override; + + // ISkinAssetData + [[nodiscard]] std::uint32_t getSkinID() override { + return DLCFile::getSkinID(); + } + [[nodiscard]] unsigned int getAnimOverrideBitmask() override { + return m_uiAnimOverrideBitmask; + } + [[nodiscard]] int getAdditionalBoxesCount() override; + [[nodiscard]] std::vector* getAdditionalBoxes() override; - virtual std::string getParameterAsString( - DLCManager::EDLCParameterType type); - virtual bool getParameterAsBool(DLCManager::EDLCParameterType type); - std::vector* getAdditionalBoxes(); - int getAdditionalBoxesCount(); - unsigned int getAnimOverrideBitmask() { return m_uiAnimOverrideBitmask; } bool isFree() { return m_bIsFree; } }; diff --git a/targets/minecraft/IGameServices.h b/targets/minecraft/IGameServices.h index a4453d2b5..54141a47b 100644 --- a/targets/minecraft/IGameServices.h +++ b/targets/minecraft/IGameServices.h @@ -11,7 +11,7 @@ class LevelChunk; class ModelPart; // Forward declarations -class DLCSkinFile; +class ISkinAssetData; class DLCPack; #include "minecraft/GameEnums.h" @@ -199,7 +199,7 @@ public: // -- DLC -- - [[nodiscard]] virtual DLCSkinFile* getDLCSkinFile( + [[nodiscard]] virtual ISkinAssetData* getSkinAssetData( const std::string& name) = 0; [[nodiscard]] virtual bool dlcNeedsCorruptCheck() = 0; virtual unsigned int dlcCheckForCorrupt(bool showMessage = true) = 0; diff --git a/targets/minecraft/client/multiplayer/ClientConnection.cpp b/targets/minecraft/client/multiplayer/ClientConnection.cpp index dee511bc8..b96a3a618 100644 --- a/targets/minecraft/client/multiplayer/ClientConnection.cpp +++ b/targets/minecraft/client/multiplayer/ClientConnection.cpp @@ -16,7 +16,7 @@ #include "app/common/ConsoleGameMode.h" #include "app/common/DLC/DLCManager.h" #include "app/common/DLC/DLCPack.h" -#include "app/common/DLC/DLCSkinFile.h" +#include "minecraft/client/skins/ISkinAssetData.h" #include "app/common/Network/Socket.h" #include "app/common/Tutorial/FullTutorialMode.h" #include "app/common/Tutorial/Tutorial.h" @@ -2313,16 +2313,16 @@ void ClientConnection::handleTextureAndGeometry( unsigned int dwBytes = 0; gameServices().getMemFileDetails(packet->textureName, &pbData, &dwBytes); - DLCSkinFile* pDLCSkinFile = - gameServices().getDLCSkinFile(packet->textureName); + ISkinAssetData* pSkinAsset = + gameServices().getSkinAssetData(packet->textureName); if (dwBytes != 0) { - if (pDLCSkinFile) { - if (pDLCSkinFile->getAdditionalBoxesCount() != 0) { + if (pSkinAsset) { + if (pSkinAsset->getAdditionalBoxesCount() != 0) { send(std::shared_ptr( new TextureAndGeometryPacket(packet->textureName, pbData, dwBytes, - pDLCSkinFile))); + pSkinAsset))); } else { send(std::shared_ptr( new TextureAndGeometryPacket(packet->textureName, diff --git a/targets/minecraft/client/skins/ISkinAssetData.h b/targets/minecraft/client/skins/ISkinAssetData.h new file mode 100644 index 000000000..2b5df49c7 --- /dev/null +++ b/targets/minecraft/client/skins/ISkinAssetData.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +#include "minecraft/client/model/SkinBox.h" + +// Domain-shaped view of a custom skin asset. +// +// minecraft/ consumers (Player, the client/server connection layers, +// the texture packet) need a handful of fields off a custom skin +// asset: the skin id, the additional body parts geometry, and an +// animation override mask. Historically those fields were read off +// app/common/DLC/DLCSkinFile, which dragged the entire DLC subsystem +// up into minecraft/ headers and broke the layering invariant. +// +// This interface is the domain abstraction. The DLC implementation in +// app/ inherits from it; minecraft/ only ever sees ISkinAssetData. +class ISkinAssetData { +public: + virtual ~ISkinAssetData() = default; + + [[nodiscard]] virtual std::uint32_t getSkinID() = 0; + [[nodiscard]] virtual unsigned int getAnimOverrideBitmask() = 0; + [[nodiscard]] virtual int getAdditionalBoxesCount() = 0; + [[nodiscard]] virtual std::vector* getAdditionalBoxes() = 0; +}; diff --git a/targets/minecraft/network/packet/TextureAndGeometryPacket.cpp b/targets/minecraft/network/packet/TextureAndGeometryPacket.cpp index 9f845a138..2f03ec0f7 100644 --- a/targets/minecraft/network/packet/TextureAndGeometryPacket.cpp +++ b/targets/minecraft/network/packet/TextureAndGeometryPacket.cpp @@ -4,10 +4,10 @@ #include #include "PacketListener.h" -#include "app/common/DLC/DLCSkinFile.h" #include "java/InputOutputStream/DataInputStream.h" #include "java/InputOutputStream/DataOutputStream.h" #include "minecraft/Minecraft_Macros.h" +#include "minecraft/client/skins/ISkinAssetData.h" TextureAndGeometryPacket::TextureAndGeometryPacket() { this->textureName = ""; @@ -51,7 +51,7 @@ TextureAndGeometryPacket::TextureAndGeometryPacket( TextureAndGeometryPacket::TextureAndGeometryPacket( const std::string& textureName, std::uint8_t* pbData, - std::uint32_t dataBytes, DLCSkinFile* pDLCSkinFile) { + std::uint32_t dataBytes, ISkinAssetData* pSkinAssetData) { this->textureName = textureName; std::string skinValue = textureName.substr(7, textureName.size()); @@ -63,11 +63,12 @@ TextureAndGeometryPacket::TextureAndGeometryPacket( this->pbData = pbData; this->dwTextureBytes = dataBytes; - this->uiAnimOverrideBitmask = pDLCSkinFile->getAnimOverrideBitmask(); - this->dwBoxC = pDLCSkinFile->getAdditionalBoxesCount(); + this->uiAnimOverrideBitmask = pSkinAssetData->getAnimOverrideBitmask(); + this->dwBoxC = pSkinAssetData->getAdditionalBoxesCount(); if (this->dwBoxC != 0) { this->BoxDataA = new SKIN_BOX[this->dwBoxC]; - std::vector* pSkinBoxes = pDLCSkinFile->getAdditionalBoxes(); + std::vector* pSkinBoxes = + pSkinAssetData->getAdditionalBoxes(); int iCount = 0; for (auto it = pSkinBoxes->begin(); it != pSkinBoxes->end(); ++it) { diff --git a/targets/minecraft/network/packet/TextureAndGeometryPacket.h b/targets/minecraft/network/packet/TextureAndGeometryPacket.h index 8b7548c9f..d8e49fd16 100644 --- a/targets/minecraft/network/packet/TextureAndGeometryPacket.h +++ b/targets/minecraft/network/packet/TextureAndGeometryPacket.h @@ -10,7 +10,7 @@ #include "minecraft/client/model/geom/Model.h" #include "minecraft/network/packet/Packet.h" -class DLCSkinFile; +class ISkinAssetData; class TextureAndGeometryPacket : public Packet, @@ -30,7 +30,7 @@ public: std::uint8_t* pbData, std::uint32_t dataBytes); TextureAndGeometryPacket(const std::string& textureName, std::uint8_t* pbData, std::uint32_t dataBytes, - DLCSkinFile* pDLCSkinFile); + ISkinAssetData* pSkinAssetData); TextureAndGeometryPacket(const std::string& textureName, std::uint8_t* pbData, std::uint32_t dataBytes, std::vector* pvSkinBoxes, diff --git a/targets/minecraft/server/network/PlayerConnection.cpp b/targets/minecraft/server/network/PlayerConnection.cpp index 4c80c8c36..c91c881bc 100644 --- a/targets/minecraft/server/network/PlayerConnection.cpp +++ b/targets/minecraft/server/network/PlayerConnection.cpp @@ -9,7 +9,6 @@ #include #include "ServerConnection.h" -#include "app/common/DLC/DLCSkinFile.h" #include "app/common/Network/Socket.h" #include "java/Class.h" #include "java/InputOutputStream/ByteArrayInputStream.h" @@ -24,6 +23,7 @@ #include "minecraft/IGameServices.h" #include "minecraft/SharedConstants.h" #include "minecraft/client/model/SkinBox.h" +#include "minecraft/client/skins/ISkinAssetData.h" #include "minecraft/commands/CommandDispatcher.h" #include "minecraft/commands/CommandsEnum.h" #include "minecraft/network/Connection.h" @@ -850,16 +850,16 @@ void PlayerConnection::handleTextureAndGeometry( unsigned int dwTextureBytes = 0; gameServices().getMemFileDetails(packet->textureName, &pbData, &dwTextureBytes); - DLCSkinFile* pDLCSkinFile = - gameServices().getDLCSkinFile(packet->textureName); + ISkinAssetData* pSkinAsset = + gameServices().getSkinAssetData(packet->textureName); if (dwTextureBytes != 0) { - if (pDLCSkinFile) { - if (pDLCSkinFile->getAdditionalBoxesCount() != 0) { + if (pSkinAsset) { + if (pSkinAsset->getAdditionalBoxesCount() != 0) { send(std::shared_ptr( new TextureAndGeometryPacket(packet->textureName, pbData, dwTextureBytes, - pDLCSkinFile))); + pSkinAsset))); } else { send(std::shared_ptr( new TextureAndGeometryPacket(packet->textureName, @@ -938,14 +938,14 @@ void PlayerConnection::handleTextureAndGeometryReceived( std::uint8_t* pbData = nullptr; unsigned int dwTextureBytes = 0; gameServices().getMemFileDetails(textureName, &pbData, &dwTextureBytes); - DLCSkinFile* pDLCSkinFile = gameServices().getDLCSkinFile(textureName); + ISkinAssetData* pSkinAsset = + gameServices().getSkinAssetData(textureName); if (dwTextureBytes != 0) { - if (pDLCSkinFile && - (pDLCSkinFile->getAdditionalBoxesCount() != 0)) { + if (pSkinAsset && (pSkinAsset->getAdditionalBoxesCount() != 0)) { send(std::shared_ptr( new TextureAndGeometryPacket( - textureName, pbData, dwTextureBytes, pDLCSkinFile))); + textureName, pbData, dwTextureBytes, pSkinAsset))); } else { // get the data from the app std::uint32_t dwSkinID = diff --git a/targets/minecraft/world/entity/player/Player.cpp b/targets/minecraft/world/entity/player/Player.cpp index ab6107849..d6acd2f98 100644 --- a/targets/minecraft/world/entity/player/Player.cpp +++ b/targets/minecraft/world/entity/player/Player.cpp @@ -22,7 +22,7 @@ #include "Inventory.h" #include "Player.h" #include "app/common/App_structs.h" -#include "app/common/DLC/DLCSkinFile.h" +#include "minecraft/client/skins/ISkinAssetData.h" #include "java/JavaMath.h" #include "java/Random.h" #include "minecraft/Direction.h" @@ -584,23 +584,23 @@ void Player::setCustomSkin(std::uint32_t skinId) { Log::info("Couldn't get model parts for skin %X\n",m_dwSkinId); // do we have it from the DLC pack? - DLCSkinFile *pDLCSkinFile = - gameServices().getDLCSkinFile(this->customTextureUrl); + ISkinAssetData *pSkinAsset = + gameServices().getSkinAssetData(this->customTextureUrl); - if(pDLCSkinFile!=nullptr) + if(pSkinAsset!=nullptr) { const int additionalBoxCount = - pDLCSkinFile->getAdditionalBoxesCount(); if(additionalBoxCount != 0) + pSkinAsset->getAdditionalBoxesCount(); if(additionalBoxCount != 0) { Log::info("Got model parts from DLCskin for skin %X\n",m_dwSkinId); - pvModelParts=gameServices().setAdditionalSkinBoxesFromVec(m_dwSkinId,pDLCSkinFile->getAdditionalBoxes()); + pvModelParts=gameServices().setAdditionalSkinBoxesFromVec(m_dwSkinId,pSkinAsset->getAdditionalBoxes()); this->SetAdditionalModelParts(pvModelParts); } else { this->SetAdditionalModelParts(nullptr); } - gameServices().setAnimOverrideBitmask(pDLCSkinFile->getSkinID(),pDLCSkinFile->getAnimOverrideBitmask()); + gameServices().setAnimOverrideBitmask(pSkinAsset->getSkinID(),pSkinAsset->getAnimOverrideBitmask()); } else { @@ -2704,12 +2704,12 @@ std::vector* Player::GetAdditionalModelParts() { m_dwSkinId); // do we have it from the DLC pack? - DLCSkinFile* pDLCSkinFile = - gameServices().getDLCSkinFile(this->customTextureUrl); + ISkinAssetData* pSkinAsset = + gameServices().getSkinAssetData(this->customTextureUrl); - if (pDLCSkinFile != nullptr) { + if (pSkinAsset != nullptr) { const int additionalBoxCount = - pDLCSkinFile->getAdditionalBoxesCount(); + pSkinAsset->getAdditionalBoxesCount(); if (additionalBoxCount != 0) { Log::info( "m_bCheckedForModelParts Got model parts from DLCskin " @@ -2717,12 +2717,12 @@ std::vector* Player::GetAdditionalModelParts() { m_dwSkinId); m_ppAdditionalModelParts = gameServices().setAdditionalSkinBoxesFromVec( - m_dwSkinId, pDLCSkinFile->getAdditionalBoxes()); + m_dwSkinId, pSkinAsset->getAdditionalBoxes()); } gameServices().setAnimOverrideBitmask( - pDLCSkinFile->getSkinID(), - pDLCSkinFile->getAnimOverrideBitmask()); + pSkinAsset->getSkinID(), + pSkinAsset->getAnimOverrideBitmask()); m_bCheckedForModelParts = true; }