DrAbc.NuggetMod.Core 0.0.7

dotnet add package DrAbc.NuggetMod.Core --version 0.0.7
                    
NuGet\Install-Package DrAbc.NuggetMod.Core -Version 0.0.7
                    
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="DrAbc.NuggetMod.Core" Version="0.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DrAbc.NuggetMod.Core" Version="0.0.7" />
                    
Directory.Packages.props
<PackageReference Include="DrAbc.NuggetMod.Core" />
                    
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 DrAbc.NuggetMod.Core --version 0.0.7
                    
#r "nuget: DrAbc.NuggetMod.Core, 0.0.7"
                    
#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 DrAbc.NuggetMod.Core@0.0.7
                    
#: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=DrAbc.NuggetMod.Core&version=0.0.7
                    
Install as a Cake Addin
#tool nuget:?package=DrAbc.NuggetMod.Core&version=0.0.7
                    
Install as a Cake Tool

NuggetMod

Write metamod plugin based on .NET 10 and later

alternate text is missing from this package README image NuGet Downloads

Features

  • Full MetaMod API Support: Complete binding for MetaMod 1.21 (Interface 5:16)
  • Memory Safety: Advanced GC lifecycle management to prevent dangling pointers
  • C#-Style API: Modern, idiomatic C# API design with optional C++ style compatibility
  • AOT Compatible: Native AOT compilation support for optimal performance
  • Type Safety: Strongly-typed wrappers for all engine structures

Installation

dotnet add package DrAbc.NuggetMod

Quick Start

Basic Plugin Structure

using NuggetMod.Interface;
using NuggetMod.Enum.Metamod;
using NuggetMod.Wrapper.Metamod;

public class MyPlugin : IPlugin
{
    public MetaPluginInfo GetPluginInfo() => new()
    {
        InterfaceVersion = InterfaceVersion.V5_16,
        Name = "MyPlugin",
        Version = "1.0.0",
        Date = "2024-01-01",
        Author = "Your Name",
        Url = "https://github.com/yourname/myplugin",
        LogTag = "[MYPLUGIN]",
        Loadable = PluginLoadTime.Anytime,
        Unloadable = PluginLoadTime.Anytime
    };

    public void MetaInit()
    {
        // Plugin initialization code
    }

    public bool MetaQuery(InterfaceVersion interfaceVersion, MetaUtilFunctions pMetaUtilFuncs)
    {
        return true; // Return true if compatible
    }

    public bool MetaAttach(PluginLoadTime now, MetaGlobals pMGlobals, MetaGameDLLFunctions pGamedllFuncs)
    {
        // Register event handlers
        var events = new DLLEvents();
        events.ClientConnect += OnClientConnect;
        
        SafeEventRegistration.Register(new EventRegistrationBuilder()
            .WithEntityApi(events));
        
        return true;
    }

    public bool MetaDetach(PluginLoadTime now, PluginUnloadReason reason)
    {
        SafeEventRegistration.UnregisterAll();
        return true;
    }

    private (MetaResult, bool) OnClientConnect(Edict pEntity, string pszName, string pszAddress, ref string szRejectReason)
    {
        Console.WriteLine($"Player {pszName} connecting from {pszAddress}");
        return (MetaResult.Handled, true);
    }
}

Usage

To quickly set up your first MetaMod plugin, refer to the template repository:

NuggetMod.Template

Or refer ChatEngine

Build and Publish

# Build with AOT for Windows x86
dotnet publish -c Release -r win-x86 -o ./build -p:PublishAot=true

# Build with AOT for Linux x86
dotnet publish -c Release -r linux-x86 -o ./build -p:PublishAot=true

Memory Safety and GC Lifecycle

Critical: When passing managed delegates to native code, you must ensure they are not garbage collected while native code may still invoke them.

Always use SafeEventRegistration to register event handlers:

// CORRECT: Uses SafeEventRegistration
var builder = new EventRegistrationBuilder()
    .WithEntityApi(new MyDLLEvents())
    .WithEngineFunctions(new MyEngineEvents());

SafeEventRegistration.Register(builder);

Pre-registration Validation

Check for conflicts before registering:

var builder = new EventRegistrationBuilder()
    .WithEntityApi(events);

var validation = SafeEventRegistration.ValidateRegistration(builder);
if (!validation.CanRegister)
{
    Console.WriteLine($"Conflicts: {string.Join(", ", validation.ConflictingTypes)}");
    return;
}

SafeEventRegistration.Register(builder);

Manual Delegate Pinning (Advanced)

For custom native interop, use DelegateLifetimeManager:

// Keep delegate alive
var myDelegate = new MyDelegateType(MyCallback);
DelegateLifetimeManager.Register("MyComponent_MyCallback", myDelegate);

// Later, when no longer needed
DelegateLifetimeManager.Unregister("MyComponent_MyCallback");

API Examples

Module Information and Code Analysis

public void AnalyzeModules()
{
    var metaUtil = MetaMod.MetaUtilFuncs;
    
    // Get engine module information
    nint engineBase = metaUtil.GetEngineBase();
    nint engineHandle = metaUtil.GetEngineHandle();
    
    // Get code section for pattern scanning
    var (codeBase, codeSize) = metaUtil.GetCodeSection(engineBase);
    Console.WriteLine($"Engine code: 0x{codeBase:X} - 0x{codeBase + codeSize:X}");
    
    // Search for pattern in code section
    byte[] pattern = [0x55, 0x8B, 0xEC]; // x86 function prologue
    nint address = metaUtil.SearchPatternInCodeSection(engineBase, pattern);
}

Hook Installation

public void InstallHook()
{
    var metaUtil = MetaMod.MetaUtilFuncs;
    
    // Get function addresses
    nint gameDllBase = metaUtil.GetGameDllBase();
    nint targetFunc = metaUtil.GetProcAddress(gameDllBase, "TargetFunction");
    nint hookFunc = metaUtil.GetProcAddress(metaUtil.GetModuleHandle("myplugin.dll"), "HookFunction");
    
    // Install inline hook
    var hook = metaUtil.InlineHook(targetFunc, hookFunc, out nint originalCall, false);
    
    // Later: remove hook
    metaUtil.UnHook(hook);
}

Client Management

public void ManageClients()
{
    var metaUtil = MetaMod.MetaUtilFuncs;
    
    // Query client cvar
    int requestId = metaUtil.MakeRequestID();
    MetaMod.EngineFuncs.QueryClientCvarValue2(playerEdict, "cl_crosshair_color", requestId);
    
    // Get user message ID
    int msgId = metaUtil.GetUserMessageId("DeathMsg", out int size);
    
    // Send center message
    metaUtil.CenterSay("Welcome to the server!");
}

Deprecated APIs

The following APIs are maintained for C++ compatibility but marked obsolete. Use the C# alternatives instead:

Deprecated API Recommended Alternative
MetaMod.RegisterEvents() SafeEventRegistration.Register()
Direct delegate assignment EventRegistrationBuilder
Manual GCHandle management DelegateLifetimeManager

Supported MetaMod Interface Versions

  • Interface 5:16 (Latest - MetaMod 1.21-p)
  • Interface 5:15 (MetaMod 1.21)
  • Interface 5:13 (MetaMod 1.20)
  • All versions back to 1.0

Testing

Run the test suite:

dotnet test

The test suite includes:

  • Memory safety validation
  • GC lifecycle tests
  • API compatibility tests
  • Event registration tests

Contributing

Contributions are welcome! Please ensure:

  1. All tests pass
  2. New features include corresponding tests
  3. Memory safety is maintained for all native interop
  4. API follows C# conventions

License

GPL-3.0-or-later

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 (1)

Showing the top 1 NuGet packages that depend on DrAbc.NuggetMod.Core:

Package Downloads
DrAbc.NuggetMod

Build MetaMod(GoldSrc) plugin with .NET 10 - Meta package including Core and SourceGenerator

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.7 123 4/1/2026