From 1ead072c458ad4f7ab3f222f92b945525d08ac3b Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:46:50 +1100 Subject: [PATCH] Add text input support: safe uint16_t* to wstring conversion Replace unsafe (wchar_t*)pchText casts with uint16_to_wstring() in all keyboard callbacks. The direct cast is incorrect on platforms where wchar_t is 4 bytes (Linux/macOS). New helpers in StringHelpers route through u16string for proper UTF-16 to wchar_t conversion. - Add uint16_len, uint16_to_u16string, uint16_to_wstring to StringHelpers - Fix casts in AnvilMenu, CreateWorldMenu, DebugCreateSchematic, DebugSetCamera, LaunchMoreOptionsMenu, SignEntryMenu - Truncate sign text to 15 chars in SignEntryMenu - Move m_bIgnoreInput reset after if-block in LaunchMoreOptionsMenu --- .../Platform/Common/UI/UIScene_AnvilMenu.cpp | 5 +++-- .../Common/UI/UIScene_CreateWorldMenu.cpp | 16 ++++++++-------- .../Common/UI/UIScene_DebugCreateSchematic.cpp | 2 +- .../Common/UI/UIScene_DebugSetCamera.cpp | 2 +- .../Common/UI/UIScene_LaunchMoreOptionsMenu.cpp | 8 +++++--- .../Platform/Common/UI/UIScene_SignEntryMenu.cpp | 6 ++++-- Minecraft.World/Util/StringHelpers.cpp | 13 +++++++++++++ Minecraft.World/Util/StringHelpers.h | 4 ++++ 8 files changed, 39 insertions(+), 17 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp index 5b4692fe8..c00466165 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp @@ -4,6 +4,7 @@ #include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" #include "../../Minecraft.Client/Minecraft.h" +#include "../../Minecraft.World/Util/StringHelpers.h" #include "UIScene_AnvilMenu.h" UIScene_AnvilMenu::UIScene_AnvilMenu(int iPad, void* _initData, @@ -300,8 +301,8 @@ int UIScene_AnvilMenu::KeyboardCompleteCallback(void* lpParam, bool bRes) { uint16_t pchText[128]; ZeroMemory(pchText, 128 * sizeof(uint16_t)); InputManager.GetText(pchText); - pClass->setEditNameValue((wchar_t*)pchText); - pClass->m_itemName = (wchar_t*)pchText; + pClass->setEditNameValue(uint16_to_wstring(pchText)); + pClass->m_itemName = uint16_to_wstring(pchText); pClass->updateItemName(); } return 0; diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp index 43dbade82..76beb132a 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp @@ -723,8 +723,8 @@ int UIScene_CreateWorldMenu::KeyboardCompleteWorldNameCallback(void* lpParam, InputManager.GetText(pchText); if (pchText[0] != 0) { - pClass->m_editWorldName.setLabel((wchar_t*)pchText); - pClass->m_worldName = (wchar_t*)pchText; + pClass->m_editWorldName.setLabel(uint16_to_wstring(pchText)); + pClass->m_worldName = uint16_to_wstring(pchText); } pClass->m_buttonCreateWorld.setEnable(!pClass->m_worldName.empty()); @@ -901,9 +901,9 @@ IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad()); return; bool pccFriendsAllowed = true; bool bContentRestricted = false; - ProfileManager.AllowedPlayerCreatedContent( - ProfileManager.GetPrimaryPad(), false, &pccAllowed, - &pccFriendsAllowed); + GetAllowedPlayerCreatedContentFlags(ProfileManager.GetPrimaryPad(), + false, &pccAllowed, + &pccFriendsAllowed); #if defined(__PS3__) || defined(__PSVITA__) if (isOnlineGame && isSignedInLive) { ProfileManager.GetChatAndContentRestrictions( @@ -1346,9 +1346,9 @@ int UIScene_CreateWorldMenu::StartGame_SignInReturned(void* pParam, bool pccAllowed = true; bool pccFriendsAllowed = true; - ProfileManager.AllowedPlayerCreatedContent( - ProfileManager.GetPrimaryPad(), false, &pccAllowed, - &pccFriendsAllowed); + GetAllowedPlayerCreatedContentFlags(ProfileManager.GetPrimaryPad(), + false, &pccAllowed, + &pccFriendsAllowed); if (!pccAllowed && !pccFriendsAllowed) noUGC = true; if (isOnlineGame && (noPrivileges || noUGC)) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp index 3e2d56504..00b175887 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp @@ -146,7 +146,7 @@ int UIScene_DebugCreateSchematic::KeyboardCompleteCallback(void* lpParam, InputManager.GetText(pchText); if (pchText[0] != 0) { - std::wstring value = (wchar_t*)pchText; + std::wstring value = uint16_to_wstring(pchText); int iVal = 0; if (!value.empty()) iVal = _fromString(value); switch (pClass->m_keyboardCallbackControl) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp index af850cb67..1472864e3 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp @@ -124,7 +124,7 @@ int UIScene_DebugSetCamera::KeyboardCompleteCallback(void* lpParam, bool bRes) { InputManager.GetText(pchText); if (pchText[0] != 0) { - std::wstring value = (wchar_t*)pchText; + std::wstring value = uint16_to_wstring(pchText); double val = 0; if (!value.empty()) val = _fromString(value); switch (pClass->m_keyboardCallbackControl) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp index 448acff95..8a7e7efda 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp @@ -1,5 +1,6 @@ #include "../../Minecraft.World/Platform/stdafx.h" #include "UI.h" +#include "../../Minecraft.World/Util/StringHelpers.h" #include "UIScene_LaunchMoreOptionsMenu.h" #define GAME_CREATE_ONLINE_TIMER_ID 0 @@ -589,7 +590,6 @@ int UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback(void* lpParam, bool bRes) { UIScene_LaunchMoreOptionsMenu* pClass = (UIScene_LaunchMoreOptionsMenu*)lpParam; - pClass->m_bIgnoreInput = false; // 4J HEG - No reason to set value if keyboard was cancelled if (bRes) { #ifdef __PSVITA__ @@ -601,9 +601,10 @@ int UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback(void* lpParam, ZeroMemory(pchText, 128 * sizeof(uint16_t)); #endif InputManager.GetText(pchText); - pClass->m_editSeed.setLabel((wchar_t*)pchText); - pClass->m_params->seed = (wchar_t*)pchText; + pClass->m_editSeed.setLabel(uint16_to_wstring(pchText)); + pClass->m_params->seed = uint16_to_wstring(pchText); } + pClass->m_bIgnoreInput = false; return 0; } @@ -643,6 +644,7 @@ void UIScene_LaunchMoreOptionsMenu::handlePress(F64 controlId, F64 childId) { 0, 60, &UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback, this, C_4JInput::EKeyboardMode_Default); + KeyboardCompleteSeedCallback(this, true); #endif } break; } diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp index ad927a1dc..70288fb1f 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp @@ -1,5 +1,6 @@ #include "../../Minecraft.World/Platform/stdafx.h" #include "UI.h" +#include "../../Minecraft.World/Util/StringHelpers.h" #include "UIScene_SignEntryMenu.h" #include "../../Minecraft.Client/Minecraft.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" @@ -144,8 +145,9 @@ int UIScene_SignEntryMenu::KeyboardCompleteCallback(void* lpParam, bool bRes) { uint16_t pchText[128]; ZeroMemory(pchText, 128 * sizeof(uint16_t)); InputManager.GetText(pchText); - pClass->m_textInputLines[pClass->m_iEditingLine].setLabel( - (wchar_t*)pchText); + std::wstring str = uint16_to_wstring(pchText); + str.resize(15); + pClass->m_textInputLines[pClass->m_iEditingLine].setLabel(str); } return 0; } diff --git a/Minecraft.World/Util/StringHelpers.cpp b/Minecraft.World/Util/StringHelpers.cpp index 9f47f92b8..43cfb171a 100644 --- a/Minecraft.World/Util/StringHelpers.cpp +++ b/Minecraft.World/Util/StringHelpers.cpp @@ -36,6 +36,19 @@ bool equalsIgnoreCase(const std::wstring& a, const std::wstring& b) { return out; } +size_t uint16_len(const uint16_t* str) { + return std::char_traits::length( + reinterpret_cast(str)); +} + +std::u16string uint16_to_u16string(const uint16_t* str) { + return std::u16string(reinterpret_cast(str), uint16_len(str)); +} + +std::wstring uint16_to_wstring(const uint16_t* str) { + return u16string_to_wstring(uint16_to_u16string(str)); +} + std::wstring convStringToWstring(const std::string& converting) { std::wstring converted(converting.length(), L' '); copy(converting.begin(), converting.end(), converted.begin()); diff --git a/Minecraft.World/Util/StringHelpers.h b/Minecraft.World/Util/StringHelpers.h index 871e46d87..4f41be369 100644 --- a/Minecraft.World/Util/StringHelpers.h +++ b/Minecraft.World/Util/StringHelpers.h @@ -29,6 +29,10 @@ T _fromHEXString(const std::wstring& s) { return t; } +size_t uint16_len(const uint16_t* str); +std::u16string uint16_to_u16string(const uint16_t* str); +std::wstring uint16_to_wstring(const uint16_t* str); + std::wstring convStringToWstring(const std::string& converting); std::wstring u16string_to_wstring(const std::u16string& converting); std::u16string wstring_to_u16string(const std::wstring& converting);