CS Plugin Examples - RaidMax/IW4M-Admin GitHub Wiki

SimpleWelcome Example Plugin

A beginner-friendly C# script plugin that demonstrates key IW4MAdmin plugin features:

  • Configuration — JSON-based settings with automatic file generation
  • Event Handling — Subscribing to player join events with proper cleanup
  • Custom Commands — Automatic command discovery and registration
  • Dependency Injection — Constructor-based service injection with logging

Copy this file to your Plugins/ folder to get started, then customize it for your needs.


#:package RaidMax.IW4MAdmin.SharedLibraryCore@2026.1.6.1

using System;
using System.Threading;
using System.Threading.Tasks;
using Data.Models.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SharedLibraryCore;
using SharedLibraryCore.Commands;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Events.Management;
using SharedLibraryCore.Interfaces;
using SharedLibraryCore.Interfaces.Events;

/// <summary>
/// A simple welcome plugin that greets players when they join and responds to chat.
/// This is a beginner-friendly example you can copy, modify, and use right away!
/// 
/// CONFIGURATION APPROACH:
/// This plugin uses the FULL DI-based configuration approach (custom config class).
/// 
/// HOW TO USE:
/// 1. Copy this file to your Plugins/ folder
/// 2. Save the file - it will automatically reload!
/// 3. Join a server to see the welcome message
/// 4. Type "!hello" or "!hey" in chat to get a response
/// 5. Edit the configuration file: Configuration/SimpleWelcomeSettings.json
/// </summary>
public class SimpleWelcomePlugin : IPluginV2
{
    // Basic plugin information
    public string Name => "Simple Welcome";
    public string Author => "Your Name Here";
    public string Version => "1.0";

    // Services we'll use (injected automatically)
    private readonly ILogger<SimpleWelcomePlugin> _logger;
    private readonly SimpleWelcomeConfiguration _config;
    private readonly IManager _manager;

    /// <summary>
    /// This method is called when the plugin loads to register any dependencies.
    /// Here we register our configuration so it can be saved/loaded from a JSON file.
    /// </summary>
    public static void RegisterDependencies(IServiceCollection serviceCollection)
    {
        // Register our configuration - this creates a file at Configuration/SimpleWelcomeSettings.json
        serviceCollection.AddConfiguration<SimpleWelcomeConfiguration>(
            "SimpleWelcomeSettings",
            new SimpleWelcomeConfiguration()); // Default config values
    }

    /// <summary>
    /// Constructor - called when the plugin is first loaded.
    /// Services are automatically injected by the dependency injection system.
    /// </summary>
    public SimpleWelcomePlugin(
        ILogger<SimpleWelcomePlugin> logger,
        SimpleWelcomeConfiguration config,
        IManager manager)
    {
        _logger = logger;
        _config = config;
        _manager = manager;

        // Subscribe to events - this is how we react to things happening in-game
        IManagementEventSubscriptions.ClientStateAuthorized += OnPlayerJoined;

        _logger.LogInformation("Simple Welcome Plugin loaded! Welcome messages: {Enabled}",
            _config.EnableWelcomeMessages);
    }

    /// <summary>
    /// This method runs when a player joins the server and is fully authorized.
    /// </summary>
    private Task OnPlayerJoined(ClientStateAuthorizeEvent clientEvent, CancellationToken token)
    {
        // Check if welcome messages are enabled
        if (!_config.EnableWelcomeMessages)
        {
            return Task.CompletedTask;
        }

        var player = clientEvent.Client;
        var server = player.CurrentServer;

        // Send a personal welcome message to the player
        var personalMessage = _config.WelcomeMessage
            .Replace("{{PlayerName}}", player.Name)
            .Replace("{{ServerName}}", server.ServerName);

        player.Tell(personalMessage);

        // Optionally broadcast to everyone on the server
        if (_config.BroadcastWelcome)
        {
            var broadcastMessage = _config.BroadcastMessage
                .Replace("{{PlayerName}}", player.Name);
            
            server.Broadcast(broadcastMessage);
        }

        _logger.LogDebug("Welcomed player: {PlayerName}", player.Name);
        
        return Task.CompletedTask;
    }


    /// <summary>
    /// This method is called when the plugin is unloaded (hot reload, shutdown, etc.).
    /// IMPORTANT: Always unsubscribe from events here to prevent memory leaks!
    /// </summary>
    public void Dispose()
    {
        // Unsubscribe from all events
        IManagementEventSubscriptions.ClientStateAuthorized -= OnPlayerJoined;

        _logger.LogInformation("Simple Welcome Plugin unloaded");
    }
}

/// <summary>
/// A simple command that players can use in-game.
/// Players type "!hello" to execute this command.
/// Commands in .cs plugin files are automatically discovered and registered!
/// </summary>
public class HelloCommand : Command
{
    public HelloCommand(CommandConfiguration config, ITranslationLookup translationLookup) 
        : base(config, translationLookup)
    {
        Name = "hello";
        Description = "Get a friendly greeting from the plugin!";
        Alias = "hey";
        Permission = EFClient.Permission.User; // Anyone can use this command
        RequiresTarget = false; // No target player needed
    }

    public override Task ExecuteAsync(GameEvent gameEvent)
    {
        // This runs when a player types "!hello" or "!hi"
        var player = gameEvent.Origin;
        var server = gameEvent.Owner;

        // Send a greeting to the player
        player.Tell("(Color::Green)Hello (Color::White)" + player.Name + "(Color::Green)! (Color::White)Thanks for using the Simple Welcome plugin!");
        
        return Task.CompletedTask;
    }
}

/// <summary>
/// Configuration settings for the Simple Welcome plugin.
/// This is automatically saved to Configuration/SimpleWelcomeSettings.json
/// You can edit that file to change settings without modifying code!
/// </summary>
public class SimpleWelcomeConfiguration
{
    /// <summary>
    /// Enable/disable welcome messages when players join
    /// </summary>
    public bool EnableWelcomeMessages { get; set; } = true;

    /// <summary>
    /// Whether to broadcast welcome messages to all players on the server
    /// </summary>
    public bool BroadcastWelcome { get; set; } = false;

    /// <summary>
    /// Message sent directly to the player when they join
    /// Use {{PlayerName}} and {{ServerName}} as placeholders
    /// </summary>
    public string WelcomeMessage { get; set; } = "(Color::Green)Welcome (Color::White){{PlayerName}}(Color::Green) to (Color::White){{ServerName}}(Color::Green)! (Color::White)Have fun!";

    /// <summary>
    /// Message broadcast to all players when someone joins (only if BroadcastWelcome is true)
    /// Use {{PlayerName}} as a placeholder
    /// </summary>
    public string BroadcastMessage { get; set; } = "(Color::Yellow){{PlayerName}} (Color::White)has joined the server!";
}

/*
 * QUICK START GUIDE:
 * 
 * 1. SAVE THIS FILE - The plugin automatically reloads when you save!
 * 
 * 2. JOIN A SERVER - You should see a welcome message when you connect
 * 
 * 3. TEST THE COMMAND - Type "!hello" or "!hi" in chat to use the command
 * 
 * 4. CUSTOMIZE IT:
 *    - Edit the configuration file: Configuration/SimpleWelcomeSettings.json
 *    - Change messages, enable/disable features
 *    - Modify the HelloCommand to change what it does
 * 
 * 5. LEARN MORE:
 *    - Events: Subscribe to different events to react to game actions
 *    - Commands: Add more Command classes (like HelloCommand) for players to use
 *    - Configuration: Add more settings to SimpleWelcomeConfiguration
 * 
 * COLOR CODES (use (Color::Name) syntax):
 * (Color::Black)   (Color::Red)     (Color::Green)   (Color::Yellow)
 * (Color::Blue)    (Color::Cyan)    (Color::Purple)  (Color::Pink)
 * (Color::White)   (Color::Grey)    (Color::Accent)
 * 
 * PLACEHOLDERS:
 * {{PlayerName}} - Name of the player
 * {{ServerName}} - Name of the server
 * 
 * TIPS:
 * - Save the file to trigger hot reload and see changes instantly!
 * - Check the logs to see plugin activity
 * - Use _logger.LogInformation() to debug your code
 */
⚠️ **GitHub.com Fallback** ⚠️