Added plugin documentation

This commit is contained in:
AeonLucid committed 2020-10-25 05:27:04 +01:00
1 parent 49284a587c
commit 55f513c071
6 files changed
+308 -1

No files matched your search

+21
View File
@@ -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.
-->
+4
View File
@@ -0,0 +1,4 @@
---
name: Api other
about: For anything about the api that does not fit in the other issues
---
+22
View File
@@ -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.
-->
+16
View File
@@ -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 -1
View File
@@ -1,5 +1,5 @@
---
name: Feature Request
name: Feature request
about: To ask and request new features with Impostor
---
+244
View File
@@ -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)