๐ฌ Plugin usage / ๐ Bug reports / ๐จโ๐ป Plugin dev discussion, join QQ group: 1085190201 ๐
๐ก Mention me in the group for faster replies ~ โจ
A Counter-Strike 2 server plugin that bridges CS2 events to external chat platforms (QQ / Discord / Kook / Telegram) via WebSocket. Works together with koishi-plugin-mclistener-ws-client to achieve cross-platform group โ server chat interoperability.
Built on CounterStrikeSharp, written in C# (.NET 10). Zero extra NuGet dependencies โ uses only System.Net.WebSockets from the BCL.
- ๐ช Player Join/Leave Broadcast โ announces when players enter or exit the CS2 server
- ๐ฌ Player Chat Forwarding โ forwards in-game chat messages to chat platforms
- ๐จ Group Message Relay โ forwards messages from QQ/Discord/etc. to CS2 in-game chat
- ๐ Token Authentication โ optional
?token=xxxURL parameter for client verification - ๐ Cross-Platform โ runs on both Windows and Linux
- โ๏ธ Auto-Generated Config โ first run creates
config.jsonwith sensible defaults
flowchart LR
KB["Koishi Bot<br/>(QQ/Discord/...)"]
CSSL["CounterStrikeSharpListener<br/>WsServer"]
CS2["CS2 Server<br/>(CounterStrikeSharp)"]
KB <==>|"WebSocket JSON<br/>ws://host:port?token=xxx"| CSSL
CSSL ---|Plugin API| CS2
-
Install Metamod:Source
See https://cs2.poggu.me/metamod/installation/
Download the Linux build and extract to thecsgo/directoryStructure after extraction:
csgo/addons/ โโโ metamod/ -
Install CounterStrikeSharp
Download the with-runtime release
Merge theaddons/folder intocsgo/Structure after merging:
csgo/ โโโ addons/ โโโ metamod/ โโโ counterstrikesharp/ โโโ api/ โโโ dotnet/ โโโ plugins/ -
Add the Plugin CSS requires plugins in
plugins/<PluginName>/<PluginName>.dll(directory name = DLL filename). Download the.dllfrom Releases:# Default Steam path is usually under ~/.local cd "path/to/Steam/steamapps/common/Counter-Strike Global Offensive/game" TAG=<latest version tag> PLUGIN_DIR=csgo/addons/counterstrikesharp/plugins/CounterStrikeSharpListenerWsServer mkdir -p $PLUGIN_DIR cd $PLUGIN_DIR wget "https://github.com/VincentZyuApps/CounterStrikeSharpListenerWsServer/releases/download/$TAG/CounterStrikeSharpListenerWsServer-$TAG.dll" mv CounterStrikeSharpListenerWsServer-$TAG.dll CounterStrikeSharpListenerWsServer.dll
Final plugin structure:
plugins/ โโโ CounterStrikeSharpListenerWsServer/ โโโ CounterStrikeSharpListenerWsServer.dll -
Start the Server
./cs2 -dedicated -game csgo +map de_dust2 +sv_lan 1
You should see
[Plugin] WS Server started on 0.0.0.0:60618in the console. A defaultconfig.jsonwill be generated automatically. -
Configure the Koishi Client In your Koishi plugin config, set:
wsServerUrl:ws://<CS2_SERVER_IP>:60618wsToken:test12345(match withconfig.json)
Important: Change the default token for production use!
๐ค Don't know what RCON is? ๐ See Source RCON Protocol.
RCON allows the plugin to receive text output from commands like status or list (via ExecCommandMode: "rcon-relay").
Create or edit csgo/cfg/server.cfg:
rcon_password "your-strong-password"
log on
sv_logecho 1
The plugin uses the same password in its RconPassword config. Restart after editing.
Add to your server startup command line (cs2ds.sh or similar):
+rcon_password "your-strong-password" \
+sv_logecho 1
โ ๏ธ RCON uses TCP on the game port. Ensure your firewall allows TCP (not only UDP) on the configured port (27015by default).โน๏ธ Some Linux Distros(mainly in Debian/Ubuntu based) note: On Linux, CS2 RCON may bind to
127.0.1.1instead of127.0.0.1(see/etc/hostshostname mapping). Test withnc -zv 127.0.0.1 <port>first; if refused, try127.0.1.1. To force RCON onto all interfaces, add-ip 0.0.0.0tocs2ds.shโ not recommended for security.
On first startup, config.json is auto-generated at csgo/addons/counterstrikesharp/plugins/CounterStrikeSharpListenerWsServer/config.json:
{
"_comment_logLevel": "๐ ๆฅๅฟ็ญ็บง๏ผsilent | fatal | error | warn | info | debug | trace",
"logLevel": "info",
"Host": "0.0.0.0",
"Port": 60618,
"WsToken": "test12345",
"enablePlayerJoinBroadcast": true,
"enablePlayerLeaveBroadcast": true,
"enablePlayerChatBroadcast": true,
"enableReceiveGroupMessage": true,
"GroupMessageFormat": "[{group_name}]({group_id}) {nickname}: {message}",
"BotSuffix": " (bot)",
"PlayerSuffix": " (player)",
"PlayerBroadcastScope": "player",
"ExecCommandMode": "disabled",
"RconHost": "127.0.0.1",
"RconPort": 27015,
"RconPassword": "",
"RconTimeoutMs": 5000
}| Field | Type | Default | Description |
|---|---|---|---|
logLevel |
string | info |
Log level: silent / fatal / error / warn / info / debug / trace |
Host |
string | 0.0.0.0 |
WebSocket server listen address |
Port |
int | 60618 |
WebSocket server listen port |
WsToken |
string | test12345 |
Auth token (empty = no auth) |
enablePlayerJoinBroadcast |
bool | true |
Broadcast player join events |
enablePlayerLeaveBroadcast |
bool | true |
Broadcast player leave events |
enablePlayerChatBroadcast |
bool | true |
Broadcast player chat to chat platforms |
enableReceiveGroupMessage |
bool | true |
Forward group messages to in-game chat |
GroupMessageFormat |
string | [{group_name}]({group_id}) {nickname}: {message} |
Template for in-game group messages |
BotSuffix |
string | (bot) |
Bot name suffix (empty = none) |
PlayerSuffix |
string | (player) |
Player name suffix (empty = none) |
PlayerBroadcastScope |
string | player |
Player event broadcast scope: player (players only) / bot (bots only) / both (all) |
ExecCommandMode |
string | disabled |
disabled (off) / csharp-native (engine, no output) / rcon-relay (RCON, with output) |
RconHost |
string | 127.0.0.1 |
RCON server address |
RconPort |
int | 27015 |
RCON server port (game port) |
RconPassword |
string | "" |
RCON password (must match server.cfg) |
RconTimeoutMs |
int | 5000 |
RCON operations timeout (ms) |
The plugin follows the same JSON protocol used by mcdr_listener_ws_server and levilamina-plugin-mclistener-ws-server, making it fully compatible with the existing koishi-plugin-mclistener-ws-client.
{"type": "player_join", "player_name": "Steve"}
{"type": "player_leave", "player_name": "Steve"}
{"type": "player_chat", "player_name": "Steve", "content": "Hello!"}{"type": "chat_platform_to_server", "group_id": "1085190201", "group_name": "onebot", "nickname": "Alice", "message": "Hi from QQ!"}When pushing to GitHub, keywords in the commit message control the pipeline.
| Keyword | Build DLL | Publish Release |
|---|---|---|
build action |
โ | โ |
build release |
โ | โ |
check โโโ build โโโ release
โ โ โ
โ โ โโโ download artifact โ create GitHub Release
โ โ
โ โโโ dotnet restore โ dotnet build โ upload artifact
โ
โโโ parse commit message โ set control flags
# Build only, no release
git commit -m "fix: fixed a bug, build action"
# Build and publish a Release
git commit -m "feat: added a new feature, build release"Edit the <Version> field in CounterStrikeSharpListenerWsServer.csproj:
<Version>x.y.z</Version>Edit the ModuleVersion string in CounterStrikeSharpListenerWsServer.cs:
public override string ModuleVersion => "x.y.z";The next Release will automatically use vx.y.z-{run_number} as the tag.



