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 "stdafx.h"
|
||||||
|
#include <fstream>
|
||||||
#include "..\..\Minecraft.World\net.minecraft.world.entity.item.h"
|
#include "..\..\Minecraft.World\net.minecraft.world.entity.item.h"
|
||||||
#include "..\..\Minecraft.World\net.minecraft.world.entity.player.h"
|
#include "..\..\Minecraft.World\net.minecraft.world.entity.player.h"
|
||||||
#include "..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h"
|
#include "..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h"
|
||||||
|
|
@ -60,9 +61,6 @@
|
||||||
#include "UI\UI.h"
|
#include "UI\UI.h"
|
||||||
#include "UI\UIScene_PauseMenu.h"
|
#include "UI\UIScene_PauseMenu.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef __PS3__
|
|
||||||
#include <sys/tty.h>
|
|
||||||
#endif
|
|
||||||
#ifdef __ORBIS__
|
#ifdef __ORBIS__
|
||||||
#include <save_data_dialog.h>
|
#include <save_data_dialog.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -9344,6 +9342,43 @@ wstring CMinecraftApp::getSkinPathFromId(DWORD skinId)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
swprintf(chars, 256, L"ugcskin%08X.png",ugcSkinIndex);
|
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;
|
return chars;
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,45 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer
|
||||||
m_bSlidingSkins = false;
|
m_bSlidingSkins = false;
|
||||||
m_bAnimatingMove = false;
|
m_bAnimatingMove = false;
|
||||||
m_bSkinIndexChanged = 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;
|
m_currentNavigation = eSkinNavigation_Skin;
|
||||||
|
|
||||||
|
|
@ -229,7 +267,8 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_MENU_X:
|
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();
|
LoadExternalSkin();
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
@ -276,7 +315,6 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
||||||
m_skinIndex = getPreviousSkinIndex(m_skinIndex);
|
m_skinIndex = getPreviousSkinIndex(m_skinIndex);
|
||||||
//handleSkinIndexChanged();
|
//handleSkinIndexChanged();
|
||||||
|
|
||||||
m_bUsingCustomSkin = false;
|
|
||||||
m_bSlidingSkins = true;
|
m_bSlidingSkins = true;
|
||||||
m_bAnimatingMove = 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);
|
m_skinIndex = getNextSkinIndex(m_skinIndex);
|
||||||
//handleSkinIndexChanged();
|
//handleSkinIndexChanged();
|
||||||
|
|
||||||
m_bUsingCustomSkin = false;
|
|
||||||
m_bSlidingSkins = true;
|
m_bSlidingSkins = true;
|
||||||
m_bAnimatingMove = true;
|
m_bAnimatingMove = true;
|
||||||
|
|
||||||
|
|
@ -415,15 +452,23 @@ void UIScene_SkinSelectMenu::InputActionOK(unsigned int iPad)
|
||||||
{
|
{
|
||||||
ui.AnimateKeyPress(iPad, ACTION_MENU_OK, false, true, false);
|
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);
|
ui.PlayUISFX(eSFX_Press);
|
||||||
|
app.SetPlayerSkin(iPad, m_customSkinTextureName);
|
||||||
m_currentSkinPath = app.GetPlayerSkinName(iPad);
|
m_currentSkinPath = app.GetPlayerSkinName(iPad);
|
||||||
m_originalSkinId = app.GetPlayerSkinId(iPad);
|
m_originalSkinId = app.GetPlayerSkinId(iPad);
|
||||||
|
m_bUsingCustomSkin = true;
|
||||||
setCharacterSelected(true);
|
setCharacterSelected(true);
|
||||||
return;
|
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
|
// 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
|
// It seems we're allowed to break the 5 minute rule if it's the result of a user action
|
||||||
switch(m_packIndex)
|
switch(m_packIndex)
|
||||||
|
|
@ -668,14 +713,23 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
||||||
|
|
||||||
m_controlSkinNamePlate.setVisible( false );
|
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_selectedCapePath = L"";
|
||||||
m_vAdditionalSkinBoxes = NULL;
|
m_vAdditionalSkinBoxes = NULL;
|
||||||
skinName = L"Custom Skin";
|
skinName = L"Custom Skin";
|
||||||
skinOrigin = L"External PNG";
|
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);
|
setCharacterLocked(false);
|
||||||
m_characters[eCharacter_Current].setVisible(true);
|
m_characters[eCharacter_Current].setVisible(true);
|
||||||
m_controlSkinNamePlate.setVisible(true);
|
m_controlSkinNamePlate.setVisible(true);
|
||||||
|
|
@ -786,11 +840,6 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
||||||
m_labelSkinName.setLabel(skinName);
|
m_labelSkinName.setLabel(skinName);
|
||||||
m_labelSkinOrigin.setLabel(skinOrigin);
|
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)
|
if (m_selectedSkinPath.compare(m_currentSkinPath) == 0)
|
||||||
{
|
{
|
||||||
setCharacterSelected(true); // Enable selection checkmark
|
setCharacterSelected(true); // Enable selection checkmark
|
||||||
|
|
@ -888,7 +937,15 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
||||||
switch(m_packIndex)
|
switch(m_packIndex)
|
||||||
{
|
{
|
||||||
case SKIN_SELECT_PACK_DEFAULT:
|
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;
|
break;
|
||||||
case SKIN_SELECT_PACK_FAVORITES:
|
case SKIN_SELECT_PACK_FAVORITES:
|
||||||
if(uiCurrentFavoriteC>0)
|
if(uiCurrentFavoriteC>0)
|
||||||
|
|
@ -959,7 +1016,15 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
|
||||||
switch(m_packIndex)
|
switch(m_packIndex)
|
||||||
{
|
{
|
||||||
case SKIN_SELECT_PACK_DEFAULT:
|
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;
|
break;
|
||||||
case SKIN_SELECT_PACK_FAVORITES:
|
case SKIN_SELECT_PACK_FAVORITES:
|
||||||
if(uiCurrentFavoriteC>0)
|
if(uiCurrentFavoriteC>0)
|
||||||
|
|
@ -1847,11 +1912,27 @@ void UIScene_SkinSelectMenu::LoadExternalSkin()
|
||||||
// 1. Add texture data to the in-memory filesystem
|
// 1. Add texture data to the in-memory filesystem
|
||||||
app.AddMemoryTextureFile(textureName, persistentBuffer, (DWORD)size);
|
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
|
// 2. Apply the skin path to the local player character
|
||||||
app.SetPlayerSkin(m_iPad, textureName);
|
app.SetPlayerSkin(m_iPad, textureName);
|
||||||
|
|
||||||
// 3. Force UI refresh and update internal state
|
// 3. Force UI refresh and update internal state
|
||||||
m_bUsingCustomSkin = true;
|
m_bUsingCustomSkin = true;
|
||||||
|
m_customSkinTextureName = textureName;
|
||||||
m_selectedSkinPath = textureName;
|
m_selectedSkinPath = textureName;
|
||||||
m_currentSkinPath = textureName;
|
m_currentSkinPath = textureName;
|
||||||
m_selectedCapePath = L"";
|
m_selectedCapePath = L"";
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ private:
|
||||||
DLCPack *m_currentPack;
|
DLCPack *m_currentPack;
|
||||||
DWORD m_packIndex, m_skinIndex;
|
DWORD m_packIndex, m_skinIndex;
|
||||||
DWORD m_originalSkinId;
|
DWORD m_originalSkinId;
|
||||||
wstring m_currentSkinPath, m_selectedSkinPath, m_selectedCapePath;
|
wstring m_currentSkinPath, m_selectedSkinPath, m_selectedCapePath, m_customSkinTextureName;
|
||||||
vector<SKIN_BOX *> *m_vAdditionalSkinBoxes;
|
vector<SKIN_BOX *> *m_vAdditionalSkinBoxes;
|
||||||
|
|
||||||
bool m_bSlidingSkins, m_bAnimatingMove;
|
bool m_bSlidingSkins, m_bAnimatingMove;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue