[Solved] Send chat message as if it came from a player?

Post Reply
isaiah658
Member
Posts: 168
Joined: Sun Jan 24, 2016 14:58
Contact:

[Solved] Send chat message as if it came from a player?

by isaiah658 » Post

I am working on a mod that uses formspecs for battles. This means players may have a formspec open for long periods of time. When a formspec is open, a player can't send chat messages.

My solution is to add a text field to the formspec to allow the player to type and send a chat message. The formspec never has to close. It just needs to send the message on behalf of the player. This is where the problem arises. As far as I know, the only way a mod can send a chat message is with minetest.chat_send_all. I know there are mods that add things like ranks, colored names, and other messages formatting. Since messages from minetest.chat_send_all won't appear to be sent from a player, this will lead to conflicts with those mods. The messages from the formspec will not be formatted like other messages.

I'm not familiar enough with chat mods to know how I should approach this. Is minetest.format_chat_message useful in this situation? Should I just ignore trying to blend in with other chat formatting and instead indicate the message is being sent during a battle?
Last edited by isaiah658 on Tue Mar 28, 2023 22:36, edited 1 time in total.

User avatar
Blockhead
Member
Posts: 1622
Joined: Wed Jul 17, 2019 10:14
GitHub: Montandalar
IRC: Blockhead256
In-game: Blockhead Blockhead256
Location: Land Down Under
Contact:

Re: Send chat message as if it came from a player?

by Blockhead » Post

Realistically I think that a general solution to the problem requires awareness of what chat mod (if any) is being used, and either using that mod's API in some way or trying to pretend like it came from it. In the absence of any other mod, it's either the Lua builtin code or the C++ engine that handles chat. If the chat mod has no API, another solution might be to fork or write an extension mod for that mod which adds an impersonation API. A chat impersonation library would be able to decouple your need for impersonation from particular mod implementations, but no such library exists to my knowledge.

Also an important consideration for using formspecs for this is strict user input validation/sanitisation. You want to make sure that users with cheat clients can't send formspec submissions that let them pretend to chat as another player.

Bit of a tangent: Also, do not forget about the API minetest.chat_send_player in case of direct messaging and so on.
/˳˳_˳˳]_[˳˳_˳˳]_[˳˳_˳˳\ Advtrains enthusiast | My map: Noah's Railyard | My Content on ContentDB ✝️♂

User avatar
LMD
Member
Posts: 1386
Joined: Sat Apr 08, 2017 08:16
GitHub: appgurueu
IRC: appguru[eu]
In-game: LMD
Location: Germany
Contact:

Re: Send chat message as if it came from a player?

by LMD » Post

This is indeed not trivial. Here's how I think you should be able to emulate this:

0. Do appropriate checks: Does the player have the formspec open? Do they have the "shout" privilege?
1. Run all minetest.registered_on_chat_messages callbacks with parameters name and message. If any of these returns true, consider the message handled and abort.
2. If none of these returned true, default to minetest.chat_send_all(minetest.format_chat_message(name, message)).
My stuff: Projects - Mods - Website

isaiah658
Member
Posts: 168
Joined: Sun Jan 24, 2016 14:58
Contact:

Re: Send chat message as if it came from a player?

by isaiah658 » Post

LMD wrote:
Mon Mar 27, 2023 14:02
This is indeed not trivial. Here's how I think you should be able to emulate this:

0. Do appropriate checks: Does the player have the formspec open? Do they have the "shout" privilege?
1. Run all minetest.registered_on_chat_messages callbacks with parameters name and message. If any of these returns true, consider the message handled and abort.
2. If none of these returned true, default to minetest.chat_send_all(minetest.format_chat_message(name, message)).
Thank you! The idea of running the callbacks is key. I do have one question about this. You mentioned I should run all of the callbacks. I did some testing by adding two of my own callbacks. The first makes the text color blue and sends the message to everyone. The second makes the text color red and sends the message to everyone. Both return true to signal the message is handled. This sort of simulates a player having two conflicting chat mods. When sending a normal message with this set up, Minetest only sends the message once as blue. It appears to run the callbacks by index order and stops once when a callback returns true. The other callbacks don't run. Should I do the same thing? Loop through the callbacks with ipairs and stop when the first one returns true? It seems to keep the behavior consistent with the Minetest engine.

User avatar
LMD
Member
Posts: 1386
Joined: Sat Apr 08, 2017 08:16
GitHub: appgurueu
IRC: appguru[eu]
In-game: LMD
Location: Germany
Contact:

Re: Send chat message as if it came from a player?

by LMD » Post

isaiah658 wrote:
Tue Mar 28, 2023 01:41
Should I do the same thing? Loop through the callbacks with ipairs and stop when the first one returns true? It seems to keep the behavior consistent with the Minetest engine.
Yes. That's what I meant by "abort". You could also use core.run_callbacks for this as the engine does, but beware: It may be broken / removed / hidden at any point since it is not documented.
My stuff: Projects - Mods - Website

Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests