Implement host chat commands

On January 21 Innersloth released a document that details a few new
features. One of these are host chat commands: any chat message that
starts with "/cmd" is forwarded to the host and to the host only.

Implement this feature in Impostor too for implementation parity.

For more info, see their GitHub page:
https://github.com/Innersloth-LLC/AmongUsModdingInformation
This commit is contained in:
miniduikboot committed 2026-01-27 22:17:03 +01:00
1 parent 9a60ce3d56
commit fbdb708941
3 files changed
+38 -3

No files matched your search

@@ -1,4 +1,4 @@
namespace Impostor.Api.Events.Player
namespace Impostor.Api.Events.Player
{
public interface IPlayerChatEvent : IPlayerEvent, IEventCancelable
{
@@ -6,5 +6,12 @@
/// Gets the message sent by the player.
/// </summary>
string Message { get; }
/// <summary>
/// Gets or sets a value indicating whether the message is sent to
/// all players (true) or only to the host (false).
/// To not send this message at all, cancel this event instead.
/// </summary>
bool SendToAllPlayers { get; set; }
}
}
@@ -1,4 +1,4 @@
using Impostor.Api.Events.Player;
using Impostor.Api.Events.Player;
using Impostor.Api.Games;
using Impostor.Api.Net;
using Impostor.Api.Net.Inner.Objects;
@@ -24,5 +24,7 @@ namespace Impostor.Server.Events.Player
public string Message { get; }
public bool IsCancelled { get; set; }
public bool SendToAllPlayers { get; set; } = true;
}
}
@@ -1183,9 +1183,35 @@ namespace Impostor.Server.Net.Inner.Objects
private async ValueTask<bool> HandleSendChat(ClientPlayer sender, string message)
{
var @event = new PlayerChatEvent(Game, sender, this, message);
// See https://github.com/Innersloth-LLC/AmongUsModdingInformation?tab=readme-ov-file#chat-commands
// Details not mentioned:
// - If the host sends a message that starts with /cmd, it is sent to all players
// - If the message starts with " /cmd" (note the space) it is sent to all players
if (Game.IsHostAuthoritive && !sender.IsHost && message.StartsWith("/cmd"))
{
@event.SendToAllPlayers = false;
}
await _eventManager.CallAsync(@event);
return !@event.IsCancelled;
if (@event.IsCancelled)
{
return false;
}
else if (@event.SendToAllPlayers == false)
{
if (Game.Host != null)
{
await SendChatToPlayerAsync(message, Game.Host.Character);
}
return false;
}
else
{
return true;
}
}
private async ValueTask HandleStartMeeting(byte targetId)