-
-
Notifications
You must be signed in to change notification settings - Fork 346
/
InstalledModule.cs
149 lines (123 loc) · 5.01 KB
/
InstalledModule.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Linq;
using System.ComponentModel;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using Newtonsoft.Json;
namespace CKAN
{
[JsonObject(MemberSerialization.OptIn)]
public class InstalledModuleFile
{
[JsonConstructor]
public InstalledModuleFile()
{
}
}
/// <summary>
/// A simple class that represents an installed module. Includes the time of installation,
/// the module itself, and a list of files installed with it.
///
/// Primarily used by the Registry class.
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
public class InstalledModule
{
#region Fields and Properties
[JsonProperty]
private readonly DateTime install_time;
[JsonProperty]
private readonly CkanModule source_module;
[JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
[DefaultValue(false)]
private bool auto_installed;
// TODO: Our InstalledModuleFile already knows its path, so this could just
// be a list. However we've left it as a dictionary for now to maintain
// registry format compatibility.
[JsonProperty]
private Dictionary<string, InstalledModuleFile> installed_files;
public IReadOnlyCollection<string> Files => installed_files.Keys;
public string identifier => source_module.identifier;
public CkanModule Module => source_module;
public DateTime InstallTime => install_time;
public bool AutoInstalled
{
get => auto_installed;
set {
if (Module.IsDLC)
{
throw new ModuleIsDLCKraken(Module);
}
auto_installed = value;
}
}
#endregion
#region Constructors
public InstalledModule(GameInstance? ksp, CkanModule module, IEnumerable<string> relative_files, bool autoInstalled)
{
install_time = DateTime.Now;
source_module = module;
// We need case insensitive path matching on Windows
installed_files = new Dictionary<string, InstalledModuleFile>(Platform.PathComparer);
auto_installed = autoInstalled;
if (ksp != null)
{
foreach (string file in relative_files)
{
if (Path.IsPathRooted(file))
{
throw new PathErrorKraken(file, "InstalledModule *must* have relative paths");
}
// IMF needs a KSP object so it can compute the SHA1.
installed_files[file] = new InstalledModuleFile();
}
}
}
#endregion
#region Serialisation Fixes
[OnDeserialized]
private void DeSerialisationFixes(StreamingContext context)
{
installed_files ??= new Dictionary<string, InstalledModuleFile>();
if (Platform.IsWindows)
{
// We need case insensitive path matching on Windows
installed_files = new Dictionary<string, InstalledModuleFile>(installed_files,
Platform.PathComparer);
}
}
/// <summary>
/// Ensures all files for this module have relative paths.
/// Called when upgrading registry versions. Should be a no-op
/// if called on newer registries.
/// </summary>
public void Renormalise(GameInstance ksp)
{
// We need case insensitive path matching on Windows
var normalised_installed_files = new Dictionary<string, InstalledModuleFile>(Platform.PathComparer);
foreach (var tuple in installed_files)
{
string path = CKANPathUtils.NormalizePath(tuple.Key);
if (Path.IsPathRooted(path))
{
path = ksp.ToRelativeGameDir(path);
}
normalised_installed_files[path] = tuple.Value;
}
installed_files = normalised_installed_files;
}
#endregion
public bool AllFilesExist(GameInstance instance,
HashSet<string> filters)
// Don't make them reinstall files they've filtered out since installing
=> Files.Where(f => !filters.Any(filt => f.Contains(filt)))
.Select(instance.ToAbsoluteGameDir)
.All(p => Directory.Exists(p) || File.Exists(p));
public override string ToString()
=> string.Format(AutoInstalled ? Properties.Resources.InstalledModuleToStringAutoInstalled
: Properties.Resources.InstalledModuleToString,
Module,
InstallTime);
}
}