Merge pull request #129 from moelrobi/claude/compassionate-heisenberg-ekazit

Chat: highlight server messages in violet
This commit is contained in:
zeex64 authored and GitHub committed 2026-10-08 20:34:48 -05:00
commit 8fe9964f73
4 files changed
+24 -6

No files matched your search

+2 -1
View File
@@ -101,12 +101,13 @@ struct MultiplayerChatLine {
std::string name, text;
bool local{}; // sent by this player
// The sender's role, as their nametag shows it: its colour (IM_COL32 layout, 0 = none)
// and a tag shown in a box before the name ("Dev", "Staff", "Creator", "Centrix", "Homie", "Admin", "Host", "Friend" or empty).
// and a tag shown in a box before the name ("Dev", "Staff", "Creator", "Centrix", "Homie", "Admin", "Host", "Friend", "Server" or empty).
std::uint32_t color{};
std::string tag;
// With the chat filter on, `text` is masked and this is the line as sent (same length), so
// the overlay can keep emote names the filter caught; empty when nothing was masked.
std::string unmasked;
bool server{}; // said by the dedicated server itself: its console, welcome or answers
};
// A command typed into chat with a leading "/" (shown as the player types "/").
struct MultiplayerChatCommand {
+3 -1
View File
@@ -39,7 +39,9 @@ inline constexpr std::uint32_t nametag_white = 0xffffffffU, nametag_developer =
nametag_staff = 0xff71cc2eU, // green (#2ECC71)
nametag_admin = 0xffc674ffU, // pink
nametag_host = 0xffffc85eU, // blue
nametag_friend = 0xff8ae07bU; // green
nametag_friend = 0xff8ae07bU, // green
nametag_server = 0xffff5c8eU, // violet (#8E5CFF)
nametag_server_text = 0xffffc8d9U; // lavender (#D9C8FF), its lines' text
// Developers, staff, content creators, homies and Centrix shimmer from these to their role
// colour (Centrix between white and its blue).
inline constexpr std::uint32_t nametag_developer_start = 0xffff206eU, // #6E20FF, IM_COL32 layout
@@ -579,7 +579,7 @@ std::pair<std::uint32_t, std::string> mark_role(IdentityList list) {
std::pair<std::uint32_t, std::string> player_role(Session &s, std::uint64_t sender, bool local, bool marks) {
if (!sender) return {};
const bool dedicated = dedicated_host(s);
if (dedicated && sender == s.host_id) return {nametag_admin, {}}; // the server itself
if (dedicated && sender == s.host_id) return {nametag_server, "Server"}; // the server itself
const auto *peer = local ? nullptr : find_peer(s, sender);
const bool vouched = local || (peer && steam_vouched(s, *peer));
// Who the backend says a player is comes before what they are in this lobby, unless they
@@ -597,7 +597,13 @@ std::pair<std::uint32_t, std::string> player_role(Session &s, std::uint64_t send
void add_chat(Session &s, std::uint64_t sender, std::string name, std::string text, bool local, bool marks) {
if (name.empty()) name = sender ? "Player" : "ReSkate";
auto [color, tag] = player_role(s, sender, local, marks);
s.chat.push_back({++s.chat_sequence, sender, now_us(), std::move(name), std::move(text), local, color, std::move(tag)});
// The dedicated server's own lines (its chat, and its answers sent to this player alone) stand out.
const bool server = dedicated_host(s) && (sender ? sender == s.host_id : name == "Server");
if (server && !sender) {
color = nametag_server;
tag = "Server";
}
s.chat.push_back({++s.chat_sequence, sender, now_us(), std::move(name), std::move(text), local, color, std::move(tag), {}, server});
while (s.chat.size() > multiplayer_chat_history) s.chat.pop_front();
publish_chat(s);
}
+11 -2
View File
@@ -78,6 +78,7 @@ Clock::time_point arrived(const ChatState& c, std::uint64_t sequence) {
// The sender's role colour, as their nametag shows it; ReSkate's notices muted. Lines without
// a role (older sessions) fall back to a steady colour per sender.
ImU32 name_colour(const MultiplayerChatLine& line) {
if (line.server) return line.color ? line.color : multiplayer::nametag_server;
if (!line.sender) return theme::muted;
if (line.color) return line.color;
if (line.local) return theme::blue;
@@ -89,6 +90,11 @@ ImU32 name_colour(const MultiplayerChatLine& line) {
return palette[mixed % palette.size()];
}
// A message's own colour: the server's lines in lavender, everyone else's white.
ImU32 text_colour(const MultiplayerChatLine& line) {
return line.server ? multiplayer::nametag_server_text : theme::paper;
}
// "name:"; a role tag is drawn in its own box before it (role_badge.h).
std::string chat_label(const MultiplayerChatLine& line) { return line.name + ":"; }
@@ -491,6 +497,7 @@ void draw_chat() {
ImGui::SameLine(0.0f, 6.0f * scale);
const auto& drawn = layout_for(layout, line, ImGui::GetFont(), ImGui::GetFontSize(), line_width,
ImGui::GetCursorScreenPos().x - line_start.x);
ImGui::PushStyleColor(ImGuiCol_Text, text_colour(line));
if (drawn.emotes) {
draw_rich(ImGui::GetWindowDrawList(), ImGui::GetFont(), ImGui::GetFontSize(), line_start, drawn.text,
drawn.rich, ImGui::GetColorU32(ImGuiCol_Text), 1.0f);
@@ -499,6 +506,7 @@ void draw_chat() {
} else {
ImGui::TextUnformatted(drawn.text.c_str());
}
ImGui::PopStyleColor();
}
if (c.feed.lines.empty()) {
ImGui::PushStyleColor(ImGuiCol_Text, theme::muted);
@@ -603,8 +611,9 @@ void draw_chat() {
draw->AddText(heading, name_size, ImVec2(at.x + badge, at.y), with_alpha(name_colour(*line), alpha), label.c_str());
shade_nametag_gradient(draw, name_vertices, at.x + badge, name_extent.x, name_colour(*line), ImGui::GetTime());
const ImVec2 text_at = beside ? ImVec2(at.x + indent, at.y) : ImVec2(at.x, at.y + name_extent.y);
if (emotes) draw_rich(draw, body, size, text_at, drawn.text, drawn.rich, with_alpha(theme::paper, alpha), alpha);
else draw->AddText(body, size, text_at, with_alpha(theme::paper, alpha), drawn.text.c_str(), nullptr, wrap);
const auto text = with_alpha(text_colour(*line), alpha);
if (emotes) draw_rich(draw, body, size, text_at, drawn.text, drawn.rich, text, alpha);
else draw->AddText(body, size, text_at, text, drawn.text.c_str(), nullptr, wrap);
bottom = top_left.y - gap;
}
}