Chat Heads

Chat Heads

35M Downloads

Server blacklist

Ryhon0 opened this issue · 16 comments

commented

I'm working on a plugin that adds chat heads to vanilla Minecraft but players that have this mod installed will end up with a duplicate head, as seen in the screenshot.
image
To fix this issue, I propose the server would send the client a packet telling the mod to stop rendering it's own heads and/or have a blacklist file with server IPs to turn off the rendering on in case the server is using a different plugin which does not send this packet. An allow list which ignores specific server's requests to disable rendering in case some packet is misinterpreted or if a server disables the head rendering despite not having it's own chat head system would be a nice addition but not necesary

commented

Some loose thoughts:

  • The blacklist is a horrible idea, maintaining it would be a pain. If a server ever gets rid of the plugin, the mod would seemingly stop working, etc.
  • A special packet is a pretty decent and simple approach. I wouldn't worry about compatibility with other plugins - I assume yours is currently the only one implementing this. Future ones will probably be aware either of your plugin, or this mod, so they would know to send the packet.
  • I don't think the allowlist is needed. Unless we manage to fuck up really bad, it's going to be basically impossible to misinterpret an unrelated packet.

Also, how does your plugin render the heads? I'm thinking that maybe we could detect server-sent heads at the beginning of the message, and then move them to the margin. The special packet would no longer be necessary, and it would look consistent with vanilla servers.

commented

It's using a custom font with 8 1x8 characters (\uE000-\uE007), each with a white pixel at a different height and a character with negative width to go back 1 ('1') or 8 pixels ('n'). These characters are in a font called x, which resolves to minecraft:x to reduce the amount of data being sent. The plugin lets you control how the messages are rendered, so the head might not be the first thing in the message, some server owners might chose to not render the head at all or have it after the username. This system can also be used to display any arbitrary image. I also saw another paid plugin which lets you display arbitrary images but I don't think it's being used to show player heads

commented

Very clever!
I can't say I've fully understood it yet. I assume the font is somehow added in a resource pack the clients download on server join?
If so, it shouldn't be hard to detect that resource pack and disable Chat Heads.
Maybe the pack could add some arbitrary chat_heads:disable asset of some form to explicitly turn off Chat Heads if needed.
Only worry I have is that players use that resource pack outside the intended servers.

Some technical questions:
This minecraft:x font, would that be found under minecraft/font/x.json?
And those characters \uE000-\uE007 would otherwise not be used or valid, is that right?

Receiving custom packets might or might not be that easy because this mod is targeting Fabric and Forge, which both have different networking implementations and adding our own Mixin could interfere with that as well.

Apart from that, the thought of a (player costumizable) blacklist isn't that bad of an idea. I was thinking about "server profiles", where different servers can have different settings, and adding an on/off switch would be trivial to add to that.
It does sound like something for the non-near future though.

commented

Yes, that font is provided by a server resource pack and is found in assets/minecraft/font/x.json.
Characters F0000–FFFFD are part of the private use area block, they are not standardized and can be used by any program in whichever way it chooses. By default it's not used in Minecraft but might be used by other servers by stuff like emojis, badges or GUIs. ItemsAdder seems to be using it for badges.
The chat_heads:disable approach seems like the best option. If the first non-empty component uses one of the defined characters and/or fonts, chat heads rendering is disabled

commented

I just hacked together a small test on the font branch, which should disable chat heads when a custom character in the \uE000-\uE007 range is received - ignoring assets for now.

Can you give it a try and see if that works? I made a fabric release for 1.20.2 here.

commented

Yes, it works, but the chat is offset to the right
image

commented

and a boolean key that forces the mod to disable head rendering without having to wait for a player message

Yeah but I mean if we are using that, there's no need to be checking for characters at all.
The main thing I want to prevent is players (accidentally?) having that pack installed and wondering why Chat Heads doesn't work at all on any server anymore.

commented

Ah, it's offset since it's a "non-player" message.

Hm... I'm not sure if we can support offsets with "server heads".
Theoretically we could try to detect if the message is starting with a server head and adjust the offset, but from the original screenshot, the rendering of the Chat Head heads and the server heads are actually slightly different, so I don't think we would have perfect text alignment anyway.

I guess we should just disable the offsets when a server head is received.
Only slight annoyance is that the first few non-server-head messages might still be offset, though that should barely be noticable.
(Just a thought: Maybe text alignment could be baked in server-side using invisible characters?)

Only question left is about the custom chat_heads:disable asset.
The idea is to disable chat heads iff the server uses \uE000-\uE007 characters and the client has that chat_heads:disable asset.
That way Chat Heads can work on other servers which are coincidentally also using those characters for other purposes and players which have that resource pack installed globally can use Chat Heads on vanilla servers too.

I need to look into how to check for that and what the asset should even be (maybe just an empty file at assets/chat_heads/disable?) - though not today.
I'll get back to you on that.

commented

chat_heads:disable can just be a JSON/YML/TOML file, whichever is easier to implement with a key telling it the start and end of the character range(s) and a boolean key that forces the mod to disable head rendering without having to wait for a player message

commented

Ah, that makes sense. Perhaps make sure the asset comes from the server pack and not a pack loaded by the user somehow? Open the zip in memory and check if it has an entry for that file?

commented

I'll see if there's a way to tell if a resource pack is a server pack. If there is, we can simplify this whole thing.

commented

Aight, I think I got it working.
Pushed to the font2 branch, here's another release, give it a go.

You should now be able to simply add an empty assets/chat_heads/disable file in your server resource pack and have it disable Chat Heads completely.
Having that resource pack installed locally won't have any effect - I found server resource packs are actually always loaded separately, even if the files and hashes match perfectly. (Convenient for us - might change in the future though.)

Note to self:
Had to make sure the "disabled" state is reset once a new connection (multiplayer, singleplayer or even realms) is opened.
That part might not work if the server is using those hub portals that connect multiple servers - I'm not actually sure how those work. Might need to look into that.
For consistency I also moved the "server sent UUID" state reset there, which previously used a "setLevel" Mixin - which also applied to dimension change on the same server.

commented

Yup, working perfectly now, thank you!
image
I would love a 1.20.1 release too because a lot of mods haven't updated yet

commented

k, backported everything down to 1.19.2, new versions are up!

Btw, does your server plugin have a name yet?

commented

Right now I'm calling it MarkdownChat but it might change in future

commented

您好,您的这个想法非常棒!希望您能顺利的完成该插件 @Ryhon0