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?
[Solved] Send chat message as if it came from a player?
[Solved] Send chat message as if it came from a player?
Last edited by isaiah658 on Tue Mar 28, 2023 22:36, edited 1 time in total.
- 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?
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.
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 ✝️♂
- 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?
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)).
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)).
Re: Send chat message as if it came from a player?
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.LMD wrote: ↑Mon Mar 27, 2023 14:02This 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)).
- 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?
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.
Who is online
Users browsing this forum: No registered users and 5 guests