A CounterStrikeSharp plugin for Counter-Strike 2 servers that lets every player curate map music and ambience through the in-game !dj console with persistent per-player preferences.
Warning
SoundControlPlugin depends on the Source 2 SosStartSoundEvent (UM 208) and SosSetSoundEventParams (UM 210) message flow. Custom server builds that block or rewrite those messages will prevent the volume overrides from applying.
- Interactive Volume Menu: Players open
!djto choose from built-in loudness presets, all previewed in real time. - Per-Player Persistence: A MySQL table stores each SteamID's preferred multiplier so the choice survives reconnects and map rotations.
- Event-Safe Hooking: The plugin watches
SosStartSoundEventand injectsSosSetSoundEventParamsinstead of muting tracks outright. - Localized Copy: Language packs in
lang/en.jsonandlang/zh-Hans.jsonkeep the menu bilingual by default. - Graceful Fallback: When a map restarts its ambient loop, the saved volume is reapplied automatically.
- Download the latest release from the SoundControlPlugin releases.
- Extract to
game/csgo/addons/counterstrikesharp/plugins/SoundControlPlugin. - Copy
Config/SoundControlPlugin.jsontoaddons/counterstrikesharp/configs/plugins/SoundControlPlugin/SoundControlPlugin.json. - Restart your CS2 server or reload via
css_plugins unload SoundControlPluginthencss_plugins load SoundControlPlugin.
Note
On first launch the plugin validates the DJ_Settings table. If an older schema is detected it is rebuilt automatically, so always back up your database before upgrading production servers.
The configuration file only needs database credentials and lives at addons/counterstrikesharp/configs/plugins/SoundControlPlugin/SoundControlPlugin.json.
{
"Database": {
"Host": "127.0.0.1",
"Port": 3306,
"User": "",
"Password": "",
"Name": ""
}
}| Field | Description |
|---|---|
Host |
Database hostname or IP address. |
Port |
Listening port (defaults to 3306). |
User |
Account with permission to create and update DJ_Settings. |
Password |
Password for the MySQL user. |
Name |
Target schema where the plugin table should be created. |
Restart the server after editing the file so CounterStrikeSharp reloads the config into the plugin.
- Table name:
DJ_Settings - Columns:
steamid64 BIGINT UNIQUE,SoundVolume FLOAT DEFAULT 1.0 - Migrations: if an old
IsSoundBlockedcolumn is detected, the table is dropped and recreated with the new structure. - Saves occur asynchronously on player updates, disconnects, and round transitions to avoid blocking gameplay threads.
This plugin's approach to adjusting ambient audio draws inspiration from a community prototype shared in the CounterStrikeSharp Discord:
The snippet below illustrates how SosStartSoundEvent (208) can be paired with SosSetSoundEventParams (210) to scale sound volume:
public HookResult HookUserMessage208(UserMessage um)
{
var soundevent = um.ReadUInt("soundevent_hash");
var soundevent_guid = um.ReadUInt("soundevent_guid");
var extend = UserMessage.FromId(210);
extend.SetUInt("soundevent_guid", soundevent_guid);
var volumeBytes = GetSoundVolumeParams(3f);
var packedParams = new byte[] { 0xE9, 0x54, 0x60, 0xBD, 0x08, 0x04, 0x00 }.
Concat(volumeBytes).ToArray();
extend.SetBytes("packed_params", packedParams);
extend.Recipients = um.Recipients;
extend.Send();
return HookResult.Continue;
}
private byte[] GetSoundVolumeParams(float volume) => BitConverter.GetBytes(volume);!dj— Opens the menu (aliasesdjor/djdepending on your chat trigger configuration).
Issues, feature requests, and pull requests are welcome! Please discuss substantial changes via issues before submitting major PRs so we can keep configuration compatibility intact.
一个用于 Counter-Strike 2 服务器的背景音乐音量控制插件,玩家可通过 !dj 菜单即时调节地图原声,设置会自动保存并在所有服务器上同步。
Warning
插件依赖 SosStartSoundEvent / SosSetSoundEventParams 消息链路。如果您的服务端屏蔽了这些消息,音量覆盖将无法生效。
- 交互式音量菜单: 玩家输入
!dj即可弹出预设音量选项,并实时生效。 - 玩家独立存档: 使用 MySQL 表记录 SteamID 对应音量,重连或换图都能保持。
- 安全事件注入: 捕获背景音启动事件后,仅修改音量参数,不破坏原始音轨。
- 多语言支持:
lang/en.json、lang/zh-Hans.json已内置,可自行扩展更多语言。 - 自动回写: 地图或回合重新播放 BGM 时,插件会自动重新设置对应音量。
- CounterStrikeSharp
- MetaMod:Source (CS2)
- CS2MenuManager
- MySQL 5.7+
- 在 Release 页面 下载最新版本。
- 解压到
game/csgo/addons/counterstrikesharp/plugins/SoundControlPlugin。 - 将
Config/SoundControlPlugin.json复制到addons/counterstrikesharp/configs/plugins/SoundControlPlugin/。 - 重启服务器或通过
css_plugins reload SoundControlPlugin热重载。
Note
首次运行会检测 DJ_Settings 表结构。如发现旧版字段会自动删除并重建,请在生产环境升级前做好备份。
本插件的配置仅包含数据库信息,示例:
{
"Database": {
"Host": "127.0.0.1",
"Port": 3306,
"User": "",
"Password": "",
"Name": ""
}
}| 字段 | 说明 |
|---|---|
Host |
数据库主机或 IP。 |
Port |
端口,默认 3306。 |
User |
拥有创建/写入 DJ_Settings 权限的账号。 |
Password |
上述账号的密码。 |
Name |
插件创建数据表的目标库名。 |
修改完成后请重启服务器以重新加载配置。
- 表名:
DJ_Settings - 字段:
steamid64 BIGINT UNIQUE、SoundVolume FLOAT DEFAULT 1.0 - 迁移逻辑:检测到旧的
IsSoundBlocked列会自动丢弃旧表并创建新结构。 - 保存策略:在玩家调节、断线和回合切换时异步写入,避免阻塞游戏线程。
插件的实现思路来自 CounterStrikeSharp Discord 中的原型分享:
下方代码演示了如何在 SosStartSoundEvent (208) 中读取事件,再通过 SosSetSoundEventParams (210) 设置音量:
public HookResult HookUserMessage208(UserMessage um)
{
var soundevent = um.ReadUInt("soundevent_hash");
var soundevent_guid = um.ReadUInt("soundevent_guid");
var extend = UserMessage.FromId(210);
extend.SetUInt("soundevent_guid", soundevent_guid);
var volumeBytes = GetSoundVolumeParams(3f);
var packedParams = new byte[] { 0xE9, 0x54, 0x60, 0xBD, 0x08, 0x04, 0x00 }.
Concat(volumeBytes).ToArray();
extend.SetBytes("packed_params", packedParams);
extend.Recipients = um.Recipients;
extend.Send();
return HookResult.Continue;
}
private byte[] GetSoundVolumeParams(float volume) => BitConverter.GetBytes(volume);!dj— 打开菜单(根据聊天前缀也可输入/dj或dj)。
欢迎提交 Issue、Pull Request 或通过 讨论区 反馈需求。大改动请先沟通以避免配置破坏性变化。