terminalCode Example
RPC-based chat system with avatars and Steam filtering
RPC-Based Chat System with Avatar Support
This example shows a complete chat system using Razor, RPC broadcasting, Steam filtering, and avatar display.
CSHARP
@using Sandbox;
@using Sandbox.UI;
@using Sandbox.Utility
@namespace Sandbox
@inherits PanelComponent
<root>
<div class="output">
@foreach (var entry in Entries)
{
<div class="chat_entry">
@if (entry.steamid > 0)
{
<div class="avatar" style="background-image: url( avatar:@entry.steamid )"></div>
}
<div class="author">@entry.author</div>
<div class="message">@entry.message</div>
</div>
}
</div>
<div class="input">
<TextEntry @ref="InputBox" onsubmit="@ChatFinished"></TextEntry>
</div>
</root>
@code
{
TextEntry InputBox = default;
public record Entry( ulong steamid, string author, string message, RealTimeSince timeSinceAdded );
List<Entry> Entries = new();
protected override void OnUpdate()
{
if (InputBox is null) return;
Panel.AcceptsFocus = false;
if (Input.Pressed("chat"))
{
InputBox.Focus();
}
// Remove entries older than 20 seconds
if (Entries.RemoveAll(x => x.timeSinceAdded > 20.0f) > 0)
{
StateHasChanged();
}
SetClass("open", InputBox.HasFocus);
SetClass("hide", Player.FindLocalPlayer()?.WantsHideHud ?? false);
}
void ChatFinished()
{
var text = InputBox.Text;
InputBox.Text = "";
if (string.IsNullOrWhiteSpace(text)) return;
AddText(text);
}
[ConCmd("say")]
private static void Say(string msg)
{
var chat = Game.ActiveScene.GetAll<Chat>().FirstOrDefault();
if (Application.IsDedicatedServer)
{
chat.AddSystemText(msg);
}
else
{
chat.AddText(msg);
}
}
[Rpc.Broadcast]
public void AddText(string message)
{
message = message.Truncate(300);
if (string.IsNullOrWhiteSpace(message)) return;
var author = Rpc.Caller.DisplayName;
var steamid = Rpc.Caller.SteamId;
Log.Info($"{author}: {message}");
// Filter name and message content
var filteredName = Steam.FilterName(author, steamid);
message = Steam.FilterChat(message, steamid);
Entries.Add(new Entry(steamid, filteredName, message, 0.0f));
StateHasChanged();
}
[Rpc.Broadcast(NetFlags.HostOnly)]
public void AddSystemText(string message, string icon = "ℹ️")
{
message = message.Truncate(300);
if (string.IsNullOrWhiteSpace(message)) return;
Entries.Add(new Entry(0, icon, message, 0.0f));
StateHasChanged();
}
}Key Features
- RPC Broadcasting: [Rpc.Broadcast] sends messages to all clients, [Rpc.Broadcast(NetFlags.HostOnly)] for server-only messages
- Steam Filtering: Steam.FilterName() and Steam.FilterChat() sanitize user content
- Avatar Display: avatar:@steamid URL pattern for Steam avatars
- Console Command: [ConCmd("say")] allows chat via console
- Auto-cleanup: Entries older than 20 seconds are automatically removed
- Dedicated Server Support: Different behavior for dedicated vs listen servers
Was this helpful?