diff --git a/IPA.Injector/Properties/AssemblyInfo.cs b/IPA.Injector/Properties/AssemblyInfo.cs
index d88c5e7b..4519cca1 100644
--- a/IPA.Injector/Properties/AssemblyInfo.cs
+++ b/IPA.Injector/Properties/AssemblyInfo.cs
@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
// 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("3.9.2")]
-[assembly: AssemblyFileVersion("3.9.2")]
+[assembly: AssemblyVersion("3.10.0")]
+[assembly: AssemblyFileVersion("3.10.0")]
diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj
index 07306013..46a172a7 100644
--- a/IPA.Loader/IPA.Loader.csproj
+++ b/IPA.Loader/IPA.Loader.csproj
@@ -69,6 +69,9 @@
+
+
+
@@ -98,6 +101,9 @@
11.0.2
+
+ 1.2.0
+
diff --git a/IPA.Loader/Loader/PluginManager.cs b/IPA.Loader/Loader/PluginManager.cs
index 2e28a2b2..1f25869c 100644
--- a/IPA.Loader/Loader/PluginManager.cs
+++ b/IPA.Loader/Loader/PluginManager.cs
@@ -111,6 +111,46 @@ namespace IPA.Loader
{
string pluginCopy = Path.Combine(cacheDir, Path.GetFileName(s));
File.Copy(Path.Combine(pluginDirectory, s), pluginCopy);
+
+ #region Fix assemblies for refactor
+
+ var module = ModuleDefinition.ReadModule(Path.Combine(pluginDirectory, s));
+ foreach (var @ref in module.AssemblyReferences)
+ { // fix assembly references
+ if (@ref.Name == "IllusionPlugin" || @ref.Name == "IllusionInjector")
+ {
+ @ref.Name = "IPA.Loader";
+ }
+ }
+
+ foreach (var @ref in module.GetTypeReferences())
+ { // fix type references
+ if (@ref.FullName == "IllusionPlugin.IPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.IEnhancedPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.IBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.IEnhancedBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.BeatSaber.ModsaberModInfo") @ref.Namespace = "IPA"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.IniFile") @ref.Namespace = "IPA.Config"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.IModPrefs") @ref.Namespace = "IPA.Config"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.ModPrefs") @ref.Namespace = "IPA.Config"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.Utils.ReflectionUtil") @ref.Namespace = "IPA.Utilities"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.Logging.Logger") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionPlugin.Logging.LogPrinter") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.PluginManager") @ref.Namespace = "IPA.Loader"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.PluginComponent") @ref.Namespace = "IPA.Loader"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.CompositeBSPlugin") @ref.Namespace = "IPA.Loader.Composite"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.CompositeIPAPlugin") @ref.Namespace = "IPA.Loader.Composite"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.Logging.UnityLogInterceptor") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.Logging.StandardLogger") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.Updating.SelfPlugin") @ref.Namespace = "IPA.Updating"; //@ref.Name = "";
+ if (@ref.FullName == "IllusionInjector.Updating.Backup.BackupUnit") @ref.Namespace = "IPA.Updating.Backup"; //@ref.Name = "";
+ if (@ref.Namespace == "IllusionInjector.Utilities") @ref.Namespace = "IPA.Utilities"; //@ref.Name = "";
+ if (@ref.Namespace == "IllusionInjector.Logging.Printers") @ref.Namespace = "IPA.Logging.Printers"; //@ref.Name = "";
+ if (@ref.Namespace == "IllusionInjector.Updating.ModsaberML") @ref.Namespace = "IPA.Updating.ModsaberML"; //@ref.Name = "";
+ }
+ module.Write(pluginCopy);
+
+ #endregion
}
var selfPlugin = new BSPluginMeta
@@ -186,49 +226,6 @@ namespace IPA.Loader
try
{
- #region Fix assemblies for refactor
-
- var module = ModuleDefinition.ReadModule(file);
- bool modifiedModule = false;
- foreach (var @ref in module.AssemblyReferences)
- { // fix assembly references
- if (@ref.Name == "IllusionPlugin" || @ref.Name == "IllusionInjector")
- {
- @ref.Name = "IPA.Loader";
- modifiedModule = true;
- }
- }
- if (modifiedModule)
- { // types don't need to be fixed if it's already referencing the new version
- foreach (var @ref in module.GetTypeReferences())
- { // fix type references
- if (@ref.FullName == "IllusionPlugin.IPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.IEnhancedPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.IBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.IEnhancedBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.BeatSaber.ModsaberModInfo") @ref.Namespace = "IPA"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.IniFile") @ref.Namespace = "IPA.Config"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.IModPrefs") @ref.Namespace = "IPA.Config"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.ModPrefs") @ref.Namespace = "IPA.Config"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.Utils.ReflectionUtil") @ref.Namespace = "IPA.Utilities"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.Logging.Logger") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
- if (@ref.FullName == "IllusionPlugin.Logging.LogPrinter") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.PluginManager") @ref.Namespace = "IPA.Loader"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.PluginComponent") @ref.Namespace = "IPA.Loader"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.CompositeBSPlugin") @ref.Namespace = "IPA.Loader.Composite"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.CompositeIPAPlugin") @ref.Namespace = "IPA.Loader.Composite"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.Logging.UnityLogInterceptor") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.Logging.StandardLogger") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.Updating.SelfPlugin") @ref.Namespace = "IPA.Updating"; //@ref.Name = "";
- if (@ref.FullName == "IllusionInjector.Updating.Backup.BackupUnit") @ref.Namespace = "IPA.Updating.Backup"; //@ref.Name = "";
- if (@ref.Namespace == "IllusionInjector.Utilities") @ref.Namespace = "IPA.Utilities"; //@ref.Name = "";
- if (@ref.Namespace == "IllusionInjector.Logging.Printers") @ref.Namespace = "IPA.Logging.Printers"; //@ref.Name = "";
- if (@ref.Namespace == "IllusionInjector.Updating.ModsaberML") @ref.Namespace = "IPA.Updating.ModsaberML"; //@ref.Name = "";
- }
- module.Write(file);
- }
-
- #endregion
Assembly assembly = Assembly.LoadFrom(file);
diff --git a/IPA.Loader/PluginInterfaces/BeatSaber/ModsaberModInfo.cs b/IPA.Loader/PluginInterfaces/BeatSaber/ModsaberModInfo.cs
index ba5fb374..33671149 100644
--- a/IPA.Loader/PluginInterfaces/BeatSaber/ModsaberModInfo.cs
+++ b/IPA.Loader/PluginInterfaces/BeatSaber/ModsaberModInfo.cs
@@ -17,8 +17,8 @@ namespace IPA
public string InternalName { get; set; }
///
- /// The version of the currently installed mod. Used to compare to the version on ModSaber.
+ /// The version of the currently installed mod. Used to compare to the version on ModSaber. Should be a valid SemVer version.
///
- public Version CurrentVersion { get; set; }
+ public string CurrentVersion { get; set; }
}
}
diff --git a/IPA.Loader/Updating/Converters/ModsaberDependencyConverter.cs b/IPA.Loader/Updating/Converters/ModsaberDependencyConverter.cs
new file mode 100644
index 00000000..43da9f89
--- /dev/null
+++ b/IPA.Loader/Updating/Converters/ModsaberDependencyConverter.cs
@@ -0,0 +1,29 @@
+using IPA.Updating.ModsaberML;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static IPA.Updating.ModsaberML.ApiEndpoint.Mod;
+
+namespace IPA.Updating.Converters
+{
+ internal class ModsaberDependencyConverter : JsonConverter
+ {
+ public override Dependency ReadJson(JsonReader reader, Type objectType, Dependency existingValue, bool hasExistingValue, JsonSerializer serializer)
+ {
+ var parts = (reader.Value as string).Split('@');
+ return new Dependency()
+ {
+ Name = parts[0],
+ VersionRange = new SemVer.Range(parts[1])
+ };
+ }
+
+ public override void WriteJson(JsonWriter writer, Dependency value, JsonSerializer serializer)
+ {
+ writer.WriteValue($"{value.Name}@{value.VersionRange.ToString()}");
+ }
+ }
+}
diff --git a/IPA.Loader/Updating/Converters/SemverRangeConverter.cs b/IPA.Loader/Updating/Converters/SemverRangeConverter.cs
new file mode 100644
index 00000000..46d2a8c2
--- /dev/null
+++ b/IPA.Loader/Updating/Converters/SemverRangeConverter.cs
@@ -0,0 +1,17 @@
+using Newtonsoft.Json;
+using SemVer;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IPA.Updating.Converters
+{
+ internal class SemverRangeConverter : JsonConverter
+ {
+ public override Range ReadJson(JsonReader reader, Type objectType, Range existingValue, bool hasExistingValue, JsonSerializer serializer) => new Range(reader.Value as string);
+
+ public override void WriteJson(JsonWriter writer, Range value, JsonSerializer serializer) => writer.WriteValue(value.ToString());
+ }
+}
diff --git a/IPA.Loader/Updating/Converters/SemverVersionConverter.cs b/IPA.Loader/Updating/Converters/SemverVersionConverter.cs
new file mode 100644
index 00000000..57804965
--- /dev/null
+++ b/IPA.Loader/Updating/Converters/SemverVersionConverter.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using SemVer;
+using Version = SemVer.Version;
+
+namespace IPA.Updating.Converters
+{
+ internal class SemverVersionConverter : JsonConverter
+ {
+ public override Version ReadJson(JsonReader reader, Type objectType, Version existingValue, bool hasExistingValue, JsonSerializer serializer) => new Version(reader.Value as string);
+
+ public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer) => writer.WriteValue(value.ToString());
+ }
+}
diff --git a/IPA.Loader/Updating/ModsaberML/ApiEndpoint.cs b/IPA.Loader/Updating/ModsaberML/ApiEndpoint.cs
index 38776d50..7c1934b7 100644
--- a/IPA.Loader/Updating/ModsaberML/ApiEndpoint.cs
+++ b/IPA.Loader/Updating/ModsaberML/ApiEndpoint.cs
@@ -1,13 +1,16 @@
using IPA.Logging;
+using IPA.Updating.Converters;
using IPA.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
+using SemVer;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Version = SemVer.Version;
namespace IPA.Updating.ModsaberML
{
@@ -71,18 +74,24 @@ namespace IPA.Updating.ModsaberML
#pragma warning disable CS0649
[JsonProperty("name")]
public string Name;
+
[JsonProperty("version"),
- JsonConverter(typeof(VersionConverter))]
+ JsonConverter(typeof(SemverVersionConverter))]
public Version Version;
+
[JsonProperty("approved")]
public bool Approved;
+
[JsonProperty("title")]
public string Title;
+
[JsonProperty("gameVersion"),
- JsonConverter(typeof(VersionConverter))]
+ JsonConverter(typeof(SemverVersionConverter))]
public Version GameVersion;
+
[JsonProperty("author")]
public string Author;
+
#pragma warning restore CS0649
[Serializable]
public class PlatformFile
@@ -90,8 +99,10 @@ namespace IPA.Updating.ModsaberML
[JsonProperty("hash"),
JsonConverter(typeof(HexArrayConverter))]
public byte[] Hash = new byte[20];
+
[JsonProperty("files", ItemConverterType = typeof(HexArrayConverter))]
public Dictionary FileHashes = new Dictionary();
+
[JsonProperty("url")]
public string DownloadPath = null;
@@ -113,6 +124,15 @@ namespace IPA.Updating.ModsaberML
[JsonProperty("files")]
public FilesObject Files = null;
+ public class Dependency
+ {
+ public string Name = null;
+ public Range VersionRange = null;
+ }
+
+ [JsonProperty("dependsOn", ItemConverterType = typeof(ModsaberDependencyConverter))]
+ public Dependency[] Dependencies = new Dependency[0];
+
public override string ToString()
{
return $"{{\"{Title} ({Name})\"v{Version} for {GameVersion} by {Author} with \"{Files.Steam}\" and \"{Files.Oculus}\"}}";
diff --git a/IPA.Loader/Updating/ModsaberML/Updater.cs b/IPA.Loader/Updating/ModsaberML/Updater.cs
index a7251911..4b171813 100644
--- a/IPA.Loader/Updating/ModsaberML/Updater.cs
+++ b/IPA.Loader/Updating/ModsaberML/Updater.cs
@@ -16,6 +16,7 @@ using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using Logger = IPA.Logging.Logger;
+using Version = SemVer.Version;
using IPA.Updating.Backup;
namespace IPA.Updating.ModsaberML
@@ -47,9 +48,30 @@ namespace IPA.Updating.ModsaberML
StartCoroutine(CheckForUpdatesCoroutine());
}
+ private class ParsedPluginMeta : PluginManager.BSPluginMeta
+ {
+ private Version _verCache = null;
+ public Version ModVersion
+ {
+ get
+ {
+ if (_verCache == null)
+ _verCache = new Version(ModsaberInfo.CurrentVersion);
+ return _verCache;
+ }
+ }
+
+ public ParsedPluginMeta(PluginManager.BSPluginMeta meta)
+ {
+ this.Plugin = meta.Plugin;
+ this.ModsaberInfo = meta.ModsaberInfo;
+ this.Filename = meta.Filename;
+ }
+ }
+
private struct UpdateStruct
{
- public PluginManager.BSPluginMeta plugin;
+ public ParsedPluginMeta plugin;
public ApiEndpoint.Mod externInfo;
}
@@ -60,8 +82,9 @@ namespace IPA.Updating.ModsaberML
var toUpdate = new List();
var GameVersion = new Version(Application.version);
- foreach (var plugin in PluginManager.BSMetas)
+ foreach (var _plugin in PluginManager.BSMetas)
{
+ var plugin = new ParsedPluginMeta(_plugin);
var info = plugin.ModsaberInfo;
if (info == null) continue;
@@ -104,8 +127,8 @@ namespace IPA.Updating.ModsaberML
}
Logger.updater.Debug($"Found Modsaber.ML registration for {plugin.Plugin.Name} ({info.InternalName})");
- Logger.updater.Debug($"Installed version: {info.CurrentVersion}; Latest version: {modRegistry.Version}");
- if (modRegistry.Version > info.CurrentVersion)
+ Logger.updater.Debug($"Installed version: {plugin.ModVersion}; Latest version: {modRegistry.Version}");
+ if (modRegistry.Version > plugin.ModVersion)
{
Logger.updater.Debug($"{plugin.Plugin.Name} needs an update!");
if (modRegistry.GameVersion == GameVersion)
diff --git a/IPA.Loader/Updating/SelfPlugin.cs b/IPA.Loader/Updating/SelfPlugin.cs
index 2fde0921..57fe3bf1 100644
--- a/IPA.Loader/Updating/SelfPlugin.cs
+++ b/IPA.Loader/Updating/SelfPlugin.cs
@@ -11,7 +11,7 @@ namespace IPA.Updating
internal class SelfPlugin : IBeatSaberPlugin
{
internal const string IPA_Name = "Beat Saber IPA";
- internal const string IPA_Version = "3.9.2";
+ internal const string IPA_Version = "3.10.0";
public string Name => IPA_Name;
@@ -19,7 +19,7 @@ namespace IPA.Updating
public ModsaberModInfo ModInfo => new ModsaberModInfo
{
- CurrentVersion = new Version(IPA_Version),
+ CurrentVersion = IPA_Version,
InternalName = "beatsaber-ipa-reloaded"
};
diff --git a/IPA/Properties/AssemblyInfo.cs b/IPA/Properties/AssemblyInfo.cs
index 63939eed..17291691 100644
--- a/IPA/Properties/AssemblyInfo.cs
+++ b/IPA/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 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("3.9.2")]
-[assembly: AssemblyFileVersion("3.9.2")]
+[assembly: AssemblyVersion("3.10.0")]
+[assembly: AssemblyFileVersion("3.10.0")]