This gist intends on clearing up some of the misinformation surrounding signed chat/the reporting feature Mojang has added to Minecraft 1.19.1. Here you can find both technical information as well as a general explanation of how these work.
When joining a server, clients now send an extra profile key used for verifying a message's authenticity. This key and thus the whole signing process is optional, but by default, servers enforce secure profiles. Whenever the player sends a chat message and has joined with a key, the message will be signed using their own private key, which the server then verifies using the public key sent on join. Assuming signature, timestamp, and message contents line up, the message goes through.
On the other end, clients can also require all broadcasted player messages to be signed, disregarding the ones without sender verified signatures.
Every signed message's signature include the sender's UUID matching the profile key's identity, a timestamp (though that cannot be verified with untrusted clients/servers), the signed message, and a random salt.
A message's signature also includes the previous message's signature of that same player. This means that, with at least one message of a player provided, you can be sure that messages before that were sent in correct order and no message of that player was omitted in a report.
Another important part of the signature is the list last seen messages. For the last 5 players of which you've seen any messages, their last message's signature will be included. This is used to verify that, up to a certain point to guarantee fully faithful context, no messages of other players have been omitted in a report and that no messages have been added to the given context after the fact either.
With signed messages, Mojang finally introduced a packet servers can use to retroactively remove already sent out messages. So if you want to clear chat or remove individual messages without having to spam empty messages that only move up the previous messages, you can properly remove them now using the ClientboundDeleteChatPacket
packet - the only requirement for this is that the message to be removed is a properly signed player message.
With message signature now depending on previous messages' signatures as well, you obviously cannot omit any message signatures of online players without breaking the chain. In order to keep a valid chain of signatures, players that shouldn't receive the contents of a signed player message, the server instead sends out the signature data only. This means a player will know that a certain other player sent some message via a chat message or signed command argument, but they won't know what the message was or who received it.
Since servers often want to modify chat messages with custom formatting, prefixes, and suffixes before broadcasting a message, you can modify the final message to your heart's content as long as the client agrees to it. Servers can send a chat preview while the player is currently typing their message, making them sign that formatted preview instead of the original plain text.
Depending on the mode you set this to on the client, you have to press enter twice in order to send out the last given preview, so that you can be sure the server doesn't trick you into something you don't want to send by giving you no time to react to a change. When only one press is required as per client setting, there still is at least a short window where you don't sign the preview (signified by slighty faded background and an orange indicator before the delay has passed), but your actual input text.
Here's a nice example of such a preview, where the colored component will be signed once the player presses enter to send the message:
This ensures you can change parts of the message and apply formatting (as long as the player agrees to the changes).
Since commands such as /say, as well as custom commands to broadcast messages or send them to a certain group of people also result in "player messages" that you would want to have verified, text arguments in commands will also be signed by the client. With the given signature, you can then distribute the message yourself and still have it show up as a signed player message.
In the wild, you can see this being used in Vanilla's say, me, msg, teammsg, ban, banip, and kick commands.
There are two different kinds of chat messages now; player chat and system chat. Player chat is accompanied by the message signature, system chat has no special format or signature attached. You can optionally attach an unsigned component to any player chat message, which will make it look like this (the informative popup is only displayed when you hover over the icon, which you can only see when you focus the chat window):
If you go as far as sending a player chat message with an invalid signature, it will look like this:
System chat messages have a gray indicator.
While the message always needs to be verified by the player that sent it, player display name, team name, and surrounding format can be freely defined by the server.
One of the default chat types looks like this when serialized:
{
"name":"minecraft:team_msg_command",
"id":3,
"element":{
"chat":{
"translation_key":"chat.type.team.text",
"parameters":[
"team_name",
"sender",
"content"
]
},
"narration":{
"translation_key":"chat.type.text.narrate",
"parameters":[
"sender",
"content"
]
}
}
},
The decoration format for the chat display here resolves as %s <%s> %s
, then using the 3 parameters team_name
, sender
, and content
. Even though the decoration element only takes a translatable argument, you can simply enter a plain string as the key that will be displayed; you can try this out by using the following command: /tellraw @s {"translate":"Hello [%s]", "with":["world"]}
Chat type formats can be easily made custom, e.g. turning the translatable into plain text like: 🚩 Broadcast by %s: %s 🚩
and only taking the sender and content parameters, to give just one example. In addition to the text display, you can also define the message to be narrated (also using a different number of arguments and a different surrounding format) and/or displayed in the actionbar as "game info". In the style field you can also apply custom formatting (color, font, italics, hover/click events, etc.) to the entire message/until the sender or content component changes the format again.
Custom chat types can be added using datapacks or by modifying the chat_type registry in the server (which modded servers such as Paper will need to add API for in the future). Custom chat types will then be sent to each player once when they join. With this, you can in theory also send the same message using different formats to different players, only the actual content is always fixed as part of the signed message.
You can find a full list of the Vanilla chat types here.
The full login and chat flow has been visualized in this beautiful graphic:
Before we part ways again, here are answers to some of the more common questions. Mojang's FAQ has been updated to answer more of the pressing questions, so it's definitely worth taking a look at.
No, only reported messages are sent away for processing.
No, Mojang have made clear they only intend on hunting down the worst of the worst (suicide threats, racial slurs, doxing, etc.). All reports will be handled in human review (aside from them most likely pre-filtering malicious reports before the final decision is made). See here for a detailed list of punishment reasons. You can still dick around with your friends.
Then they get temporarily or permanently banned; the number of reports does not matter.
No, they need the private key only you and Mojang have to sign messages as coming from your account. You cannot be impersonated unless you download a malicious client/mod.
Reports require and automatically send a handful of messages around the selected ones to be included as context. Forging false context by omitting or adding messages has been addressed and is - as far as we know - impossible.
While you can theoretically remove the body of messages and only leave a signature, if even one other player writes something inbetween, reports become invalid. Even if not, you still know there was some message you either removed or the other person didn't see. Sending private messages also does nothing to incriminate a reported player, as that also breaks with other players writing messages, you still need a publicly visible (!) message with its full message content right before the other player replies (which also has to be included in the report), and with that it becomes obvious the other player did not reply to any of the private messages.
That's simply not going to happen considering how different the underlying tech of filtering vs. reporting/chat signing is... even if it were to, it would be trivial to disable.
No, and if you think you were banned without reason, you can make an appeal.
Yes, very easily. However, considering this comes at the cost of effectively taking power away from your users, making them more vulnerable to repeated bullying, it'd not be as merciful of a move as you might think it is.
Players may also opt-in to only display signed (and thus reportable) messages.
A lot of people have voiced concerns regarding Mojang possibly outsourcing message moderation and thus having a poor quality of report processing. While it is a somewhat reasonable fear, this is still based on extremely high amounts of speculation. Looking at the facts, Microsoft already has a well working chat moderation at xbox live, where no such drama of false bans or being banned because you spoke out negatively about Microsoft has occurred - the rules regarding Minecraft chat are also a lot more lenient compared to that.
With this in mind, such speculation does not make for a good argument and I implore you to wait and see what actually happens. If your worst fears do end up coming true and false bans occur with an additional lack of appeal processing, I myself will be sure to join the riot as well and provide easy to use means to disable reporting.
You can't if either your friends don't feel attacked by your messages or you just disable reporting with a plugin or mod. However... Opinion time: Everything you do or say has consequences, even towards friends, and even if you don't realize they exist. You're not going to be banned for a playful and harmless insult, but considering the large number of children and young adults playing the game, such a reporting feature was long overdue.
Someone who is toxic on one server isn't unlikely to behave the same on any other server. You might be capable of handling simple disputes and insults, but Mojang is better equipped to properly deal with people putting out personal threats, child predators and the alike than you are. This also includes the smaller or even private servers.
Proper moderation takes time, and a lot of servers aren't able to provide that or willfully neglect it. Nevertheless, you can still easily lever out reporting on your server if you wish to do so.
Whatever you do, don't join the angry mob; instead, provide constructive and useful feedback either on Minecraft's feedback site or open a ticket on their bug tracker - and remember to keep it civil.