diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj
index 1ebe67fd..7f3fd570 100644
--- a/IPA.Loader/IPA.Loader.csproj
+++ b/IPA.Loader/IPA.Loader.csproj
@@ -130,5 +130,8 @@
+
+
+
\ No newline at end of file
diff --git a/IPA.Loader/Loader/PluginLoader.cs b/IPA.Loader/Loader/PluginLoader.cs
index 98d85cbb..762fb6d6 100644
--- a/IPA.Loader/Loader/PluginLoader.cs
+++ b/IPA.Loader/Loader/PluginLoader.cs
@@ -223,20 +223,38 @@ namespace IPA.Loader
var m = embeddedTextDescriptionPattern.Match(lines[0]);
if (m.Success)
{
- var name = m.Groups[1].Value;
- var resc = meta.PluginType.Module.Resources.Select(r => r as EmbeddedResource)
- .Where(r => r != null)
- .FirstOrDefault(r => r.Name == name);
- if (resc == null)
+ if (meta.IsBare)
{
- Logger.loader.Warn($"Could not find description file for plugin {meta.Name} ({name}); ignoring include");
+ Logger.loader.Warn($"Bare manifest cannot specify description file");
meta.Manifest.Description = string.Join("\n", lines.Skip(1)); // ignore first line
continue;
}
+ var name = m.Groups[1].Value;
string description;
- using (var reader = new StreamReader(resc.GetResourceStream()))
- description = reader.ReadToEnd();
+ if (!meta.IsSelf)
+ {
+ var resc = meta.PluginType.Module.Resources.Select(r => r as EmbeddedResource)
+ .Where(r => r != null)
+ .FirstOrDefault(r => r.Name == name);
+ if (resc == null)
+ {
+ Logger.loader.Warn($"Could not find description file for plugin {meta.Name} ({name}); ignoring include");
+ meta.Manifest.Description = string.Join("\n", lines.Skip(1)); // ignore first line
+ continue;
+ }
+
+ using (var reader = new StreamReader(resc.GetResourceStream()))
+ description = reader.ReadToEnd();
+ }
+ else
+ {
+ using (var descriptionReader =
+ new StreamReader(
+ meta.Assembly.GetManifestResourceStream(name) ??
+ throw new InvalidOperationException()))
+ description = descriptionReader.ReadToEnd();
+ }
meta.Manifest.Description = description;
}
diff --git a/IPA.Loader/Loader/description.md b/IPA.Loader/Loader/description.md
new file mode 100644
index 00000000..851899eb
--- /dev/null
+++ b/IPA.Loader/Loader/description.md
@@ -0,0 +1,16 @@
+BSIPA
+=====
+
+BSIPA is a mod loader based off of [Illusion Plugin Architecture](https://github.com/russianGecko/IPA-Reloaded), designed for Beat Saber.
+While it retains backwards compatability, the recommended interface has been completely redesigned for a more consistent and stable installation.
+
+Taking some inspiration from mod injectors like [BepInEx](https://github.com/BepInEx/BepInEx), it uses a fork of [Unity Doorstop](https://github.com/NeighTools/UnityDoorstop)
+to actually inject itself into the game.
+
+***
+
+The particular method of injection that BSIPA uses lets its user experience be far nicer than most others, not requiring a repatch for every game update.
+
+With updating the game being seamless, it also makes sense to make updating the mods themselves seamless. BSIPA's internal updater will automatically ask [BeatMods](https://beatmods.com/)
+for newer versions of your installed mods. Of course, this is configurable either in the config at `UserData\Beat Saber IPA.json` or with the Mod List, which lets you control the process
+to a greater extend than even the configs.
\ No newline at end of file
diff --git a/IPA.Loader/Loader/manifest.json b/IPA.Loader/Loader/manifest.json
index 2d622f94..11ea7cce 100644
--- a/IPA.Loader/Loader/manifest.json
+++ b/IPA.Loader/Loader/manifest.json
@@ -1,7 +1,10 @@
{
"$schema": "https://raw.githubusercontent.com/beat-saber-modding-group/BSIPA-MetadataFileSchema/master/Schema.json",
"author": "DaNike",
- "description": "A mod loader specifically for Beat Saber.",
+ "description": [
+ "#![IPA.Loader.description.md]",
+ "A mod loader specifically for Beat Saber."
+ ],
"gameVersion": "0.13.2",
"id": "BSIPA",
"name": "Beat Saber IPA",
diff --git a/IPA/IPA.csproj b/IPA/IPA.csproj
index a940b558..6b7bc3c1 100644
--- a/IPA/IPA.csproj
+++ b/IPA/IPA.csproj
@@ -111,7 +111,6 @@
-
0.10.3