# Hooks

Hooks are what give your plugin functionality. They are essentially custom event handlers that can be written in any language. They can run code whenever something happens, or inject new items into some of the data-driven parts of Nitrolaunch. Handlers for hooks are defined in the plugin manifest.

## Parts of a Hook

- ID: Every hook has a unique ID used to identify it
- Argument and Result: These are the inputs and outputs of the hook. They can be any JSON type, such as a string or object, and depend on which hook you are handling.

## How Hooks are Run

Most of the time when Nitrolaunch calls a hook, it will check every plugin that supports that hook, and call the hook on each one to create a final list of results. Handlers are not exclusive; multiple plugins can subscribe to the same hook. However, some hooks are only called on specific plugins. For example, the `on_load` hook is only called on a specific plugin once it is loaded.

## General Hooks

### `on_load`

Called when this plugin is loaded. Can be used to set up state and such.

- Argument: None
- Result: None

### `subcommand`

Called whenever one of the subcommands that this hook registers are run. The arguments are the list of arguments that were provided to the subcommand, _including_ the subcommand itself. Note that this hook also takes over output, meaning anything coming from stdout will be output to the console instead.

- Argument:

```
{
	"args": string[],
	"instances": {
		"id": InstanceConfig,
		...
	}
}
```

- Result: None

### `add_versions`

This hook allows you to add extra Minecraft versions to the version manifest, allowing them to be specified in instance configuration and automatically downloaded. Versions that already exist in the list with the same ID will be replaced, and if they don't already exist, they will be appended to the front as the newest possible version.

- Argument: None
- Result:

```
[
	{
		"id": string,
		"type": "release" | "snapshot" | "old_alpha" | "old_beta",
		"url": string,
		"is_zipped": bool
	},
	...
]
```

### `add_translations`

Adds extra translations to Nitrolaunch

- Argument: None
- Result:

```
{
	"language": {
		"key": "translation",
		...
	},
	...
}
```

### `custom_action`

Runs an arbitrary custom action, basically allowing you to define your own hooks. Used often by the GUI.

- Argument:

```
{
	"id": string,
	"payload": any
}
```

- Result: `any`

- `id`: The custom identifier for this action (can be whatever you want)
- `payload` The custom argument for this action run (can also be whatever you want)

## Configuration Hooks

### `add_instances`

Adds new instances to the config

- Argument: None
- Result:

```
{
	"inst1": InstanceConfig,
	"inst2": InstanceConfig,
	...
}
```

### `add_templates`

Adds new templates to the config

- Argument: None
- Result:

```
{
	"prof1": TemplateConfig,
	"prof2": TemplateConfig,
	...
}
```

### `save_instance_config`

Adds or updates config for an editable custom instance from this plugin, whatever that means for your custom instance

- Argument:

```
{
	"id": string,
	"config": InstanceConfig
}
```

- Result: None

### `save_template_config`

Adds or updates config for an editable custom template from this plugin, whatever that means for your custom template

- Argument:

```
{
	"id": string,
	"config": TemplateConfig
}
```

- Result: None

### `delete_instance`

Deletes a plugin instance and it's files

- Argument:

```
{
	"id": string,
	"config": InstanceConfig
}
```

- Result: None

### `delete_template`

Deletes a plugin template

- Argument:

```
{
	"id": string,
	"config": TemplateConfig
}
```

- Result: None

### `add_instance_icons`

Adds new options for instance and template icons in the UI

- Argument: None

- Result: `string[]`

The strings can be filesystem paths (often using `${PLUGIN_DIR}` for plugin-relative paths) or web links

## Instance Setup Hooks

### `on_instance_setup`

Called when an instance is being set up, for update or launch. Can return modifications to make to the launch parameters
resulting from installing a certain modification

- Argument:

```
{
	"id": string,
	"side": "client" | "server",
	"game_dir": string,
	"version_info": {
		"version": string,
		"versions": [string]
	},
	"old_version": string,
	"loader": Loader,
	"current_loader_version": string | null,
	"desired_loader_version": string | null,
	"config": InstanceConfig,
	"internal_dir": string,
	"update_depth": "shallow" | "full" | "force",
	"jvm_path": string,
	"game_jar_path": string
}
```

- Result:

```
{
	"main_class_override": string | null,
	"jar_path_override": string | null,
	"classpath_extension": [string]
}
```

### `add_supported_loaders`

Adds extra loaders to the list of supported ones for installation. This should be done
if you plan to install these loaders with your plugin.

- Argument: None
- Result: `Loader[]`

### `get_loader_versions`

Gets a list of available versions for a loader. Feel free to make network requests if you need.

- Argument:

```
{
	"loader": string,
	"minecraft_version": string
}
```

- Result: `string[]`

### `remove_loader`

Called when the loader of an instance changes, to allow cleaning up old or invalid files. Will be given the loader that needs to be removed.

- Argument:

```
{
	"id": string,
	"side": "client" | "server",
	"game_dir": string,
	"version_info": {
		"version": string,
		"versions": [string]
	},
	"loader": Loader,
	"custom_config": {...},
	"internal_dir": string,
	"update_depth": "shallow" | "full" | "force"
}
```

- Result: None

## Launch Hooks

### `on_instance_launch`

Called whenever an instance is launched

- Argument: InstanceLaunchArg
- Result: None

### `while_instance_launch`

Also called when an instance is launched, but is non-blocking, and runs alongside the instance. Can be used for periodic tasks and such.

- Argument: InstanceLaunchArg
- Result: None

### `on_instance_stop`

Called when an instance is stopped. This happens when Minecraft is closed or crashes. This hook will _not_ be called if Nitrolaunch crashes while the instance is running.

- Argument: InstanceLaunchArg
- Result: None

### `update_world_files`

Called when shared world files are updated on an instance.

- Argument: InstanceLaunchArg
- Result: None

## Instance Logging Hooks

### `get_instance_logs`

Gets logs for an instance with `custom_logging_plugin` set. Returns a list of unique log IDs (whatever that means to your plugin) that will be used later with the `get_instance_log` hook. Returned logs should be ordered oldest to newest if possible.

- Argument:

```
{
	"id": string,
	"config": InstanceConfig
}
```

- Result: `string[]`

### `get_instance_log`

Gets the contents of a log for the given instance with an ID returned from the `get_instance_logs` hook

- Argument:

```
{
	"instance_id": string,
	"log_id": string,
	"config": InstanceConfig
}
```

- Result: `string`

## Package Hooks

### `custom_package_instruction`

Handles custom instructions in script packages.

- Argument:

```
{
	"pkg_id": string,
	"command": string,
	"args": [string]
}
```

- Result:

```
{
	"handled": bool,
	"addon_reqs": [
		{
			"id": string,
			"file_name": string | null,
			"kind": "resource_pack" | "mod" | "plugin" | "shader" | "datapack",
			"url": string | null,
			"path": string | null,
			"version": string | null,
			"hashes": {
				"sha256": string | null,
				"sha512": string | null
			}
		}
	],
	"deps": [
		{
			"value": string,
			"explicit": bool
		}
	],
	"conflicts": [string],
	"recommendations": [
		{
			"value": string,
			"invert": bool
		}
	],
	"bundled": [string],
	"compats": [[string, string]],
	"extensions": [string],
	"notices": [string]
}
```

- `handled`: Whether this instruction was handled or not. Should be false if this instruction is not for your plugin.

## Account Hooks

### `add_account_types`

Adds new custom account types

- Argument: None

- Result:

```
[
	{
		"id": string,
		"name": string,
		"color": string
	},
	...
]
```

### `handle_auth`

Handles authentication with custom account types

- Argument:

```
{
	"account_id": string,
	"account_type": string
}
```

- Result:

```
{
	"handled": bool,
	"profile": {
		"name": string,
		"id": string,
		"skins": [
			{
				"id": string,
				"url" string,
				"state": "active" | "inactive",
				"variant": "classic" | "slim"
			}
		],
		"capes": [
			{
				"id": string,
				"url" string,
				"state": "active" | "inactive",
				"alias": string
			}
		]
	} | null
}
```

- `profile.id`: The UUID of the account

### `get_account_cosmetics`

Gets the cosmetics available on a custom account

- Argument:
```
{
	"id": string,
	"kind": string
}
```

- Result:

```
{
	"skins": [
		{
			"id": string,
			"url": string,
			"state": "ACTIVE" | "INACTIVE",
			"variant": "CLASSIC" | "SLIM"
		},
		...
	],
	"capes": [
		{
			"id": string,
			"url": string,
			"state": "ACTIVE" | "INACTIVE",
			"alias": string
		},
		...
	]
}
```

### `upload_skin`

Uploads and activates a new skin for a custom account

- Argument:
```
{
	"id": string,
	"kind": string,
	"data": number[],
	"variant": "CLASSIC" | "SLIM"
}
```

- Result: None

- `data`: The skin data as PNG bytes

### `activate_cape`

Activates or deactivates a cape for a custom account

- Argument:
```
{
	"id": string,
	"kind": string,
	"cape": string | null
}
```

- Result: None

### `add_skin_repositories`

Adds a repository to search for skins from

- Argument: None

- Result:

```
[
	{
		"id": string,
		"name": string
	}
]
```

### `search_skin_repository`

Searches a custom skin repository

- Argument:
```
{
	"repository": string,
	"search": string | null
}
```

- Result:

```
[
	Skin,
	...
]
```

## Instance Transfer Hooks

### `add_instance_transfer_formats`

Adds information about new transfer formats that this plugin adds support for. Returns a list of formats, including information about features that they support and don't support.

- Argument: None
- Result:

```
[
	{
		"id": string,
		"name": string,
		"import": {
			"modloader": "supported" | "format_unsupported" | "plugin_unsupported",
			"mods": "supported" | "format_unsupported" | "plugin_unsupported",
			"launch_settings": "supported" | "format_unsupported" | "plugin_unsupported"
		} | null,
		"export": {
			"modloader": "supported" | "format_unsupported" | "plugin_unsupported",
			"mods": "supported" | "format_unsupported" | "plugin_unsupported",
			"launch_settings": "supported" | "format_unsupported" | "plugin_unsupported"
		} | null
	},
	...
]
```

### `export_instance`

Hook called on a specific plugin to export an instance using one of the formats it supports

- Argument:

```
{
	"format": string,
	"id": string,
	"config": InstanceConfig,
	"minecraft_version": string,
	"loader_version": string,
	"game_dir": string,
	"result_path": string
}
```

- `id`: The instance ID
- `result_path`: The desired path to the output file
- Result: None

### `import_instance`

Hook called on a specific plugin to import an instance using one of the formats it supports

- Argument:

```
{
	"format": string,
	"id": string,
	"source_path": string,
	"result_path": string
}
```

- `id`: The desired ID of the resulting instance
- `source_path`: The path to the instance to import
- `result_path`: Where to place the files for the imported instance
- Result:

```
{
	"format": string,
	"config": InstanceConfig
}
```

### `migrate_instances`

Hook called to migrate all instances from another launcher using one of the formats this plugin supports

- Argument: string
- This is the transfer format to use

- Result:

```
{
	"format": string,
	"instances": {
		"id": InstanceConfig,
		...
	}
}
```

## Custom Repository Hooks

### `add_custom_package_repositories`

Adds new package repositories that can be queried and searched

- Argument: None

- Result:

```
[
	{
		"id": string,
		"is_preferred": bool,
		"metadata": RepoMetadata
	},
	...
]
```

- `is_preferred`: Whether this repository should be loaded before or after repositories like `std` and `core`
- `metadata`: [RepoMetadata](../../packages/index.md)

### `query_custom_package_repository`

Asks for a package from a custom repository that this plugin registered with `add_custom_package_repositories`.

- Argument:

```
{
	"repository": string,
	"package": string
}
```

- Result:

```
{
	"contents": string,
	"content_type": "script" | "declarative",
	"flags": [
		"out_of_date" | "deprecated" | "insecure" | "malicious", ...
	]
} | null
```

### `search_custom_package_repository`

Searches / browses for packages from a custom repository that this plugin registered with `add_custom_package_repositories`.

- Argument:

```
{
	"repository": string,
	"parameters": {
		"count": integer,
		"skip": integer,
		"search": string | null,
		"types": PackageType[],
		"minecraft_versions": string[],
		"loaders": Loader[],
		"categories": PackageCategory[]
	}
}
```

- Result:

```
{
	"results": string[],
	"total_results": integer,
	"previews": {
		"package": [PackageMetadata, PackageProperties],
		...
	}
}
```

- `previews`: Limited data about packages used to make quick previews. Useful if your API returns them, as it makes browsing much faster.

### `search_custom_package_repository`

Synchronizes the cache for a custom repository that this plugin registered with `add_custom_package_repositories`. Should remove all cached packages associated with the repository so that new versions of packages can be used.

- Argument:

```
{
	"repository": string
}
```

- Result: None

## Control Hooks

### `add_instance_config_controls`

Defines additional schema for instance or template configuration

- Argument:

```
{
	"id": string,
	"kind": "instance" | "template" | "base_template",
	"plugin": string | null
}
```

- Result:
```
{
	"controls": [
		Control,
		...
	]
}
```

### `add_plugin_config_controls`

Defines additional schema for configuring this plugin globally

- Argument: None

- Result:
```
[
	Control,
	...
]
```

## Modpack Hooks

### `add_modpack_formats`

Add new formats for modpacks

- Argument: None

- Result:
```
[
	{
		"id": string,
		"name": string,
		"transfer_format": string | null
	}
	...
]
```

- `transfer_format`: The instance transfer format associated with this modpack format. It is necessary to implement instance transfer if you want to be able to import a modpack instance from a file or package.

### `install_modpack`

Installs a modpack on an existing instance. Use instance transfer for supporting importing an instance.

- Argument:
```
{
	"format": string,
	"path": string,
	"old_path": string | null,
	"target_path": string,
	"side": "client" | "server"
}
```

- Result:
```
{
	"name": string,
	"packages": string[],
	"addons": [
		{
			"kind": "mod" | "resource_pack" | "datapack" | "shader" | "plugin",
			"file_name": string,
			"original_path": string | null,
			"target_paths": string[],
			"source": string | null,
			"hashes": {
				"sha256": string | null,
				"sha512": string | null
			}
		}
	]
}
```

- `path`: Path to the modpack file
- `old_path`: Path to the previous version of the modpack. Will not be passed if it is equal to the path.
- `target_path`: The instance directory to install files in
- `name`: The name of the modpack
- `packages`: List of packages that this modpack provides that can be suppressed in package resolution
- `addons`: List of addons, like mods or resource packs, that this modpack provides and can be used to prevent duplicates and manage updates

## GUI Hooks

### `inject_page_script`

Called whenever certain pages in the GUI are opened. Runs whatever the result of the hook is as Javascript on the page.

- Argument:

```
{
	"page": "instances" | "instance" | "instance_config" | "template_config" | "base_template_config" | "packages" | "plugins",
	"object": string | null
}
```

- Result: string

- `object`: The identifier for whatever 'thing' this page is representing. Could be an instance, template, anything else, or nothing.

### `add_sidebar_buttons`

Adds custom buttons to the sidebar

- Argument: None

- Result:

```
[
	{
		"html": string,
		"href": string,
		"selected_url": string | null,
		"selected_url_start": string | null,
		"color": string
	},
	...
]
```

- `html`: The inner HTML of the button
- `href`: Where the button leads to, likely a custom page
- `selected_url`: What the current URL should equal to select this item
- `selected_url_start`: What the current URL should start with to select this item

### `get_page`

Lets you add custom pages. The page will be available at `/custom/yourcustompagedata`. You can include custom data like a specific ID in the data section of the URL as well.

- Argument: `string`

This is the custom page data in the URL

- Result: `string | null`

This is the resulting page as HTML. Only include things that would be in a `<body>` tag.

### `add_themes`

Adds custom themes for the GUI

- Argument: None

- Result:

```
[
	{
		"id": string,
		"name": string,
		"description": string | null,
		"css": string,
		"color": string,
	},
	...
]
```

### `add_dropdown_buttons`

Adds custom buttons to certain dropdowns in the UI

- Argument: None

- Result:

```
[
	{
		"plugin": string,
		"location": "add_template_or_instance" | "instance_launch" | "instance_update" | "instance_more_options",
		"icon": string,
		"text": string,
		"color": string | null,
		"tip": string | null,
		"action": string | null,
		"on_click": string | null
	},
	...
]
```

- `plugin`: The plugin this button is from
- `location`: Which dropdown to add the button to
- `icon`: SVG icon for this button
- `tip`: An optional tooltip for this option
- `action`: A custom plugin action to run when this button is clicked
- `on_click`: JavaScript to run when this button is clicked

### `add_instance_tiles`

Adds custom tiles to the instance page in the GUI

- Argument: None

- Result:

```
[
	{
		"id": string,
		"contents": string,
		"size": "small" | "large"
	},
	...
]
```

- `id`: A unique ID for this tile. Ensures consistent location.
- `contents`: The HTML contents of the tile. Script tags will not be called, so it is important to include a page script as well to hook into the tile if you want functionality.
- `size`: About how much space this tile needs to take up. Will be taken into account by the layout algorithm.

### `add_instance_icons`

Adds extra options for instance icons for the user to choose from. Returns a list of absolute image file paths.

- Argument: None

- Result: `string[]`

## Java Hooks

### `add_java_types`

Adds new Java types that will be installed with `install_custom_java`

- Argument: None

- Result:

```
[
	{
		"id": string,
		"name": string,
		"color": string
	},
	...
]
```

### `install_custom_java`

Installs a custom Java installation added with `add_java_types`.

- Argument:

```
{
	"kind": string,
	"major_version": string,
	"update_depth": UpdateDepth
}
```

- Result:

```
{
	"path": string,
	"version": string
}
```

- `kind`: The ID of the Java matching the one from `add_java_types`
- `major_version`: The major version of Java that is being installed
- `path`: Path to the resulting installation, which contains a `bin` directory with the `java` executable in it
- `version`: The version of the resulting installation of whatever Java flavor you are using

## Common Types

### InstanceLaunchArg

```
{
	"id": string,
	"side": "client" | "server",
	"dir": string,
	"game_dir": string,
	"version_info": {
		"version": string,
		"versions": [string]
	},
	"config": InstanceConfig,
	"pid": integer | null,
	"classpath": string | null,
	"stdout_path": string | null,
	"stdin_path": string | null
}
```

Note: The `pid`, `classpath`, `stdout_path`, and `stdin_path` fields will all be `null` for the `on_instance_launch` hook, and are only available in the other hooks.
