diff --git a/Counters+/Counters+.csproj b/Counters+/Counters+.csproj
index 2de8f2b..6cc026b 100644
--- a/Counters+/Counters+.csproj
+++ b/Counters+/Counters+.csproj
@@ -93,10 +93,10 @@
False
False
-
+
False
$(BeatSaberDir)\Libs\Newtonsoft.Json.dll
- False
+ True
False
@@ -234,6 +234,7 @@
+
diff --git a/Counters+/Custom/CustomCounterFeature.cs b/Counters+/Custom/CustomCounterFeature.cs
new file mode 100644
index 0000000..946a2e2
--- /dev/null
+++ b/Counters+/Custom/CustomCounterFeature.cs
@@ -0,0 +1,101 @@
+using IPA.Loader;
+using IPA.Loader.Features;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace CountersPlus.Custom
+{
+ public class CustomCounterFeature : Feature
+ {
+ private Dictionary incompleteCustomCounters = new Dictionary(0);
+
+ protected override bool Initialize(PluginMetadata meta, JObject featureData)
+ {
+ CustomCounter counter;
+ try
+ {
+ counter = featureData.ToObject();
+ }
+ catch (Exception e)
+ {
+ InvalidMessage = $"Invalid data: {e}";
+ return false;
+ }
+
+ incompleteCustomCounters.Add(meta, counter);
+ return true;
+ }
+
+ public override void AfterInit(PluginMetadata meta)
+ {
+ if (incompleteCustomCounters.TryGetValue(meta, out CustomCounter counter))
+ {
+ if (!TryLoadType(ref counter.CounterType, meta, counter.CounterLocation))
+ {
+ Plugin.Logger.Error($"Failed to load a Type from the provided CounterLocation for {counter.Name}.");
+ return;
+ }
+ if (counter.BSML != null && counter.BSML.HasType && !TryLoadType(ref counter.BSML.HostType, meta, counter.BSML.Host))
+ {
+ Plugin.Logger.Error($"Failed to load a Type from the provided BSML Host for {counter.Name}.");
+ return;
+ }
+
+ Plugin.LoadedCustomCounters.Add(counter);
+ Plugin.Logger.Notice($"Loaded a Custom Counter ({counter.Name}).");
+ }
+ else
+ {
+ Plugin.Logger.Critical(@"A plugin has a defined Custom Counter, but Initialise was somehow not called.
+ How the hell did we even get here?");
+ }
+ }
+
+ private bool TryLoadType(ref Type typeToLoad, PluginMetadata meta, string location)
+ {
+ // totally didn't yoink this from BSIPA's ConfigProviderFeature
+ try
+ {
+ typeToLoad = meta.Assembly.GetType(location);
+ }
+ catch (ArgumentException)
+ {
+ InvalidMessage = $"Invalid type name {location}";
+ return false;
+ }
+ catch (Exception e) when (e is FileNotFoundException || e is FileLoadException || e is BadImageFormatException)
+ {
+ string filename;
+
+ switch (e)
+ {
+ case FileNotFoundException fn:
+ filename = fn.FileName;
+ goto hasFilename;
+ case FileLoadException fl:
+ filename = fl.FileName;
+ goto hasFilename;
+ case BadImageFormatException bi:
+ filename = bi.FileName;
+ hasFilename:
+ InvalidMessage = $"Could not find {filename} while loading type";
+ break;
+ default:
+ InvalidMessage = $"Error while loading type: {e}";
+ break;
+ }
+
+ return false;
+ }
+ catch (Exception e) // Is this unnecessary? Maybe.
+ {
+ InvalidMessage = $"An unknown error occured: {e}";
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Counters+/Properties/AssemblyInfo.cs b/Counters+/Properties/AssemblyInfo.cs
index e12d097..341cbfa 100644
--- a/Counters+/Properties/AssemblyInfo.cs
+++ b/Counters+/Properties/AssemblyInfo.cs
@@ -33,5 +33,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.3.4")]
-[assembly: AssemblyFileVersion("2.3.4")]
+[assembly: AssemblyVersion("2.3.5")]
+[assembly: AssemblyFileVersion("2.3.5")]
diff --git a/Counters+/manifest.json b/Counters+/manifest.json
index 403d941..8cc2411 100644
--- a/Counters+/manifest.json
+++ b/Counters+/manifest.json
@@ -3,7 +3,7 @@
"id": "Counters+",
"name": "Counters+",
"author": "Caeden117",
- "version": "2.3.4",
+ "version": "2.3.5",
"description": "A suite of enhancements for Beat Saber's UI.",
"icon": "CountersPlus.UI.Images.Logo.png",
"gameVersion": "1.34.2",
@@ -11,5 +11,11 @@
"BSIPA": "^4.3.2",
"BeatSaberMarkupLanguage": "^1.8.1",
"SiraUtil": "^3.1.6"
+ },
+ "features": {
+ "IPA.DefineFeature": {
+ "name": "CountersPlus.CustomCounter",
+ "type": "CountersPlus.Custom.CustomCounterFeature"
+ }
}
-}
+}
\ No newline at end of file