aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/ChatScreen.cpp
diff options
context:
space:
mode:
authorKevin <115616336+lag@users.noreply.github.com>2026-03-06 09:52:28 -0600
committerGitHub <noreply@github.com>2026-03-06 09:52:28 -0600
commitea65542c1b63d7ee37025837bf205e55ace0c863 (patch)
tree0ba5abdfdbf055d11bd85a460b98b51f2c9c9904 /Minecraft.Client/ChatScreen.cpp
parent1755cd58bebf19053c6b4bbf9915b07237e1c14e (diff)
Add Chat / Pastes / Formatting (#682)
* Initial fixes for ContainerSetSlotPacket and CraftItemPacket * Chat: paste, history, ยง formatting, 1-9 block when open (Windows64) Made-with: Cursor * static_cast refactor
Diffstat (limited to 'Minecraft.Client/ChatScreen.cpp')
-rw-r--r--Minecraft.Client/ChatScreen.cpp126
1 files changed, 110 insertions, 16 deletions
diff --git a/Minecraft.Client/ChatScreen.cpp b/Minecraft.Client/ChatScreen.cpp
index b68e6cac..543cab76 100644
--- a/Minecraft.Client/ChatScreen.cpp
+++ b/Minecraft.Client/ChatScreen.cpp
@@ -1,14 +1,27 @@
#include "stdafx.h"
#include "ChatScreen.h"
+#include "ClientConnection.h"
+#include "Font.h"
#include "MultiplayerLocalPlayer.h"
#include "..\Minecraft.World\SharedConstants.h"
#include "..\Minecraft.World\StringHelpers.h"
+#include "..\Minecraft.World\ChatPacket.h"
const wstring ChatScreen::allowedChars = SharedConstants::acceptableLetters;
+vector<wstring> ChatScreen::s_chatHistory;
+int ChatScreen::s_historyIndex = -1;
+wstring ChatScreen::s_historyDraft;
+
+bool ChatScreen::isAllowedChatChar(wchar_t c)
+{
+ return c >= 0x20 && (c == L'\u00A7' || allowedChars.empty() || allowedChars.find(c) != wstring::npos);
+}
ChatScreen::ChatScreen()
{
frame = 0;
+ cursorIndex = 0;
+ s_historyIndex = -1;
}
void ChatScreen::init()
@@ -24,6 +37,50 @@ void ChatScreen::removed()
void ChatScreen::tick()
{
frame++;
+ if (cursorIndex > static_cast<int>(message.length()))
+ cursorIndex = static_cast<int>(message.length());
+}
+
+void ChatScreen::handlePasteRequest()
+{
+ wstring pasted = Screen::getClipboard();
+ for (size_t i = 0; i < pasted.length() && static_cast<int>(message.length()) < SharedConstants::maxChatLength; i++)
+ {
+ if (isAllowedChatChar(pasted[i]))
+ {
+ message.insert(cursorIndex, 1, pasted[i]);
+ cursorIndex++;
+ }
+ }
+}
+
+void ChatScreen::applyHistoryMessage()
+{
+ message = s_historyIndex >= 0 ? s_chatHistory[s_historyIndex] : s_historyDraft;
+ cursorIndex = static_cast<int>(message.length());
+}
+
+void ChatScreen::handleHistoryUp()
+{
+ if (s_chatHistory.empty()) return;
+ if (s_historyIndex == -1)
+ {
+ s_historyDraft = message;
+ s_historyIndex = static_cast<int>(s_chatHistory.size()) - 1;
+ }
+ else if (s_historyIndex > 0)
+ s_historyIndex--;
+ applyHistoryMessage();
+}
+
+void ChatScreen::handleHistoryDown()
+{
+ if (s_chatHistory.empty()) return;
+ if (s_historyIndex < static_cast<int>(s_chatHistory.size()) - 1)
+ s_historyIndex++;
+ else
+ s_historyIndex = -1;
+ applyHistoryMessage();
}
void ChatScreen::keyPressed(wchar_t ch, int eventKey)
@@ -35,31 +92,67 @@ void ChatScreen::keyPressed(wchar_t ch, int eventKey)
}
if (eventKey == Keyboard::KEY_RETURN)
{
- wstring msg = trimString(message);
- if (msg.length() > 0)
+ wstring trim = trimString(message);
+ if (trim.length() > 0)
{
- wstring trim = trimString(message);
if (!minecraft->handleClientSideCommand(trim))
{
- minecraft->player->chat(trim);
+ MultiplayerLocalPlayer* mplp = dynamic_cast<MultiplayerLocalPlayer*>(minecraft->player.get());
+ if (mplp && mplp->connection)
+ mplp->connection->send(shared_ptr<ChatPacket>(new ChatPacket(trim)));
+ }
+ if (s_chatHistory.empty() || s_chatHistory.back() != trim)
+ {
+ s_chatHistory.push_back(trim);
+ if (s_chatHistory.size() > CHAT_HISTORY_MAX)
+ s_chatHistory.erase(s_chatHistory.begin());
}
}
minecraft->setScreen(NULL);
return;
}
- if (eventKey == Keyboard::KEY_BACK && message.length() > 0) message = message.substr(0, message.length() - 1);
- if (allowedChars.find(ch) >= 0 && message.length() < SharedConstants::maxChatLength)
+ if (eventKey == Keyboard::KEY_UP) { handleHistoryUp(); return; }
+ if (eventKey == Keyboard::KEY_DOWN) { handleHistoryDown(); return; }
+ if (eventKey == Keyboard::KEY_LEFT)
{
- message += ch;
+ if (cursorIndex > 0)
+ cursorIndex--;
+ return;
+ }
+ if (eventKey == Keyboard::KEY_RIGHT)
+ {
+ if (cursorIndex < static_cast<int>(message.length()))
+ cursorIndex++;
+ return;
+ }
+ if (eventKey == Keyboard::KEY_BACK && cursorIndex > 0)
+ {
+ message.erase(cursorIndex - 1, 1);
+ cursorIndex--;
+ return;
+ }
+ if (isAllowedChatChar(ch) && static_cast<int>(message.length()) < SharedConstants::maxChatLength)
+ {
+ message.insert(cursorIndex, 1, ch);
+ cursorIndex++;
}
-
}
void ChatScreen::render(int xm, int ym, float a)
{
fill(2, height - 14, width - 2, height - 2, 0x80000000);
- drawString(font, L"> " + message + (frame / 6 % 2 == 0 ? L"_" : L""), 4, height - 12, 0xe0e0e0);
-
+ const wstring prefix = L"> ";
+ int x = 4;
+ drawString(font, prefix, x, height - 12, 0xe0e0e0);
+ x += font->width(prefix);
+ wstring beforeCursor = message.substr(0, cursorIndex);
+ wstring afterCursor = message.substr(cursorIndex);
+ drawStringLiteral(font, beforeCursor, x, height - 12, 0xe0e0e0);
+ x += font->widthLiteral(beforeCursor);
+ if (frame / 6 % 2 == 0)
+ drawString(font, L"_", x, height - 12, 0xe0e0e0);
+ x += font->width(L"_");
+ drawStringLiteral(font, afterCursor, x, height - 12, 0xe0e0e0);
Screen::render(xm, ym, a);
}
@@ -71,13 +164,15 @@ void ChatScreen::mouseClicked(int x, int y, int buttonNum)
{
if (message.length() > 0 && message[message.length()-1]!=L' ')
{
- message += L" ";
+ message = message.substr(0, cursorIndex) + L" " + message.substr(cursorIndex);
+ cursorIndex++;
}
- message += minecraft->gui->selectedName;
- unsigned int maxLength = SharedConstants::maxChatLength;
- if (message.length() > maxLength)
+ size_t nameLen = minecraft->gui->selectedName.length();
+ size_t insertLen = (message.length() + nameLen <= SharedConstants::maxChatLength) ? nameLen : (SharedConstants::maxChatLength - message.length());
+ if (insertLen > 0)
{
- message = message.substr(0, maxLength);
+ message = message.substr(0, cursorIndex) + minecraft->gui->selectedName.substr(0, insertLen) + message.substr(cursorIndex);
+ cursorIndex += static_cast<int>(insertLen);
}
}
else
@@ -85,5 +180,4 @@ void ChatScreen::mouseClicked(int x, int y, int buttonNum)
Screen::mouseClicked(x, y, buttonNum);
}
}
-
} \ No newline at end of file