Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only auto-delete manually installed DLLs if also replacing them #4024

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 && registry.FileOwner(dll) == null)
{
// 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
Loading