mirror of
https://github.com/Impostor/Impostor.git
synced 2026-10-20 01:46:11 +00:00
Added plugin documentation
This commit is contained in:
1 parent
49284a587c
commit
55f513c071
6 files changed
+308
-1
No files matched your search
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Api invalid data
|
||||
about: To let us know about invalid data in the api
|
||||
---
|
||||
|
||||
# Api missing data
|
||||
|
||||
## Data
|
||||
<!--
|
||||
Describe about the missing data that you need.
|
||||
-->
|
||||
|
||||
## Expectations
|
||||
<!--
|
||||
Describe what the api gave you and what you expected.
|
||||
-->
|
||||
|
||||
## Reproduce
|
||||
<!--
|
||||
Describe how to reproduce the issue.
|
||||
-->
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
name: Api other
|
||||
about: For anything about the api that does not fit in the other issues
|
||||
---
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Api suggestion
|
||||
about: To make suggestions for the plugin api
|
||||
---
|
||||
|
||||
# Api Suggestion
|
||||
|
||||
## Suggestion
|
||||
<!--
|
||||
Describe your suggestion as detailed as possible.
|
||||
-->
|
||||
|
||||
## Use case
|
||||
<!--
|
||||
Describe what you need it for.
|
||||
-->
|
||||
|
||||
## Expected result
|
||||
<!--
|
||||
Describe the expected result.
|
||||
This is necessary so we can estimate whether your suggestion is possible.
|
||||
-->
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Api unavailable data
|
||||
about: To let us know about unavailable data from the api that you would like to use
|
||||
---
|
||||
|
||||
# Api missing data
|
||||
|
||||
## Data
|
||||
<!--
|
||||
Describe about the unavailable data that you need.
|
||||
-->
|
||||
|
||||
## Use-case
|
||||
<!--
|
||||
Describe what you need it for.
|
||||
-->
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: Feature Request
|
||||
name: Feature request
|
||||
about: To ask and request new features with Impostor
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
# Writing a plugin
|
||||
|
||||
Impostor has support for plugins. This document will help you to setup a development environment for writing a plugin.
|
||||
|
||||
- [1. Install .NET Core SDK](#1-install-net-core-sdk)
|
||||
- [2. Create a C# project](#2-create-a-c-project)
|
||||
- [3. Add the Impostor.Api library](#3-add-the-impostorapi-library)
|
||||
- [Quick](#quick)
|
||||
- [Visual Studio](#visual-studio)
|
||||
- [4. The plugin class](#4-the-plugin-class)
|
||||
- [5. Adding an event listener](#5-adding-an-event-listener)
|
||||
- [6. Build and run your plugin](#6-build-and-run-your-plugin)
|
||||
- [7. Extra](#7-extra)
|
||||
- [Event listeners](#event-listeners)
|
||||
- [Dependency injection](#dependency-injection)
|
||||
- [8. Missing/invalid data or want more functions?](#8-missinginvalid-data-or-want-more-functions)
|
||||
|
||||
## 1. Install .NET Core SDK
|
||||
|
||||
Download and install the latest .NET Core SDK.
|
||||
|
||||
https://dotnet.microsoft.com/download
|
||||
|
||||
## 2. Create a C# project
|
||||
|
||||
The first step is creating a new C# project, it must be a **Class Library (.NET Standard)**. The target framework can be any of those compatible with .NET 5, which includes:
|
||||
|
||||
- .NET Standard 2.0
|
||||
- .NET Standard 2.1
|
||||
- .NET Core 3.1
|
||||
- .NET 5
|
||||
|
||||
For more information about compatibility, see https://docs.microsoft.com/en-us/dotnet/standard/net-standard.
|
||||
|
||||
> At the moment of writing this document, I recommend you to use **.NET Standard 2.1** until .NET 5 is released officially. This should give you enough functionality. If not, upgrade to .NET Core 3.1.
|
||||
|
||||
When the project has been created, you should have `Class.cs` and `Project.csproj` files. Your `Project.csproj` should look something like this.
|
||||
|
||||
```xml
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
## 3. Add the Impostor.Api library
|
||||
|
||||
You only have to follow the instructions of one below.
|
||||
|
||||
### Quick
|
||||
|
||||
Install the `Impostor.Api` NuGet package.
|
||||
Make sure to get a prerelease if you are writing a plugin for a dev release of the server.
|
||||
|
||||
### Visual Studio
|
||||
|
||||
1. Right click your project.
|
||||
2. Click `Manage NuGet Packages`.
|
||||
3. Click `Browse`.
|
||||
4. Next to the search bar, enable `Include prerelease`.
|
||||
5. Search for `Impostor.Api`.
|
||||
6. Click the `Impostor.Api` result and press install on the right side.
|
||||
|
||||
## 4. The plugin class
|
||||
|
||||
Now the `Impostor.Api` is installed, you need to create a class for your plugin. A plugin **must** contain exactly one. See the code below for an example.
|
||||
|
||||
```csharp
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Events.Managers;
|
||||
using Impostor.Api.Plugins;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Impostor.Plugins.Example
|
||||
{
|
||||
/// <summary>
|
||||
/// The metadata information of your plugin, this is required.
|
||||
/// </summary>
|
||||
[ImpostorPlugin(
|
||||
package: "gg.impostor.example",
|
||||
name: "Example",
|
||||
author: "AeonLucid",
|
||||
version: "1.0.0")]
|
||||
public class ExamplePlugin : PluginBase // This is also required ": PluginBase".
|
||||
{
|
||||
/// <summary>
|
||||
/// A logger that works seamlessly with the server.
|
||||
/// </summary>
|
||||
private readonly ILogger<ExamplePlugin> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor of the plugin. There are a few parameters you can add here and they
|
||||
/// will be injected automatically by the server, two examples are used here.
|
||||
///
|
||||
/// They are not necessary but very recommended.
|
||||
/// </summary>
|
||||
/// <param name="logger">
|
||||
/// A logger to write messages in the console.
|
||||
/// </param>
|
||||
/// <param name="eventManager">
|
||||
/// An event manager to register event listeners.
|
||||
/// Useful if you want your plugin to interact with the game.
|
||||
/// </param>
|
||||
public ExamplePlugin(ILogger<ExamplePlugin> logger, IEventManager eventManager)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when your plugin is enabled by the server.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override ValueTask EnableAsync()
|
||||
{
|
||||
_logger.LogInformation("Example is being enabled.");
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when your plugin is disabled by the server.
|
||||
/// Most likely because it is shutting down, this is the place to clean up any managed resources.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override ValueTask DisableAsync()
|
||||
{
|
||||
_logger.LogInformation("Example is being disabled.");
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Adding an event listener
|
||||
|
||||
Currently you should have a plugin that loads and does nothing. In order to get some actual functionality, you need to add an event listener.
|
||||
|
||||
Create a new class called `GameEventListener`. Example code:
|
||||
|
||||
```csharp
|
||||
using Impostor.Api.Events;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Impostor.Plugins.Example.Handlers
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that listens for two events.
|
||||
/// It may be more but this is just an example.
|
||||
///
|
||||
/// Make sure your class implements <see cref="IEventListener"/>.
|
||||
/// </summary>
|
||||
public class GameEventListener : IEventListener
|
||||
{
|
||||
private readonly ILogger<ExamplePlugin> _logger;
|
||||
|
||||
public GameEventListener(ILogger<ExamplePlugin> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An example event listener.
|
||||
/// </summary>
|
||||
/// <param name="e">
|
||||
/// The event you want to listen for.
|
||||
/// </param>
|
||||
[EventListener]
|
||||
public void OnGameStarted(GameStartedEvent e)
|
||||
{
|
||||
_logger.LogInformation($"Game is starting.");
|
||||
|
||||
// This prints out for all players if they are impostor or crewmate.
|
||||
foreach (var player in e.Game.Players)
|
||||
{
|
||||
var info = player.Character.PlayerInfo;
|
||||
var isImpostor = info.IsImpostor;
|
||||
if (isImpostor)
|
||||
{
|
||||
_logger.LogInformation($"- {info.PlayerName} is an impostor.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation($"- {info.PlayerName} is a crewmate.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[EventListener]
|
||||
public void OnGameEnded(GameEndedEvent e)
|
||||
{
|
||||
_logger.LogInformation($"Game has ended.");
|
||||
}
|
||||
|
||||
[EventListener]
|
||||
public void OnPlayerChat(PlayerChatEvent e)
|
||||
{
|
||||
_logger.LogInformation($"{e.PlayerControl.PlayerInfo.PlayerName} said {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. Build and run your plugin
|
||||
|
||||
Now your plugin is ready to be tested.
|
||||
|
||||
1. Right click your project and press `Build`.
|
||||
2. Right click your project and press `Open Folder in File Explorer`.
|
||||
3. Go to `bin/Debug/netstandard2.1/`.
|
||||
4. In this directory, you should find your plugin named `Project.dll`.
|
||||
5. Copy the `Project.dll` to the `plugins` directory in your Impostor server directory.
|
||||
6. (Re)start your Impostor server.
|
||||
7. Open Among Us, create a game and send a chat message. In the console you should see your plugin being loaded and the messages from the example.
|
||||
|
||||
## 7. Extra
|
||||
|
||||
Some extra information that might be useful for those developing plugins.
|
||||
|
||||
### Event listeners
|
||||
|
||||
- You can have multiple event listener on the same event.
|
||||
- An event listener can be given a priority `[EventListener(EventPriority.Normal)]` and is called in order.
|
||||
- It is not recommended to block for a long time inside `EventListener` because the events are called from inside the packet handlers. Blocking too long causes the client to time out. You should create a new `Task` for operations that will take a lot of time.
|
||||
|
||||
### Dependency injection
|
||||
|
||||
- The main plugin class is constructed by the `IServiceProvider` of the server and can inject everything the server uses. A few examples are:
|
||||
- `ILogger<T>`
|
||||
- `IEventManager`
|
||||
- `IClientManager`
|
||||
- `IOptions<ServerConfig>`
|
||||
- `IOptions<ServerRedirectorConfig>`
|
||||
- You can add your own classes and `EventListener` implementation to the `IServiceProvider` by creating a new class and implementing `IPluginStartup`. Make sure to register them as a singleton `services.AddSingleton<IEventListener, GameEventListener>();`.
|
||||
|
||||
## 8. Missing/invalid data or want more functions?
|
||||
|
||||
The `Impostor.Api` is currently in beta. There are a lot of things still missing and we would like to hear from you what you need to develop a plugin.
|
||||
|
||||
Create an issue:
|
||||
|
||||
- [Suggest a function](https://github.com/Impostor/Impostor/issues/new?template=api-suggestion.md)
|
||||
- [Data is invalid](https://github.com/Impostor/Impostor/issues/new?template=api-invalid.md)
|
||||
- [Data is unavailable](https://github.com/Impostor/Impostor/issues/new?template=api-missing.md)
|
||||
- [Other](https://github.com/Impostor/Impostor/issues/new?template=api-other.md)
|
||||
Reference in new issue
Block a user