mirror of
https://github.com/NuclearPowered/Reactor.git
synced 2026-10-21 05:37:38 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e27a79249e | ||
|
|
2c1eeaff9d | ||
|
|
7d3ffa3975 | ||
|
|
2b357512c4 | ||
|
|
32875a2d3d | ||
|
|
de3b20e205 | ||
|
|
bbdbd5bec8 | ||
|
|
f55036efbc | ||
|
|
809b8957a4 | ||
|
|
27e8cb12e5 |
No files matched your search
+1
-1
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.679" Private="false" ExcludeAssets="runtime;native" />
|
||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2024.6.18" PrivateAssets="all" />
|
||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2024.8.13" PrivateAssets="all" />
|
||||
|
||||
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
|
||||
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.0.1" PrivateAssets="all" ExcludeAssets="runtime" />
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
|
||||
<VersionPrefix>2.2.0</VersionPrefix>
|
||||
<VersionPrefix>2.3.1</VersionPrefix>
|
||||
<VersionSuffix>dev</VersionSuffix>
|
||||
|
||||
<Authors>NuclearPowered</Authors>
|
||||
@@ -35,7 +35,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.507" PrivateAssets="all" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
|
||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" Visible="false" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -29,7 +29,7 @@ public class AssetBundleBenchmarks
|
||||
|
||||
public static IEnumerable<string> ValuesForAssetBundleName()
|
||||
{
|
||||
yield return $"default-{AssetBundleManager.TargetName}{AssetBundleManager.BundleExtension}";
|
||||
yield return $"{AssetBundleManager.GetFileName("default", false)}";
|
||||
// yield return "submerged";
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"net6.0": {
|
||||
"AmongUs.GameLibs.Steam": {
|
||||
"type": "Direct",
|
||||
"requested": "[2024.6.18, )",
|
||||
"resolved": "2024.6.18",
|
||||
"contentHash": "xb+HP1xXn4/ES8AgXpk9xeoW568LFYw5NTjY6bHwd6vQjHDf2kT1xHMmQ1me5Vfee/Gp69YIMZDXUAUToG7Elg=="
|
||||
"requested": "[2024.8.13, )",
|
||||
"resolved": "2024.8.13",
|
||||
"contentHash": "xYZBHQJcwSF5wABtJIZlmpNwZ7jXWafe6vid6/YEWSxpk1fcYLxz42bHSTYcGjpu4wVz1p1ZG/QC4Eu0SbGhrg=="
|
||||
},
|
||||
"BenchmarkDotNet": {
|
||||
"type": "Direct",
|
||||
@@ -57,11 +57,11 @@
|
||||
},
|
||||
"StyleCop.Analyzers": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.0-beta.507, )",
|
||||
"resolved": "1.2.0-beta.507",
|
||||
"contentHash": "/FtugDT66cKJJ+GGH7rNpG6UDrT4iIWz45M6lrXXHobDUFDHw+q5VgkbiR+6ffTO564ge7w6fQh/eoQhVdJO8Q==",
|
||||
"requested": "[1.2.0-beta.556, )",
|
||||
"resolved": "1.2.0-beta.556",
|
||||
"contentHash": "llRPgmA1fhC0I0QyFLEcjvtM2239QzKr/tcnbsjArLMJxJlu0AA5G7Fft0OI30pHF3MW63Gf4aSSsjc5m82J1Q==",
|
||||
"dependencies": {
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.507"
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.556"
|
||||
}
|
||||
},
|
||||
"AsmResolver": {
|
||||
@@ -519,8 +519,8 @@
|
||||
},
|
||||
"StyleCop.Analyzers.Unstable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.2.0.507",
|
||||
"contentHash": "gTY3IQdRqDJ4hbhSA3e/R48oE8b/OiKfvwkt1QdNVfrJK2gMHBV8ldaHJ885jxWZfllK66soa/sdcjh9bX49Tw=="
|
||||
"resolved": "1.2.0.556",
|
||||
"contentHash": "zvn9Mqs/ox/83cpYPignI8hJEM2A93s2HkHs8HYMOAQW0PkampyoErAiIyKxgTLqbbad29HX/shv/6LGSjPJNQ=="
|
||||
},
|
||||
"System.CodeDom": {
|
||||
"type": "Transitive",
|
||||
@@ -1152,4 +1152,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,17 +7,30 @@ namespace Reactor.Debugger.Utilities;
|
||||
|
||||
internal static class Extensions
|
||||
{
|
||||
public static IEnumerator CoCreateLocalGame(this AmongUsClient client)
|
||||
public static IEnumerator CoCreateLocalGame(this AmongUsClient client, bool isFreePlay = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
client.NetworkMode = NetworkModes.LocalGame;
|
||||
if (isFreePlay)
|
||||
{
|
||||
client.NetworkMode = NetworkModes.FreePlay;
|
||||
|
||||
InnerNetServer.Instance.StartAsServer();
|
||||
InnerNetServer.Instance.StartAsLocalServer();
|
||||
|
||||
client.MainMenuScene = "MainMenu";
|
||||
client.OnlineScene = "Tutorial";
|
||||
}
|
||||
else
|
||||
{
|
||||
client.NetworkMode = NetworkModes.LocalGame;
|
||||
|
||||
InnerNetServer.Instance.StartAsServer();
|
||||
|
||||
client.MainMenuScene = "MatchMaking";
|
||||
client.OnlineScene = "OnlineGame";
|
||||
}
|
||||
|
||||
client.SetEndpoint(Constants.LocalNetAddress, Constants.GamePlayPort, false);
|
||||
client.MainMenuScene = "MatchMaking";
|
||||
client.OnlineScene = "OnlineGame";
|
||||
}
|
||||
catch (Il2CppException e)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using AmongUs.Data;
|
||||
using BepInEx.Unity.IL2CPP.Utils;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using Il2CppInterop.Runtime.InteropTypes;
|
||||
using Reactor.Debugger.Utilities;
|
||||
using Reactor.Debugger.Window.Tabs;
|
||||
using Reactor.Utilities.Attributes;
|
||||
using Reactor.Utilities.ImGui;
|
||||
@@ -34,6 +39,43 @@ internal sealed class DebuggerWindow : MonoBehaviour
|
||||
if (AmongUsClient.Instance && AmongUsClient.Instance.AmHost) clientName += " (host)";
|
||||
GUILayout.Label("Name: " + clientName);
|
||||
|
||||
if (GUILayout.Button("Hard crash"))
|
||||
{
|
||||
static unsafe void Corrupt(Il2CppObjectBase o)
|
||||
{
|
||||
var x = (IntPtr*) o.Pointer;
|
||||
x[0] = (IntPtr) 0xF00;
|
||||
}
|
||||
|
||||
static IEnumerator CoCrash()
|
||||
{
|
||||
if (!PlayerControl.LocalPlayer || !ShipStatus.Instance)
|
||||
{
|
||||
yield return AmongUsClient.Instance.CoCreateLocalGame(true);
|
||||
|
||||
while (!PlayerControl.LocalPlayer || !ShipStatus.Instance)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
var usable = FindObjectsOfType<MonoBehaviour>().First(x => x.TryCast<IUsable>() != null);
|
||||
if (!usable)
|
||||
{
|
||||
Error("Failed to find an IUsable to crash with");
|
||||
yield break;
|
||||
}
|
||||
|
||||
var cloned = Instantiate(usable, PlayerControl.LocalPlayer.transform.position, default);
|
||||
|
||||
Warning($"Crashing with {cloned.name}");
|
||||
|
||||
Corrupt(cloned);
|
||||
}
|
||||
|
||||
this.StartCoroutine(CoCrash());
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
foreach (var tab in Tabs)
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"net6.0": {
|
||||
"AmongUs.GameLibs.Steam": {
|
||||
"type": "Direct",
|
||||
"requested": "[2024.6.18, )",
|
||||
"resolved": "2024.6.18",
|
||||
"contentHash": "xb+HP1xXn4/ES8AgXpk9xeoW568LFYw5NTjY6bHwd6vQjHDf2kT1xHMmQ1me5Vfee/Gp69YIMZDXUAUToG7Elg=="
|
||||
"requested": "[2024.8.13, )",
|
||||
"resolved": "2024.8.13",
|
||||
"contentHash": "xYZBHQJcwSF5wABtJIZlmpNwZ7jXWafe6vid6/YEWSxpk1fcYLxz42bHSTYcGjpu4wVz1p1ZG/QC4Eu0SbGhrg=="
|
||||
},
|
||||
"BepInEx.AutoPlugin": {
|
||||
"type": "Direct",
|
||||
@@ -39,11 +39,11 @@
|
||||
},
|
||||
"StyleCop.Analyzers": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.0-beta.507, )",
|
||||
"resolved": "1.2.0-beta.507",
|
||||
"contentHash": "/FtugDT66cKJJ+GGH7rNpG6UDrT4iIWz45M6lrXXHobDUFDHw+q5VgkbiR+6ffTO564ge7w6fQh/eoQhVdJO8Q==",
|
||||
"requested": "[1.2.0-beta.556, )",
|
||||
"resolved": "1.2.0-beta.556",
|
||||
"contentHash": "llRPgmA1fhC0I0QyFLEcjvtM2239QzKr/tcnbsjArLMJxJlu0AA5G7Fft0OI30pHF3MW63Gf4aSSsjc5m82J1Q==",
|
||||
"dependencies": {
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.507"
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.556"
|
||||
}
|
||||
},
|
||||
"AsmResolver": {
|
||||
@@ -347,8 +347,8 @@
|
||||
},
|
||||
"StyleCop.Analyzers.Unstable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.2.0.507",
|
||||
"contentHash": "gTY3IQdRqDJ4hbhSA3e/R48oE8b/OiKfvwkt1QdNVfrJK2gMHBV8ldaHJ885jxWZfllK66soa/sdcjh9bX49Tw=="
|
||||
"resolved": "1.2.0.556",
|
||||
"contentHash": "zvn9Mqs/ox/83cpYPignI8hJEM2A93s2HkHs8HYMOAQW0PkampyoErAiIyKxgTLqbbad29HX/shv/6LGSjPJNQ=="
|
||||
},
|
||||
"System.Collections": {
|
||||
"type": "Transitive",
|
||||
|
||||
@@ -25,6 +25,8 @@ public partial class ExamplePlugin : BasePlugin
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
ReactorCredits.Register<ExamplePlugin>(ReactorCredits.AlwaysShow);
|
||||
|
||||
this.AddComponent<ExampleComponent>();
|
||||
|
||||
_helloStringName = CustomStringName.CreateAndRegister("Hello!");
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"net6.0": {
|
||||
"AmongUs.GameLibs.Steam": {
|
||||
"type": "Direct",
|
||||
"requested": "[2024.6.18, )",
|
||||
"resolved": "2024.6.18",
|
||||
"contentHash": "xb+HP1xXn4/ES8AgXpk9xeoW568LFYw5NTjY6bHwd6vQjHDf2kT1xHMmQ1me5Vfee/Gp69YIMZDXUAUToG7Elg=="
|
||||
"requested": "[2024.8.13, )",
|
||||
"resolved": "2024.8.13",
|
||||
"contentHash": "xYZBHQJcwSF5wABtJIZlmpNwZ7jXWafe6vid6/YEWSxpk1fcYLxz42bHSTYcGjpu4wVz1p1ZG/QC4Eu0SbGhrg=="
|
||||
},
|
||||
"BepInEx.AutoPlugin": {
|
||||
"type": "Direct",
|
||||
@@ -39,11 +39,11 @@
|
||||
},
|
||||
"StyleCop.Analyzers": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.0-beta.507, )",
|
||||
"resolved": "1.2.0-beta.507",
|
||||
"contentHash": "/FtugDT66cKJJ+GGH7rNpG6UDrT4iIWz45M6lrXXHobDUFDHw+q5VgkbiR+6ffTO564ge7w6fQh/eoQhVdJO8Q==",
|
||||
"requested": "[1.2.0-beta.556, )",
|
||||
"resolved": "1.2.0-beta.556",
|
||||
"contentHash": "llRPgmA1fhC0I0QyFLEcjvtM2239QzKr/tcnbsjArLMJxJlu0AA5G7Fft0OI30pHF3MW63Gf4aSSsjc5m82J1Q==",
|
||||
"dependencies": {
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.507"
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.556"
|
||||
}
|
||||
},
|
||||
"AsmResolver": {
|
||||
@@ -347,8 +347,8 @@
|
||||
},
|
||||
"StyleCop.Analyzers.Unstable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.2.0.507",
|
||||
"contentHash": "gTY3IQdRqDJ4hbhSA3e/R48oE8b/OiKfvwkt1QdNVfrJK2gMHBV8ldaHJ885jxWZfllK66soa/sdcjh9bX49Tw=="
|
||||
"resolved": "1.2.0.556",
|
||||
"contentHash": "zvn9Mqs/ox/83cpYPignI8hJEM2A93s2HkHs8HYMOAQW0PkampyoErAiIyKxgTLqbbad29HX/shv/6LGSjPJNQ=="
|
||||
},
|
||||
"System.Collections": {
|
||||
"type": "Transitive",
|
||||
@@ -922,4 +922,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -8,14 +10,20 @@ namespace Reactor.Patches.Fixes;
|
||||
/// <summary>
|
||||
/// "Fixes" an issue where empty TextBoxes have wrong cursor positions.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(TextMeshProExtensions), nameof(TextMeshProExtensions.CursorPos))]
|
||||
[HarmonyPatch]
|
||||
internal static class CursorPosPatch
|
||||
{
|
||||
public static IEnumerable<MethodBase> TargetMethods()
|
||||
{
|
||||
return AccessTools.GetDeclaredMethods(typeof(TextMeshProExtensions)).Where(m => m.Name == nameof(TextMeshProExtensions.CursorPos));
|
||||
}
|
||||
|
||||
public static bool Prefix(TextMeshPro self, ref Vector2 __result)
|
||||
{
|
||||
if (self.textInfo == null || self.textInfo.lineCount == 0 || self.textInfo.lineInfo[0].characterCount <= 0)
|
||||
{
|
||||
__result = self.GetTextInfo(" ").lineInfo.First().lineExtents.max;
|
||||
self.text = string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,15 +35,12 @@ internal static class FreeNamePatch
|
||||
var textBox = nameText.GetComponent<TextBoxTMP>();
|
||||
textBox.outputText.alignment = TextAlignmentOptions.CenterGeoAligned;
|
||||
textBox.outputText.transform.position = nameText.transform.position;
|
||||
textBox.outputText.fontSize = 4f;
|
||||
|
||||
textBox.OnChange.AddListener((Action) (() =>
|
||||
{
|
||||
DataManager.Player.Customization.Name = textBox.text;
|
||||
}));
|
||||
textBox.OnEnter = textBox.OnFocusLost = textBox.OnChange;
|
||||
|
||||
textBox.Pipe.GetComponent<TextMeshPro>().fontSize = 4f;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using HarmonyLib;
|
||||
using Reactor.Utilities;
|
||||
|
||||
namespace Reactor.Patches.Miscellaneous;
|
||||
|
||||
[HarmonyPatch(typeof(PingTracker), nameof(PingTracker.Update))]
|
||||
internal static class PingTrackerPatch
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPriority(Priority.Last)]
|
||||
public static void Postfix(PingTracker __instance)
|
||||
{
|
||||
var extraText = ReactorCredits.GetText(ReactorCredits.Location.PingTracker);
|
||||
if (extraText != null)
|
||||
{
|
||||
if (!__instance.text.text.EndsWith("\n", StringComparison.InvariantCulture)) __instance.text.text += "\n";
|
||||
__instance.text.text += extraText;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using BepInEx;
|
||||
using BepInEx.Unity.IL2CPP;
|
||||
using HarmonyLib;
|
||||
using Reactor.Utilities;
|
||||
using Reactor.Utilities.Extensions;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -89,20 +90,22 @@ public static class ReactorVersionShower
|
||||
}));
|
||||
}
|
||||
|
||||
private static string ToStringWithoutBuild(Version version)
|
||||
{
|
||||
return $"{version.Major}.{version.Minor}.{version.Patch}{(version.PreRelease == null ? string.Empty : $"-{version.PreRelease}")}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates <see cref="Text"/> with reactor version and fires <see cref="TextUpdated"/>.
|
||||
/// </summary>
|
||||
public static void UpdateText()
|
||||
{
|
||||
if (Text == null) return;
|
||||
Text.text = "Reactor " + ReactorPlugin.Version;
|
||||
Text.text += "\nBepInEx " + ToStringWithoutBuild(Paths.BepInExVersion);
|
||||
Text.text = "Reactor " + Version.Parse(ReactorPlugin.Version).WithoutBuild();
|
||||
Text.text += "\nBepInEx " + Paths.BepInExVersion.WithoutBuild();
|
||||
Text.text += "\nMods: " + IL2CPPChainloader.Instance.Plugins.Count;
|
||||
|
||||
var creditsText = ReactorCredits.GetText(ReactorCredits.Location.MainMenu);
|
||||
if (creditsText != null)
|
||||
{
|
||||
Text.text += "\n" + creditsText;
|
||||
}
|
||||
|
||||
TextUpdated?.Invoke(Text);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
namespace Reactor.Utilities.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for TestMeshPro's Rich Text.
|
||||
/// </summary>
|
||||
internal static class RichTextExtensions
|
||||
{
|
||||
private static string Wrap(this string text, string tag)
|
||||
{
|
||||
return $"<{tag}>{text}</{tag}>";
|
||||
}
|
||||
|
||||
private static string Wrap(this string text, string tag, string value)
|
||||
{
|
||||
return $"<{tag}={value}>{text}</{tag}>";
|
||||
}
|
||||
|
||||
public static string Align(this string text, string value)
|
||||
{
|
||||
return text.Wrap("align", value);
|
||||
}
|
||||
|
||||
public static string Color(this string text, string value)
|
||||
{
|
||||
return text.Wrap("color", value);
|
||||
}
|
||||
|
||||
public static string Size(this string text, string value)
|
||||
{
|
||||
return text.Wrap("size", value);
|
||||
}
|
||||
|
||||
public static string EscapeRichText(this string text)
|
||||
{
|
||||
return text
|
||||
.Replace("<noparse>", string.Empty)
|
||||
.Replace("</noparse>", string.Empty)
|
||||
.Wrap("noparse");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using SemanticVersioning;
|
||||
|
||||
namespace Reactor.Utilities.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for <see cref="SemanticVersioning.Version"/>.
|
||||
/// </summary>
|
||||
public static class VersionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the provided <paramref name="version"/> without the build string (everything after the + symbol like the commit hash is stripped).
|
||||
/// </summary>
|
||||
/// <param name="version">The <see cref="SemanticVersioning.Version"/>.</param>
|
||||
/// <returns>The <paramref name="version"/> without build.</returns>
|
||||
public static Version WithoutBuild(this Version version)
|
||||
{
|
||||
return new Version(version.Major, version.Minor, version.Patch, version.PreRelease);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace Reactor.Utilities.ImGui;
|
||||
/// </summary>
|
||||
public class Window
|
||||
{
|
||||
private static int _lastWindowId;
|
||||
private static int _lastWindowId = 2135184938;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next window id.
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BepInEx.Unity.IL2CPP;
|
||||
using Reactor.Patches;
|
||||
using Reactor.Utilities.Extensions;
|
||||
|
||||
namespace Reactor.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Provides a way for mods to show their version information in-game.
|
||||
/// </summary>
|
||||
public static class ReactorCredits
|
||||
{
|
||||
private readonly struct ModIdentifier(string name, string version, Func<Location, bool>? shouldShow, bool isPreRelease)
|
||||
{
|
||||
private const string NormalColor = "#fff";
|
||||
private const string PreReleaseColor = "#f00";
|
||||
|
||||
public string Name => name;
|
||||
|
||||
public string Text { get; } = $"{name} {version}".EscapeRichText().Color(isPreRelease ? PreReleaseColor : NormalColor);
|
||||
|
||||
public bool ShouldShow(Location location)
|
||||
{
|
||||
return shouldShow == AlwaysShow || shouldShow(location);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly List<ModIdentifier> _modIdentifiers = [];
|
||||
|
||||
/// <summary>
|
||||
/// Represents the location of where the credit is shown.
|
||||
/// </summary>
|
||||
public enum Location
|
||||
{
|
||||
/// <summary>
|
||||
/// In the main menu under Reactor/BepInEx versions.
|
||||
/// </summary>
|
||||
MainMenu,
|
||||
|
||||
/// <summary>
|
||||
/// During game under the ping tracker.
|
||||
/// </summary>
|
||||
PingTracker,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A special value indicating a mod should always show.
|
||||
/// </summary>
|
||||
public const Func<Location, bool>? AlwaysShow = null;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a mod with the <see cref="ReactorCredits"/>, adding it to the list of mods that will be displayed.
|
||||
/// </summary>
|
||||
/// <param name="name">The user-friendly name of the mod. Can contain spaces or special characters.</param>
|
||||
/// <param name="version">The version of the mod.</param>
|
||||
/// <param name="isPreRelease">If this version is a development or beta version. If true, it will display the mod in red.</param>
|
||||
/// <param name="shouldShow">
|
||||
/// This function will be called every frame to determine if the mod should be displayed or not.
|
||||
/// This function should return false if your mod is currently disabled or has no effect on gameplay at the time.
|
||||
/// If you want the mod to be displayed at all times, you can set this parameter to <see cref="ReactorCredits.AlwaysShow"/>.
|
||||
/// </param>
|
||||
public static void Register(string name, string version, bool isPreRelease, Func<Location, bool>? shouldShow)
|
||||
{
|
||||
const int MaxLength = 60;
|
||||
|
||||
if (name.Length + version.Length > MaxLength)
|
||||
{
|
||||
Error($"Not registering mod \"{name}\" with version \"{version}\" in {nameof(ReactorCredits)} because the combined length of the mod name and version is greater than {MaxLength} characters.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_modIdentifiers.Any(m => m.Name == name))
|
||||
{
|
||||
Error($"Mod \"{name}\" is already registered in {nameof(ReactorCredits)}.");
|
||||
return;
|
||||
}
|
||||
|
||||
_modIdentifiers.Add(new ModIdentifier(name, version, shouldShow, isPreRelease));
|
||||
|
||||
_modIdentifiers.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));
|
||||
|
||||
if (!isPreRelease)
|
||||
{
|
||||
Info($"Mod \"{name}\" registered in {nameof(ReactorCredits)} with version {version}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning($"Mod \"{name}\" registered in {nameof(ReactorCredits)} with DEVELOPMENT/BETA version {version}.");
|
||||
}
|
||||
|
||||
ReactorVersionShower.UpdateText();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a mod with the <see cref="ReactorCredits"/>, adding it to the list of mods that will be displayed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The BepInEx plugin type to get the name and version from.</typeparam>
|
||||
/// <param name="shouldShow"><inheritdoc cref="Register(string,string,bool,System.Func{Location,bool})" path="/param[@name='shouldShow']"/></param>
|
||||
public static void Register<T>(Func<Location, bool>? shouldShow) where T : BasePlugin
|
||||
{
|
||||
var pluginInfo = IL2CPPChainloader.Instance.Plugins.Values.SingleOrDefault(p => p.TypeName == typeof(T).FullName)
|
||||
?? throw new ArgumentException("Couldn't find the metadata for the provided plugin type", nameof(T));
|
||||
|
||||
var metadata = pluginInfo.Metadata;
|
||||
|
||||
Register(metadata.Name, metadata.Version.WithoutBuild().Clean(), metadata.Version.IsPreRelease, shouldShow);
|
||||
}
|
||||
|
||||
internal static string? GetText(Location location)
|
||||
{
|
||||
var modTexts = _modIdentifiers.Where(m => m.ShouldShow(location)).Select(m => m.Text).ToArray();
|
||||
if (modTexts.Length == 0) return null;
|
||||
|
||||
return location switch
|
||||
{
|
||||
Location.MainMenu => string.Join('\n', modTexts),
|
||||
Location.PingTracker => ("<space=3em>" + string.Join(", ", modTexts)).Size("50%").Align("center"),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(location), location, null),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@
|
||||
"net6.0": {
|
||||
"AmongUs.GameLibs.Steam": {
|
||||
"type": "Direct",
|
||||
"requested": "[2024.6.18, )",
|
||||
"resolved": "2024.6.18",
|
||||
"contentHash": "xb+HP1xXn4/ES8AgXpk9xeoW568LFYw5NTjY6bHwd6vQjHDf2kT1xHMmQ1me5Vfee/Gp69YIMZDXUAUToG7Elg=="
|
||||
"requested": "[2024.8.13, )",
|
||||
"resolved": "2024.8.13",
|
||||
"contentHash": "xYZBHQJcwSF5wABtJIZlmpNwZ7jXWafe6vid6/YEWSxpk1fcYLxz42bHSTYcGjpu4wVz1p1ZG/QC4Eu0SbGhrg=="
|
||||
},
|
||||
"BepInEx.AutoPlugin": {
|
||||
"type": "Direct",
|
||||
@@ -39,11 +39,11 @@
|
||||
},
|
||||
"StyleCop.Analyzers": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.0-beta.507, )",
|
||||
"resolved": "1.2.0-beta.507",
|
||||
"contentHash": "/FtugDT66cKJJ+GGH7rNpG6UDrT4iIWz45M6lrXXHobDUFDHw+q5VgkbiR+6ffTO564ge7w6fQh/eoQhVdJO8Q==",
|
||||
"requested": "[1.2.0-beta.556, )",
|
||||
"resolved": "1.2.0-beta.556",
|
||||
"contentHash": "llRPgmA1fhC0I0QyFLEcjvtM2239QzKr/tcnbsjArLMJxJlu0AA5G7Fft0OI30pHF3MW63Gf4aSSsjc5m82J1Q==",
|
||||
"dependencies": {
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.507"
|
||||
"StyleCop.Analyzers.Unstable": "1.2.0.556"
|
||||
}
|
||||
},
|
||||
"AsmResolver": {
|
||||
@@ -347,8 +347,8 @@
|
||||
},
|
||||
"StyleCop.Analyzers.Unstable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.2.0.507",
|
||||
"contentHash": "gTY3IQdRqDJ4hbhSA3e/R48oE8b/OiKfvwkt1QdNVfrJK2gMHBV8ldaHJ885jxWZfllK66soa/sdcjh9bX49Tw=="
|
||||
"resolved": "1.2.0.556",
|
||||
"contentHash": "zvn9Mqs/ox/83cpYPignI8hJEM2A93s2HkHs8HYMOAQW0PkampyoErAiIyKxgTLqbbad29HX/shv/6LGSjPJNQ=="
|
||||
},
|
||||
"System.Collections": {
|
||||
"type": "Transitive",
|
||||
|
||||
Reference in new issue
Block a user