diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index 41a337d29..41108ace0 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -65,7 +65,6 @@ #include "../Minecraft.World/DurangoStats.h" #include "../Minecraft.World/GenericStats.h" #endif -#include ClientConnection::ClientConnection(Minecraft *minecraft, const wstring& ip, int port) { @@ -1547,8 +1546,6 @@ void ClientConnection::handleChat(shared_ptr packet) bool replaceEntitySource = false; bool replaceItem = false; - static std::wregex IDS_Pattern(LR"(\{\*IDS_(\d+)\*\})"); //maybe theres a better way to do translateable IDS - int stringArgsSize = packet->m_stringArgs.size(); wstring playerDisplayName = L""; @@ -1565,15 +1562,10 @@ void ClientConnection::handleChat(shared_ptr packet) if (stringArgsSize >= 1) { message = packet->m_stringArgs[0]; - std::wsmatch match; - while (std::regex_search(message, match, IDS_Pattern)) { - message = replaceAll(message, match[0], app.GetString(std::stoi(match[1].str()))); - } - message = app.EscapeHTMLString(message); //do this to enforce escaped string message = app.FormatChatMessage(message); //this needs to be last cause it converts colors to html colors that would have been escaped } else { - message = L"empty message"; + message = L""; } displayOnGui = (packet->m_messageType == ChatPacket::e_ChatCustom); break; diff --git a/Minecraft.Client/Common/App_enums.h b/Minecraft.Client/Common/App_enums.h index 15a179787..422652783 100644 --- a/Minecraft.Client/Common/App_enums.h +++ b/Minecraft.Client/Common/App_enums.h @@ -878,7 +878,8 @@ enum EControllerActions MINECRAFT_ACTION_SPAWN_CREEPER, MINECRAFT_ACTION_CHANGE_SKIN, MINECRAFT_ACTION_FLY_TOGGLE, - MINECRAFT_ACTION_RENDER_DEBUG + MINECRAFT_ACTION_RENDER_DEBUG, + MINECRAFT_ACTION_SCREENSHOT }; enum eMCLang diff --git a/Minecraft.Client/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Common/Audio/SoundEngine.cpp index fc3ae86ab..b4210b178 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Common/Audio/SoundEngine.cpp @@ -583,23 +583,26 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) { U8 szSoundName[256]; wstring name; + const char* soundDir; if (iSound >= eSFX_MAX) { strcpy((char*)szSoundName, "Minecraft/"); name = wchSoundNames[iSound]; + soundDir = "Minecraft"; } else { strcpy((char*)szSoundName, "Minecraft/UI/"); name = wchUISoundNames[iSound]; + soundDir = "Minecraft/UI"; } char* SoundName = (char*)ConvertSoundPathToName(name); strcat((char*)szSoundName, SoundName); char basePath[256]; - sprintf_s(basePath, "Windows64Media/Sound/Minecraft/UI/%s", ConvertSoundPathToName(name)); + sprintf_s(basePath, "Windows64Media/Sound/%s/%s", soundDir, ConvertSoundPathToName(name)); char finalPath[256]; sprintf_s(finalPath, "%s.wav", basePath); diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index 323386169..f733fd439 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -70,6 +70,7 @@ #endif #include "../Common/Leaderboards/LeaderboardManager.h" +#include //CMinecraftApp app; unsigned int CMinecraftApp::m_uiLastSignInData = 0; @@ -6618,60 +6619,70 @@ wstring CMinecraftApp::EscapeHTMLString(const wstring& desc) return finalString; } -wstring CMinecraftApp::FormatChatMessage(const wstring& desc, bool applyColor) +wstring CMinecraftApp::FormatChatMessage(const wstring& desc, bool applyStyling) { - static std::wstring_view colorFormatString = L""; + static std::wregex IDS_Pattern(LR"(\{\*IDS_(\d+)\*\})"); //maybe theres a better way to do translateable IDS + static std::wstring_view colorFormatString = L""; wstring results = desc; wchar_t replacements[64]; - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_0), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_0), 0xFFFFFFFF); results = replaceAll(results, L"§0", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_1), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_1), 0xFFFFFFFF); results = replaceAll(results, L"§1", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_2), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_2), 0xFFFFFFFF); results = replaceAll(results, L"§2", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_3), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_3), 0xFFFFFFFF); results = replaceAll(results, L"§3", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_4), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_4), 0xFFFFFFFF); results = replaceAll(results, L"§4", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_5), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_5), 0xFFFFFFFF); results = replaceAll(results, L"§5", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_6), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_6), 0xFFFFFFFF); results = replaceAll(results, L"§6", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_7), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_7), 0xFFFFFFFF); results = replaceAll(results, L"§7", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_8), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_8), 0xFFFFFFFF); results = replaceAll(results, L"§8", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_9), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_9), 0xFFFFFFFF); results = replaceAll(results, L"§9", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_a), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_a), 0xFFFFFFFF); results = replaceAll(results, L"§a", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_b), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_b), 0xFFFFFFFF); results = replaceAll(results, L"§b", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_c), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_c), 0xFFFFFFFF); results = replaceAll(results, L"§c", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_d), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_d), 0xFFFFFFFF); results = replaceAll(results, L"§d", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_e), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_e), 0xFFFFFFFF); results = replaceAll(results, L"§e", replacements); - swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_f), 0xFFFFFFFF); + swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_f), 0xFFFFFFFF); results = replaceAll(results, L"§f", replacements); + results = replaceAll(results, L"§r", replacements); //we only support color so reset is the same as white color + + if (applyStyling) { + std::wsmatch match; + while (std::regex_search(results, match, IDS_Pattern)) { + results = replaceAll(results, match[0], app.GetString(std::stoi(match[1].str()))); + } + } + return results; } diff --git a/Minecraft.Client/Common/Consoles_App.h b/Minecraft.Client/Common/Consoles_App.h index fa0a4d8be..6401c8395 100644 --- a/Minecraft.Client/Common/Consoles_App.h +++ b/Minecraft.Client/Common/Consoles_App.h @@ -566,7 +566,7 @@ public: int GetHTMLFontSize(EHTMLFontSize size); wstring FormatHTMLString(int iPad, const wstring& desc, int shadowColour = 0xFFFFFFFF); wstring EscapeHTMLString(const wstring &desc); - wstring FormatChatMessage(const wstring& desc, bool applyColor = true); + wstring FormatChatMessage(const wstring& desc, bool applyStyling = true); wstring GetActionReplacement(int iPad, unsigned char ucAction); wstring GetVKReplacement(unsigned int uiVKey); wstring GetIconReplacement(unsigned int uiIcon); diff --git a/Minecraft.Client/Common/UI/UIScene_HUD.cpp b/Minecraft.Client/Common/UI/UIScene_HUD.cpp index 6dc010c6e..452fa09b0 100644 --- a/Minecraft.Client/Common/UI/UIScene_HUD.cpp +++ b/Minecraft.Client/Common/UI/UIScene_HUD.cpp @@ -257,8 +257,10 @@ void UIScene_HUD::handleReload() for(unsigned int i = 0; i < CHAT_LINES_COUNT; ++i) { m_labelChatText[i].init(L""); + IggyValueSetBooleanRS(m_labelChatText[i].getIggyValuePath(), 0, "m_bUseHtmlText", true); } m_labelJukebox.init(L""); + IggyValueSetBooleanRS(m_labelJukebox.getIggyValuePath(), 0, "m_bUseHtmlText", true); int iGuiScale; Minecraft *pMinecraft = Minecraft::GetInstance(); diff --git a/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp b/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp index 5945e10e5..0e858213a 100644 --- a/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp @@ -110,6 +110,8 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye m_bThumbnailGetFailed = false; m_seed = 0; m_bIsCorrupt = false; + m_pbThumbnailData = nullptr; + m_uiThumbnailSize = 0; m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); // 4J-PB - read the settings for the online flag. We'll only save this setting if the user changed it. @@ -249,13 +251,32 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye #endif #endif #ifdef _WINDOWS64 - if (params->saveDetails != nullptr && params->saveDetails->UTF8SaveName[0] != '\0') + if (params->saveDetails != nullptr) { - wchar_t wSaveName[128]; - ZeroMemory(wSaveName, sizeof(wSaveName)); - mbstowcs(wSaveName, params->saveDetails->UTF8SaveName, 127); - m_levelName = wstring(wSaveName); - m_labelGameName.init(m_levelName); + if (params->saveDetails->UTF8SaveName[0] != '\0') + { + wchar_t wSaveName[128]; + ZeroMemory(wSaveName, sizeof(wSaveName)); + mbstowcs(wSaveName, params->saveDetails->UTF8SaveName, 127); + m_levelName = wstring(wSaveName); + m_labelGameName.init(m_levelName); + } + + wchar_t wFilename[MAX_SAVEFILENAME_LENGTH]; + ZeroMemory(wFilename, sizeof(wFilename)); + mbstowcs(wFilename, params->saveDetails->UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH - 1); + m_thumbnailName = wFilename; + + if (params->saveDetails->pbThumbnailData && params->saveDetails->dwThumbnailSize > 0) + { + // save list already loaded this, register and display it + registerSubstitutionTexture(wFilename, params->saveDetails->pbThumbnailData, params->saveDetails->dwThumbnailSize); + m_bitmapIcon.setTextureName(wFilename); + m_pbThumbnailData = params->saveDetails->pbThumbnailData; + m_uiThumbnailSize = params->saveDetails->dwThumbnailSize; + } + + m_bRetrievingSaveThumbnail = false; } #endif } diff --git a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp index dd6318e6b..daf78083c 100644 --- a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp @@ -1127,15 +1127,6 @@ void UIScene_SkinSelectMenu::handlePackIndexChanged() updatePackDisplay(); } -std::wstring fakeWideToRealWide(const wchar_t* original) -{ - const char* name = reinterpret_cast(original); - int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, nullptr, 0); - std::wstring wName(len, 0); - MultiByteToWideChar(CP_UTF8, 0, name, -1, &wName[0], len); - return wName.c_str(); -} - void UIScene_SkinSelectMenu::updatePackDisplay() { m_currentPackCount = app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin) + SKIN_SELECT_MAX_DEFAULTS; @@ -1143,18 +1134,16 @@ void UIScene_SkinSelectMenu::updatePackDisplay() if(m_packIndex >= SKIN_SELECT_MAX_DEFAULTS) { DLCPack *thisPack = app.m_dlcManager.getPack(m_packIndex - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); - // Fix the incorrect string type on title to display correctly - setCentreLabel(fakeWideToRealWide(thisPack->getName().c_str())); - //setCentreLabel(thisPack->getName().c_str()); + setCentreLabel(thisPack->getName().c_str()); } else { switch(m_packIndex) { - case SKIN_SELECT_PACK_DEFAULT: + case SKIN_SELECT_PACK_DEFAULT: setCentreLabel(app.GetString(IDS_NO_SKIN_PACK)); break; - case SKIN_SELECT_PACK_FAVORITES: + case SKIN_SELECT_PACK_FAVORITES: setCentreLabel(app.GetString(IDS_FAVORITES_SKIN_PACK)); break; } @@ -1164,18 +1153,16 @@ void UIScene_SkinSelectMenu::updatePackDisplay() if(nextPackIndex >= SKIN_SELECT_MAX_DEFAULTS) { DLCPack *thisPack = app.m_dlcManager.getPack(nextPackIndex - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); - // Fix the incorrect string type on title to display correctly - setRightLabel(fakeWideToRealWide(thisPack->getName().c_str())); - //setRightLabel(thisPack->getName().c_str()); + setRightLabel(thisPack->getName().c_str()); } else { switch(nextPackIndex) { - case SKIN_SELECT_PACK_DEFAULT: + case SKIN_SELECT_PACK_DEFAULT: setRightLabel(app.GetString(IDS_NO_SKIN_PACK)); break; - case SKIN_SELECT_PACK_FAVORITES: + case SKIN_SELECT_PACK_FAVORITES: setRightLabel(app.GetString(IDS_FAVORITES_SKIN_PACK)); break; } @@ -1185,18 +1172,16 @@ void UIScene_SkinSelectMenu::updatePackDisplay() if(previousPackIndex >= SKIN_SELECT_MAX_DEFAULTS) { DLCPack *thisPack = app.m_dlcManager.getPack(previousPackIndex - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); - // Fix the incorrect string type on title to display correctly - setLeftLabel(fakeWideToRealWide(thisPack->getName().c_str())); - //setLeftLabel(thisPack->getName().c_str()); + setLeftLabel(thisPack->getName().c_str()); } else { switch(previousPackIndex) { - case SKIN_SELECT_PACK_DEFAULT: + case SKIN_SELECT_PACK_DEFAULT: setLeftLabel(app.GetString(IDS_NO_SKIN_PACK)); break; - case SKIN_SELECT_PACK_FAVORITES: + case SKIN_SELECT_PACK_FAVORITES: setLeftLabel(app.GetString(IDS_FAVORITES_SKIN_PACK)); break; } diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp index 8ffae6a24..7e056e15b 100644 --- a/Minecraft.Client/Gui.cpp +++ b/Minecraft.Client/Gui.cpp @@ -1437,6 +1437,37 @@ void Gui::clearMessages(int iPad) } } +int getVisibleMessageLength(const wstring& _string) { + int visibleMessageLength = 0; + bool inHtmlTag = false; + + for (wchar_t _char : _string) { + if (_char == L'<') inHtmlTag = true; + if (_char == L'>') inHtmlTag = false; + + if (!inHtmlTag) visibleMessageLength++; + } + + return visibleMessageLength; +} + +int getVisibleIndexToRaw(const wstring& _string, size_t target) { + int visibleMessageLength = 0; + bool inHtmlTag = false; + + for (size_t i = 0; i < _string.size(); i++) { + if (_string[i] == L'<') inHtmlTag = true; + if (_string[i] == L'>') inHtmlTag = false; + + if (!inHtmlTag) { + if (visibleMessageLength == target) return i; + + visibleMessageLength++; + } + } + return _string.size(); +} + void Gui::addMessage(const wstring& _string,int iPad,bool bIsDeathMessage) { @@ -1517,15 +1548,11 @@ void Gui::addMessage(const wstring& _string,int iPad,bool bIsDeathMessage) break; } - - while (string.length() > maximumChars) + while (getVisibleMessageLength(string) > maximumChars) { - unsigned int i = 1; - while (i < string.length() && (i + 1) <= maximumChars) - { - i++; - } - size_t iLast=string.find_last_of(L" ",i); + size_t cutOffset = getVisibleIndexToRaw(string, maximumChars); + + size_t iLast=string.find_last_of(L" ", cutOffset); switch(XGetLanguage()) { case XC_LANGUAGE_JAPANESE: @@ -1534,12 +1561,12 @@ void Gui::addMessage(const wstring& _string,int iPad,bool bIsDeathMessage) iLast = maximumChars; break; default: - iLast=string.find_last_of(L" ",i); + iLast=string.find_last_of(L" ", cutOffset); break; } // if a space was found, include the space on this line - if(iLast!=i) + if(iLast!=cutOffset) { iLast++; } diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index f8493dded..d04bdc785 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1553,6 +1553,9 @@ void Minecraft::run_middle() localplayers[i]->ullButtonsPressed|=1LL<ullButtonsPressed|=1LL<thirdPersonView = !options->thirdPersonView; } +#ifdef _WINDOWS64 + if(player->ullButtonsPressed&(1LL<ullButtonsPressed&(1LL<isInputAllowed(MINECRAFT_ACTION_GAME_INFO)) { ui.NavigateToScene(iPad,eUIScene_InGameInfoMenu); diff --git a/Minecraft.Client/ServerPlayer.cpp b/Minecraft.Client/ServerPlayer.cpp index 883047fca..6738360ab 100644 --- a/Minecraft.Client/ServerPlayer.cpp +++ b/Minecraft.Client/ServerPlayer.cpp @@ -8,6 +8,9 @@ #include "Settings.h" #include "PlayerList.h" #include "MultiPlayerLevel.h" +#include "Minecraft.h" +#include "Common/Audio/SoundEngine.h" +#include "../Minecraft.World/SoundTypes.h" #include "../Minecraft.World/net.minecraft.network.packet.h" #include "../Minecraft.World/net.minecraft.world.damagesource.h" @@ -783,6 +786,13 @@ void ServerPlayer::changeDimension(int i) // 4J: Removed on the advice of the mighty King of Achievments (JV) // awardStat(GenericStats::portal(), GenericStats::param_portal()); } + // play the travel whoosh right before the actual dimension swap + Minecraft *mc = Minecraft::GetInstance(); + if (mc != nullptr && mc->soundEngine != nullptr) + { + mc->soundEngine->playUI(eSoundType_PORTAL_TRAVEL, 1, 1.0f); + } + server->getPlayers()->toggleDimension( dynamic_pointer_cast(shared_from_this()), i); lastSentExp = -1; lastSentHealth = -1; diff --git a/Minecraft.Client/Windows64/KeyboardMouseInput.h b/Minecraft.Client/Windows64/KeyboardMouseInput.h index e8b5f5888..9b25c929d 100644 --- a/Minecraft.Client/Windows64/KeyboardMouseInput.h +++ b/Minecraft.Client/Windows64/KeyboardMouseInput.h @@ -36,8 +36,6 @@ public: static const int KEY_DEBUG_CONSOLE = VK_F6; static const int KEY_HOST_SETTINGS = VK_TAB; static const int KEY_FULLSCREEN = VK_F11; - - // todo: implement and shi static const int KEY_SCREENSHOT = VK_F2; void Init();