My game is currently integrating to the new TextChatService. My game has custom chat commands which runs on the server (No, I am NOT using the built-in TextChatCommand provided by TextChatService) . When a chat command is ran, some commands will be sent out and be seen by everyone while some will not be seen by everyone.
This is the code when using Chat Service. A command function will be ran and it returns a boolean that indicates whether the chat message will be hidden or not.
game:GetService("Chat"):RegisterChatCallback(Enum.ChatCallbackType.OnServerReceivingMessage, function(msg)
for _, plr in pairs (Players:GetPlayers()) do
if plr.UserId == msg.SpeakerUserId then
local hide = Commands.onCommand(plr, msg.Message)
if hide then
msg.ShouldDeliver = false
end
return msg
end
end
end)
After integrating with the new TextChatService, I tried to hide the chat message by calling ShouldDeliverCallback.
local TextChatService = game:GetService("TextChatService")
local generalChannel : TextChannel = TextChatService:WaitForChild("TextChannels"):WaitForChild("RBXGeneral")
generalChannel.ShouldDeliverCallback = function(textChatMessage: TextChatMessage, targetTextSource: TextSource)
if targetTextSource.UserId == textChatMessage.TextSource.UserId then
local hide = Commands.onCommand(Players:GetPlayerByUserId(targetTextSource.UserId), textChatMessage.Text)
return not hide
end
end
However, since ShouldDeliverCallback loops through every receiving player, some player will be able to see the hidden message and some players will not, depending on the looping order of ShouldDeliverCallback. Is there a workaround such that I can seamlessly achieve the old behavior?
It will also be ideal if the local player is not be able to see the hidden message, since apparently, ShouldDeliverCallback displays the message to local player even if it should not be delivered.
It is called for every player. However, the order that it calls does not seems to be guaranteed. It is not like the player who initiated the command will trigger âShouldDeliverCallbackâ first. Which means some player will receive âShouldDeliverCallbackâ before the command function was even run.
I found a way you can stop chat messages from showing up whilst still allowing you to detect and run commands: By setting the TextChatMessageâs Text to an empty string within the TextChatServiceâs OnIncomingMessage callback, and doing so when the messageâs status is Sending (I used a LocalScript inside of StarterPlayerScripts):
local TextChatService = game:GetService("TextChatService")
local HIDDEN_COMMAND = "/explode"
local function explode()
print("Boom!")
end
local function onIncomingMessage(message: TextChatMessage)
if message.TextSource and message.Status == Enum.TextChatMessageStatus.Sending then
if message.Text == HIDDEN_COMMAND then
explode()
message.Text = "" -- Setting the message.text to an empty string will stop it from showing up in the chat
end
end
end
TextChatService.OnIncomingMessage = onIncomingMessage
Using the method above will prevent the message from being sent though, so it will need to be modified if you wish for certain players to be able to see that you ran the command in chat
Most of TextChatServiceâs methods can only work on client-sided scripts, so dealing with chat messages on the server-side is, as youâre experiencing, difficult
You can execute the commands on the server-side using RemoteEvents, which would allow you to securely restrict which players can make them by checking if their user ID is in a whitelist
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TextChatService = game:GetService("TextChatService")
local HIDDEN_COMMAND = "/explode"
local explodeEvent = ReplicatedStorage:WaitForChild("Explode")
local function onIncomingMessage(message: TextChatMessage)
if message.TextSource and message.Status == Enum.TextChatMessageStatus.Sending then
if message.Text == HIDDEN_COMMAND then
explodeEvent:FireServer()
message.Text = "" -- Setting the message.text to an empty string will stop it from showing up in the chat
end
end
end
TextChatService.OnIncomingMessage = onIncomingMessage
Server-sided script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local explodeEvent = ReplicatedStorage.Explode
local whitelisted = {
[5027420] = true
}
local function onServerEvent(player)
if whitelisted[player.UserId] then
print("Boom!")
end
end
explodeEvent.OnServerEvent:Connect(onServerEvent)