Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cs2-rules

A CounterStrikeSharp plugin for CS2 surf servers that requires each human Steam player to accept versioned server rules / an acceptable-use policy before playing.

Behaviour

  • Identifies players by SteamID64 and stores acceptance in accepted_players.json beside the plugin DLL.
  • Allows the initial T/CT selection, then immediately freezes an unaccepted player before they can move or play.
  • Shows all rules together in a large, centered GameHUD world-text panel after the initial team selector closes.
  • Places a private, opaque two-tile model panel behind that GameHUD text while acceptance is pending; other players never receive those panel entities.
  • Automatically falls back to the native CounterStrikeSharp center panel if GameHUD is missing or unavailable.
  • Prints the rules and acceptance commands to chat as a guaranteed fallback if a CS2 Panorama update suppresses center HTML during initial team selection.
  • Accepts !accept or !agree in chat; !decline disconnects.
  • Blocks normal public/team chat and mutes outgoing voice while acceptance is pending; the rules commands remain available.
  • Hides only the player's crosshair while acceptance is pending without changing their saved client crosshair settings.
  • Leaves the player on their chosen team and unfreezes them immediately after acceptance. The freeze flag prevents player input while still allowing normal game physics such as gravity.
  • Can optionally put the player straight onto CT or T and explicitly respawn them.
  • Keeps the GameHUD message present while acceptance is pending without recreating its entity on every enforcement tick. Its private solid panel carries Source's keep-on-recreate flag so an empty-server round restart does not delete it.
  • Disconnects a player who declines.
  • Exempts bots and HLTV/GOTV.
  • Requires everyone to accept again whenever PolicyVersion changes.
  • Keeps a backup of the previous consent file before each write.

The default GAMEHUD display has no numbered controls and can be positioned and scaled. Native CENTER_TEXT and CENTER_HTML_MENU modes remain available. The rules prompt is deliberately displayed after initial team selection because CS2's Panorama team selector can suppress center HTML. The complete configured text is also printed to chat and the player's console.

Build

Install the .NET 10 SDK, then run:

dotnet restore
dotnet build -c Release

The plugin DLL is produced at:

bin/Release/net10.0/cs2-rules.dll

Install

  1. Install Metamod:Source and CounterStrikeSharp on the CS2 server. CounterStrikeSharp API 369 or newer is required.

  2. Install CS2-GameHUD, including both its plugin and shared/CS2-GameHUDAPI/CS2-GameHUDAPI.dll component.

  3. Create this directory:

    game/csgo/addons/counterstrikesharp/plugins/cs2-rules/
    
  4. Copy cs2-rules.dll into that directory. Do not copy CS2-GameHUDAPI.dll or the NuGet-provided CounterStrikeSharp.API.dll; the server uses its installed shared copies.

  5. Start or restart the server. CounterStrikeSharp creates the config on first load at:

    game/csgo/addons/counterstrikesharp/configs/plugins/cs2-rules/cs2-rules.json
    
  6. Edit the generated config with your real rules and URL. Increment PolicyVersion whenever the terms materially change.

  7. Reload the plugin or restart the server after editing the configuration.

Verify from the server console with:

css_plugins list

Upgrading from the former plugin name

Version 2.0.0 changes the deployment identity to cs2-rules. CounterStrikeSharp therefore uses a new plugin and configuration directory.

  1. Stop the server and remove the former plugin directory so both assemblies cannot load together.
  2. Install the new plugins/cs2-rules/ directory.
  3. Copy the former accepted_players.json into plugins/cs2-rules/ to preserve recorded acceptances.
  4. Copy the former plugin JSON configuration to configs/plugins/cs2-rules/cs2-rules.json to preserve the configured policy and rules.
  5. Start the server and confirm that css_plugins list reports cs2-rules version 2.0.0.

The JSON formats are unchanged; only the deployment identity and paths changed. The redraw command is now !rules / css_rules.

Example configuration

{
  "PolicyVersion": "2026-01",
  "Title": "SERVER RULES / ACCEPTABLE USE POLICY",
  "Rules": [
    "No cheating, scripting, exploiting, or ban evasion.",
    "Treat players and staff with respect; no harassment or hate speech.",
    "Do not disrupt runs, spam communications, or evade server rules.",
    "Follow staff directions and the complete rules published by the server."
  ],
  "RulesUrl": "https://example.com/rules",
  "AcceptedMessage": "Thank you. Your acceptance has been recorded.",
  "DisplayMode": "GAMEHUD",
  "GameHudChannel": 240,
  "GameHudPositionX": 0.0,
  "GameHudPositionY": 0.0,
  "GameHudDistance": 7.0,
  "GameHudFontSize": 32,
  "GameHudFontName": "Verdana",
  "GameHudWorldUnitsPerPixel": 0.025,
  "GameHudScale": 0.35,
  "GameHudColor": "#F2C94C",
  "GameHudBackgroundBorderHeight": 0.35,
  "GameHudBackgroundBorderWidth": 0.5,
  "GameHudDrawBackground": true,
  "GameHudOpaquePanelEnabled": true,
  "GameHudOpaquePanelModel": "models/props/de_train/hr_train_s2/train_logos/train_logo_rough_metal_signboard_18x18_01.vmdl",
  "GameHudOpaquePanelScale": 0.25,
  "GameHudOpaquePanelOverlap": 0.15,
  "GameHudOpaquePanelDepthOffset": 0.15,
  "GameHudOpaquePanelVerticalOffset": 0.0,
  "GameHudOpaquePanelWarmupDelay": 1.25,
  "GameHudOpaquePanelPostMatchStartDelay": 0.15,
  "GameHudOpaquePanelWarmupFallbackSeconds": 4.0,
  "GameHudBackgroundLayers": 1,
  "GameHudBackgroundLayerSpacing": 0.002,
  "GameHudBackgroundMaterial": "",
  "GameHudWrapCharacters": 52,
  "TeamAfterAccept": "SELECT",
  "ReminderIntervalSeconds": 2.0,
  "BlockChatBeforeAccept": true,
  "BlockVoiceBeforeAccept": true,
  "HideCrosshairBeforeAccept": true,
  "ConfigVersion": 1
}

Players can enter !rules or css_rules to redraw the prompt while acceptance is pending. They type !accept / !agree to accept; !decline disconnects. After acceptance, !rules reports the active policy version and rules URL.

DisplayMode may be GAMEHUD (the default large, command-only world-text HUD), CENTER_TEXT (the compact native command-only panel), or CENTER_HTML_MENU (the original compact menu with numbered choices). GAMEHUD falls back to CENTER_TEXT automatically if its API is unavailable.

For GameHUD sizing, GameHudScale is the simplest overall size control; the default 0.35 is 35% of the original 1.4.x size. GameHudFontSize changes the text raster size and GameHudWorldUnitsPerPixel changes its base physical scale. GameHudPositionX and GameHudPositionY move the panel relative to the player's view; GameHudDistance controls its depth. GameHudWrapCharacters controls the panel's line width. GameHudDrawBackground enables GameHUD's stable built-in translucent background and configured padding. GameHudOpaquePanelEnabled adds the experimental solid black model layer behind it. The two stock-model tiles are camera-following, collisionless, and transmitted only to their pending owner. GameHudOpaquePanelScale controls the tile size, GameHudOpaquePanelOverlap closes their middle seam, GameHudOpaquePanelDepthOffset moves them farther behind the text, and GameHudOpaquePanelVerticalOffset adjusts their height. During warmup, the plugin waits for CS2's actual begin_new_match event and creates the tiles after GameHudOpaquePanelPostMatchStartDelay; the stable native backing remains visible until then. GameHudOpaquePanelWarmupFallbackSeconds handles unusual maps that never emit that event. GameHudOpaquePanelWarmupDelay is retained for configuration compatibility and acts as the switch that enables warmup deferral when greater than zero. GameHudBackgroundLayers and GameHudBackgroundLayerSpacing remain in the config for compatibility but point-world-text stacking is disabled. GameHudBackgroundMaterial is reserved for future GameHUD support and currently ignored. Channel 240 is reserved for this plugin; change it if another plugin uses that channel.

GameHUD uses camera-following point_worldtext. It is world geometry, so CS2 renders the weapon viewmodel and Panorama HUD over it. GameHUD does not expose a way to move that text into the topmost Panorama layer.

BlockChatBeforeAccept prevents pending players from sending normal say and say_team messages while allowing !accept, !agree, !decline, and !rules. BlockVoiceBeforeAccept applies CounterStrikeSharp's muted voice flag until the gate releases the player. Both are enabled by default.

HideCrosshairBeforeAccept sets only the crosshair bit in the pawn's networked m_iHideHUD mask. The plugin removes its bit on acceptance or unload while preserving other HUD flags; it never writes the player's archived client crosshair settings.

TeamAfterAccept should normally remain SELECT: the player chooses their team before the rules prompt appears and stays on that team after acceptance. CT and T can force and respawn the newly accepted player; NONE leaves their selected team unchanged. Stored acceptance never forces a team again on later connections.

Operational notes

  • Back up accepted_players.json with the rest of the server data.
  • The opaque panel uses a stock CS2 model that must be entered into the map resource manifest. After first installing 1.8.x, restart the server or change map before testing it. Hot-reloading alone cannot change the active map's manifest. CS2 AdBlock is not required.
  • Keep the on-screen rule summary concise enough to fit at the player's resolution; put the full legal text at RulesUrl.
  • This records the SteamID64, name, policy version, and UTC acceptance time. It is an enforcement/audit aid, not legal advice.

About

A CounterStrikeSharp plugin for CS2 servers that requires each player to accept versioned server rules / an acceptable-use policy before playing.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages