Files
CS2-SimpleAdmin/CS2-SimpleAdmin-docs/docs/developer/api/overview.md
Dawid Bepierszcz b0d8696756 Add CS2-SimpleAdmin documentation site
Introduces a new documentation site for CS2-SimpleAdmin using Docusaurus, including developer API references, tutorials, user guides, and module documentation. Removes the CleanModule example and updates FunCommands and ExampleModule. Also updates main plugin and API files to support new documentation and module structure.
2025-10-20 01:27:01 +02:00

13 KiB

sidebar_position
sidebar_position
1

API Overview

Complete reference for the CS2-SimpleAdmin API (ICS2_SimpleAdminApi).

Introduction

The CS2-SimpleAdmin API is exposed via the ICS2_SimpleAdminApi interface, accessible through CounterStrikeSharp's capability system.


Getting the API

Using Capability System

using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Capabilities;
using CS2_SimpleAdminApi;

public class YourPlugin : BasePlugin
{
    private ICS2_SimpleAdminApi? _api;
    private readonly PluginCapability<ICS2_SimpleAdminApi> _pluginCapability =
        new("simpleadmin:api");

    public override void OnAllPluginsLoaded(bool hotReload)
    {
        _api = _pluginCapability.Get();

        if (_api == null)
        {
            Logger.LogError("CS2-SimpleAdmin API not found!");
            Unload(false);
            return;
        }

        // API is ready to use
        RegisterFeatures();
    }
}

Static Capability Reference

// Alternative approach
var capability = ICS2_SimpleAdminApi.PluginCapability;
var api = capability?.Get();

API Categories

The API is organized into logical categories:

Category Description Learn More
Commands Register/unregister commands, parse targets
Menus Create admin menus with player selection
Penalties Issue bans, mutes, gags, warnings
Events Subscribe to plugin events
Utilities Helper functions, player info, activity messages

Quick Reference

Command Management

// Register command
_api.RegisterCommand(name, description, callback);

// Unregister command
_api.UnRegisterCommand(name);

// Parse player targets
var targets = _api.GetTarget(command);

// Log command
_api.LogCommand(caller, command);

Full Documentation →


Menu System

// Register category
_api.RegisterMenuCategory(categoryId, categoryName, permission);

// Register menu
_api.RegisterMenu(categoryId, menuId, menuName, menuFactory, permission, commandName);

// Create menu with players
_api.CreateMenuWithPlayers(context, admin, filter, onSelect);

// Create menu with back button
_api.CreateMenuWithBack(context, admin);

// Add menu option
_api.AddMenuOption(menu, name, action, disabled, permission);

// Add submenu
_api.AddSubMenu(menu, name, subMenuFactory, disabled, permission);

// Open menu
_api.OpenMenu(menu, player);

// Unregister menu
_api.UnregisterMenu(categoryId, menuId);

Full Documentation →


Penalty Management

// Issue penalty to online player
_api.IssuePenalty(player, admin, penaltyType, reason, duration);

// Issue penalty by SteamID
_api.IssuePenalty(steamId, admin, penaltyType, reason, duration);

// Get player info
var playerInfo = _api.GetPlayerInfo(player);

// Get mute status
var muteStatus = _api.GetPlayerMuteStatus(player);

Penalty Types:

  • PenaltyType.Ban - Ban player
  • PenaltyType.Kick - Kick player
  • PenaltyType.Gag - Block text chat
  • PenaltyType.Mute - Block voice chat
  • PenaltyType.Silence - Block both
  • PenaltyType.Warn - Issue warning

Full Documentation →


Event System

// Plugin ready event
_api.OnSimpleAdminReady += OnReady;

// Player penaltied
_api.OnPlayerPenaltied += OnPlayerPenaltied;

// Offline penalty added
_api.OnPlayerPenaltiedAdded += OnPlayerPenaltiedAdded;

// Admin activity
_api.OnAdminShowActivity += OnAdminActivity;

// Admin silent toggle
_api.OnAdminToggleSilent += OnAdminToggleSilent;

Full Documentation →


Utility Functions

// Get player info with penalties
var info = _api.GetPlayerInfo(player);

// Get database connection string
var connectionString = _api.GetConnectionString();

// Get server address
var serverAddress = _api.GetServerAddress();

// Get server ID
var serverId = _api.GetServerId();

// Get valid players
var players = _api.GetValidPlayers();

// Check if admin is silent
bool isSilent = _api.IsAdminSilent(player);

// Get all silent admins
var silentAdmins = _api.ListSilentAdminsSlots();

// Show admin activity
_api.ShowAdminActivity(messageKey, callerName, dontPublish, args);

// Show admin activity with custom translation
_api.ShowAdminActivityTranslated(translatedMessage, callerName, dontPublish);

// Show admin activity with module localizer (recommended)
_api.ShowAdminActivityLocalized(moduleLocalizer, messageKey, callerName, dontPublish, args);

Full Documentation →


Common Patterns

Basic Module Structure

using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Capabilities;
using CS2_SimpleAdminApi;

namespace MyModule;

public class MyModule : BasePlugin
{
    private ICS2_SimpleAdminApi? _api;
    private readonly PluginCapability<ICS2_SimpleAdminApi> _pluginCapability =
        new("simpleadmin:api");

    public override string ModuleName => "My Module";
    public override string ModuleVersion => "1.0.0";

    public override void OnAllPluginsLoaded(bool hotReload)
    {
        _api = _pluginCapability.Get();
        if (_api == null) return;

        // Register features
        RegisterCommands();

        // Wait for SimpleAdmin ready
        _api.OnSimpleAdminReady += RegisterMenus;
        RegisterMenus();  // Fallback for hot reload
    }

    public override void Unload(bool hotReload)
    {
        if (_api == null) return;

        // Cleanup
        _api.UnRegisterCommand("css_mycommand");
        _api.UnregisterMenu("category", "menu");
        _api.OnSimpleAdminReady -= RegisterMenus;
    }
}

Command with Target Selection

[CommandHelper(1, "<#userid or name>")]
[RequiresPermissions("@css/generic")]
private void OnMyCommand(CCSPlayerController? caller, CommandInfo command)
{
    // Parse targets
    var targets = _api!.GetTarget(command);
    if (targets == null) return;

    // Filter valid players
    var players = targets.Players
        .Where(p => p.IsValid && !p.IsBot && caller!.CanTarget(p))
        .ToList();

    // Process each player
    foreach (var player in players)
    {
        DoSomethingToPlayer(caller, player);
    }

    // Log command
    _api.LogCommand(caller, command);
}

Menu with Player Selection

private object CreateMyMenu(CCSPlayerController admin, MenuContext context)
{
    // Context contains categoryId, menuId, menuName, permission, commandName
    return _api!.CreateMenuWithPlayers(
        context,  // Automatic title and category
        admin,
        player => player.IsValid && admin.CanTarget(player),
        (admin, target) =>
        {
            // Action when player selected
            PerformAction(admin, target);
        }
    );
}

Nested Menu

private object CreatePlayerMenu(CCSPlayerController admin, MenuContext context)
{
    var menu = _api!.CreateMenuWithBack(context, admin);

    var players = _api.GetValidPlayers()
        .Where(p => admin.CanTarget(p));

    foreach (var player in players)
    {
        _api.AddSubMenu(menu, player.PlayerName, admin =>
        {
            return CreateActionMenu(admin, player);
        });
    }

    return menu;
}

private object CreateActionMenu(CCSPlayerController admin, CCSPlayerController target)
{
    var menu = _api!.CreateMenuWithBack($"Actions for {target.PlayerName}", "category", admin);

    _api.AddMenuOption(menu, "Action 1", _ => DoAction1(admin, target));
    _api.AddMenuOption(menu, "Action 2", _ => DoAction2(admin, target));

    return menu;
}

Issue Penalty

private void BanPlayer(CCSPlayerController? admin, CCSPlayerController target, int duration, string reason)
{
    // Issue ban
    _api!.IssuePenalty(
        target,
        admin,
        PenaltyType.Ban,
        reason,
        duration  // minutes, 0 = permanent
    );

    // Show activity
    if (admin == null || !_api.IsAdminSilent(admin))
    {
        _api.ShowAdminActivityLocalized(
            Localizer,
            "ban_message",
            admin?.PlayerName,
            false,
            target.PlayerName,
            duration
        );
    }
}

Event Subscription

public override void OnAllPluginsLoaded(bool hotReload)
{
    _api = _pluginCapability.Get();
    if (_api == null) return;

    // Subscribe to events
    _api.OnPlayerPenaltied += OnPlayerPenaltied;
}

private void OnPlayerPenaltied(
    PlayerInfo player,
    PlayerInfo? admin,
    PenaltyType type,
    string reason,
    int duration,
    int? penaltyId,
    int? serverId)
{
    Logger.LogInformation($"{player.PlayerName} received {type}: {reason} ({duration} min)");

    // React to penalty
    if (type == PenaltyType.Ban)
    {
        // Handle ban
    }
}

public override void Unload(bool hotReload)
{
    if (_api == null) return;
    _api.OnPlayerPenaltied -= OnPlayerPenaltied;
}

Best Practices

1. Always Check for Null

if (_api == null)
{
    Logger.LogError("API not available!");
    return;
}

2. Use OnSimpleAdminReady Event

_api.OnSimpleAdminReady += () =>
{
    // Register menus only when SimpleAdmin is ready
    RegisterMenus();
};

// Also call directly for hot reload case
RegisterMenus();

3. Clean Up on Unload

public override void Unload(bool hotReload)
{
    if (_api == null) return;

    // Unregister all commands
    _api.UnRegisterCommand("css_mycommand");

    // Unregister all menus
    _api.UnregisterMenu("category", "menu");

    // Unsubscribe all events
    _api.OnSimpleAdminReady -= OnReady;
}

4. Validate Player State

if (!player.IsValid || !player.PawnIsAlive)
{
    return;
}

if (!caller.CanTarget(player))
{
    return;  // Immunity check
}

5. Use Per-Player Translations

// Each player sees message in their configured language
_api.ShowAdminActivityLocalized(
    Localizer,  // Your module's localizer
    "translation_key",
    caller?.PlayerName,
    false,
    args
);

6. Log All Admin Actions

_api.LogCommand(caller, command);
// or
_api.LogCommand(caller, $"css_mycommand {player.PlayerName}");

API Versioning

The API uses semantic versioning:

  • Major - Breaking changes
  • Minor - New features, backwards compatible
  • Patch - Bug fixes

Current Version: Check GitHub Releases


Thread Safety

The API is designed for single-threaded use within the CounterStrikeSharp game thread.

Do NOT:

  • Call API methods from background threads
  • Use async/await with API calls without proper synchronization

Do:

  • Call API methods from event handlers
  • Call API methods from commands
  • Call API methods from timers

Error Handling

The API uses exceptions for critical errors:

try
{
    _api.RegisterCommand("css_cmd", "Desc", callback);
}
catch (ArgumentException ex)
{
    Logger.LogError($"Failed to register command: {ex.Message}");
}

Common exceptions:

  • ArgumentException - Invalid arguments
  • InvalidOperationException - Invalid state
  • KeyNotFoundException - Player not found

Performance Considerations

Efficient Player Filtering

// ✅ Good - single LINQ query
var players = _api.GetValidPlayers()
    .Where(p => p.IsValid && admin.CanTarget(p))
    .ToList();

// ❌ Bad - multiple iterations
var players = _api.GetValidPlayers();
players = players.Where(p => p.IsValid).ToList();
players = players.Where(p => admin.CanTarget(p)).ToList();

Cache Expensive Operations

// Cache menu creation if used multiple times
private object? _cachedMenu;

private object GetMenu(CCSPlayerController player)
{
    if (_cachedMenu == null)
    {
        _cachedMenu = CreateMenu(player);
    }
    return _cachedMenu;
}

Debugging

Enable Detailed Logging

Logger.LogInformation("Debug: API loaded");
Logger.LogWarning("Warning: Player not found");
Logger.LogError("Error: Failed to execute command");

Check API Availability

public override void OnAllPluginsLoaded(bool hotReload)
{
    _api = _pluginCapability.Get();

    if (_api == null)
    {
        Logger.LogError("❌ CS2-SimpleAdmin API not found!");
        Logger.LogError("Make sure CS2-SimpleAdmin is installed and loaded.");
        return;
    }

    Logger.LogInformation("✅ CS2-SimpleAdmin API loaded successfully");
}

Next Steps


Resources