summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-08-19 21:50:42 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-08-19 21:50:42 -0400
commit9f64dd2abb182b588cf5ae11201ca4dfbe26c45f (patch)
treeed64776e346005eff32ac9151839370e847c7459 /src
parentca8699c68f238f3092966a550643859bce357a86 (diff)
downloadSMAPI-9f64dd2abb182b588cf5ae11201ca4dfbe26c45f.tar.gz
SMAPI-9f64dd2abb182b588cf5ae11201ca4dfbe26c45f.tar.bz2
SMAPI-9f64dd2abb182b588cf5ae11201ca4dfbe26c45f.zip
add installer logic to detect if player moved the bundled mods (#583)
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI.Installer/InteractiveInstaller.cs57
-rw-r--r--src/SMAPI.Installer/Program.cs47
-rw-r--r--src/SMAPI.Installer/StardewModdingAPI.Installer.csproj6
3 files changed, 89 insertions, 21 deletions
diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs
index a92edadf..565ad732 100644
--- a/src/SMAPI.Installer/InteractiveInstaller.cs
+++ b/src/SMAPI.Installer/InteractiveInstaller.cs
@@ -10,6 +10,9 @@ using StardewModdingApi.Installer.Enums;
using StardewModdingAPI.Installer.Framework;
using StardewModdingAPI.Internal;
using StardewModdingAPI.Internal.ConsoleWriting;
+using StardewModdingAPI.Toolkit;
+using StardewModdingAPI.Toolkit.Framework.ModScanning;
+using StardewModdingAPI.Toolkit.Utilities;
namespace StardewModdingApi.Installer
{
@@ -468,31 +471,45 @@ namespace StardewModdingApi.Installer
{
this.PrintDebug("Adding bundled mods...");
- // add bundled mods
- foreach (DirectoryInfo sourceDir in packagedModsDir.EnumerateDirectories())
+ ModToolkit toolkit = new ModToolkit();
+ ModFolder[] targetMods = toolkit.GetModFolders(paths.ModsPath).ToArray();
+ foreach (ModFolder sourceMod in toolkit.GetModFolders(packagedModsDir.FullName))
{
- this.PrintDebug($" adding {sourceDir.Name}...");
-
- // init/clear target dir
- DirectoryInfo targetDir = new DirectoryInfo(Path.Combine(paths.ModsDir.FullName, sourceDir.Name));
- if (targetDir.Exists)
- this.InteractivelyDelete(targetDir.FullName);
- targetDir.Create();
+ // validate source mod
+ if (sourceMod.Manifest == null)
+ {
+ this.PrintWarning($" ignored invalid bundled mod {sourceMod.DisplayName}: {sourceMod.ManifestParseError}");
+ continue;
+ }
+
+ // find target folder
+ ModFolder targetMod = targetMods.FirstOrDefault(p => p.Manifest?.UniqueID?.Equals(sourceMod.Manifest.UniqueID, StringComparison.InvariantCultureIgnoreCase) == true);
+ DirectoryInfo defaultTargetFolder = new DirectoryInfo(Path.Combine(paths.ModsPath, sourceMod.Directory.Name));
+ DirectoryInfo targetFolder = targetMod?.Directory ?? defaultTargetFolder;
+ this.PrintDebug(targetFolder.FullName == defaultTargetFolder.FullName
+ ? $" adding {sourceMod.Manifest.Name}..."
+ : $" adding {sourceMod.Manifest.Name} to {Path.Combine(paths.ModsDir.Name, PathUtilities.GetRelativePath(paths.ModsPath, targetFolder.FullName))}..."
+ );
+
+ // (re)create target folder
+ if (targetFolder.Exists)
+ this.InteractivelyDelete(targetFolder.FullName);
+ targetFolder.Create();
// copy files
- foreach (FileInfo sourceFile in sourceDir.EnumerateFiles().Where(this.ShouldCopy))
- sourceFile.CopyTo(Path.Combine(targetDir.FullName, sourceFile.Name));
+ foreach (FileInfo sourceFile in sourceMod.Directory.EnumerateFiles().Where(this.ShouldCopy))
+ sourceFile.CopyTo(Path.Combine(targetFolder.FullName, sourceFile.Name));
}
+ }
- // set SMAPI's color scheme if defined
- if (scheme != MonitorColorScheme.AutoDetect)
- {
- string configPath = Path.Combine(paths.GamePath, "StardewModdingAPI.config.json");
- string text = File
- .ReadAllText(configPath)
- .Replace(@"""ColorScheme"": ""AutoDetect""", $@"""ColorScheme"": ""{scheme}""");
- File.WriteAllText(configPath, text);
- }
+ // set SMAPI's color scheme if defined
+ if (scheme != MonitorColorScheme.AutoDetect)
+ {
+ string configPath = Path.Combine(paths.GamePath, "StardewModdingAPI.config.json");
+ string text = File
+ .ReadAllText(configPath)
+ .Replace(@"""ColorScheme"": ""AutoDetect""", $@"""ColorScheme"": ""{scheme}""");
+ File.WriteAllText(configPath, text);
}
// remove obsolete appdata mods
diff --git a/src/SMAPI.Installer/Program.cs b/src/SMAPI.Installer/Program.cs
index 8f328ecf..4d259fd3 100644
--- a/src/SMAPI.Installer/Program.cs
+++ b/src/SMAPI.Installer/Program.cs
@@ -1,17 +1,62 @@
-namespace StardewModdingApi.Installer
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Reflection;
+using StardewModdingAPI.Internal;
+
+namespace StardewModdingApi.Installer
{
/// <summary>The entry point for SMAPI's install and uninstall console app.</summary>
internal class Program
{
/*********
+ ** Properties
+ *********/
+ /// <summary>The absolute path to search for referenced assemblies.</summary>
+ [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute", Justification = "The assembly location is never null in this context.")]
+ private static string DllSearchPath;
+
+
+ /*********
** Public methods
*********/
/// <summary>Run the install or uninstall script.</summary>
/// <param name="args">The command line arguments.</param>
public static void Main(string[] args)
{
+ // set up assembly resolution
+ string installerPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ Program.DllSearchPath = Path.Combine(installerPath, "internal", EnvironmentUtility.DetectPlatform() == Platform.Windows ? "Windows" : "Mono", "smapi-internal");
+ AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve;
+
+ // launch installer
var installer = new InteractiveInstaller();
installer.Run(args);
}
+
+ /*********
+ ** Private methods
+ *********/
+ /// <summary>Method called when assembly resolution fails, which may return a manually resolved assembly.</summary>
+ /// <param name="sender">The event sender.</param>
+ /// <param name="e">The event arguments.</param>
+ private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e)
+ {
+ AssemblyName name = new AssemblyName(e.Name);
+ foreach (FileInfo dll in new DirectoryInfo(Program.DllSearchPath).EnumerateFiles("*.dll"))
+ {
+ try
+ {
+ if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.InvariantCultureIgnoreCase))
+ return Assembly.LoadFrom(dll.FullName);
+ }
+ catch (Exception ex)
+ {
+ throw new InvalidOperationException($"Could not load dependency 'smapi-lib/{dll.Name}'. Consider deleting and redownloading the SMAPI installer.", ex);
+ }
+ }
+
+ return null;
+ }
}
}
diff --git a/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj b/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj
index e82c6093..e9af16c5 100644
--- a/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj
+++ b/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj
@@ -58,6 +58,12 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\StardewModdingAPI.Toolkit\StardewModdingAPI.Toolkit.csproj">
+ <Project>{ea5cfd2e-9453-4d29-b80f-8e0ea23f4ac6}</Project>
+ <Name>StardewModdingAPI.Toolkit</Name>
+ </ProjectReference>
+ </ItemGroup>
<Import Project="..\SMAPI.Internal\SMAPI.Internal.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\build\common.targets" />