SetNet.Chat
1.1.0
See the version list below for details.
dotnet add package SetNet.Chat --version 1.1.0
NuGet\Install-Package SetNet.Chat -Version 1.1.0
<PackageReference Include="SetNet.Chat" Version="1.1.0" />
<PackageVersion Include="SetNet.Chat" Version="1.1.0" />
<PackageReference Include="SetNet.Chat" />
paket add SetNet.Chat --version 1.1.0
#r "nuget: SetNet.Chat, 1.1.0"
#:package SetNet.Chat@1.1.0
#addin nuget:?package=SetNet.Chat&version=1.1.0
#tool nuget:?package=SetNet.Chat&version=1.1.0
<p align="center"> <img src="https://raw.githubusercontent.com/Povstalez/SetNet/master/assets/icon.png" alt="SetNet" width="96"> </p>
SetNet.Chat
Text chat for SetNet.
Almost every multiplayer game wants a chat box — a lobby chat, a team channel, a global feed. This package gives you a channel-based, server-relayed text chat by composition: clients join channels by name, send text to a channel, and receive everyone else's messages on the channels they've joined. The server relays and moderates; you don't write any of the plumbing.
It ships with light moderation built in:
- length limiting — messages longer than
MaxLengthare truncated, - profanity filtering — a whole-word, case-insensitive censor that replaces matched words with asterisks,
- auto-cleanup — a peer is removed from all its channels when it disconnects.
Added alongside your regular messages — no base class, no subclassing.
Install
dotnet add package SetNet
dotnet add package SetNet.Chat
Setup
ChatRuntime.Enable(); // once at startup, both ends, before creating client/server
Server
var chat = server.UseChat(new ChatOptions
{
MaxLength = 500, // longer messages are truncated
ProfanityWords = new[] { "badword", "anotherone" }, // whole-word, case-insensitive censor
});
That's it — the server relays each message to every peer on the same channel and drops disconnected peers from their channels automatically. UseChat() with no options uses the defaults (MaxLength = 500, no profanity list).
Client
var chat = client.UseChat();
chat.MessageReceived += (channel, senderPlayerId, text) =>
AppendToChatBox(channel, senderPlayerId, text);
// join the channels you care about:
await chat.JoinAsync("global");
await chat.JoinAsync("team-red");
// send a message to a channel:
await chat.SendAsync("global", "gg wp");
// leave a channel when you're done:
await chat.LeaveAsync("team-red");
senderPlayerId is the sender's peer id as a compact string (Guid.ToString("N")). You only receive messages for channels you've joined.
API
Client — ChatClient (client.UseChat()):
| Member | Purpose |
|---|---|
Task JoinAsync(string channel) |
join a channel |
Task LeaveAsync(string channel) |
leave a channel |
Task SendAsync(string channel, string text) |
send a message to a channel |
event Action<string,string,string> MessageReceived |
incoming message — (channel, senderPlayerId, text) |
Server — ChatServer (server.UseChat(options?)): installs the channel relay + moderation and auto-removes peers on disconnect.
ChatOptions:
| Option | Default | Purpose |
|---|---|---|
MaxLength |
500 |
messages longer than this are truncated |
ProfanityWords |
null |
words to censor (whole-word, case-insensitive), replaced with asterisks |
Notes
- Server-relayed, not peer-to-peer. The server is the hub: it moderates and fans a message out to the channel's members. Sanitizing happens server-side, so clients can't bypass it.
- Profanity matching is case-insensitive substring replacement; each match is swapped for the same number of asterisks. It's a simple filter, not a full moderation system — layer your own logic on top if you need more.
- Channels are ad-hoc — a channel exists as soon as someone joins it; there's no separate "create". Use any naming scheme you like (
"global","team-red",$"room-{code}"). - Reliable delivery. Chat rides
DeliveryMethod.Reliable, so messages are ordered and not dropped. - Node-local. Channels are live peers on one server node. A multi-node deployment would coordinate through a shared bus.
- Reserved wire types
65509 / 65510. Serializer-agnostic (hand-framed protocol) — chat works regardless of which serializer you register.
Documentation & source
- 🐙 https://github.com/Povstalez/SetNet — full module catalog in docs/MODULES.md
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- SetNet (>= 1.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.