refactor: extract ISkinAssetData so minecraft/ stops including DLCSkinFile.h

This commit is contained in:
MatthewBeshay 2026-04-09 21:11:41 +10:00
parent 80019158da
commit 8b202ba5f1
10 changed files with 89 additions and 51 deletions

View file

@ -1,5 +1,6 @@
#include "app/common/AppGameServices.h" #include "app/common/AppGameServices.h"
#include "app/common/DLC/DLCSkinFile.h"
#include "app/common/Game.h" #include "app/common/Game.h"
#include "java/Class.h" // eINSTANCEOF #include "java/Class.h" // eINSTANCEOF
#include "platform/game/game.h" #include "platform/game/game.h"
@ -386,7 +387,7 @@ void AppGameServices::debugPrintf(const char* msg) {
// -- DLC -- // -- DLC --
DLCSkinFile* AppGameServices::getDLCSkinFile(const std::string& name) { ISkinAssetData* AppGameServices::getSkinAssetData(const std::string& name) {
return game_.m_dlcManager.getSkinFile(name); return game_.m_dlcManager.getSkinFile(name);
} }
bool AppGameServices::dlcNeedsCorruptCheck() { bool AppGameServices::dlcNeedsCorruptCheck() {

View file

@ -4,6 +4,7 @@
class Game; class Game;
class IMenuService; class IMenuService;
class ISkinAssetData;
class AppGameServices : public IGameServices { class AppGameServices : public IGameServices {
public: public:
@ -150,7 +151,7 @@ public:
void debugPrintf(const char* msg) override; void debugPrintf(const char* msg) override;
// -- DLC -- // -- DLC --
DLCSkinFile* getDLCSkinFile(const std::string& name) override; ISkinAssetData* getSkinAssetData(const std::string& name) override;
bool dlcNeedsCorruptCheck() override; bool dlcNeedsCorruptCheck() override;
unsigned int dlcCheckForCorrupt(bool showMessage) override; unsigned int dlcCheckForCorrupt(bool showMessage) override;
bool dlcReadDataFile(unsigned int& filesProcessed, const std::string& path, bool dlcReadDataFile(unsigned int& filesProcessed, const std::string& path,

View file

@ -8,8 +8,9 @@
#include "app/common/DLC/DLCManager.h" #include "app/common/DLC/DLCManager.h"
#include "minecraft/client/model/HumanoidModel.h" #include "minecraft/client/model/HumanoidModel.h"
#include "minecraft/client/model/SkinBox.h" #include "minecraft/client/model/SkinBox.h"
#include "minecraft/client/skins/ISkinAssetData.h"
class DLCSkinFile : public DLCFile { class DLCSkinFile : public DLCFile, public ISkinAssetData {
private: private:
std::string m_displayName; std::string m_displayName;
std::string m_themeName; std::string m_themeName;
@ -21,15 +22,23 @@ private:
public: public:
DLCSkinFile(const std::string& path); DLCSkinFile(const std::string& path);
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes); void addData(std::uint8_t* pbData, std::uint32_t dataBytes) override;
virtual void addParameter(DLCManager::EDLCParameterType type, void addParameter(DLCManager::EDLCParameterType type,
const std::string& value); 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<SKIN_BOX*>* getAdditionalBoxes() override;
virtual std::string getParameterAsString(
DLCManager::EDLCParameterType type);
virtual bool getParameterAsBool(DLCManager::EDLCParameterType type);
std::vector<SKIN_BOX*>* getAdditionalBoxes();
int getAdditionalBoxesCount();
unsigned int getAnimOverrideBitmask() { return m_uiAnimOverrideBitmask; }
bool isFree() { return m_bIsFree; } bool isFree() { return m_bIsFree; }
}; };

View file

@ -11,7 +11,7 @@ class LevelChunk;
class ModelPart; class ModelPart;
// Forward declarations // Forward declarations
class DLCSkinFile; class ISkinAssetData;
class DLCPack; class DLCPack;
#include "minecraft/GameEnums.h" #include "minecraft/GameEnums.h"
@ -199,7 +199,7 @@ public:
// -- DLC -- // -- DLC --
[[nodiscard]] virtual DLCSkinFile* getDLCSkinFile( [[nodiscard]] virtual ISkinAssetData* getSkinAssetData(
const std::string& name) = 0; const std::string& name) = 0;
[[nodiscard]] virtual bool dlcNeedsCorruptCheck() = 0; [[nodiscard]] virtual bool dlcNeedsCorruptCheck() = 0;
virtual unsigned int dlcCheckForCorrupt(bool showMessage = true) = 0; virtual unsigned int dlcCheckForCorrupt(bool showMessage = true) = 0;

View file

@ -16,7 +16,7 @@
#include "app/common/ConsoleGameMode.h" #include "app/common/ConsoleGameMode.h"
#include "app/common/DLC/DLCManager.h" #include "app/common/DLC/DLCManager.h"
#include "app/common/DLC/DLCPack.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/Network/Socket.h"
#include "app/common/Tutorial/FullTutorialMode.h" #include "app/common/Tutorial/FullTutorialMode.h"
#include "app/common/Tutorial/Tutorial.h" #include "app/common/Tutorial/Tutorial.h"
@ -2313,16 +2313,16 @@ void ClientConnection::handleTextureAndGeometry(
unsigned int dwBytes = 0; unsigned int dwBytes = 0;
gameServices().getMemFileDetails(packet->textureName, &pbData, gameServices().getMemFileDetails(packet->textureName, &pbData,
&dwBytes); &dwBytes);
DLCSkinFile* pDLCSkinFile = ISkinAssetData* pSkinAsset =
gameServices().getDLCSkinFile(packet->textureName); gameServices().getSkinAssetData(packet->textureName);
if (dwBytes != 0) { if (dwBytes != 0) {
if (pDLCSkinFile) { if (pSkinAsset) {
if (pDLCSkinFile->getAdditionalBoxesCount() != 0) { if (pSkinAsset->getAdditionalBoxesCount() != 0) {
send(std::shared_ptr<TextureAndGeometryPacket>( send(std::shared_ptr<TextureAndGeometryPacket>(
new TextureAndGeometryPacket(packet->textureName, new TextureAndGeometryPacket(packet->textureName,
pbData, dwBytes, pbData, dwBytes,
pDLCSkinFile))); pSkinAsset)));
} else { } else {
send(std::shared_ptr<TextureAndGeometryPacket>( send(std::shared_ptr<TextureAndGeometryPacket>(
new TextureAndGeometryPacket(packet->textureName, new TextureAndGeometryPacket(packet->textureName,

View file

@ -0,0 +1,26 @@
#pragma once
#include <cstdint>
#include <vector>
#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<SKIN_BOX*>* getAdditionalBoxes() = 0;
};

View file

@ -4,10 +4,10 @@
#include <vector> #include <vector>
#include "PacketListener.h" #include "PacketListener.h"
#include "app/common/DLC/DLCSkinFile.h"
#include "java/InputOutputStream/DataInputStream.h" #include "java/InputOutputStream/DataInputStream.h"
#include "java/InputOutputStream/DataOutputStream.h" #include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/Minecraft_Macros.h" #include "minecraft/Minecraft_Macros.h"
#include "minecraft/client/skins/ISkinAssetData.h"
TextureAndGeometryPacket::TextureAndGeometryPacket() { TextureAndGeometryPacket::TextureAndGeometryPacket() {
this->textureName = ""; this->textureName = "";
@ -51,7 +51,7 @@ TextureAndGeometryPacket::TextureAndGeometryPacket(
TextureAndGeometryPacket::TextureAndGeometryPacket( TextureAndGeometryPacket::TextureAndGeometryPacket(
const std::string& textureName, std::uint8_t* pbData, const std::string& textureName, std::uint8_t* pbData,
std::uint32_t dataBytes, DLCSkinFile* pDLCSkinFile) { std::uint32_t dataBytes, ISkinAssetData* pSkinAssetData) {
this->textureName = textureName; this->textureName = textureName;
std::string skinValue = textureName.substr(7, textureName.size()); std::string skinValue = textureName.substr(7, textureName.size());
@ -63,11 +63,12 @@ TextureAndGeometryPacket::TextureAndGeometryPacket(
this->pbData = pbData; this->pbData = pbData;
this->dwTextureBytes = dataBytes; this->dwTextureBytes = dataBytes;
this->uiAnimOverrideBitmask = pDLCSkinFile->getAnimOverrideBitmask(); this->uiAnimOverrideBitmask = pSkinAssetData->getAnimOverrideBitmask();
this->dwBoxC = pDLCSkinFile->getAdditionalBoxesCount(); this->dwBoxC = pSkinAssetData->getAdditionalBoxesCount();
if (this->dwBoxC != 0) { if (this->dwBoxC != 0) {
this->BoxDataA = new SKIN_BOX[this->dwBoxC]; this->BoxDataA = new SKIN_BOX[this->dwBoxC];
std::vector<SKIN_BOX*>* pSkinBoxes = pDLCSkinFile->getAdditionalBoxes(); std::vector<SKIN_BOX*>* pSkinBoxes =
pSkinAssetData->getAdditionalBoxes();
int iCount = 0; int iCount = 0;
for (auto it = pSkinBoxes->begin(); it != pSkinBoxes->end(); ++it) { for (auto it = pSkinBoxes->begin(); it != pSkinBoxes->end(); ++it) {

View file

@ -10,7 +10,7 @@
#include "minecraft/client/model/geom/Model.h" #include "minecraft/client/model/geom/Model.h"
#include "minecraft/network/packet/Packet.h" #include "minecraft/network/packet/Packet.h"
class DLCSkinFile; class ISkinAssetData;
class TextureAndGeometryPacket class TextureAndGeometryPacket
: public Packet, : public Packet,
@ -30,7 +30,7 @@ public:
std::uint8_t* pbData, std::uint32_t dataBytes); std::uint8_t* pbData, std::uint32_t dataBytes);
TextureAndGeometryPacket(const std::string& textureName, TextureAndGeometryPacket(const std::string& textureName,
std::uint8_t* pbData, std::uint32_t dataBytes, std::uint8_t* pbData, std::uint32_t dataBytes,
DLCSkinFile* pDLCSkinFile); ISkinAssetData* pSkinAssetData);
TextureAndGeometryPacket(const std::string& textureName, TextureAndGeometryPacket(const std::string& textureName,
std::uint8_t* pbData, std::uint32_t dataBytes, std::uint8_t* pbData, std::uint32_t dataBytes,
std::vector<SKIN_BOX*>* pvSkinBoxes, std::vector<SKIN_BOX*>* pvSkinBoxes,

View file

@ -9,7 +9,6 @@
#include <utility> #include <utility>
#include "ServerConnection.h" #include "ServerConnection.h"
#include "app/common/DLC/DLCSkinFile.h"
#include "app/common/Network/Socket.h" #include "app/common/Network/Socket.h"
#include "java/Class.h" #include "java/Class.h"
#include "java/InputOutputStream/ByteArrayInputStream.h" #include "java/InputOutputStream/ByteArrayInputStream.h"
@ -24,6 +23,7 @@
#include "minecraft/IGameServices.h" #include "minecraft/IGameServices.h"
#include "minecraft/SharedConstants.h" #include "minecraft/SharedConstants.h"
#include "minecraft/client/model/SkinBox.h" #include "minecraft/client/model/SkinBox.h"
#include "minecraft/client/skins/ISkinAssetData.h"
#include "minecraft/commands/CommandDispatcher.h" #include "minecraft/commands/CommandDispatcher.h"
#include "minecraft/commands/CommandsEnum.h" #include "minecraft/commands/CommandsEnum.h"
#include "minecraft/network/Connection.h" #include "minecraft/network/Connection.h"
@ -850,16 +850,16 @@ void PlayerConnection::handleTextureAndGeometry(
unsigned int dwTextureBytes = 0; unsigned int dwTextureBytes = 0;
gameServices().getMemFileDetails(packet->textureName, &pbData, gameServices().getMemFileDetails(packet->textureName, &pbData,
&dwTextureBytes); &dwTextureBytes);
DLCSkinFile* pDLCSkinFile = ISkinAssetData* pSkinAsset =
gameServices().getDLCSkinFile(packet->textureName); gameServices().getSkinAssetData(packet->textureName);
if (dwTextureBytes != 0) { if (dwTextureBytes != 0) {
if (pDLCSkinFile) { if (pSkinAsset) {
if (pDLCSkinFile->getAdditionalBoxesCount() != 0) { if (pSkinAsset->getAdditionalBoxesCount() != 0) {
send(std::shared_ptr<TextureAndGeometryPacket>( send(std::shared_ptr<TextureAndGeometryPacket>(
new TextureAndGeometryPacket(packet->textureName, new TextureAndGeometryPacket(packet->textureName,
pbData, dwTextureBytes, pbData, dwTextureBytes,
pDLCSkinFile))); pSkinAsset)));
} else { } else {
send(std::shared_ptr<TextureAndGeometryPacket>( send(std::shared_ptr<TextureAndGeometryPacket>(
new TextureAndGeometryPacket(packet->textureName, new TextureAndGeometryPacket(packet->textureName,
@ -938,14 +938,14 @@ void PlayerConnection::handleTextureAndGeometryReceived(
std::uint8_t* pbData = nullptr; std::uint8_t* pbData = nullptr;
unsigned int dwTextureBytes = 0; unsigned int dwTextureBytes = 0;
gameServices().getMemFileDetails(textureName, &pbData, &dwTextureBytes); gameServices().getMemFileDetails(textureName, &pbData, &dwTextureBytes);
DLCSkinFile* pDLCSkinFile = gameServices().getDLCSkinFile(textureName); ISkinAssetData* pSkinAsset =
gameServices().getSkinAssetData(textureName);
if (dwTextureBytes != 0) { if (dwTextureBytes != 0) {
if (pDLCSkinFile && if (pSkinAsset && (pSkinAsset->getAdditionalBoxesCount() != 0)) {
(pDLCSkinFile->getAdditionalBoxesCount() != 0)) {
send(std::shared_ptr<TextureAndGeometryPacket>( send(std::shared_ptr<TextureAndGeometryPacket>(
new TextureAndGeometryPacket( new TextureAndGeometryPacket(
textureName, pbData, dwTextureBytes, pDLCSkinFile))); textureName, pbData, dwTextureBytes, pSkinAsset)));
} else { } else {
// get the data from the app // get the data from the app
std::uint32_t dwSkinID = std::uint32_t dwSkinID =

View file

@ -22,7 +22,7 @@
#include "Inventory.h" #include "Inventory.h"
#include "Player.h" #include "Player.h"
#include "app/common/App_structs.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/JavaMath.h"
#include "java/Random.h" #include "java/Random.h"
#include "minecraft/Direction.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); Log::info("Couldn't get model parts for skin %X\n",m_dwSkinId);
// do we have it from the DLC pack? // do we have it from the DLC pack?
DLCSkinFile *pDLCSkinFile = ISkinAssetData *pSkinAsset =
gameServices().getDLCSkinFile(this->customTextureUrl); gameServices().getSkinAssetData(this->customTextureUrl);
if(pDLCSkinFile!=nullptr) if(pSkinAsset!=nullptr)
{ {
const int additionalBoxCount = 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); 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); this->SetAdditionalModelParts(pvModelParts);
} }
else else
{ {
this->SetAdditionalModelParts(nullptr); this->SetAdditionalModelParts(nullptr);
} }
gameServices().setAnimOverrideBitmask(pDLCSkinFile->getSkinID(),pDLCSkinFile->getAnimOverrideBitmask()); gameServices().setAnimOverrideBitmask(pSkinAsset->getSkinID(),pSkinAsset->getAnimOverrideBitmask());
} }
else else
{ {
@ -2704,12 +2704,12 @@ std::vector<ModelPart*>* Player::GetAdditionalModelParts() {
m_dwSkinId); m_dwSkinId);
// do we have it from the DLC pack? // do we have it from the DLC pack?
DLCSkinFile* pDLCSkinFile = ISkinAssetData* pSkinAsset =
gameServices().getDLCSkinFile(this->customTextureUrl); gameServices().getSkinAssetData(this->customTextureUrl);
if (pDLCSkinFile != nullptr) { if (pSkinAsset != nullptr) {
const int additionalBoxCount = const int additionalBoxCount =
pDLCSkinFile->getAdditionalBoxesCount(); pSkinAsset->getAdditionalBoxesCount();
if (additionalBoxCount != 0) { if (additionalBoxCount != 0) {
Log::info( Log::info(
"m_bCheckedForModelParts Got model parts from DLCskin " "m_bCheckedForModelParts Got model parts from DLCskin "
@ -2717,12 +2717,12 @@ std::vector<ModelPart*>* Player::GetAdditionalModelParts() {
m_dwSkinId); m_dwSkinId);
m_ppAdditionalModelParts = m_ppAdditionalModelParts =
gameServices().setAdditionalSkinBoxesFromVec( gameServices().setAdditionalSkinBoxesFromVec(
m_dwSkinId, pDLCSkinFile->getAdditionalBoxes()); m_dwSkinId, pSkinAsset->getAdditionalBoxes());
} }
gameServices().setAnimOverrideBitmask( gameServices().setAnimOverrideBitmask(
pDLCSkinFile->getSkinID(), pSkinAsset->getSkinID(),
pDLCSkinFile->getAnimOverrideBitmask()); pSkinAsset->getAnimOverrideBitmask());
m_bCheckedForModelParts = true; m_bCheckedForModelParts = true;
} }