Skip to content

Plugins: Creating a basic plugin

Katy edited this page Jan 4, 2021 · 4 revisions

Plugin definition (IPlugin)

A plugin is a single class which implements IPlugin. This interface provides basic details about the plugin and looks like this:

using Il2CppInspector.PluginAPI.V100;

namespace MyPlugin
{
    public class ExamplePlugin : IPlugin
    {
        // The ID that will be used to load the plugin from the command-line, ie. --plugins "myplugin"
        public string Id => "myplugin";

        // The full name of the plugin
        public string Name => "Baby's first plugin";

        // The nickname of the plugin author
        public string Author => "l33t-h4x0r-42069blazeitxxx"; 

        // The version of the plugin. Always use version numbers in increasing lexical order when you create a new version.
        public string Version => "1.0";

        // A description of what the plugin does
        public string Description => "Performs some kind of action on an IL2CPP application";

        // No options
        public List<IPluginOption> Options => null;
    }
}

See complete example

Initialization

A single plugin object is instantiated for the entire lifetime of Il2CppInspector. Plugins are only reloaded if the user clicks Refresh in the GUI.

One-time initialization of plugins should be performed in the plugin's (optional) public parameterless instance constructor:

public class ExamplePlugin : IPlugin
{
    public ExamplePlugin() {
        // put your one-time initialization code here
    }
}

NOTE: This initialization is performed when the plugin is loaded at application startup, not when the user imports an IL2CPP application. If you need to perform per-import initialization (ie. setup that should be done each time a new IL2CPP application is loaded), use ILoadPipeline.LoadPipelineStarting instead.

Options (IPluginOption)

Plugins can have user-supplied options that are exposed via the CLI and GUI. All options implement IPluginOption. Il2CppInspector includes built-in support for freeform text, numbers (with optional hex format), booleans, file/folder paths, multiple choice and enums:

PluginOptionText
PluginOptionNumber<T>
PluginOptionBoolean
PluginOptionFilePath
PluginOptionChoice<T>

Create a basic option as follows:

private PluginOptionNumber<int> numberOption = new PluginOptionNumber<int> {
  Name = "number",
  Description = "A numeric option"
}

Each option should be a private member field of your plugin class. Use the Options member to register all options with Il2CppInspector:

public List<IPluginOption> Options => new List<IPluginOption> { firstOption, secondOption, ... };

Access current option values by reading the Value property of each option, eg. numberOption.Value.

Default values

If an option has a default value, set Value = X where X is the default value of the option.

Required options

If an option must be specified, set Required = true.

Display and built-in validation

Some option types have a Style property.

For numbers, set Style = PluginOptionNumberStyle.Hex to force a number to be entered and validated as a hex string.

For choices, set Style = PluginOptionChoiceStyle.List to change the GUI display from a drop-down box to a list of radio buttons.

For file paths, the MustExist, MustNotExist, IsFolder and AllowedExtensions properties can be used to enforce the corresponding validation.

Validation

Il2CppInspector will validate numbers, file paths and choices automatically. Use the Validate lambda property to add custom validation. Throw an exception if the value is invalid, eg:

private PluginOptionNumber<int> numberOption = new PluginOptionNumber<int> {
  Name = "number",
  Description = "A numeric option",
  Validate = n => n >= 1 && n <= 10? true : throw new ArgumentException("Number must be between 1 and 10")
}

Dependent options

For the GUI, you can cause options to be enabled or disabled based on the state of other options or parameters. This should be done in the plugin's constructor:

private PluginOptionNumber<int> number1 = new PluginOptionNumber<int> {
  Name = "number1",
  Description = "A numeric option",
}

private PluginOptionNumber<int> number2 = new PluginOptionNumber<int> {
  Name = "number2",
  Description = "Another numeric option",
}

public ExamplePlugin() {
  number2.If = () => number1 > 100;
}

The option for number2 will only be enabled in the GUI if the value of number1 is greater than 100.

Option change notification (IPlugin.OptionsChanged)

Il2CppInspector updates options by calling the option's Value property setter, overwriting the default options with user-specified values. If you would like to receive a notification when options are updated, implement IPlugin.OptionsChanged

See a complete example of using options.

Examples and source code documentation

All of the available interface members have XML documentation available. See all interface definitions.

More examples of basic plugins can be found in the Examples folder.