YappersHQ.ReservedSlots.Shared 1.0.1

dotnet add package YappersHQ.ReservedSlots.Shared --version 1.0.1
                    
NuGet\Install-Package YappersHQ.ReservedSlots.Shared -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="YappersHQ.ReservedSlots.Shared" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="YappersHQ.ReservedSlots.Shared" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="YappersHQ.ReservedSlots.Shared" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add YappersHQ.ReservedSlots.Shared --version 1.0.1
                    
#r "nuget: YappersHQ.ReservedSlots.Shared, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package YappersHQ.ReservedSlots.Shared@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=YappersHQ.ReservedSlots.Shared&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=YappersHQ.ReservedSlots.Shared&version=1.0.1
                    
Install as a Cake Tool

<div align="center"> <h1><strong>ReservedSlots</strong></h1> <p>Reserved slots for CS2 / ModSharp — keep seats free for your VIPs and admins on a full server.</p> </div>

<p align="center"> <a href="https://github.com/Kxnrl/modsharp-public"><img src="https://img.shields.io/badge/framework-ModSharp-5865F2?logo=github" alt="ModSharp"></a> <img src="https://img.shields.io/badge/game-CS2-orange" alt="CS2"> <img src="https://img.shields.io/badge/license-MIT-green" alt="MIT"> <img src="https://img.shields.io/gitlab/stars/cs2-server-plugins/cs2-reservedslots?gitlab_url=https%3A%2F%2Fgitlab.com" alt="Stars"> </p>


ReservedSlots keeps a configurable number of slots reserved for privileged players. When the public quota is full, ordinary players are rejected at connection time while VIPs and admins are still let in. It can optionally kick a non-privileged player when the server fills completely, so a seat is always free for the next VIP/admin. VIP membership is supplied by other plugins through a small shared interface (IReservedSlotsShared); admin/VIP flags come from ModSharp's AdminManager.

🚀 Install

Copy the build output into your ModSharp install (<sharp> = your sharp directory):

From To
.build/modules/ReservedSlots.Core/ <sharp>/modules/ReservedSlots.Core/
.build/shared/ReservedSlots.Shared/ <sharp>/shared/ReservedSlots.Shared/
.build/configs/cs2-reservedslots.json <sharp>/configs/cs2-reservedslots.json

Restart the server (or change map) to load. The config is written with defaults on first run if it doesn't exist. AdminManager (ships with ModSharp) is used for admin/VIP flags — without it, flag-based access is skipped (a warning is logged) and only the shared-interface VIP source applies.

⚙️ Configuration

configs/cs2-reservedslots.json (auto-generated on first run):

Setting Default Meaning
TotalReservedSlots 3 Total reserved slots. Public limit = MaxClients - TotalReservedSlots. Set 0 to disable the gate entirely.
VipSlots 2 How many of the reserved slots VIPs (and the VipFlag) may fill.
AdminSlots 1 Admin-only reserved slots (the depth between VipSlots and TotalReservedSlots).
AdminFlag @reservedslots/admin Admin permission that grants admin-level reserved access.
VipFlag @reservedslots/vip Admin permission that grants VIP-level reserved access.
KickType None None = join-gating only (nobody already connected is touched). Kick = when the server is completely full, kick a non-privileged player to keep a slot free. Legacy Spectate is treated as Kick.
AllowAdminsToFillVipSlots true If true, admins may also occupy VIP slots, not just admin-only slots.

Both @reservedslots/admin and @reservedslots/vip are registered with AdminManager on load, so they can be assigned to admin groups.

🔧 How it works

Reservation is enforced at the connection hook (ConnectClient), not the admin check — OnClientPreAdminCheck can't reject a connection. The connecting player is counted as +1; if that pushes the human count past the public limit (MaxClients - TotalReservedSlots), the player must hold reserved access or they're rejected with RejectServerFull. Reserved access is tiered: VIPs and the VIP flag fill the first VipSlots of depth, admins fill the remaining admin-only depth (and the VIP depth too when AllowAdminsToFillVipSlots is set). Players who just disconnected get a 180-second reconnect grace so changelevel / reconnect storms never bump someone who was already in the match.

With KickType: Kick, a completely full server instead kicks one non-privileged player after a new join — spectators first, then the most recently connected (long-time players keep their seat) — deferred to the end of the frame to avoid racing the engine's snapshot send path.

CS2 has no maxplayers convar — the gate reads the engine's live MaxClients. If that's unavailable the gate is inert (fails open). The live slot math is logged at every map start.

🧩 Public API

VIP membership is not stored here — other plugins declare who is a VIP through IReservedSlotsShared. Resolve it in OnAllModulesLoaded and subscribe a predicate:

var rs = sharpModuleManager
    .GetOptionalSharpModuleInterface<IReservedSlotsShared>(IReservedSlotsShared.Identity)?.Instance;

rs!.IsVipFor        += client => /* is this IGameClient a VIP? */;
rs!.IsVipForSteamId += steamId => /* is this SteamID a VIP? */;

IsVipBySteamId(ulong) is also exposed for direct queries. If no subscriber claims a player, they're treated as non-VIP.

📦 Build

dotnet build -c Release

Outputs the module to .build/modules/ReservedSlots.Core/ReservedSlots.dll, the shared contract to .build/shared/ReservedSlots.Shared/ReservedSlots.Shared.dll, and the default config to .build/configs/cs2-reservedslots.json.


<div align="center"> <p>Made with ❤️ by <a href="https://gitlab.com/cs2-server-plugins">cs2-server-plugins</a></p> <p>⭐ Star this repo if you find it useful!</p> </div>

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 103 8/10/2026
1.0.0 116 8/1/2026