diff --git a/IllusionInjector/BeatSaber/CompositeBSPlugin.cs b/IllusionInjector/BeatSaber/CompositeBSPlugin.cs
index 8ba4fb7e..96d6ddf0 100644
--- a/IllusionInjector/BeatSaber/CompositeBSPlugin.cs
+++ b/IllusionInjector/BeatSaber/CompositeBSPlugin.cs
@@ -1,4 +1,5 @@
using IllusionPlugin;
+using IllusionPlugin.BeatSaber;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -78,16 +79,14 @@ namespace IllusionInjector {
Invoke(plugin => plugin.OnFixedUpdate());
}
- public string Name {
- get { throw new NotImplementedException(); }
- }
+ public string Name => throw new NotImplementedException();
- public Version Version {
- get { throw new NotImplementedException(); }
- }
+ public string Version => throw new NotImplementedException();
public Uri UpdateUri => throw new NotImplementedException();
+ public ModsaberModInfo ModInfo => throw new NotImplementedException();
+
public void OnLateUpdate() {
Invoke(plugin => {
if (plugin is IEnhancedBeatSaberPlugin)
diff --git a/IllusionInjector/IllusionInjector.csproj b/IllusionInjector/IllusionInjector.csproj
index 8e29ff76..c59cd9a7 100644
--- a/IllusionInjector/IllusionInjector.csproj
+++ b/IllusionInjector/IllusionInjector.csproj
@@ -69,6 +69,7 @@
+
diff --git a/IllusionInjector/PluginComponent.cs b/IllusionInjector/PluginComponent.cs
index 9db293ba..9f62e10c 100644
--- a/IllusionInjector/PluginComponent.cs
+++ b/IllusionInjector/PluginComponent.cs
@@ -1,5 +1,4 @@
-using IllusionInjector.Updating;
-using System;
+using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
@@ -27,6 +26,7 @@ namespace IllusionInjector
// this has no relevance since there is a new mod updater system
//gameObject.AddComponent(); // AFTER plugins are loaded, but before most things
+ gameObject.AddComponent();
bsPlugins.OnApplicationStart();
ipaPlugins.OnApplicationStart();
diff --git a/IllusionInjector/PluginManager.cs b/IllusionInjector/PluginManager.cs
index d1db08b7..1a03c771 100644
--- a/IllusionInjector/PluginManager.cs
+++ b/IllusionInjector/PluginManager.cs
@@ -1,5 +1,6 @@
using IllusionInjector.Logging;
using IllusionPlugin;
+using IllusionPlugin.BeatSaber;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -15,11 +16,12 @@ namespace IllusionInjector
public static class PluginManager
{
#pragma warning disable CS0618 // Type or member is obsolete (IPlugin)
-
+
public class BSPluginMeta
{
public IBeatSaberPlugin Plugin { get; internal set; }
public string Filename { get; internal set; }
+ public ModsaberModInfo ModsaberInfo { get; internal set; }
}
public static IEnumerable BSPlugins
@@ -100,15 +102,16 @@ namespace IllusionInjector
foreach (string s in copiedPlugins)
{
var result = LoadPluginsFromFile(s, exeName);
- _bsPlugins.AddRange(result.Item1.Select(p => new BSPluginMeta { Plugin = p, Filename = s }));
+ _bsPlugins.AddRange(result.Item1);
_ipaPlugins.AddRange(result.Item2);
}
// DEBUG
Logger.log.Info($"Running on Unity {UnityEngine.Application.unityVersion}");
+ Logger.log.Info($"Game version {UnityEngine.Application.version}");
Logger.log.Info("-----------------------------");
- Logger.log.Info($"Loading plugins from {pluginDirectory} and found {_bsPlugins.Count}");
+ Logger.log.Info($"Loading plugins from {GetRelativePath(pluginDirectory, Environment.CurrentDirectory)} and found {_bsPlugins.Count + _ipaPlugins.Count}");
Logger.log.Info("-----------------------------");
foreach (var plugin in _bsPlugins)
{
@@ -122,13 +125,25 @@ namespace IllusionInjector
Logger.log.Info("-----------------------------");
}
- private static Tuple, IEnumerable> LoadPluginsFromFile(string file, string exeName)
+ private static string GetRelativePath(string filespec, string folder)
+ {
+ Uri pathUri = new Uri(filespec);
+ // Folders must end in a slash
+ if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString()))
+ {
+ folder += Path.DirectorySeparatorChar;
+ }
+ Uri folderUri = new Uri(folder);
+ return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString().Replace('/', Path.DirectorySeparatorChar));
+ }
+
+ private static Tuple, IEnumerable> LoadPluginsFromFile(string file, string exeName)
{
- List bsPlugins = new List();
+ List bsPlugins = new List();
List ipaPlugins = new List();
if (!File.Exists(file) || !file.EndsWith(".dll", true, null))
- return new Tuple, IEnumerable>(bsPlugins, ipaPlugins);
+ return new Tuple, IEnumerable>(bsPlugins, ipaPlugins);
T OptionalGetPlugin(Type t) where T : class
{
@@ -166,7 +181,12 @@ namespace IllusionInjector
IBeatSaberPlugin bsPlugin = OptionalGetPlugin(t);
if (bsPlugin != null)
{
- bsPlugins.Add(bsPlugin);
+ bsPlugins.Add(new BSPluginMeta
+ {
+ Plugin = bsPlugin,
+ Filename = file,
+ ModsaberInfo = bsPlugin.ModInfo
+ });
}
else
{
@@ -184,7 +204,7 @@ namespace IllusionInjector
Logger.log.Error($"Could not load {Path.GetFileName(file)}! {e}");
}
- return new Tuple, IEnumerable>(bsPlugins, ipaPlugins);
+ return new Tuple, IEnumerable>(bsPlugins, ipaPlugins);
}
public class AppInfo
diff --git a/IllusionInjector/Updating/ModsaberML/ApiEndpoint.cs b/IllusionInjector/Updating/ModsaberML/ApiEndpoint.cs
index d5b312ec..a4d3d047 100644
--- a/IllusionInjector/Updating/ModsaberML/ApiEndpoint.cs
+++ b/IllusionInjector/Updating/ModsaberML/ApiEndpoint.cs
@@ -9,8 +9,13 @@ namespace IllusionInjector.Updating.ModsaberML
{
class ApiEndpoint
{
- const string ApiBase = "https://www.modsaber.ml/api/";
- const string GetApprovedEndpoint = "public/temp/approved";
+#if DEBUG
+ public const string ApiBase = "https://www.modsaber.ml/api/";
+ public const string GetApprovedEndpoint = "public/temp/approved";
+#else
+ public const string ApiBase = "https://www.modsaber.ml/api/";
+ public const string GetApprovedEndpoint = "public/temp/approved";
+#endif
public class Mod
{
@@ -35,17 +40,22 @@ namespace IllusionInjector.Updating.ModsaberML
Author = obj["author"]
};
- foreach (var item in obj["files"].Keys)
+ foreach (var item in obj["files"])
{
- var key = item as JSONString;
- if (key.Value == "steam")
- outp.SteamFile = obj[key.Value]["url"];
- if (key.Value == "oculus")
- outp.OculusFile = obj[key.Value]["url"];
+ var key = item.Key;
+ if (key == "steam")
+ outp.SteamFile = item.Value["url"];
+ if (key == "oculus")
+ outp.OculusFile = item.Value["url"];
}
return outp;
}
+
+ public override string ToString()
+ {
+ return $"{{\"{Title} ({Name})\"v{Version} for {GameVersion} by {Author} with \"{SteamFile}\" and \"{OculusFile}\"}}";
+ }
}
}
diff --git a/IllusionInjector/Updating/ModsaberML/Updater.cs b/IllusionInjector/Updating/ModsaberML/Updater.cs
new file mode 100644
index 00000000..64f998fc
--- /dev/null
+++ b/IllusionInjector/Updating/ModsaberML/Updater.cs
@@ -0,0 +1,167 @@
+using SimpleJSON;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using UnityEngine;
+using UnityEngine.Networking;
+using Logger = IllusionInjector.Logging.Logger;
+
+namespace IllusionInjector.Updating.ModsaberML
+{
+ class Updater : MonoBehaviour
+ {
+ public Updater instance;
+
+ public void Awake()
+ {
+ instance = this;
+ CheckForUpdates();
+ }
+
+ public void CheckForUpdates()
+ {
+ StartCoroutine(CheckForUpdatesCoroutine());
+ }
+
+ private Regex commentRegex = new Regex(@"(?: \/\/.+)?$", RegexOptions.Compiled | RegexOptions.Multiline);
+ private Dictionary cachedRequests = new Dictionary();
+ IEnumerator CheckForUpdatesCoroutine()
+ {
+ Logger.log.Info("Checking for mod updates...");
+
+ var toUpdate = new List();
+
+ var modList = new List();
+ using (var request = UnityWebRequest.Get(ApiEndpoint.ApiBase+ApiEndpoint.GetApprovedEndpoint))
+ {
+ yield return request.SendWebRequest();
+
+ if (request.isNetworkError)
+ {
+ Logger.log.Error("Network error while trying to update mods");
+ Logger.log.Error(request.error);
+ yield break;
+ }
+ if (request.isHttpError)
+ {
+ Logger.log.Error($"Server returned an error code while trying to update mods");
+ Logger.log.Error(request.error);
+ }
+
+ var json = request.downloadHandler.text;
+
+ JSONObject obj = null;
+ try
+ {
+ obj = JSON.Parse(json).AsObject;
+ }
+ catch (InvalidCastException)
+ {
+ Logger.log.Error($"Parse error while trying to update mods");
+ Logger.log.Error($"Response doesn't seem to be a JSON object");
+ yield break;
+ }
+ catch (Exception e)
+ {
+ Logger.log.Error($"Parse error while trying to update mods");
+ Logger.log.Error(e);
+ yield break;
+ }
+
+ foreach (var modObj in obj["mods"].AsArray.Children)
+ {
+ try
+ {
+ modList.Add(ApiEndpoint.Mod.DecodeJSON(modObj.AsObject));
+ }
+ catch (Exception e)
+ {
+ Logger.log.Error($"Parse error while trying to update mods");
+ Logger.log.Error($"Response doesn't seem to be correctly formatted");
+ Logger.log.Error(e);
+ break;
+ }
+ }
+ }
+
+ var GameVersion = new Version(Application.version);
+
+ foreach (var plugin in PluginManager.BSMetas)
+ {
+ var info = plugin.ModsaberInfo;
+ var modRegistry = modList.FirstOrDefault(o => o.Name == info.InternalName);
+ if (modRegistry != null)
+ { // a.k.a we found it
+ Logger.log.Debug($"Found Modsaber.ML registration for {plugin.Plugin.Name} ({info.InternalName})");
+ Logger.log.Debug($"Installed version: {info.CurrentVersion}; Latest version: {modRegistry.Version}");
+ if (modRegistry.Version > info.CurrentVersion)
+ {
+ Logger.log.Debug($"{plugin.Plugin.Name} needs an update!");
+ if (modRegistry.GameVersion == GameVersion)
+ {
+ Logger.log.Debug($"Queueing update...");
+ toUpdate.Add(plugin);
+ }
+ else
+ {
+ Logger.log.Warn($"Update avaliable for {plugin.Plugin.Name}, but for a different Beat Saber version!");
+ }
+ }
+ }
+ }
+
+ Logger.log.Info($"{toUpdate.Count} mods need updating");
+
+ if (toUpdate.Count == 0) yield break;
+
+ string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + Path.GetRandomFileName());
+ Directory.CreateDirectory(tempDirectory);
+ Logger.log.Debug($"Created temp download dirtectory {tempDirectory}");
+ foreach (var item in toUpdate)
+ {
+ StartCoroutine(DownloadPluginCoroutine(tempDirectory, item));
+ }
+ }
+
+ IEnumerator DownloadPluginCoroutine(string tempdir, PluginManager.BSPluginMeta item)
+ {
+
+ yield return null;
+ /*var file = Path.Combine(tempdir, item. + ".dll");
+
+ using (var req = UnityWebRequest.Get(item.DownloadUri))
+ {
+ req.downloadHandler = new DownloadHandlerFile(file);
+ yield return req.SendWebRequest();
+
+ if (req.isNetworkError)
+ {
+ Logger.log.Error($"Network error while trying to download update for {item.Plugin.Plugin.Name}");
+ Logger.log.Error(req.error);
+ yield break;
+ }
+ if (req.isHttpError)
+ {
+ Logger.log.Error($"Server returned an error code while trying to download update for {item.Plugin.Plugin.Name}");
+ Logger.log.Error(req.error);
+ yield break;
+ }
+ }
+
+ var pluginDir = Path.GetDirectoryName(item.Plugin.Filename);
+ var newFile = Path.Combine(pluginDir, item.Name + ".dll");
+
+ File.Delete(item.Plugin.Filename);
+ if (File.Exists(newFile))
+ File.Delete(newFile);
+ File.Move(file, newFile);
+
+ Logger.log.Info($"{item.Plugin.Plugin.Name} updated to {item.NewVersion}");*/
+ }
+ }
+}
diff --git a/IllusionInjector/Updating/Old/ModUpdater.cs b/IllusionInjector/Updating/Old/ModUpdater.cs
index 8c4000e9..99ab7409 100644
--- a/IllusionInjector/Updating/Old/ModUpdater.cs
+++ b/IllusionInjector/Updating/Old/ModUpdater.cs
@@ -17,6 +17,7 @@ using Logger = IllusionInjector.Logging.Logger;
namespace IllusionInjector.Updating
{
+#if OLD_UPDATER
class ModUpdater : MonoBehaviour
{
public ModUpdater instance;
@@ -202,4 +203,5 @@ namespace IllusionInjector.Updating
Logger.log.Info($"{item.Plugin.Plugin.Name} updated to {item.NewVersion}");
}
}
+#endif
}
diff --git a/IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache b/IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache
index 278fe638..fd4317e3 100644
--- a/IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache
+++ b/IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-1b7ab3d058c6a212976e4869e8586d3cc95bb707
+4b98b2d3f93866107d7a8621254570f2cc16296c
diff --git a/IllusionPlugin/BeatSaber/IBeatSaberPlugin.cs b/IllusionPlugin/BeatSaber/IBeatSaberPlugin.cs
index 89889cec..af5672aa 100644
--- a/IllusionPlugin/BeatSaber/IBeatSaberPlugin.cs
+++ b/IllusionPlugin/BeatSaber/IBeatSaberPlugin.cs
@@ -1,4 +1,5 @@
-using System;
+using IllusionPlugin.BeatSaber;
+using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.SceneManagement;
@@ -20,13 +21,20 @@ namespace IllusionPlugin
///
/// Gets the version of the plugin.
///
- Version Version { get; }
+ string Version { get; }
+#if OLD_UPDATER
///
/// The URI to the update script for the plugin. May be .
/// Actually tho this does nothing I just don't want to try to remove it completely
///
Uri UpdateUri { get; }
+#endif
+
+ ///
+ /// Gets the info for the Modsaber release of this plugin.
+ ///
+ ModsaberModInfo ModInfo { get; }
///
/// Gets invoked when the application is started.
diff --git a/IllusionPlugin/BeatSaber/ModsaberModInfo.cs b/IllusionPlugin/BeatSaber/ModsaberModInfo.cs
new file mode 100644
index 00000000..52942af3
--- /dev/null
+++ b/IllusionPlugin/BeatSaber/ModsaberModInfo.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IllusionPlugin.BeatSaber
+{
+ public class ModsaberModInfo
+ {
+ public string InternalName { get; set; }
+ public Version CurrentVersion { get; set; }
+ }
+}
diff --git a/IllusionPlugin/IllusionPlugin.csproj b/IllusionPlugin/IllusionPlugin.csproj
index 74f97711..9aa220d7 100644
--- a/IllusionPlugin/IllusionPlugin.csproj
+++ b/IllusionPlugin/IllusionPlugin.csproj
@@ -44,6 +44,7 @@
+
diff --git a/IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache b/IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache
index b45009b5..fcd958a6 100644
--- a/IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache
+++ b/IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-1bbd9ba53463d8e0c57caf8203d0145bfc70fa26
+9c8aaadb0a1830ce0d658b39574b7acf02507f4a