blob: d3662c9cf51afaf389ea1be7738edec644ed4a3d (
plain)
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
|
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using StardewModdingAPI.Toolkit.Serialisation;
using StardewModdingAPI.Toolkit.Serialisation.Models;
namespace StardewModdingAPI.Toolkit.Framework.ModScanning
{
/// <summary>Scans folders for mod data.</summary>
public class ModScanner
{
/*********
** Properties
*********/
/// <summary>The JSON helper with which to read manifests.</summary>
private readonly JsonHelper JsonHelper;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="jsonHelper">The JSON helper with which to read manifests.</param>
public ModScanner(JsonHelper jsonHelper)
{
this.JsonHelper = jsonHelper;
}
/// <summary>Extract information about all mods in the given folder.</summary>
/// <param name="rootPath">The root folder containing mods.</param>
public IEnumerable<ModFolder> GetModFolders(string rootPath)
{
foreach (DirectoryInfo folder in new DirectoryInfo(rootPath).EnumerateDirectories())
yield return this.ReadFolder(rootPath, folder);
}
/// <summary>Extract information from a mod folder.</summary>
/// <param name="rootPath">The root folder containing mods.</param>
/// <param name="searchFolder">The folder to search for a mod.</param>
public ModFolder ReadFolder(string rootPath, DirectoryInfo searchFolder)
{
// find manifest.json
FileInfo manifestFile = this.FindManifest(searchFolder);
if (manifestFile == null)
return new ModFolder(searchFolder);
// read mod info
Manifest manifest = null;
string manifestError = null;
{
try
{
manifest = this.JsonHelper.ReadJsonFile<Manifest>(manifestFile.FullName);
if (manifest == null)
{
manifestError = File.Exists(manifestFile.FullName)
? "its manifest is invalid."
: "it doesn't have a manifest.";
}
}
catch (SParseException ex)
{
manifestError = $"parsing its manifest failed: {ex.Message}";
}
catch (Exception ex)
{
manifestError = $"parsing its manifest failed:\n{ex}";
}
}
return new ModFolder(searchFolder, manifestFile.Directory, manifest, manifestError);
}
/*********
** Private methods
*********/
/// <summary>Find the manifest for a mod folder.</summary>
/// <param name="folder">The folder to search.</param>
private FileInfo FindManifest(DirectoryInfo folder)
{
while (true)
{
// check for manifest in current folder
FileInfo file = new FileInfo(Path.Combine(folder.FullName, "manifest.json"));
if (file.Exists)
return file;
// check for single subfolder
FileSystemInfo[] entries = folder.EnumerateFileSystemInfos().Take(2).ToArray();
if (entries.Length == 1 && entries[0] is DirectoryInfo subfolder)
{
folder = subfolder;
continue;
}
// not found
return null;
}
}
}
}
|