Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
# SecretAPI ![Downloads](https://img.shields.io/github/downloads/Misfiy/SecretAPI/total)
* SecretAPI is a plugin that extends [LabAPI](https://github.com/northwood-studios/LabAPI) by providing extra features to help devs.

# Dependencies
- SecretAPI relies on Harmony to implement features
- You can find the latest version [here](https://github.com/pardeike/Harmony/releases/latest)
- You should download Harmony-Fat and put the **0harmony.dll** (found in /net48) into your dependencies folder!

# Features
- CollectionExtensions: Extensions to provide utility for collections like lists and arrays.
- RoomExtensions: Extensions to help with room specific tasks, like checking if a room is safe to teleport to.
- HarmonyExtensions: Extensions to provide more utility to Harmony patching, like adding some updated Harmony features which can't be utilised, i.e. patching by category.
- CustomPlayerEffect: Create custom status effects using the base-game system.
- IRegister: Handle auto registering certain plugin features inheriting this interface and then running `IRegister.RegisterAll(Assembly)` in your plugin's initialise method.
- CallOnLoadAttribute: Allows calling static initialize methods on enable via ``CallOnLoadAttribute.Load(Assembly)``
- CustomSetting: Server Specific Settings without the management hassle, control everything for 1 setting in 1 class, including permissions. A better setting system overall.
- **CustomPlayerEffect**: Create custom status effects using the base-game system.
- BlastResistance: Grants 0.5% resistance to explosion damage
- Depleted: Disables stamina and its regen
- Energized: Disables stamina usage
- **IRegister**: Handle auto registering certain plugin features inheriting this interface and then running `IRegister.RegisterAll(Assembly)` in your plugin's initialize method.
- **CallOnLoadAttribute**: Allows calling static initialize methods on enable via ``CallOnLoadAttribute.Load(Assembly)``
- **CustomSetting**: Server Specific Settings without the management hassle, control everything for 1 setting in 1 class, including permissions. A better setting system overall.
- **PrefabStore** and **PrefabManager**: Designed to help access prefabs in a clean way
- Extensions:
- CodeMatcherExtensions: Extensions related to ``HarmonyLib.CodeMatcher``.
- CollectionExtensions: Extensions to provide utility for collections like lists and arrays.
- MirrorExtensions: Extensions providing help with fake-syncing ``SyncVar``, ``SyncList`` and ``Rpc``
- ReflectionExtensions: Extensions related to C# Reflection
- RoomExtensions: Extensions to help with room specific tasks, like checking if a room is safe to teleport to.

# Examples
You can find examples inside the `SecretAPI.Examples` folder above, this contains some example settings, patches using categories and some more.
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Nullable>enable</Nullable>
<Version>3.4.0</Version>
<Version>3.5.0-beta1</Version>
</PropertyGroup>

<PropertyGroup Label="Nuget">
Expand Down
18 changes: 15 additions & 3 deletions SecretAPI.Examples/ExampleEntry.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
namespace SecretAPI.Examples;
/*
Temp until 4.0
*/
#pragma warning disable SA1200
global using HarmonyPatchCategoryAttribute = HarmonyLib.HarmonyPatchCategory;
#pragma warning restore SA1200

namespace SecretAPI.Examples;

using System;
using System.Reflection;
using HarmonyLib;
using LabApi.Loader.Features.Plugins;
using SecretAPI.Examples.Settings;
using SecretAPI.Extensions;
using SecretAPI.Features.UserSettings;

/// <summary>
Expand All @@ -29,11 +36,16 @@ public class ExampleEntry : Plugin
/// <inheritdoc/>
public override Version RequiredApiVersion { get; } = new(LabApi.Features.LabApiProperties.CompiledVersion);

/// <summary>
/// Gets the <see cref="Assembly"/> of SecretAPI.Examples.
/// </summary>
internal Assembly Assembly { get; } = typeof(ExampleEntry).Assembly;

/// <inheritdoc/>
public override void Enable()
{
CustomSetting.Register(new ExampleKeybindSetting(), new ExampleDropdownSetting(), new ExampleButtonSetting(), new ExampleFakeSyncButton());
harmony.PatchCategory(nameof(ExampleFakeSyncButton));
harmony.PatchCategory(Assembly, nameof(ExampleFakeSyncButton));
}

/// <inheritdoc/>
Expand Down
8 changes: 3 additions & 5 deletions SecretAPI.Examples/Patches/ExampleAmmoPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ private static void Prefix()

// gets called after the original method is called
// We grab the method params of ammoType and player, the names must be correct
// ref __result will become a reference to the return value
#pragma warning disable SA1313
private static void Postfix(ItemType ammoType, ReferenceHub player, ref ushort __result)
#pragma warning restore SA1313
// ref result will become a reference to the return value
private static void Postfix(ItemType ammoType, ReferenceHub player, [HarmonyArgument("__result")] ref ushort result)
{
// make sure we don't modify the max ammo if its not the correct ammo type or the player hasn't been fake synced
if (ammoType != ExampleFakeSyncButton.AmmoFakeSync || !ExampleFakeSyncButton.FakeSyncs.TryGetValue(player, out ushort sync))
return;

__result = sync;
result = sync;
}
}
5 changes: 1 addition & 4 deletions SecretAPI.Examples/SecretAPI.Examples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@

<ItemGroup>
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2" PrivateAssets="all" />
<PackageReference Include="Lib.Harmony" Version="2.2.2" />
<!--
<PackageReference Include="Northwood.LabAPI" Version="1.1.4" IncludeAssets="All" PrivateAssets="All" />
-->
<PackageReference Include="Lib.Harmony" Version="2.4.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" IncludeAssets="All" PrivateAssets="All" />
</ItemGroup>

Expand Down
4 changes: 3 additions & 1 deletion SecretAPI/Attributes/HarmonyPatchCategory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
/// Category handling for <see cref="HarmonyExtensions"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class HarmonyPatchCategory : Attribute
[Obsolete("Please use HarmonyLib.HarmonyPatchCategoryAttribute - This will be removed in 4.0")]
public class HarmonyPatchCategory : HarmonyLib.HarmonyPatchCategory
{
/// <summary>
/// Initializes a new instance of the <see cref="HarmonyPatchCategory"/> class.
/// </summary>
/// <param name="category">The category of the patch.</param>
public HarmonyPatchCategory(string category)
: base(category)
{
Category = category;
}
Expand Down
11 changes: 4 additions & 7 deletions SecretAPI/Extensions/CodeMatcherExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@ public static class CodeMatcherExtensions
/// <param name="localType">The <see cref="Type"/> of the local to declare.</param>
/// <param name="localBuilder">The <see cref="LocalBuilder"/> declared.</param>
/// <returns>The current <see cref="CodeMatcher"/>.</returns>
public CodeMatcher DeclareLocal(Type localType, out LocalBuilder localBuilder)
{
localBuilder = matcher.generator.DeclareLocal(localType);
return matcher;
}
[Obsolete("Use CodeMatcher::DeclareLocal(Type, out LocalBuilder)")]
public CodeMatcher DeclareLocal(Type localType, out LocalBuilder localBuilder) => matcher.DeclareLocal(localType, out localBuilder);

/// <summary>
/// Declares a local to be used of a certain <see cref="Type"/>.
Expand All @@ -39,7 +36,7 @@ public CodeMatcher DeclareLocal(Type localType, out LocalBuilder localBuilder)
/// <returns>The current <see cref="CodeMatcher"/>.</returns>
public CodeMatcher DeclareLocal(Type localType, out int localIndex)
{
DeclareLocal(matcher, localType, out LocalBuilder builder);
matcher.DeclareLocal(localType, out LocalBuilder builder);
localIndex = builder.LocalIndex;
return matcher;
}
Expand All @@ -63,7 +60,7 @@ public CodeMatcher GetFirstLabel(out Label label)
/// <returns>The current <see cref="CodeMatcher"/>.</returns>
public CodeMatcher GetFirstLabelAt(int position, out Label label)
{
label = matcher.codes[position].labels.FirstOrDefault();
label = matcher.Instructions()[position].labels.FirstOrDefault();
return matcher;
}
}
Expand Down
16 changes: 10 additions & 6 deletions SecretAPI/Extensions/HarmonyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,36 @@ public static class HarmonyExtensions
/// </summary>
/// <param name="category">The category to patch.</param>
/// <param name="assembly">The assembly to find patches in.</param>
[Obsolete("Use Harmony::PatchCategory(Assembly, string)")]
public void PatchCategory(string category, Assembly? assembly = null)
{
assembly ??= Assembly.GetCallingAssembly();
harmony.PatchCategory(assembly, category);

assembly.GetTypes().Where(type =>
/*assembly.GetTypes().Where(type =>
{
IEnumerable<HarmonyPatchCategory> categories = type.GetCustomAttributes<HarmonyPatchCategory>();
return categories.Any(c => c.Category == category);
return categories.Any(c => c.info.category == category);
})
.Do(type => SafePatch(harmony, type));
.Do(type => SafePatch(harmony, type));*/
}

/// <summary>
/// Patches all patches that don't have a <see cref="HarmonyPatchCategory"/>.
/// </summary>
/// <param name="assembly">The assembly to look for patches.</param>
[Obsolete("Use Harmony::PatchAllUncategorized(Assembly)")]
public void PatchAllNoCategory(Assembly? assembly = null)
{
assembly ??= Assembly.GetCallingAssembly();
harmony.PatchAllUncategorized(assembly);

assembly.GetTypes().Where(type =>
/*assembly.GetTypes().Where(type =>
{
IEnumerable<HarmonyPatchCategory> categories = type.GetCustomAttributes<HarmonyPatchCategory>();
return !categories.Any();
})
.Do(type => SafePatch(harmony, type));
.Do(type => SafePatch(harmony, type));*/
}

/// <summary>
Expand All @@ -61,7 +65,7 @@ public void SafePatch(Type type)
}
catch (Exception ex)
{
Logger.Error($"[HarmonyExtensions] failed to safely patch {harmony.Id} ({type.FullName}): {ex}");
Logger.Error($"[HarmonyExtensions] Failed to safely patch {harmony.Id} ({type.FullName}): {ex}");
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions SecretAPI/Features/UserSettings/CustomSetting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using LabApi.Features.Wrappers;
using Mirror;
using NorthwoodLib.Pools;
using SecretAPI.Extensions;

/// <summary>
/// Wraps <see cref="ServerSpecificSettingBase"/>.
Expand All @@ -23,7 +22,7 @@ public abstract class CustomSetting : ISetting<ServerSpecificSettingBase>

static CustomSetting()
{
SecretApi.Harmony.PatchCategory(nameof(CustomSetting), SecretApi.Assembly);
SecretApi.Harmony.PatchCategory(SecretApi.Assembly, nameof(CustomSetting));

ServerSpecificSettingsSync.SendOnJoinFilter = null;
ServerSpecificSettingsSync.DefinedSettings ??= []; // fix null ref
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@
[HarmonyPatch(typeof(ServerSpecificSettingBase), nameof(ServerSpecificSettingBase.OriginalDefinition), MethodType.Getter)]
internal static class SettingsOriginalDefinitionFix
{
#pragma warning disable SA1313 // Parameter '__result' should begin with lower-case letter
private static void Postfix(ServerSpecificSettingBase __instance, ref ServerSpecificSettingBase __result)
#pragma warning restore SA1313
private static void Postfix([HarmonyArgument("__instance")] ServerSpecificSettingBase instance, [HarmonyArgument("__result")] ref ServerSpecificSettingBase result)
{
// Prevent handling non SecretAPI settings.
if (__result != null)
if (result != null)
return;

__result = CustomSetting.Get(__instance.GetType(), __instance.SettingId)?.Base ?? null!;
result = CustomSetting.Get(instance.GetType(), instance.SettingId)?.Base ?? null!;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@
[HarmonyPatch(typeof(ServerSpecificSettingsSync), nameof(ServerSpecificSettingsSync.ServerPrevalidateClientResponse))]
internal static class SettingsSyncValidateFix
{
#pragma warning disable SA1313 // Parameter '__result' should begin with lower-case letter
private static void Postfix(SSSClientResponse msg, ref bool __result)
#pragma warning restore SA1313
private static void Postfix(SSSClientResponse msg, [HarmonyArgument("__result")] ref bool result)
{
// prevent overriding already validated settings
if (__result)
if (result)
return;

__result = CustomSetting.Get(msg.SettingType, msg.Id) != null;
result = CustomSetting.Get(msg.SettingType, msg.Id) != null;
}
}
12 changes: 7 additions & 5 deletions SecretAPI/SecretAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<TargetFramework>net48</TargetFramework>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
<ImplicitUsings>false</ImplicitUsings>
</PropertyGroup>

<PropertyGroup Label="Nuget">
Expand All @@ -23,10 +25,7 @@

<ItemGroup>
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2" PrivateAssets="all" />
<!--
<PackageReference Include="Northwood.LabAPI" Version="1.1.4" IncludeAssets="All" PrivateAssets="All" />
-->
<PackageReference Include="Lib.Harmony" Version="2.2.2" Publicize="true" />
<PackageReference Include="Lib.Harmony" Version="2.4.2"/> <!-- Do not publicize Harmony as it will publicize internal monomod references -->
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" IncludeAssets="All" PrivateAssets="All" />
</ItemGroup>

Expand All @@ -40,11 +39,14 @@
<Reference Include="Assembly-CSharp-firstpass" />
<Reference Include="Pooling" />
<Reference Include="Mirror" />
<Reference Include="mscorlib" />
<Reference Include="UnityEngine" />
<Reference Include="UnityEngine.CoreModule" />
<Reference Include="UnityEngine.PhysicsModule" />
<Reference Include="Unity.TextMeshPro" />

<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>

</Project>
9 changes: 8 additions & 1 deletion SecretAPI/SecretApi.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
namespace SecretAPI;
/*
Temp until 4.0
*/
#pragma warning disable SA1200
global using HarmonyPatchCategoryAttribute = HarmonyLib.HarmonyPatchCategory;
#pragma warning restore SA1200

namespace SecretAPI;

using System;
using System.IO;
Expand Down
Loading