-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: js6pak <[email protected]>
- Loading branch information
1 parent
2c1eeaf
commit e27a792
Showing
6 changed files
with
215 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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), | ||
}; | ||
} | ||
} |