diff --git a/IPA.Loader/Loader/Features/Feature.cs b/IPA.Loader/Loader/Features/Feature.cs
index df70401e..d354bb6f 100644
--- a/IPA.Loader/Loader/Features/Feature.cs
+++ b/IPA.Loader/Loader/Features/Feature.cs
@@ -1,9 +1,8 @@
-using Mono.Cecil;
+#nullable enable
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
-using System.Reflection;
-using System.Text;
+using System.Diagnostics.CodeAnalysis;
#if NET3
using Net3_Proxy;
#endif
@@ -35,7 +34,7 @@ namespace IPA.Loader.Features
/// This should also be set whenever either returns false.
///
/// the message to show when the feature is marked invalid
- public virtual string InvalidMessage { get; protected set; }
+ public virtual string? InvalidMessage { get; protected set; }
///
/// Called before a plugin's `Init` method is called. This will not be called if there is no `Init` method. This should never throw an exception. An exception will abort the loading of the plugin with an error.
@@ -65,6 +64,7 @@ namespace IPA.Loader.Features
// TODO: rework features to take arguments as JSON objects
+ [SuppressMessage("Nullability", "CS8618", Justification = "Reset sets those fields.")]
static Feature()
{
Reset();
@@ -72,18 +72,18 @@ namespace IPA.Loader.Features
internal static void Reset()
{
- featureTypes = new Dictionary
+ featureTypes = new()
{
{ "IPA.DefineFeature", typeof(DefineFeature) }
};
- featureDelcarers = new Dictionary
+ featureDelcarers = new()
{
{ "IPA.DefineFeature", null }
};
}
private static Dictionary featureTypes;
- private static Dictionary featureDelcarers;
+ private static Dictionary featureDelcarers;
internal static bool HasFeature(string name) => featureTypes.ContainsKey(name);
@@ -123,7 +123,7 @@ namespace IPA.Loader.Features
}
}
- internal string FeatureName;
+ internal string FeatureName = null!;
internal class Instance
{
@@ -139,8 +139,8 @@ namespace IPA.Loader.Features
type = null;
}
- private Type type;
- public bool TryGetDefiningPlugin(out PluginMetadata plugin)
+ private Type? type;
+ public bool TryGetDefiningPlugin(out PluginMetadata? plugin)
{
return featureDelcarers.TryGetValue(Name, out plugin);
}
@@ -173,101 +173,5 @@ namespace IPA.Loader.Features
return result;
}
}
-
- /*
- // returns false with both outs null for no such feature
- internal static bool TryParseFeature(string featureString, PluginMetadata plugin,
- out Feature feature, out Exception failException, out bool featureValid, out Instance parsed,
- Instance? preParsed = null)
- {
- failException = null;
- feature = null;
- featureValid = false;
-
- if (preParsed == null)
- {
- var builder = new StringBuilder();
- string name = null;
- var parameters = new List();
-
- bool escape = false;
- int parens = 0;
- bool removeWhitespace = true;
- foreach (var chr in featureString)
- {
- if (escape)
- {
- builder.Append(chr);
- escape = false;
- }
- else
- {
- switch (chr)
- {
- case '\\':
- escape = true;
- break;
- case '(':
- parens++;
- if (parens != 1) goto default;
- removeWhitespace = true;
- name = builder.ToString();
- builder.Clear();
- break;
- case ')':
- parens--;
- if (parens != 0) goto default;
- goto case ',';
- case ',':
- if (parens > 1) goto default;
- parameters.Add(builder.ToString());
- builder.Clear();
- removeWhitespace = true;
- break;
- default:
- if (removeWhitespace && !char.IsWhiteSpace(chr))
- removeWhitespace = false;
- if (!removeWhitespace)
- builder.Append(chr);
- break;
- }
- }
- }
-
- if (name == null)
- name = builder.ToString();
-
- parsed = new Instance(name, parameters.ToArray());
-
- if (parens != 0)
- {
- failException = new Exception("Malformed feature definition");
- return false;
- }
- }
- else
- parsed = preParsed.Value;
-
- if (!featureTypes.TryGetValue(parsed.Name, out var featureType))
- return false;
-
- try
- {
- if (!(Activator.CreateInstance(featureType) is Feature aFeature))
- {
- failException = new InvalidCastException("Feature type not a subtype of Feature");
- return false;
- }
-
- featureValid = aFeature.Initialize(plugin, TODO);
- feature = aFeature;
- return true;
- }
- catch (Exception e)
- {
- failException = e;
- return false;
- }
- }*/
}
}
\ No newline at end of file
diff --git a/IPA.Loader/Loader/PluginLoader.cs b/IPA.Loader/Loader/PluginLoader.cs
index 679b4bb9..bab9cfba 100644
--- a/IPA.Loader/Loader/PluginLoader.cs
+++ b/IPA.Loader/Loader/PluginLoader.cs
@@ -1,4 +1,5 @@
-using IPA.Config;
+#nullable enable
+using IPA.Config;
using IPA.Loader.Features;
using IPA.Logging;
using IPA.Utilities;
@@ -32,7 +33,7 @@ namespace IPA.Loader
internal partial class PluginLoader
{
- internal static PluginMetadata SelfMeta;
+ internal static PluginMetadata SelfMeta = null!;
internal static Task LoadTask() =>
TaskEx.Run(() =>
@@ -40,6 +41,9 @@ namespace IPA.Loader
YeetIfNeeded();
LoadMetadata();
+
+ // old loader system
+#if false
Resolve();
InitFeatures();
ComputeLoadOrder();
@@ -47,6 +51,7 @@ namespace IPA.Loader
FilterWithoutFiles();
ResolveDependencies();
+#endif
});
internal static void YeetIfNeeded()
@@ -68,10 +73,10 @@ namespace IPA.Loader
}
}
- internal static List PluginsMetadata = new List();
- internal static List DisabledPlugins = new List();
+ internal static List PluginsMetadata = new();
+ internal static List DisabledPlugins = new();
- private static readonly Regex embeddedTextDescriptionPattern = new Regex(@"#!\[(.+)\]", RegexOptions.Compiled | RegexOptions.Singleline);
+ private static readonly Regex embeddedTextDescriptionPattern = new(@"#!\[(.+)\]", RegexOptions.Compiled | RegexOptions.Singleline);
internal static void LoadMetadata()
{
@@ -130,7 +135,7 @@ namespace IPA.Loader
foreach (var resource in pluginModule.Resources)
{
const string manifestSuffix = ".manifest.json";
- if (!(resource is EmbeddedResource embedded) ||
+ if (resource is not EmbeddedResource embedded ||
!embedded.Name.EndsWith(manifestSuffix)) continue;
pluginNs = embedded.Name.Substring(0, embedded.Name.Length - manifestSuffix.Length);
@@ -297,6 +302,7 @@ namespace IPA.Loader
}
}
+ #region Ignore stuff
///
/// An enum that represents several categories of ignore reasons that the loader may encounter.
///
@@ -372,15 +378,15 @@ namespace IPA.Loader
/// Gets the textual description of the particular ignore reason. This will typically
/// include details about why the plugin was ignored, if it is present.
///
- public string ReasonText { get; internal set; }
+ public string? ReasonText { get; internal set; }
///
/// Gets the that caused this plugin to be ignored, if any.
///
- public Exception Error { get; internal set; }
+ public Exception? Error { get; internal set; }
///
/// Gets the metadata of the plugin that this ignore was related to, if any.
///
- public PluginMetadata RelatedTo { get; internal set; }
+ public PluginMetadata? RelatedTo { get; internal set; }
///
/// Initializes an with the provided data.
///
@@ -388,7 +394,7 @@ namespace IPA.Loader
/// the textual description of this ignore reason, if any
/// the that caused this , if any
/// the this reason is related to, if any
- public IgnoreReason(Reason reason, string reasonText = null, Exception error = null, PluginMetadata relatedTo = null)
+ public IgnoreReason(Reason reason, string? reasonText = null, Exception? error = null, PluginMetadata? relatedTo = null)
{
Reason = reason;
ReasonText = reasonText;
@@ -412,10 +418,10 @@ namespace IPA.Loader
public override int GetHashCode()
{
int hashCode = 778404373;
- hashCode = hashCode * -1521134295 + Reason.GetHashCode();
- hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ReasonText);
- hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Error);
- hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(RelatedTo);
+ hashCode = (hashCode * -1521134295) + Reason.GetHashCode();
+ hashCode = (hashCode * -1521134295) + ReasonText?.GetHashCode() ?? 0;
+ hashCode = (hashCode * -1521134295) + Error?.GetHashCode() ?? 0;
+ hashCode = (hashCode * -1521134295) + RelatedTo?.GetHashCode() ?? 0;
return hashCode;
}
@@ -437,13 +443,15 @@ namespace IPA.Loader
public static bool operator !=(IgnoreReason left, IgnoreReason right)
=> !(left == right);
}
+ #endregion
internal partial class PluginLoader
{
// keep track of these for the updater; it should still be able to update mods not loaded
// the thing -> the reason
- internal static Dictionary ignoredPlugins = new Dictionary();
+ internal static Dictionary ignoredPlugins = new();
+#if false
internal static void Resolve()
{ // resolves duplicates and conflicts, etc
PluginsMetadata.Sort((a, b) => b.Version.CompareTo(a.Version));
@@ -706,6 +714,7 @@ namespace IPA.Loader
DisabledConfig.Instance.Changed();
PluginsMetadata = metadata;
}
+#endif
internal static void InitFeatures()
{
@@ -726,7 +735,7 @@ namespace IPA.Loader
}
else
{ // this is literally any other feature, so we want to delay its initialization
- meta.UnloadedFeatures.Add(feature);
+ _ = meta.UnloadedFeatures.Add(feature);
}
}
}
@@ -740,10 +749,13 @@ namespace IPA.Loader
{
if (plugin != meta)
{ // if the feature is not applied to the defining feature
- meta.LoadsAfter.Add(plugin);
+ _ = meta.LoadsAfter.Add(plugin);
}
- plugin.CreateFeaturesWhenLoaded.Add(feature);
+ if (plugin != null)
+ {
+ plugin.CreateFeaturesWhenLoaded.Add(feature);
+ }
}
else
{
@@ -776,11 +788,11 @@ namespace IPA.Loader
internal static void Load(PluginMetadata meta)
{
- if (meta.Assembly == null && meta.PluginType != null)
+ if (meta is { Assembly: null, PluginType: not null })
meta.Assembly = Assembly.LoadFrom(meta.File.FullName);
}
- internal static PluginExecutor InitPlugin(PluginMetadata meta, IEnumerable alreadyLoaded)
+ internal static PluginExecutor? InitPlugin(PluginMetadata meta, IEnumerable alreadyLoaded)
{
if (meta.Manifest.GameVersion != UnityGame.GameVersion)
Logger.loader.Warn($"Mod {meta.Name} developed for game version {meta.Manifest.GameVersion}, so it may not work properly.");
@@ -870,7 +882,7 @@ namespace IPA.Loader
else
{
feature.AppliedTo.InternalFeatures.Add(inst);
- feature.AppliedTo.UnloadedFeatures.Remove(feature);
+ _ = feature.AppliedTo.UnloadedFeatures.Remove(feature);
}
}
meta.CreateFeaturesWhenLoaded.Clear(); // if a plugin is loaded twice, for the moment, we don't want to create the feature twice
@@ -905,7 +917,7 @@ namespace IPA.Loader
if (exec != null)
{
list.Add(exec);
- loaded.Add(meta);
+ _ = loaded.Add(meta);
}
}
catch (Exception e)
diff --git a/IPA.Loader/Utilities/EnumerableExtensions.cs b/IPA.Loader/Utilities/EnumerableExtensions.cs
index fa2978dc..bf74bc63 100644
--- a/IPA.Loader/Utilities/EnumerableExtensions.cs
+++ b/IPA.Loader/Utilities/EnumerableExtensions.cs
@@ -1,4 +1,5 @@
-using System;
+#nullable enable
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -33,7 +34,7 @@ namespace IPA.Utilities
this.first = first;
}
- public PrependEnumerator GetEnumerator() => new PrependEnumerator(this);
+ public PrependEnumerator GetEnumerator() => new(this);
public struct PrependEnumerator : IEnumerator
{
@@ -45,12 +46,12 @@ namespace IPA.Utilities
this.enumerable = enumerable;
restEnum = enumerable.rest.GetEnumerator();
state = 0;
- Current = default;
+ Current = default!;
}
public T Current { get; private set; }
- object IEnumerator.Current => Current;
+ object? IEnumerator.Current => Current;
public void Dispose() => restEnum.Dispose();
@@ -109,7 +110,7 @@ namespace IPA.Utilities
this.last = last;
}
- public AppendEnumerator GetEnumerator() => new AppendEnumerator(this);
+ public AppendEnumerator GetEnumerator() => new(this);
public struct AppendEnumerator : IEnumerator
{
@@ -121,12 +122,12 @@ namespace IPA.Utilities
this.enumerable = enumerable;
restEnum = enumerable.rest.GetEnumerator();
state = 0;
- Current = default;
+ Current = default!;
}
public T Current { get; private set; }
- object IEnumerator.Current => Current;
+ object? IEnumerator.Current => Current;
public void Dispose() => restEnum.Dispose();
@@ -170,8 +171,8 @@ namespace IPA.Utilities
/// the type of the enumeration
/// the enumeration to filter
/// a filtered enumerable
- public static IEnumerable NonNull(this IEnumerable self) where T : class
- => self.Where(o => o != null);
+ public static IEnumerable NonNull(this IEnumerable self) where T : class
+ => self.Where(o => o != null)!;
///
/// LINQ-style extension method that filters elements out of an enumeration based on a converter.
@@ -181,7 +182,7 @@ namespace IPA.Utilities
/// the enumeration to filter
/// the predicate to select for filtering
/// a filtered enumerable
- public static IEnumerable NonNull(this IEnumerable self, Func pred) where U : class
+ public static IEnumerable NonNull(this IEnumerable self, Func pred) where U : class
=> self.Where(o => pred(o) != null);
///
@@ -191,7 +192,7 @@ namespace IPA.Utilities
/// the enumeration to filter
/// a filtered enumerable
public static IEnumerable NonNull(this IEnumerable self) where T : struct
- => self.Where(o => o != null).Select(o => o.Value);
+ => self.Where(o => o != null).Select(o => o!.Value);
///
/// LINQ-style extension method that filters elements out of an enumeration based on a converter to a nullable type.