mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
za
This commit is contained in:
parent
6f021d40eb
commit
a0fc7d6845
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include <fstream>
|
||||
#include "..\..\Minecraft.World\net.minecraft.world.entity.item.h"
|
||||
#include "..\..\Minecraft.World\net.minecraft.world.entity.player.h"
|
||||
#include "..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h"
|
||||
|
|
@ -60,9 +61,6 @@
|
|||
#include "UI\UI.h"
|
||||
#include "UI\UIScene_PauseMenu.h"
|
||||
#endif
|
||||
#ifdef __PS3__
|
||||
#include <sys/tty.h>
|
||||
#endif
|
||||
#ifdef __ORBIS__
|
||||
#include <save_data_dialog.h>
|
||||
#endif
|
||||
|
|
@ -9344,6 +9342,43 @@ wstring CMinecraftApp::getSkinPathFromId(DWORD skinId)
|
|||
else
|
||||
{
|
||||
swprintf(chars, 256, L"ugcskin%08X.png",ugcSkinIndex);
|
||||
|
||||
// --- PERSISTENCE: Check if we need to load this skin from disk ---
|
||||
// Iterate through all possible active players (max 4) to find if this skin belongs to one of them.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (ProfileManager.IsSignedIn(i)) // Check if player is signed in
|
||||
{
|
||||
wstring username = ProfileManager.GetDisplayName(i);
|
||||
if (username.empty()) username = L"default";
|
||||
|
||||
WCHAR expectedSkinPath[MAX_PATH];
|
||||
swprintf(expectedSkinPath, 256, L"CustomSkin\\custom_skin_%ls.png", username.c_str());
|
||||
|
||||
// If the file is not already in memory textures, load it.
|
||||
// Note: app.IsFileInMemoryTextures check is internal to app.AddMemoryTextureFile normally,
|
||||
// but we check here to avoid redundant file I/O.
|
||||
if (!app.IsFileInMemoryTextures(chars))
|
||||
{
|
||||
std::ifstream file(expectedSkinPath, std::ios::binary | std::ios::ate);
|
||||
if (file.is_open())
|
||||
{
|
||||
std::streamsize size = file.tellg();
|
||||
if (size > 0 && size <= 2 * 1024 * 1024)
|
||||
{
|
||||
file.seekg(0, std::ios::beg);
|
||||
PBYTE buffer = new (std::nothrow) BYTE[(size_t)size];
|
||||
if (buffer && file.read((char*)buffer, size))
|
||||
{
|
||||
app.AddMemoryTextureFile(chars, buffer, (DWORD)size);
|
||||
}
|
||||
else if (buffer) delete[] buffer;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return chars;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,45 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer
|
|||
m_bSlidingSkins = false;
|
||||
m_bAnimatingMove = false;
|
||||
m_bSkinIndexChanged = false;
|
||||
m_bUsingCustomSkin = (!GET_IS_DLC_SKIN_FROM_BITMASK(m_originalSkinId) && GET_UGC_SKIN_ID_FROM_BITMASK(m_originalSkinId) != 0);
|
||||
|
||||
m_customSkinTextureName = L"";
|
||||
m_bUsingCustomSkin = false;
|
||||
|
||||
// --- PERSISTENCE: Check for existing custom skin on disk ---
|
||||
wstring username = ProfileManager.GetDisplayName(iPad);
|
||||
if (username.empty()) username = L"default";
|
||||
WCHAR skinPath[MAX_PATH];
|
||||
swprintf(skinPath, 256, L"CustomSkin\\custom_skin_%ls.png", username.c_str());
|
||||
|
||||
std::ifstream file(skinPath, std::ios::binary | std::ios::ate);
|
||||
if (file.is_open())
|
||||
{
|
||||
std::streamsize size = file.tellg();
|
||||
if (size > 0 && size <= 2 * 1024 * 1024)
|
||||
{
|
||||
file.seekg(0, std::ios::beg);
|
||||
PBYTE buffer = new (std::nothrow) BYTE[(size_t)size];
|
||||
if (buffer && file.read((char*)buffer, size))
|
||||
{
|
||||
static int s_persistentLoadCount = 0;
|
||||
s_persistentLoadCount++;
|
||||
wchar_t nameBuf[256];
|
||||
swprintf(nameBuf, 256, L"ugcskin%08X.png", 0x300 + (s_persistentLoadCount << 5));
|
||||
m_customSkinTextureName = nameBuf;
|
||||
app.AddMemoryTextureFile(m_customSkinTextureName, buffer, (DWORD)size);
|
||||
m_bUsingCustomSkin = true;
|
||||
}
|
||||
else if (buffer) delete[] buffer;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
// If the player is already wearing a custom skin, override with the current one
|
||||
if (!GET_IS_DLC_SKIN_FROM_BITMASK(m_originalSkinId) && GET_UGC_SKIN_ID_FROM_BITMASK(m_originalSkinId) != 0)
|
||||
{
|
||||
m_customSkinTextureName = m_currentSkinPath;
|
||||
m_bUsingCustomSkin = true;
|
||||
}
|
||||
|
||||
m_currentNavigation = eSkinNavigation_Skin;
|
||||
|
||||
|
|
@ -229,7 +267,8 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
|||
}
|
||||
break;
|
||||
case ACTION_MENU_X:
|
||||
if (pressed && !repeat)
|
||||
// Only allow changing the external skin if we are on the first slot of the default pack
|
||||
if (pressed && !repeat && m_packIndex == SKIN_SELECT_PACK_DEFAULT && m_skinIndex == 0)
|
||||
{
|
||||
LoadExternalSkin();
|
||||
handled = true;
|
||||
|
|
@ -276,7 +315,6 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
|||
m_skinIndex = getPreviousSkinIndex(m_skinIndex);
|
||||
//handleSkinIndexChanged();
|
||||
|
||||
m_bUsingCustomSkin = false;
|
||||
m_bSlidingSkins = true;
|
||||
m_bAnimatingMove = true;
|
||||
|
||||
|
|
@ -312,7 +350,6 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
|||
m_skinIndex = getNextSkinIndex(m_skinIndex);
|
||||
//handleSkinIndexChanged();
|
||||
|
||||
m_bUsingCustomSkin = false;
|
||||
m_bSlidingSkins = true;
|
||||
m_bAnimatingMove = true;
|
||||
|
||||
|
|
@ -415,15 +452,23 @@ void UIScene_SkinSelectMenu::InputActionOK(unsigned int iPad)
|
|||
{
|
||||
ui.AnimateKeyPress(iPad, ACTION_MENU_OK, false, true, false);
|
||||
|
||||
if (m_bUsingCustomSkin)
|
||||
// If we are specifically on the custom skin slot (0) and we have a custom skin loaded,
|
||||
// apply it and set the active flag to true.
|
||||
if (!m_customSkinTextureName.empty() && m_packIndex == SKIN_SELECT_PACK_DEFAULT && m_skinIndex == 0)
|
||||
{
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
app.SetPlayerSkin(iPad, m_customSkinTextureName);
|
||||
m_currentSkinPath = app.GetPlayerSkinName(iPad);
|
||||
m_originalSkinId = app.GetPlayerSkinId(iPad);
|
||||
m_bUsingCustomSkin = true;
|
||||
setCharacterSelected(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the user selects a DIFFERENT skin (DLC, Default, etc.), clear the active flag
|
||||
// but KEEP m_customSkinTextureName so it stays in the menu.
|
||||
m_bUsingCustomSkin = false;
|
||||
|
||||
// if the profile data has been changed, then force a profile write
|
||||
// It seems we're allowed to break the 5 minute rule if it's the result of a user action
|
||||
switch(m_packIndex)
|
||||
|
|
@ -668,14 +713,23 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
|||
|
||||
m_controlSkinNamePlate.setVisible( false );
|
||||
|
||||
if (m_bUsingCustomSkin)
|
||||
// --- PERSISTENCE: Custom Skin UI Display ---
|
||||
// Show the "Custom Skin" info if we have a custom skin loaded and are on slot 0.
|
||||
if (!m_customSkinTextureName.empty() && m_packIndex == SKIN_SELECT_PACK_DEFAULT && m_skinIndex == 0)
|
||||
{
|
||||
m_selectedSkinPath = m_currentSkinPath;
|
||||
m_selectedSkinPath = m_customSkinTextureName;
|
||||
m_selectedCapePath = L"";
|
||||
m_vAdditionalSkinBoxes = NULL;
|
||||
skinName = L"Custom Skin";
|
||||
skinOrigin = L"External PNG";
|
||||
setCharacterSelected(true);
|
||||
|
||||
// If the player is currently wearing THE custom skin, show the checkmark.
|
||||
// We use m_currentSkinPath (what the player is actually wearing) to decide.
|
||||
if (m_selectedSkinPath.compare(app.GetPlayerSkinName(m_iPad)) == 0)
|
||||
{
|
||||
setCharacterSelected(true);
|
||||
}
|
||||
|
||||
setCharacterLocked(false);
|
||||
m_characters[eCharacter_Current].setVisible(true);
|
||||
m_controlSkinNamePlate.setVisible(true);
|
||||
|
|
@ -786,11 +840,6 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
|||
m_labelSkinName.setLabel(skinName);
|
||||
m_labelSkinOrigin.setLabel(skinOrigin);
|
||||
|
||||
if (m_packIndex == SKIN_SELECT_PACK_DEFAULT && m_bUsingCustomSkin)
|
||||
{
|
||||
m_labelSkinOrigin.setLabel(L"X: Custom Skin"); // Display visual aid for custom skin
|
||||
}
|
||||
|
||||
if (m_selectedSkinPath.compare(m_currentSkinPath) == 0)
|
||||
{
|
||||
setCharacterSelected(true); // Enable selection checkmark
|
||||
|
|
@ -888,7 +937,15 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
|||
switch(m_packIndex)
|
||||
{
|
||||
case SKIN_SELECT_PACK_DEFAULT:
|
||||
backupTexture = getTextureId(nextIndex);
|
||||
if (nextIndex == 0 && !m_customSkinTextureName.empty())
|
||||
{
|
||||
otherSkinPath = m_customSkinTextureName;
|
||||
backupTexture = TN_MOB_CHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
backupTexture = getTextureId(nextIndex);
|
||||
}
|
||||
break;
|
||||
case SKIN_SELECT_PACK_FAVORITES:
|
||||
if(uiCurrentFavoriteC>0)
|
||||
|
|
@ -959,7 +1016,15 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
|||
switch(m_packIndex)
|
||||
{
|
||||
case SKIN_SELECT_PACK_DEFAULT:
|
||||
backupTexture = getTextureId(previousIndex);
|
||||
if (previousIndex == 0 && !m_customSkinTextureName.empty())
|
||||
{
|
||||
otherSkinPath = m_customSkinTextureName;
|
||||
backupTexture = TN_MOB_CHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
backupTexture = getTextureId(previousIndex);
|
||||
}
|
||||
break;
|
||||
case SKIN_SELECT_PACK_FAVORITES:
|
||||
if(uiCurrentFavoriteC>0)
|
||||
|
|
@ -1847,11 +1912,27 @@ void UIScene_SkinSelectMenu::LoadExternalSkin()
|
|||
// 1. Add texture data to the in-memory filesystem
|
||||
app.AddMemoryTextureFile(textureName, persistentBuffer, (DWORD)size);
|
||||
|
||||
// --- PERSISTENCE: Save the custom skin to disk ---
|
||||
// Create the 'CustomSkin' directory if it doesn't exist, and save as 'custom_skin_%username%.png'
|
||||
CreateDirectoryW(L"CustomSkin", NULL);
|
||||
wstring username = ProfileManager.GetDisplayName(m_iPad);
|
||||
if (username.empty()) username = L"default";
|
||||
WCHAR skinPath[MAX_PATH];
|
||||
swprintf(skinPath, 256, L"CustomSkin\\custom_skin_%ls.png", username.c_str());
|
||||
|
||||
std::ofstream outFile(skinPath, std::ios::binary);
|
||||
if (outFile.is_open())
|
||||
{
|
||||
outFile.write((char*)persistentBuffer, size);
|
||||
outFile.close();
|
||||
}
|
||||
|
||||
// 2. Apply the skin path to the local player character
|
||||
app.SetPlayerSkin(m_iPad, textureName);
|
||||
|
||||
// 3. Force UI refresh and update internal state
|
||||
m_bUsingCustomSkin = true;
|
||||
m_customSkinTextureName = textureName;
|
||||
m_selectedSkinPath = textureName;
|
||||
m_currentSkinPath = textureName;
|
||||
m_selectedCapePath = L"";
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ private:
|
|||
DLCPack *m_currentPack;
|
||||
DWORD m_packIndex, m_skinIndex;
|
||||
DWORD m_originalSkinId;
|
||||
wstring m_currentSkinPath, m_selectedSkinPath, m_selectedCapePath;
|
||||
wstring m_currentSkinPath, m_selectedSkinPath, m_selectedCapePath, m_customSkinTextureName;
|
||||
vector<SKIN_BOX *> *m_vAdditionalSkinBoxes;
|
||||
|
||||
bool m_bSlidingSkins, m_bAnimatingMove;
|
||||
|
|
|
|||
Loading…
Reference in a new issue