Skip to content

Commit

Permalink
Only auto-delete manually installed DLLs unless also replacing them
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Feb 13, 2024
1 parent 05631a8 commit 383c7eb
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 21 deletions.
28 changes: 15 additions & 13 deletions Core/ModuleInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public void InstallList(ICollection<CkanModule> modules,
}
}

if (ConfirmPrompt && !User.RaiseYesNoDialog("Continue?"))
if (ConfirmPrompt && !User.RaiseYesNoDialog(Properties.Resources.ModuleInstallerContinuePrompt))
{
throw new CancelledActionKraken(Properties.Resources.ModuleInstallerUserDeclined);
}
Expand Down Expand Up @@ -347,20 +347,22 @@ private IEnumerable<string> InstallModule(CkanModule module, string zip_filename
.ToHashSet();
// Make sure that the DLL is actually included in the install
// (NearFutureElectrical, NearFutureElectrical-Core)
if (dllFolders.Count > 0
&& !dllFolders.Contains(Path.GetDirectoryName(dll)))
if (dllFolders.Count > 0)
{
// Manually installed DLL is somewhere else where we're not installing files,
// probable bad install, alert user and abort
throw new DllLocationMismatchKraken(dll, string.Format(
Properties.Resources.ModuleInstallerBadDLLLocation, module.identifier, dll));
if (!dllFolders.Contains(Path.GetDirectoryName(dll)))
{
// Manually installed DLL is somewhere else where we're not installing files,
// probable bad install, alert user and abort
throw new DllLocationMismatchKraken(dll, string.Format(
Properties.Resources.ModuleInstallerBadDLLLocation, module.identifier, dll));
}
// Delete the manually installed DLL transaction-style because we believe we'll be replacing it
var toDelete = ksp.ToAbsoluteGameDir(dll);
log.DebugFormat("Deleting manually installed DLL {0}", toDelete);
TxFileManager file_transaction = new TxFileManager();
file_transaction.Snapshot(toDelete);
file_transaction.Delete(toDelete);
}
// Delete the manually installed DLL transaction-style because we believe we'll be replacing it
var toDelete = ksp.ToAbsoluteGameDir(dll);
log.DebugFormat("Deleting manually installed DLL {0}", toDelete);
TxFileManager file_transaction = new TxFileManager();
file_transaction.Snapshot(toDelete);
file_transaction.Delete(toDelete);
}

// Look for overwritable files if session is interactive
Expand Down
20 changes: 12 additions & 8 deletions Core/Registry/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class Registry : IEnlistmentNotification, IRegistryQuerier
[JsonProperty("sorted_repositories")]
private SortedDictionary<string, Repository> repositories;

// name => path
// name => relative path
[JsonProperty]
private Dictionary<string, string> installed_dlls;

Expand Down Expand Up @@ -834,7 +834,7 @@ public List<CkanModule> LatestAvailableWithProvides(
/// track of its metadata and files.
/// </summary>
public void RegisterModule(CkanModule mod,
IEnumerable<string> absolute_files,
IEnumerable<string> absoluteFiles,
GameInstance inst,
bool autoInstalled)
{
Expand All @@ -850,13 +850,14 @@ public void RegisterModule(CkanModule mod,
var inconsistencies = new List<string>();

// We always work with relative files, so let's get some!
IEnumerable<string> relative_files = absolute_files
.Select(x => inst.ToRelativeGameDir(x))
.Memoize();
var relativeFiles = absoluteFiles.Select(x => inst.ToRelativeGameDir(x))
.ToHashSet(Platform.IsWindows
? StringComparer.OrdinalIgnoreCase
: StringComparer.Ordinal);

// For now, it's always cool if a module wants to register a directory.
// We have to flip back to absolute paths to actually test this.
foreach (string file in relative_files.Where(file => !Directory.Exists(inst.ToAbsoluteGameDir(file))))
foreach (string file in relativeFiles.Where(file => !Directory.Exists(inst.ToAbsoluteGameDir(file))))
{
if (installed_files.TryGetValue(file, out string owner))
{
Expand All @@ -881,14 +882,17 @@ public void RegisterModule(CkanModule mod,
// directories aren't really owned like files are. However because each mod maintains
// its own list of files, we'll remove directories when the last mod using them
// is uninstalled.
foreach (string file in relative_files)
foreach (string file in relativeFiles)
{
installed_files[file] = mod.identifier;
}

// Make sure mod-owned files aren't in the manually installed DLL dict
installed_dlls.RemoveWhere(kvp => relativeFiles.Contains(kvp.Value));

// Finally register our module proper
installed_modules.Add(mod.identifier,
new InstalledModule(inst, mod, relative_files, autoInstalled));
new InstalledModule(inst, mod, relativeFiles, autoInstalled));

// Installing and uninstalling mods can change compatibility due to conflicts,
// so we'll need to reset the compatibility sorter
Expand Down

0 comments on commit 383c7eb

Please sign in to comment.