Skip to content

Commit

Permalink
Feat register method (#44)
Browse files Browse the repository at this point in the history
* Add register method

* Clean up PluginHelper

* Update README with register info
  • Loading branch information
MaxWasUnavailable authored Feb 18, 2024
1 parent ed1902e commit c29e090
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 21 deletions.
57 changes: 41 additions & 16 deletions LobbyCompatibility/Features/PluginHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,38 @@ namespace LobbyCompatibility.Features;
/// </summary>
internal static class PluginHelper
{
/// <summary>
/// PluginInfos registered through the register command, rather than found using the attribute.
/// </summary>
private static readonly List<PluginInfoRecord> RegisteredPluginInfoRecords = new();

/// <summary>
/// Cached checksum of the required plugins.
/// </summary>
private static string? _cachedChecksum;

/// <summary>
/// Get the checksum of the required plugins, using the cached value if available.
/// </summary>
internal static string Checksum
{
get => _cachedChecksum ?? GetRequiredPluginsChecksum();
set => _cachedChecksum = value;
}

/// <summary>
/// Register a plugin's compatibility information manually.
/// </summary>
/// <param name="guid"> The GUID of the plugin. </param>
/// <param name="version"> The version of the plugin. </param>
/// <param name="compatibilityLevel"> The compatibility level of the plugin. </param>
/// <param name="versionStrictness"> The version strictness of the plugin. </param>
public static void RegisterPlugin(string guid, Version version, CompatibilityLevel compatibilityLevel, VersionStrictness versionStrictness)
{
RegisteredPluginInfoRecords.Add(new PluginInfoRecord(guid, version, compatibilityLevel, versionStrictness));
_cachedChecksum = null;
}

/// <summary>
/// Check if a plugin has the <see cref="LobbyCompatibilityAttribute" /> attribute.
/// </summary>
Expand Down Expand Up @@ -67,14 +99,14 @@ internal static IEnumerable<PluginInfoRecord> GetAllPluginInfo()
pluginInfos.AddRange(nonCompatibilityPlugins.Select(plugin =>
new PluginInfoRecord(plugin.Metadata.GUID, plugin.Metadata.Version, null, null)));

return pluginInfos;
return pluginInfos.Concat(RegisteredPluginInfoRecords);
}

/// <summary>
/// Creates a json string containing the metadata of all plugins, to add to the lobby.
/// </summary>
/// <returns> A json string containing the metadata of all plugins. </returns>
public static string GetLobbyPluginsMetadata()
internal static string GetLobbyPluginsMetadata()
{
return JsonConvert.SerializeObject(GetAllPluginInfo().ToList(), new VersionConverter());
}
Expand Down Expand Up @@ -191,7 +223,8 @@ public static IEnumerable<PluginDiff> FilterPluginDiffs(IEnumerable<PluginDiff>
}

/// <summary>
/// Creates a checksum of all <see cref="CompatibilityLevel.Everyone"/> level plugins at their lowest acceptable version.
/// Creates a checksum of all <see cref="CompatibilityLevel.Everyone" /> level plugins at their lowest acceptable
/// version.
/// </summary>
/// <returns> The generated filter checksum of installed plugins </returns>
private static string GetRequiredPluginsChecksum()
Expand All @@ -209,7 +242,7 @@ private static string GetRequiredPluginsChecksum()
foreach (var plugin in requiredPlugins)
{
pluginString += plugin.GUID;

// ReSharper disable twice RedundantCaseLabel
switch (plugin.VersionStrictness)
{
Expand All @@ -228,23 +261,15 @@ private static string GetRequiredPluginsChecksum()
break;
}
}

var checksum = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(pluginString));

var stringBuilder = new StringBuilder();

// Convert every byte to hexadecimal
foreach (var checksumByte in checksum)
stringBuilder.Append(checksumByte.ToString("X2"));

return _cachedChecksum = stringBuilder.ToString();
}

private static string? _cachedChecksum;

public static string Checksum
{
get => _cachedChecksum ?? GetRequiredPluginsChecksum();
internal set => _cachedChecksum = value;
return _cachedChecksum = stringBuilder.ToString();
}
}
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ with vanilla runs.

## For Developers

To use this, you need to add a package reference to `LethalCompany.LobbyCompatibility` in your `.csproj` file. You can use the
To use this, you need to add a package reference to `LethalCompany.LobbyCompatibility` in your `.csproj` file. You can
use the
following code:

```xml
Expand All @@ -46,11 +47,14 @@ following code:
```

You can also use your IDE's interface to add the reference. For Visual Studio 2022, you do so by clicking on
the `Project` dropdown, and clicking `Manage NuGet Packages`. You then can search for `LethalCompany.LobbyCompatibility` and add
the `Project` dropdown, and clicking `Manage NuGet Packages`. You then can search for `LethalCompany.LobbyCompatibility`
and add
it from there.

### Usage

#### Attribute

Simply add `[LobbyCompatibility(CompatibilityLevel, VersionStrictness)]` above your `Plugin` class like so:

```csharp
Expand All @@ -65,7 +69,7 @@ class MyPlugin : BaseUnityPlugin

The enums used are as follows:

#### `CompatibilityLevel`
##### `CompatibilityLevel`

- `ClientOnly`
- Mod only impacts the client.
Expand All @@ -82,7 +86,7 @@ The enums used are as follows:
Generally used for mods that add extra (optional) functionality to the client if the server has it installed.
- Mod must be loaded on server. Version checking depends on the VersionStrictness.

#### `VersionStrictness`
##### `VersionStrictness`

- `None`
- No version check is done (x.x.x)
Expand All @@ -91,4 +95,18 @@ The enums used are as follows:
- `Minor`
- Mods must have the same Minor and Major version (1.1.x)
- `Patch`
- Mods must have the same Patch, Minor, and Major version (1.1.1)
- Mods must have the same Patch, Minor, and Major version (1.1.1)

#### Method

Alternatively, as a way to support soft dependencies, you can use the `PluginHelper.RegisterPlugin` method with the
following signature:

```csharp
public static void RegisterPlugin(string guid, Version version, CompatibilityLevel compatibilityLevel, VersionStrictness versionStrictness)
```

> [!IMPORTANT]
>
> This method should be called in the `Awake` method of your plugin's main class, as we cache some data when fetching
> the lobby list.

0 comments on commit c29e090

Please sign in to comment.