From 744048f4551af13a0281a78d5136223810a588fb Mon Sep 17 00:00:00 2001 From: DrPerkyLegit <116128211+DrPerkyLegit@users.noreply.github.com> Date: Sun, 12 Apr 2026 23:48:08 -0400 Subject: [PATCH 01/11] Better Text Scaling (#1494) * f3 menu text scaling * Reduce overscaling above 1080p Restores original scaling for 1440p to try and keep the text size more sane on high DPI monitors --------- Co-authored-by: Loki Rautio --- Minecraft.Client/Gui.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp index 5e3a954f..a01cad89 100644 --- a/Minecraft.Client/Gui.cpp +++ b/Minecraft.Client/Gui.cpp @@ -1208,7 +1208,20 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) // Disable the depth test so the text shows on top of the paperdoll glDisable(GL_DEPTH_TEST); +#ifdef _WINDOWS64 + float scaleWidth = (g_rScreenWidth / 1920.0f); + float scaleHeight = (g_rScreenHeight / 1080.0f); + float scale = min(scaleWidth, scaleHeight); //stop stretching + + if (scale < 0.5f) scale = 0.5f; // force minimum scale + if (scale > 1.2f) // resolutions over 1296 pixels tall + { + scale = scale - 0.33f; // tame overscaling on 1440p + } + + glScalef(scale, scale, 1); +#endif // Loop through the lines and draw them all on screen int yPos = debugTop; for (const auto &line : lines) @@ -1217,6 +1230,9 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) yPos += 10; } +#ifdef _WINDOWS64 + glScalef(1, 1, 1); +#endif // Restore the depth test glEnable(GL_DEPTH_TEST); From c7014f6b18b042b3a6af2b5408b5eef6aa74f0ea Mon Sep 17 00:00:00 2001 From: DrPerkyLegit <116128211+DrPerkyLegit@users.noreply.github.com> Date: Sun, 12 Apr 2026 23:50:16 -0400 Subject: [PATCH 02/11] feat: Scrollable chat (#1493) * chat scrolling * allow escape to close chat instead of opening pause --- Minecraft.Client/ChatScreen.cpp | 18 ++++++++++++ Minecraft.Client/ChatScreen.h | 4 +++ Minecraft.Client/Common/UI/UIController.cpp | 4 +++ Minecraft.Client/Common/UI/UIScene_HUD.cpp | 31 ++++++++++++++++----- Minecraft.Client/Gui.h | 1 + Minecraft.Client/Minecraft.cpp | 8 ++++-- Minecraft.Client/Screen.cpp | 2 +- 7 files changed, 58 insertions(+), 10 deletions(-) diff --git a/Minecraft.Client/ChatScreen.cpp b/Minecraft.Client/ChatScreen.cpp index 53c90722..cb1d875d 100644 --- a/Minecraft.Client/ChatScreen.cpp +++ b/Minecraft.Client/ChatScreen.cpp @@ -11,6 +11,7 @@ const wstring ChatScreen::allowedChars = SharedConstants::acceptableLetters; vector ChatScreen::s_chatHistory; int ChatScreen::s_historyIndex = -1; wstring ChatScreen::s_historyDraft; +int ChatScreen::s_chatIndex = 0; bool ChatScreen::isAllowedChatChar(wchar_t c) { @@ -22,6 +23,8 @@ ChatScreen::ChatScreen() frame = 0; cursorIndex = 0; s_historyIndex = -1; + + ChatScreen::s_chatIndex = 0; } void ChatScreen::init() @@ -83,6 +86,20 @@ void ChatScreen::handleHistoryDown() applyHistoryMessage(); } +int ChatScreen::getChatIndex() +{ + return ChatScreen::s_chatIndex; +} + +void ChatScreen::correctChatIndex(int newChatIndex) { + ChatScreen::s_chatIndex = newChatIndex; +} + +void ChatScreen::setWheelValue(int wheel) { + ChatScreen::s_chatIndex += wheel; + if (ChatScreen::s_chatIndex < 0) ChatScreen::s_chatIndex = 0; +} + void ChatScreen::keyPressed(wchar_t ch, int eventKey) { if (eventKey == Keyboard::KEY_ESCAPE) @@ -131,6 +148,7 @@ void ChatScreen::keyPressed(wchar_t ch, int eventKey) cursorIndex--; return; } + if (isAllowedChatChar(ch) && static_cast(message.length()) < SharedConstants::maxChatLength) { message.insert(cursorIndex, 1, ch); diff --git a/Minecraft.Client/ChatScreen.h b/Minecraft.Client/ChatScreen.h index c4e37a93..70d65e8c 100644 --- a/Minecraft.Client/ChatScreen.h +++ b/Minecraft.Client/ChatScreen.h @@ -16,6 +16,7 @@ private: static std::vector s_chatHistory; static int s_historyIndex; static wstring s_historyDraft; + static int s_chatIndex; static const wstring allowedChars; static bool isAllowedChatChar(wchar_t c); @@ -28,6 +29,9 @@ public: virtual void handleHistoryUp(); virtual void handleHistoryDown(); + static int getChatIndex(); + static void correctChatIndex(int newChatIndex); + static void setWheelValue(int wheel); protected: void keyPressed(wchar_t ch, int eventKey); public: diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index b12ea5e7..046acefe 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "UIController.h" +#include #include "UI.h" #include "UIScene.h" #include "UIControl_Slider.h" @@ -1428,6 +1429,9 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key) } #endif + if (key == 4) ChatScreen::setWheelValue(1); + if (key == 5) ChatScreen::setWheelValue(-1); + if(pressed) app.DebugPrintf("Pressed %d\n",key); if(released) app.DebugPrintf("Released %d\n",key); // Repeat handling diff --git a/Minecraft.Client/Common/UI/UIScene_HUD.cpp b/Minecraft.Client/Common/UI/UIScene_HUD.cpp index 213caa8d..7d34ba0d 100644 --- a/Minecraft.Client/Common/UI/UIScene_HUD.cpp +++ b/Minecraft.Client/Common/UI/UIScene_HUD.cpp @@ -9,6 +9,7 @@ #include "..\..\EnderDragonRenderer.h" #include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h" #include "..\..\..\Minecraft.World\StringHelpers.h" +#include UIScene_HUD::UIScene_HUD(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) { @@ -761,16 +762,31 @@ void UIScene_HUD::render(S32 width, S32 height, C4JRender::eViewportType viewpor void UIScene_HUD::handleTimerComplete(int id) { Minecraft *pMinecraft = Minecraft::GetInstance(); + bool isChatOpen = (dynamic_cast(pMinecraft->getScreen()) != nullptr); bool anyVisible = false; if(pMinecraft->localplayers[m_iPad]!= nullptr) { Gui *pGui = pMinecraft->gui; - //DWORD messagesToDisplay = min( CHAT_LINES_COUNT, pGui->getMessagesCount(m_iPad) ); - for( unsigned int i = 0; i < CHAT_LINES_COUNT; ++i ) + DWORD totalMessages = pGui->getMessagesCount(m_iPad); + DWORD messagesToDisplay = min( CHAT_LINES_COUNT, totalMessages); + DWORD maxScroll = max(0, totalMessages - messagesToDisplay); + + bool canScroll = messagesToDisplay < totalMessages; + int startIndex = (canScroll && isChatOpen ? ChatScreen::getChatIndex() : 0); + + if (startIndex > maxScroll) { + ChatScreen::correctChatIndex(maxScroll); + startIndex = maxScroll; + } + + app.DebugPrintf("handleTimerComplete: %d | %d | %d\n", maxScroll, startIndex, totalMessages); + + for( unsigned int i = 0; i < messagesToDisplay; ++i ) { - float opacity = pGui->getOpacity(m_iPad, i); - if( opacity > 0 ) + unsigned int msgIndex = startIndex + i; + float opacity = pGui->getOpacity(m_iPad, msgIndex); + if( opacity > 0 || isChatOpen) { #if 0 // def _WINDOWS64 // Use Iggy chat until Gui::render has visual parity // Chat drawn by Gui::render with color codes. Hides Iggy chat to avoid double chats. @@ -778,9 +794,10 @@ void UIScene_HUD::handleTimerComplete(int id) m_labelChatText[i].setOpacity(0); m_labelChatText[i].setLabel(L""); #else - m_controlLabelBackground[i].setOpacity(opacity); - m_labelChatText[i].setOpacity(opacity); - m_labelChatText[i].setLabel( pGui->getMessagesCount(m_iPad) ? pGui->getMessage(m_iPad,i) : L"" ); + + m_controlLabelBackground[i].setOpacity((isChatOpen ? 1 : opacity)); + m_labelChatText[i].setOpacity((isChatOpen ? 1 : opacity)); + m_labelChatText[i].setLabel(pGui->getMessage(m_iPad, msgIndex)); #endif anyVisible = true; } diff --git a/Minecraft.Client/Gui.h b/Minecraft.Client/Gui.h index 64b8dfbe..440d4e5b 100644 --- a/Minecraft.Client/Gui.h +++ b/Minecraft.Client/Gui.h @@ -17,6 +17,7 @@ private: static const int m_iMaxMessageWidth = 280; static ItemRenderer *itemRenderer; vector guiMessages[XUSER_MAX_COUNT]; + int chatIndex = 0; Random *random; Minecraft *minecraft; diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 1ba432fd..10167f95 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1537,8 +1537,12 @@ void Minecraft::run_middle() // Utility keys always work regardless of KBM active state if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_PAUSE) && !ui.GetMenuDisplayed(i)) { - localplayers[i]->ullButtonsPressed|=1LL<(getScreen()) != nullptr) { + setScreen(nullptr); + } else { + localplayers[i]->ullButtonsPressed|=1LL< Date: Sun, 12 Apr 2026 23:50:46 -0400 Subject: [PATCH 03/11] fix: Increase entity network limit to 16k entities (#1492) --- Minecraft.Client/EntityTracker.cpp | 2 +- Minecraft.Client/ServerPlayer.cpp | 4 +-- Minecraft.Server/cmake/sources/Common.cmake | 1 + Minecraft.World/Entity.cpp | 34 ++++++++++++--------- Minecraft.World/Entity.h | 9 ++++-- Minecraft.World/MoveEntityPacket.cpp | 2 +- Minecraft.World/MoveEntityPacketSmall.cpp | 10 +++--- 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/Minecraft.Client/EntityTracker.cpp b/Minecraft.Client/EntityTracker.cpp index 087227e7..6f482b60 100644 --- a/Minecraft.Client/EntityTracker.cpp +++ b/Minecraft.Client/EntityTracker.cpp @@ -81,7 +81,7 @@ void EntityTracker::addEntity(shared_ptr e, int range, int updateInterva { assert(false); // Entity already tracked } - if( e->entityId >= 2048 ) + if( e->entityId >= 16384 ) { __debugbreak(); } diff --git a/Minecraft.Client/ServerPlayer.cpp b/Minecraft.Client/ServerPlayer.cpp index f57e8a3c..41f74af5 100644 --- a/Minecraft.Client/ServerPlayer.cpp +++ b/Minecraft.Client/ServerPlayer.cpp @@ -147,12 +147,12 @@ void ServerPlayer::flagEntitiesToBeRemoved(unsigned int *flags, bool *removedFou { *removedFound = true; // before this left 192 bytes uninitialized!!!!! - memset(flags, 0, (2048 / 32) * sizeof(unsigned int)); + memset(flags, 0, (16384 / 32) * sizeof(unsigned int)); } for(int index : entitiesToRemove) { - if( index < 2048 ) + if( index < 16384 ) { unsigned int i = index / 32; unsigned int j = index % 32; diff --git a/Minecraft.Server/cmake/sources/Common.cmake b/Minecraft.Server/cmake/sources/Common.cmake index 1eaceee1..58ae26ce 100644 --- a/Minecraft.Server/cmake/sources/Common.cmake +++ b/Minecraft.Server/cmake/sources/Common.cmake @@ -494,6 +494,7 @@ set(_MINECRAFT_SERVER_COMMON_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.Client/iob_shim.asm" "${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.Client/stdafx.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.Client/stubs.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/Entity.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/ConsoleSaveFileOriginal.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/ConsoleSaveFileOriginal.h" "${CMAKE_CURRENT_SOURCE_DIR}/../include/lce_filesystem/lce_filesystem.cpp" diff --git a/Minecraft.World/Entity.cpp b/Minecraft.World/Entity.cpp index 924312e5..6e275a2c 100644 --- a/Minecraft.World/Entity.cpp +++ b/Minecraft.World/Entity.cpp @@ -27,13 +27,17 @@ const wstring Entity::RIDING_TAG = L"Riding"; -int Entity::entityCounter = 2048; // 4J - changed initialiser to 2048, as we are using range 0 - 2047 as special unique smaller ids for things that need network tracked +//int Entity::entityCounter = 2048; // 4J - changed initialiser to 2048, as we are using range 0 - 2047 as special unique smaller ids for things that need network tracked +int Entity::entityCounter = 16384; //now using full range of 0 - 16383, limit is 32k but we shouldnt need that yet DWORD Entity::tlsIdx = TlsAlloc(); // 4J - added getSmallId & freeSmallId methods -unsigned int Entity::entityIdUsedFlags[2048/32] = {0}; -unsigned int Entity::entityIdWanderFlags[2048/32] = {0}; -unsigned int Entity::entityIdRemovingFlags[2048/32] = {0}; +//unsigned int Entity::entityIdUsedFlags[2048/32] = {0}; +//unsigned int Entity::entityIdWanderFlags[2048/32] = {0}; +//unsigned int Entity::entityIdRemovingFlags[2048/32] = {0}; +unsigned int Entity::entityIdUsedFlags[16384/32] = {0}; +unsigned int Entity::entityIdWanderFlags[16384/32] = {0}; +unsigned int Entity::entityIdRemovingFlags[16384/32] = {0}; int Entity::extraWanderIds[EXTRA_WANDER_MAX] = {0}; int Entity::extraWanderTicks = 0; int Entity::extraWanderCount = 0; @@ -65,7 +69,7 @@ int Entity::getSmallId() } } - for( int i = 0; i < (2048 / 32 ); i++ ) + for( int i = 0; i < (16384 / 32 ); i++ ) { unsigned int uiFlags = *puiUsedFlags; if( uiFlags != 0xffffffff ) @@ -102,7 +106,7 @@ int Entity::getSmallId() if (entityCounter == 0x7ffffff) { - entityCounter = 2048; + entityCounter = 16384; } return fallbackId; #else @@ -116,7 +120,7 @@ void Entity::countFlagsForPIX() { int freecount = 0; unsigned int *puiUsedFlags = entityIdUsedFlags; - for( int i = 0; i < (2048 / 32 ); i++ ) + for( int i = 0; i < (16384 / 32 ); i++ ) { unsigned int uiFlags = *puiUsedFlags; if( uiFlags != 0xffffffff ) @@ -134,7 +138,7 @@ void Entity::countFlagsForPIX() puiUsedFlags++; } PIXAddNamedCounter(freecount,"Small Ids free"); - PIXAddNamedCounter(2048 - freecount,"Small Ids used"); + PIXAddNamedCounter(16384 - freecount,"Small Ids used"); } void Entity::resetSmallId() @@ -149,7 +153,7 @@ void Entity::resetSmallId() void Entity::freeSmallId(int index) { if( ( (size_t)TlsGetValue(tlsIdx) ) == 0 ) return; // Don't do anything with small ids if this isn't the server thread - if( index >= 2048 ) return; // Don't do anything if this isn't a short id + if( index >= 16384 ) return; // Don't do anything if this isn't a short id unsigned int i = index / 32; unsigned int j = index % 32; @@ -172,7 +176,7 @@ void Entity::useSmallIds() void Entity::considerForExtraWandering(bool enable) { if( ( (size_t)TlsGetValue(tlsIdx) ) == 0 ) return; // Don't do anything with small ids if this isn't the server thread - if( entityId >= 2048 ) return; // Don't do anything if this isn't a short id + if( entityId >= 16384 ) return; // Don't do anything if this isn't a short id unsigned int i = entityId / 32; unsigned int j = entityId % 32; @@ -192,7 +196,7 @@ void Entity::considerForExtraWandering(bool enable) bool Entity::isExtraWanderingEnabled() { if( ( (size_t)TlsGetValue(tlsIdx) ) == 0 ) return false; // Don't do anything with small ids if this isn't the server thread - if( entityId >= 2048 ) return false; // Don't do anything if this isn't a short id + if( entityId >= 16384 ) return false; // Don't do anything if this isn't a short id for( int i = 0; i < extraWanderCount; i++ ) { @@ -224,12 +228,12 @@ void Entity::tickExtraWandering() int entityId = 0; if( extraWanderCount ) { - entityId = ( extraWanderIds[ extraWanderCount - 1 ] + 1 ) % 2048; + entityId = ( extraWanderIds[ extraWanderCount - 1 ] + 1 ) % 16384; } extraWanderCount = 0; - for( int k = 0; ( k < 2048 ) && ( extraWanderCount < EXTRA_WANDER_MAX); k++ ) + for( int k = 0; ( k < 16384 ) && ( extraWanderCount < EXTRA_WANDER_MAX); k++ ) { unsigned int i = entityId / 32; unsigned int j = entityId % 32; @@ -241,7 +245,7 @@ void Entity::tickExtraWandering() // printf("%d, ", entityId); } - entityId = ( entityId + 1 ) % 2048; + entityId = ( entityId + 1 ) % 16384; } // printf("\n"); } @@ -261,7 +265,7 @@ void Entity::_init(bool useSmallId, Level *level) else { entityId = Entity::entityCounter++; - if(entityCounter == 0x7ffffff ) entityCounter = 2048; + if(entityCounter == 0x7ffffff ) entityCounter = 16384; } viewScale = 1.0; diff --git a/Minecraft.World/Entity.h b/Minecraft.World/Entity.h index a738c2ba..9fb0f548 100644 --- a/Minecraft.World/Entity.h +++ b/Minecraft.World/Entity.h @@ -382,9 +382,12 @@ private: int getSmallId(); void freeSmallId(int index); - static unsigned int entityIdUsedFlags[2048/32]; - static unsigned int entityIdWanderFlags[2048/32]; - static unsigned int entityIdRemovingFlags[2048/32]; + //static unsigned int entityIdUsedFlags[2048/32]; + //static unsigned int entityIdWanderFlags[2048/32]; + //static unsigned int entityIdRemovingFlags[2048/32]; + static unsigned int entityIdUsedFlags[16384/32]; + static unsigned int entityIdWanderFlags[16384/32]; + static unsigned int entityIdRemovingFlags[16384/32]; static int extraWanderIds[EXTRA_WANDER_MAX]; static int extraWanderCount; static int extraWanderTicks; diff --git a/Minecraft.World/MoveEntityPacket.cpp b/Minecraft.World/MoveEntityPacket.cpp index cae28e91..aef9e621 100644 --- a/Minecraft.World/MoveEntityPacket.cpp +++ b/Minecraft.World/MoveEntityPacket.cpp @@ -35,7 +35,7 @@ void MoveEntityPacket::read(DataInputStream *dis) //throws IOException void MoveEntityPacket::write(DataOutputStream *dos) //throws IOException { - if( (id < 0 ) || (id >= 2048 ) ) + if( (id < 0 ) || (id >= 16384 ) ) { // We shouln't be tracking an entity that doesn't have a short type of id __debugbreak(); diff --git a/Minecraft.World/MoveEntityPacketSmall.cpp b/Minecraft.World/MoveEntityPacketSmall.cpp index ec67f37f..7d91a15d 100644 --- a/Minecraft.World/MoveEntityPacketSmall.cpp +++ b/Minecraft.World/MoveEntityPacketSmall.cpp @@ -19,7 +19,7 @@ MoveEntityPacketSmall::MoveEntityPacketSmall() MoveEntityPacketSmall::MoveEntityPacketSmall(int id) { - if( (id < 0 ) || (id >= 2048 ) ) + if( (id < 0 ) || (id >= 16384 ) ) { // We shouln't be tracking an entity that doesn't have a short type of id __debugbreak(); @@ -42,7 +42,7 @@ void MoveEntityPacketSmall::read(DataInputStream *dis) //throws IOException void MoveEntityPacketSmall::write(DataOutputStream *dos) //throws IOException { - if( (id < 0 ) || (id >= 2048 ) ) + if( (id < 0 ) || (id >= 16384 ) ) { // We shouln't be tracking an entity that doesn't have a short type of id __debugbreak(); @@ -99,7 +99,7 @@ void MoveEntityPacketSmall::PosRot::read(DataInputStream *dis) //throws IOExcept void MoveEntityPacketSmall::PosRot::write(DataOutputStream *dos) //throws IOException { - if( (id < 0 ) || (id >= 2048 ) ) + if( (id < 0 ) || (id >= 16384 ) ) { // We shouln't be tracking an entity that doesn't have a short type of id __debugbreak(); @@ -138,7 +138,7 @@ void MoveEntityPacketSmall::Pos::read(DataInputStream *dis) //throws IOException void MoveEntityPacketSmall::Pos::write(DataOutputStream *dos) //throws IOException { - if( (id < 0 ) || (id >= 2048 ) ) + if( (id < 0 ) || (id >= 16384 ) ) { // We shouln't be tracking an entity that doesn't have a short type of id __debugbreak(); @@ -176,7 +176,7 @@ void MoveEntityPacketSmall::Rot::read(DataInputStream *dis) //throws IOException void MoveEntityPacketSmall::Rot::write(DataOutputStream *dos) //throws IOException { - if( (id < 0 ) || (id >= 2048 ) ) + if( (id < 0 ) || (id >= 16384 ) ) { // We shouln't be tracking an entity that doesn't have a short type of id __debugbreak(); From 9e6e3de33807358f33a9d3a4dbb5c1e3c11830f7 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 13 Apr 2026 04:52:34 +0100 Subject: [PATCH 04/11] Improve actions file ignore rules (#1491) * Add clang-format workflow for pull request checks * Modify push paths in nightly workflow Updated paths for push event to include all files except specified ones. * Update paths for nightly-server workflow triggers * Modify paths for pull request triggers Update pull request workflow to include specific paths. * Remove formatting check workflow --- .github/workflows/nightly-server.yml | 11 ++++++----- .github/workflows/nightly.yml | 11 ++++++----- .github/workflows/pull-request.yml | 10 ++++++---- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/.github/workflows/nightly-server.yml b/.github/workflows/nightly-server.yml index 5450de9a..0fc20eb1 100644 --- a/.github/workflows/nightly-server.yml +++ b/.github/workflows/nightly-server.yml @@ -5,11 +5,12 @@ on: push: branches: - 'main' - paths-ignore: - - '.gitignore' - - '*.md' - - '.github/**' - - '!.github/workflows/nightly-server.yml' + paths: + - '**' + - '!.gitignore' + - '!*.md' + - '!.github/**' + - '.github/workflows/nightly-server.yml' permissions: contents: write diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 789db3e8..a5b53be0 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -5,11 +5,12 @@ on: push: branches: - 'main' - paths-ignore: - - '.gitignore' - - '*.md' - - '.github/**' - - '!.github/workflows/nightly.yml' + paths: + - '**' + - '!.gitignore' + - '!*.md' + - '!.github/**' + - '.github/workflows/nightly.yml' permissions: contents: write diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 9d57f4b4..3b5398a0 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -4,10 +4,12 @@ on: workflow_dispatch: pull_request: types: [opened, reopened, synchronize] - paths-ignore: - - '.gitignore' - - '*.md' - - '.github/*.md' + paths: + - '**' + - '!.gitignore' + - '!*.md' + - '!.github/**' + - '.github/workflows/pull-request.yml' jobs: build: From e730033bcc13c6b9b257680ae36108cdbb53cadd Mon Sep 17 00:00:00 2001 From: "Us3ful\"-Dev" Date: Mon, 13 Apr 2026 05:53:39 +0200 Subject: [PATCH 05/11] fix: Prevent end poem crash (#1489) Removed player name check that always fails to work on non host instances --- Minecraft.Client/Common/UI/UIScene_EndPoem.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Minecraft.Client/Common/UI/UIScene_EndPoem.cpp b/Minecraft.Client/Common/UI/UIScene_EndPoem.cpp index 5b10e8cf..6ca6abb1 100644 --- a/Minecraft.Client/Common/UI/UIScene_EndPoem.cpp +++ b/Minecraft.Client/Common/UI/UIScene_EndPoem.cpp @@ -50,14 +50,7 @@ UIScene_EndPoem::UIScene_EndPoem(int iPad, void *initData, UILayer *parentLayer) Minecraft *pMinecraft = Minecraft::GetInstance(); wstring playerName = L""; - if(pMinecraft->localplayers[ui.GetWinUserIndex()] != nullptr) - { - playerName = escapeXML( pMinecraft->localplayers[ui.GetWinUserIndex()]->getDisplayName() ); - } - else - { - playerName = escapeXML( pMinecraft->localplayers[ProfileManager.GetPrimaryPad()]->getDisplayName() ); - } + playerName = escapeXML( pMinecraft->localplayers[ProfileManager.GetPrimaryPad()]->getDisplayName() ); noNoiseString = replaceAll(noNoiseString,L"{*PLAYER*}",playerName); Random random(8124371); From e5ce9a06cdcd25a7bd1155160a2a95f1a48998fc Mon Sep 17 00:00:00 2001 From: Botch Date: Sun, 12 Apr 2026 21:55:07 -0600 Subject: [PATCH 06/11] fix: Disable font mipmapping (#1410) Fixes visual artifacts with signs, improving legibility at distances --- Minecraft.Client/Font.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Minecraft.Client/Font.cpp b/Minecraft.Client/Font.cpp index 1040eaa0..ff5b7ef2 100644 --- a/Minecraft.Client/Font.cpp +++ b/Minecraft.Client/Font.cpp @@ -310,6 +310,8 @@ void Font::draw(const wstring &str, bool dropShadow, int initialColor) t->begin(); t->color(currentColor & 0x00ffffff, (currentColor >> 24) & 255); + bool prev = t->setMipmapEnable(false); // Disable mipmapping for fonts, and save previous enabled value to be restored later - Botch + for (int i = 0; i < static_cast(cleanStr.length()); ++i) { // Map character @@ -371,6 +373,8 @@ void Font::draw(const wstring &str, bool dropShadow, int initialColor) addCharacterQuad(c); } + t->setMipmapEnable(prev); //Reinstates previously used enabled value - Botch + t->end(); } From 050c501786e2a0d8a610cdf82e190889b27287ee Mon Sep 17 00:00:00 2001 From: Toru the Red Fox Date: Mon, 13 Apr 2026 04:56:24 +0100 Subject: [PATCH 07/11] Request dedicated GPU (#850) --- Minecraft.Client/Windows64/Windows64_Minecraft.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index bee49df0..3019c6f2 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -57,6 +57,13 @@ extern Renderer InternalRenderManager; #include "Xbox/resource.h" +// request use of dedicated GPU from AMD and Nvidia drivers +extern "C" +{ + __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; + __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; +} + #ifdef _MSC_VER #pragma comment(lib, "legacy_stdio_definitions.lib") #endif From bfcb621808dc07d7a3fc1f548be28f9620197547 Mon Sep 17 00:00:00 2001 From: GabsPuNs <136205131+GabsPuNs@users.noreply.github.com> Date: Mon, 13 Apr 2026 00:17:21 -0400 Subject: [PATCH 08/11] Exclude more files, reduce build .zip size (#1374) * Fix Sign * Exclude more files from the compilation. * Remove Trial and Tutorial folder in Common, Tutorial world is in windows64media --- Minecraft.Client/CMakeLists.txt | 2 -- Minecraft.Client/cmake/sources/Windows.cmake | 8 -------- cmake/CopyAssets.cmake | 5 ++++- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Minecraft.Client/CMakeLists.txt b/Minecraft.Client/CMakeLists.txt index 9f75efd2..3b029610 100644 --- a/Minecraft.Client/CMakeLists.txt +++ b/Minecraft.Client/CMakeLists.txt @@ -81,8 +81,6 @@ set(ASSET_FOLDER_PAIRS "${CMAKE_CURRENT_SOURCE_DIR}/music" "music" "${CMAKE_CURRENT_SOURCE_DIR}/Common/Media" "Common/Media" "${CMAKE_CURRENT_SOURCE_DIR}/Common/res" "Common/res" - "${CMAKE_CURRENT_SOURCE_DIR}/Common/Trial" "Common/Trial" - "${CMAKE_CURRENT_SOURCE_DIR}/Common/Tutorial" "Common/Tutorial" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}Media" "${PLATFORM_NAME}Media" ) setup_asset_folder_copy(Minecraft.Client "${ASSET_FOLDER_PAIRS}") diff --git a/Minecraft.Client/cmake/sources/Windows.cmake b/Minecraft.Client/cmake/sources/Windows.cmake index 7fc07abd..e07f46e3 100644 --- a/Minecraft.Client/cmake/sources/Windows.cmake +++ b/Minecraft.Client/cmake/sources/Windows.cmake @@ -1,12 +1,5 @@ set(BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Windows64/") -set(_MINECRAFT_CLIENT_WINDOWS_COMMON_RES_AUDIO - "${CMAKE_CURRENT_SOURCE_DIR}/Common/res/audio/minecraft.xsb" - "${CMAKE_CURRENT_SOURCE_DIR}/Common/res/audio/resident.xwb" - "${CMAKE_CURRENT_SOURCE_DIR}/Common/res/audio/streamed.xwb" -) -source_group("Common/res/audio" FILES ${_MINECRAFT_CLIENT_WINDOWS_COMMON_RES_AUDIO}) - set(_MINECRAFT_CLIENT_WINDOWS_COMMON_AUDIO "${CMAKE_CURRENT_SOURCE_DIR}/Common/Audio/SoundEngine.cpp" ) @@ -470,7 +463,6 @@ set(_MINECRAFT_CLIENT_WINDOWS_NET_MINECRAFT_STATS source_group("net/minecraft/stats" FILES ${_MINECRAFT_CLIENT_WINDOWS_NET_MINECRAFT_STATS}) set(MINECRAFT_CLIENT_WINDOWS - ${_MINECRAFT_CLIENT_WINDOWS_COMMON_RES_AUDIO} ${_MINECRAFT_CLIENT_WINDOWS_COMMON_AUDIO} ${_MINECRAFT_CLIENT_WINDOWS_COMMON_NETWORK} ${_MINECRAFT_CLIENT_WINDOWS_COMMON_UI} diff --git a/cmake/CopyAssets.cmake b/cmake/CopyAssets.cmake index a78c9170..3090265e 100644 --- a/cmake/CopyAssets.cmake +++ b/cmake/CopyAssets.cmake @@ -10,12 +10,15 @@ function(setup_asset_folder_copy TARGET_NAME ASSET_FOLDER_PAIRS) "*.swf" # These are built into the .arc "*.resx" "*.loc" "*.wav" # Unsupported audio format - "*.xui" + "*.xui" "*.xgs" + "*.xwb" "*.xsb" + "*.xap" "*.xzp" ) # Global folder exclusions applied to every folder copy set(ASSET_EXCLUDE_FOLDERS "Graphics" + "Gamerules" ) # Exclude platform-specific arc media files From 14f8d793dd7b6ff0d0f992edeb892012d9b4ceef Mon Sep 17 00:00:00 2001 From: DrPerkyLegit <116128211+DrPerkyLegit@users.noreply.github.com> Date: Mon, 13 Apr 2026 00:17:45 -0400 Subject: [PATCH 09/11] Add Chat Formatting Support For Servers (#1483) * add chat support for html formatting * html character serialization, normal color format support * change for chat input handling on color has a bug where the text after the cursor gets stripped of its color, need to make a function to backstep on a string and find the last used color codes, or get all color codes used before the string is split, and apply them to the start of the next string * expose jukebox label as action bar like java * prevent players from sending chat color * restore non styled chat size check --- Minecraft.Client/ChatScreen.cpp | 3 +- Minecraft.Client/ClientConnection.cpp | 31 +++++++-- Minecraft.Client/Common/Consoles_App.cpp | 81 ++++++++++++++++++++++ Minecraft.Client/Common/Consoles_App.h | 4 +- Minecraft.Client/Common/UI/UIScene_HUD.cpp | 2 + Minecraft.Client/Common/UI/UIScene_HUD.h | 2 +- Minecraft.Client/Gui.cpp | 9 ++- Minecraft.Client/Gui.h | 2 + Minecraft.Client/PlayerConnection.cpp | 2 +- Minecraft.World/ChatPacket.h | 1 + Minecraft.World/SharedConstants.h | 3 +- 11 files changed, 128 insertions(+), 12 deletions(-) diff --git a/Minecraft.Client/ChatScreen.cpp b/Minecraft.Client/ChatScreen.cpp index cb1d875d..992ae48d 100644 --- a/Minecraft.Client/ChatScreen.cpp +++ b/Minecraft.Client/ChatScreen.cpp @@ -148,8 +148,7 @@ void ChatScreen::keyPressed(wchar_t ch, int eventKey) cursorIndex--; return; } - - if (isAllowedChatChar(ch) && static_cast(message.length()) < SharedConstants::maxChatLength) + if (isAllowedChatChar(ch) && static_cast(message.length()) < SharedConstants::maxVisibleLength) { message.insert(cursorIndex, 1, ch); cursorIndex++; diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index a80af5d2..603c8a07 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -65,6 +65,7 @@ #include "..\Minecraft.World\DurangoStats.h" #include "..\Minecraft.World\GenericStats.h" #endif +#include ClientConnection::ClientConnection(Minecraft *minecraft, const wstring& ip, int port) { @@ -1546,17 +1547,35 @@ 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""; wstring sourceDisplayName = L""; // On platforms other than Xbox One this just sets display name to gamertag - if (packet->m_stringArgs.size() >= 1) playerDisplayName = GetDisplayNameByGamertag(packet->m_stringArgs[0]); - if (packet->m_stringArgs.size() >= 2) sourceDisplayName = GetDisplayNameByGamertag(packet->m_stringArgs[1]); + if (stringArgsSize >= 1) playerDisplayName = GetDisplayNameByGamertag(packet->m_stringArgs[0]); + if (stringArgsSize >= 2) sourceDisplayName = GetDisplayNameByGamertag(packet->m_stringArgs[1]); switch(packet->m_messageType) { case ChatPacket::e_ChatCustom: - message = (packet->m_stringArgs.size() >= 1) ? packet->m_stringArgs[0] : L""; + case ChatPacket::e_ChatActionBar: + 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"; + } + displayOnGui = (packet->m_messageType == ChatPacket::e_ChatCustom); break; case ChatPacket::e_ChatBedOccupied: message = app.GetString(IDS_TILE_BED_OCCUPIED); @@ -1906,7 +1925,7 @@ void ClientConnection::handleChat(shared_ptr packet) if(replacePlayer) { - message = replaceAll(message,L"{*PLAYER*}",playerDisplayName); + message = replaceAll(message,L"{*PLAYER*}", playerDisplayName); } if(replaceEntitySource) @@ -1941,7 +1960,9 @@ void ClientConnection::handleChat(shared_ptr packet) // flag that a message is a death message bool bIsDeathMessage = (packet->m_messageType>=ChatPacket::e_ChatDeathInFire) && (packet->m_messageType<=ChatPacket::e_ChatDeathIndirectMagicItem); - if( displayOnGui ) minecraft->gui->addMessage(message,m_userIndex, bIsDeathMessage); + if( displayOnGui ) minecraft->gui->addMessage(message, m_userIndex, bIsDeathMessage); + + if (!displayOnGui && !message.empty()) minecraft->gui->setActionBarMessage(message); } void ClientConnection::handleAnimate(shared_ptr packet) diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index 0a2fd159..21b032ce 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -6595,6 +6595,87 @@ wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shado return text; } +//found list of html escapes at https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html +wstring CMinecraftApp::EscapeHTMLString(const wstring& desc) +{ + static std::unordered_map replacementMap = { + {L'&', L"&"}, + {L'<', L"<"}, + {L'>', L">"}, + {L'\"', L"""}, + {L'\'', L"'"}, + }; + + wstring finalString = L""; + for (int i = 0; i < desc.size(); i++) { + wchar_t _char = desc[i]; + auto it = replacementMap.find(_char); + + if (it != replacementMap.end()) finalString += it->second; + else finalString += _char; + } + + return finalString; +} + +wstring CMinecraftApp::FormatChatMessage(const wstring& desc, bool applyColor) +{ + static std::wstring_view colorFormatString = L""; + + wstring results = desc; + wchar_t replacements[64]; + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_0), 0xFFFFFFFF); + results = replaceAll(results, L"§0", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_1), 0xFFFFFFFF); + results = replaceAll(results, L"§1", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_2), 0xFFFFFFFF); + results = replaceAll(results, L"§2", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_3), 0xFFFFFFFF); + results = replaceAll(results, L"§3", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_4), 0xFFFFFFFF); + results = replaceAll(results, L"§4", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_5), 0xFFFFFFFF); + results = replaceAll(results, L"§5", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_6), 0xFFFFFFFF); + results = replaceAll(results, L"§6", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_7), 0xFFFFFFFF); + results = replaceAll(results, L"§7", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_8), 0xFFFFFFFF); + results = replaceAll(results, L"§8", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_9), 0xFFFFFFFF); + results = replaceAll(results, L"§9", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_a), 0xFFFFFFFF); + results = replaceAll(results, L"§a", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_b), 0xFFFFFFFF); + results = replaceAll(results, L"§b", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_c), 0xFFFFFFFF); + results = replaceAll(results, L"§c", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_d), 0xFFFFFFFF); + results = replaceAll(results, L"§d", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_e), 0xFFFFFFFF); + results = replaceAll(results, L"§e", replacements); + + swprintf(replacements, 64, (applyColor ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_f), 0xFFFFFFFF); + results = replaceAll(results, L"§f", replacements); + + return results; +} + wstring CMinecraftApp::GetActionReplacement(int iPad, unsigned char ucAction) { unsigned int input = InputManager.GetGameJoypadMaps(InputManager.GetJoypadMapVal(iPad) ,ucAction); diff --git a/Minecraft.Client/Common/Consoles_App.h b/Minecraft.Client/Common/Consoles_App.h index 0c1c261e..eb59ded8 100644 --- a/Minecraft.Client/Common/Consoles_App.h +++ b/Minecraft.Client/Common/Consoles_App.h @@ -564,7 +564,9 @@ public: int GetHTMLColour(eMinecraftColour colour); int GetHTMLColor(eMinecraftColour colour) { return GetHTMLColour(colour); } int GetHTMLFontSize(EHTMLFontSize size); - wstring FormatHTMLString(int iPad, const wstring &desc, int shadowColour = 0xFFFFFFFF); + wstring FormatHTMLString(int iPad, const wstring& desc, int shadowColour = 0xFFFFFFFF); + wstring EscapeHTMLString(const wstring &desc); + wstring FormatChatMessage(const wstring& desc, bool applyColor = 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 7d34ba0d..04023fb9 100644 --- a/Minecraft.Client/Common/UI/UIScene_HUD.cpp +++ b/Minecraft.Client/Common/UI/UIScene_HUD.cpp @@ -24,8 +24,10 @@ UIScene_HUD::UIScene_HUD(int iPad, void *initData, UILayer *parentLayer) : UISce 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); addTimer(0, 100); } diff --git a/Minecraft.Client/Common/UI/UIScene_HUD.h b/Minecraft.Client/Common/UI/UIScene_HUD.h index 04468c8e..caadb50a 100644 --- a/Minecraft.Client/Common/UI/UIScene_HUD.h +++ b/Minecraft.Client/Common/UI/UIScene_HUD.h @@ -11,7 +11,7 @@ private: bool m_bSplitscreen; protected: - UIControl_Label m_labelChatText[CHAT_LINES_COUNT]; + UIControl_HTMLLabel m_labelChatText[CHAT_LINES_COUNT]; UIControl_Label m_labelJukebox; UIControl m_controlLabelBackground[CHAT_LINES_COUNT]; UIControl_Label m_labelDisplayName; diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp index a01cad89..18257ba4 100644 --- a/Minecraft.Client/Gui.cpp +++ b/Minecraft.Client/Gui.cpp @@ -1591,6 +1591,13 @@ float Gui::getOpacity(int iPad, DWORD index) return opacityPercentage; } +//just like java functionality it overwrites the jukebox label +void Gui::setActionBarMessage(wstring message) +{ + overlayMessageString = message; + overlayMessageTime = 20 * 4; //idk how long it should last, need to check java usage +} + float Gui::getJukeboxOpacity(int iPad) { float t = overlayMessageTime - lastTickA; @@ -1606,7 +1613,7 @@ void Gui::setNowPlaying(const wstring& string) // overlayMessageString = L"Now playing: " + string; overlayMessageString = app.GetString(IDS_NOWPLAYING) + string; overlayMessageTime = 20 * 3; - animateOverlayMessageColor = true; + animateOverlayMessageColor = true; //appears to be unused, @DrPerkyLegit plans to add in later pr } void Gui::displayClientMessage(int messageId, int iPad) diff --git a/Minecraft.Client/Gui.h b/Minecraft.Client/Gui.h index 440d4e5b..527b0237 100644 --- a/Minecraft.Client/Gui.h +++ b/Minecraft.Client/Gui.h @@ -64,6 +64,8 @@ public: wstring getMessage(int iPad, DWORD index) { return guiMessages[iPad].at(index).string; } float getOpacity(int iPad, DWORD index); + void setActionBarMessage(wstring message); //uses jukebox label + wstring getJukeboxMessage(int iPad) { return overlayMessageString; } float getJukeboxOpacity(int iPad); diff --git a/Minecraft.Client/PlayerConnection.cpp b/Minecraft.Client/PlayerConnection.cpp index 1fb7c398..b23b6999 100644 --- a/Minecraft.Client/PlayerConnection.cpp +++ b/Minecraft.Client/PlayerConnection.cpp @@ -679,7 +679,7 @@ void PlayerConnection::handleChat(shared_ptr packet) return; } wstring formatted = L"<" + player->name + L"> " + message; - server->getPlayers()->broadcastAll(shared_ptr(new ChatPacket(formatted))); + server->getPlayers()->broadcastAll(shared_ptr(new ChatPacket(app.FormatChatMessage(formatted, false)))); chatSpamTickCount += SharedConstants::TICKS_PER_SECOND; if (chatSpamTickCount > SharedConstants::TICKS_PER_SECOND * 10) { diff --git a/Minecraft.World/ChatPacket.h b/Minecraft.World/ChatPacket.h index ea9b3806..7ffebc5e 100644 --- a/Minecraft.World/ChatPacket.h +++ b/Minecraft.World/ChatPacket.h @@ -98,6 +98,7 @@ public: e_ChatCommandTeleportMe, e_ChatCommandTeleportToMe, + e_ChatActionBar, }; public: diff --git a/Minecraft.World/SharedConstants.h b/Minecraft.World/SharedConstants.h index a8924e47..c4db88ae 100644 --- a/Minecraft.World/SharedConstants.h +++ b/Minecraft.World/SharedConstants.h @@ -20,7 +20,8 @@ class SharedConstants static wstring readAcceptableChars(); public: - static const int maxChatLength = 100; + static const int maxChatLength = 255; + static const int maxVisibleLength = 100; //to be changed static wstring acceptableLetters; static const int ILLEGAL_FILE_CHARACTERS_LENGTH = 15; From 2d417110551444f7e06430709c6d22e9a8ae890f Mon Sep 17 00:00:00 2001 From: Tyler Reese Date: Sun, 12 Apr 2026 21:22:14 -0700 Subject: [PATCH 10/11] fix: Prevent contextually wrong music from playing (#1138) --- Minecraft.Client/Common/Audio/SoundEngine.cpp | 36 +++++++++++++------ Minecraft.Client/Common/Audio/SoundEngine.h | 12 ++++--- Minecraft.Client/Common/Consoles_App.cpp | 2 +- Minecraft.Client/Common/UI/UIController.cpp | 2 +- Minecraft.Client/DLCTexturePack.cpp | 3 +- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/Minecraft.Client/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Common/Audio/SoundEngine.cpp index cf140c78..80383958 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Common/Audio/SoundEngine.cpp @@ -114,7 +114,9 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]= "hal4", "nuance1", "nuance2", - + "piano1", + "piano2", + "piano3", #ifndef _XBOX "creative1", "creative2", @@ -127,11 +129,6 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]= "menu3", "menu4", #endif - - "piano1", - "piano2", - "piano3", - // Nether "nether1", "nether2", @@ -191,7 +188,7 @@ void SoundEngine::init(Options* pOptions) return; } -void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1) +void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1, int iCreativeMin, int iCreativeMax, int iMenuMin, int iMenuMax) { m_iStream_Overworld_Min=iOverworldMin; m_iStream_Overworld_Max=iOverWorldMax; @@ -199,6 +196,10 @@ void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int i m_iStream_Nether_Max=iNetherMax; m_iStream_End_Min=iEndMin; m_iStream_End_Max=iEndMax; + m_iStream_Creative_Min=iCreativeMin; + m_iStream_Creative_Max=iCreativeMax; + m_iStream_Menu_Min=iMenuMin; + m_iStream_Menu_Max=iMenuMax; m_iStream_CD_1=iCD1; // array to monitor recently played tracks @@ -407,7 +408,7 @@ SoundEngine::SoundEngine() SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, eStream_Nether1,eStream_Nether4, eStream_end_dragon,eStream_end_end, - eStream_CD_1); + eStream_CD_1, eStream_Overworld_Creative1, eStream_Overworld_Creative6, eStream_Overworld_Menu1, eStream_Overworld_Menu4); m_musicID=getMusicID(LevelData::DIMENSION_OVERWORLD); @@ -800,7 +801,16 @@ int SoundEngine::getMusicID(int iDomain) if(pMinecraft==nullptr) { // any track from the overworld - return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max); + return GetRandomishTrack(m_iStream_Menu_Min,m_iStream_Menu_Max); + } + + int localPlayerIdx = pMinecraft->getLocalPlayerIdx(); + std::shared_ptr localPlayer = pMinecraft->localplayers[localPlayerIdx]; + + if (localPlayer == nullptr) + { + // any track from the overworld + return GetRandomishTrack(m_iStream_Menu_Min,m_iStream_Menu_Max); } if(pMinecraft->skins->isUsingDefaultSkin()) @@ -814,7 +824,13 @@ int SoundEngine::getMusicID(int iDomain) return GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max); //return m_iStream_Nether_Min + random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min); default: //overworld + GameType* gt = Player::getPlayerGamePrivilege(localPlayer->getAllPlayerGamePrivileges(), Player::ePlayerGamePrivilege_CreativeMode) ? GameType::CREATIVE : GameType::SURVIVAL; //return m_iStream_Overworld_Min + random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min); + + if (gt == GameType::CREATIVE) + { + return GetRandomishTrack(m_iStream_Creative_Min,m_iStream_Creative_Max); + } return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max); } } @@ -829,7 +845,7 @@ int SoundEngine::getMusicID(int iDomain) //return m_iStream_Nether_Min + random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min); return GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max); default: //overworld - //return m_iStream_Overworld_Min + random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min); + //Mash-ups don't have special ranges. return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max); } } diff --git a/Minecraft.Client/Common/Audio/SoundEngine.h b/Minecraft.Client/Common/Audio/SoundEngine.h index 38d70d41..5c71ef67 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.h +++ b/Minecraft.Client/Common/Audio/SoundEngine.h @@ -23,6 +23,10 @@ enum eMUSICFILES eStream_Overworld_hal4, eStream_Overworld_nuance1, eStream_Overworld_nuance2, + //Moved these to separate + eStream_Overworld_piano1, + eStream_Overworld_piano2, + eStream_Overworld_piano3, // <-- make piano3 the last overworld one #ifndef _XBOX // Add the new music tracks eStream_Overworld_Creative1, @@ -36,9 +40,7 @@ enum eMUSICFILES eStream_Overworld_Menu3, eStream_Overworld_Menu4, #endif - eStream_Overworld_piano1, - eStream_Overworld_piano2, - eStream_Overworld_piano3, // <-- make piano3 the last overworld one + // Nether eStream_Nether1, eStream_Nether2, @@ -134,7 +136,7 @@ public: bool isStreamingWavebankReady(); // 4J Added int getMusicID(int iDomain); int getMusicID(const wstring& name); - void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1); + void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1, int iCreativeMin, int iCreativeMax, int iMenuMin, int iMenuMax); void updateMiniAudio(); void playMusicUpdate(); @@ -185,6 +187,8 @@ private: int m_iStream_Nether_Min,m_iStream_Nether_Max; int m_iStream_End_Min,m_iStream_End_Max; int m_iStream_CD_1; + int m_iStream_Creative_Min,m_iStream_Creative_Max; + int m_iStream_Menu_Min,m_iStream_Menu_Max; bool *m_bHeardTrackA; #ifdef __ORBIS__ diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index 21b032ce..d145c0bf 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -3778,7 +3778,7 @@ void CMinecraftApp::HandleXuiActions(void) pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, eStream_Nether1,eStream_Nether4, eStream_end_dragon,eStream_end_end, - eStream_CD_1); + eStream_CD_1, eStream_Overworld_Creative1, eStream_Overworld_Creative6, eStream_Overworld_Menu1, eStream_Overworld_Menu4); #endif pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index 046acefe..fe6e425b 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -2071,7 +2071,7 @@ void UIController::NavigateToHomeMenu() pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, eStream_Nether1,eStream_Nether4, eStream_end_dragon,eStream_end_end, - eStream_CD_1); + eStream_CD_1, eStream_Overworld_Creative1, eStream_Overworld_Creative6, eStream_Overworld_Menu1, eStream_Overworld_Menu4); pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); // if(pDLCTexPack->m_pStreamedWaveBank!=nullptr) diff --git a/Minecraft.Client/DLCTexturePack.cpp b/Minecraft.Client/DLCTexturePack.cpp index f1304a9e..29b38ebf 100644 --- a/Minecraft.Client/DLCTexturePack.cpp +++ b/Minecraft.Client/DLCTexturePack.cpp @@ -483,8 +483,9 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen iEndStart=iOverworldC+iNetherC; iEndC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_End); + //Mash-up packs don't have these custom ranges. Minecraft::GetInstance()->soundEngine->SetStreamingSounds(iOverworldStart,iOverworldStart+iOverworldC-1, - iNetherStart,iNetherStart+iNetherC-1,iEndStart,iEndStart+iEndC-1,iEndStart+iEndC); // push the CD start to after + iNetherStart,iNetherStart+iNetherC-1,iEndStart,iEndStart+iEndC-1,iEndStart+iEndC, iOverworldStart,iOverworldStart+iOverworldC-1,iOverworldStart,iOverworldStart+iOverworldC-1); // push the CD start to after } #endif } From 78afb091a4ba7403d17d50a937f243c1f7478b34 Mon Sep 17 00:00:00 2001 From: Tyler Reese Date: Sun, 12 Apr 2026 21:24:29 -0700 Subject: [PATCH 11/11] fix: Implement missing critical hit sound (#1141) * Fix * Crit Sound Now Plays On Death * Revert BuildVer.h --------- Co-authored-by: Loki --- Minecraft.Client/Common/Audio/SoundNames.cpp | 2 + .../Sound/Minecraft/damage/critical.mp3 | Bin 0 -> 18178 bytes Minecraft.World/DamageSource.cpp | 11 +++- Minecraft.World/DamageSource.h | 3 ++ Minecraft.World/EntityEvent.h | 3 ++ Minecraft.World/LivingEntity.cpp | 47 +++++++++++++++--- Minecraft.World/LivingEntity.h | 1 + Minecraft.World/Player.cpp | 4 ++ Minecraft.World/SoundTypes.h | 2 + 9 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 Minecraft.Client/Windows64Media/Sound/Minecraft/damage/critical.mp3 diff --git a/Minecraft.Client/Common/Audio/SoundNames.cpp b/Minecraft.Client/Common/Audio/SoundNames.cpp index ebb7e9ee..dd16efca 100644 --- a/Minecraft.Client/Common/Audio/SoundNames.cpp +++ b/Minecraft.Client/Common/Audio/SoundNames.cpp @@ -223,6 +223,8 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]= // 4J-PB - Some sounds were updated, but we can't do that for the 360 or we have to do a new sound bank // instead, we'll add the sounds as new ones and change the code to reference them L"fire.new_ignite", + + L"damage.critical", //eSoundType_DAMAGE_CRITICAL, }; diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/damage/critical.mp3 b/Minecraft.Client/Windows64Media/Sound/Minecraft/damage/critical.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b3687e43e30688ba5235fbbbab06ee6ba6ca02b7 GIT binary patch literal 18178 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 = msgId; m_msgId = msgId; @@ -153,7 +154,15 @@ DamageSource *DamageSource::bypassInvul() _bypassInvul = true; return this; } - +bool DamageSource::isCritical() +{ + return _isCritical; +} +DamageSource *DamageSource::setIsCritical() +{ + _isCritical = true; + return this; +} DamageSource *DamageSource::setIsFire() { isFireSource = true; diff --git a/Minecraft.World/DamageSource.h b/Minecraft.World/DamageSource.h index 1173db4d..6d0d5326 100644 --- a/Minecraft.World/DamageSource.h +++ b/Minecraft.World/DamageSource.h @@ -47,8 +47,11 @@ private: bool _scalesWithDifficulty; bool _isMagic; bool _isExplosion; + bool _isCritical; public: + bool isCritical(); + DamageSource *setIsCritical(); bool isProjectile(); DamageSource *setProjectile(); bool isExplosion(); diff --git a/Minecraft.World/EntityEvent.h b/Minecraft.World/EntityEvent.h index 4d2064ab..20e363c6 100644 --- a/Minecraft.World/EntityEvent.h +++ b/Minecraft.World/EntityEvent.h @@ -5,6 +5,9 @@ class EntityEvent public: static const BYTE JUMP = 1; static const BYTE HURT = 2; + //New + static const BYTE HURT_CRITICAL = 19; + static const BYTE DEATH_CRITICAL = 20; static const BYTE DEATH = 3; static const BYTE START_ATTACKING = 4; static const BYTE STOP_ATTACKING = 5; diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index 3af9efe9..46b75e5b 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -831,7 +831,12 @@ bool LivingEntity::hurt(DamageSource *source, float dmg) if (sound) { - level->broadcastEntityEvent(shared_from_this(), EntityEvent::HURT); + if (source->isCritical()) { + level->broadcastEntityEvent(shared_from_this(), EntityEvent::HURT_CRITICAL); + } + else { + level->broadcastEntityEvent(shared_from_this(), EntityEvent::HURT); + } if (source != DamageSource::drown) markHurt(); if (sourceEntity != nullptr) { @@ -854,12 +859,19 @@ bool LivingEntity::hurt(DamageSource *source, float dmg) MemSect(31); if (getHealth() <= 0) { - if (sound) playSound(getDeathSound(), getSoundVolume(), getVoicePitch()); + if (sound) { + //New: both death AND hurt sounds should play critical sound as well. + if (source->isCritical()) playSound(getCriticalSound(), getSoundVolume(), getVoicePitch()); + playSound(getDeathSound(), getSoundVolume(), getVoicePitch()); + }; die(source); } else { - if (sound) playSound(getHurtSound(), getSoundVolume(), getVoicePitch()); + if (sound) { + if (source->isCritical()) playSound(getCriticalSound(), getSoundVolume(), getVoicePitch()); + playSound(getHurtSound(), getSoundVolume(), getVoicePitch()); + } } MemSect(0); @@ -926,7 +938,11 @@ void LivingEntity::die(DamageSource *source) } } - level->broadcastEntityEvent(shared_from_this(), EntityEvent::DEATH); + if (source->isCritical()) { + level->broadcastEntityEvent(shared_from_this(), EntityEvent::DEATH_CRITICAL); + } else { + level->broadcastEntityEvent(shared_from_this(), EntityEvent::DEATH); + } } void LivingEntity::dropEquipment(bool byPlayer, int playerBonusLevel) @@ -959,7 +975,10 @@ int LivingEntity::getHurtSound() { return eSoundType_DAMAGE_HURT; } - +int LivingEntity::getCriticalSound() +{ + return eSoundType_DAMAGE_CRITICAL; +} int LivingEntity::getDeathSound() { return eSoundType_DAMAGE_HURT; @@ -1181,7 +1200,8 @@ void LivingEntity::swing() void LivingEntity::handleEntityEvent(byte id) { - if (id == EntityEvent::HURT) + //These gotta be in parentheses + if ((id == EntityEvent::HURT) || (id == EntityEvent::HURT_CRITICAL)) { walkAnimSpeed = 1.5f; @@ -1191,19 +1211,30 @@ void LivingEntity::handleEntityEvent(byte id) MemSect(31); // 4J-PB -added because villagers have no sounds - int iHurtSound=getHurtSound(); + int iHurtSound = getHurtSound(); + int iCritSound = getCriticalSound(); if(iHurtSound!=-1) { playSound(iHurtSound, getSoundVolume(), (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f); } + if(iCritSound!=-1 && (id == EntityEvent::HURT_CRITICAL)) + { + playSound(iCritSound, getSoundVolume(), (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f); + } MemSect(0); hurt(DamageSource::genericSource, 0); } - else if (id == EntityEvent::DEATH) + else if ((id == EntityEvent::DEATH) || (id == EntityEvent::DEATH_CRITICAL)) { MemSect(31); // 4J-PB -added because villagers have no sounds int iDeathSound=getDeathSound(); + int iCritSound = getCriticalSound(); + + if (iCritSound != -1 && (id == EntityEvent::DEATH_CRITICAL)) + { + playSound(iCritSound, getSoundVolume(), (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f); + } if(iDeathSound!=-1) { playSound(iDeathSound, getSoundVolume(), (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f); diff --git a/Minecraft.World/LivingEntity.h b/Minecraft.World/LivingEntity.h index ecc819df..086935ef 100644 --- a/Minecraft.World/LivingEntity.h +++ b/Minecraft.World/LivingEntity.h @@ -185,6 +185,7 @@ public: virtual void knockback(shared_ptr source, float dmg, double xd, double zd); protected: + virtual int getCriticalSound(); virtual int getHurtSound(); virtual int getDeathSound(); diff --git a/Minecraft.World/Player.cpp b/Minecraft.World/Player.cpp index 00c7148e..c3677862 100644 --- a/Minecraft.World/Player.cpp +++ b/Minecraft.World/Player.cpp @@ -1631,6 +1631,10 @@ void Player::attack(shared_ptr entity) } DamageSource *damageSource = DamageSource::playerAttack(dynamic_pointer_cast(shared_from_this())); + + if (bCrit) { + damageSource->setIsCritical(); + } bool wasHurt = entity->hurt(damageSource, dmg); delete damageSource; if (wasHurt) diff --git a/Minecraft.World/SoundTypes.h b/Minecraft.World/SoundTypes.h index 81e81d79..cae541df 100644 --- a/Minecraft.World/SoundTypes.h +++ b/Minecraft.World/SoundTypes.h @@ -213,6 +213,8 @@ enum eSOUND_TYPE eSoundType_FIRE_NEWIGNITE, + eSoundType_DAMAGE_CRITICAL, + eSoundType_MAX };