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
|
using System;
using System.Collections.Generic;
using System.Linq;
namespace StardewModdingAPI.Toolkit.Framework.ModData
{
/// <summary>The parsed mod metadata from SMAPI's internal mod list.</summary>
public class ModDataRecord
{
/*********
** Accessors
*********/
/// <summary>The mod's default display name.</summary>
public string DisplayName { get; }
/// <summary>The mod's current unique ID.</summary>
public string ID { get; }
/// <summary>The former mod IDs (if any).</summary>
public string[] FormerIDs { get; }
/// <summary>Maps local versions to a semantic version for update checks.</summary>
public IDictionary<string, string> MapLocalVersions { get; }
/// <summary>Maps remote versions to a semantic version for update checks.</summary>
public IDictionary<string, string> MapRemoteVersions { get; }
/// <summary>The versioned field data.</summary>
public ModDataField[] Fields { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="displayName">The mod's default display name.</param>
/// <param name="model">The raw data model.</param>
internal ModDataRecord(string displayName, ModDataModel model)
{
this.DisplayName = displayName;
this.ID = model.ID;
this.FormerIDs = model.GetFormerIDs().ToArray();
this.MapLocalVersions = new Dictionary<string, string>(model.MapLocalVersions, StringComparer.InvariantCultureIgnoreCase);
this.MapRemoteVersions = new Dictionary<string, string>(model.MapRemoteVersions, StringComparer.InvariantCultureIgnoreCase);
this.Fields = model.GetFields().ToArray();
}
/// <summary>Get whether the mod has (or previously had) the given ID.</summary>
/// <param name="id">The mod ID.</param>
public bool HasID(string id)
{
// try main ID
if (this.ID.Equals(id, StringComparison.InvariantCultureIgnoreCase))
return true;
// try former IDs
foreach (string formerID in this.FormerIDs)
{
if (formerID.Equals(id, StringComparison.InvariantCultureIgnoreCase))
return true;
}
return false;
}
/// <summary>Get a semantic local version for update checks.</summary>
/// <param name="version">The remote version to normalise.</param>
public ISemanticVersion GetLocalVersionForUpdateChecks(ISemanticVersion version)
{
return this.MapLocalVersions != null && this.MapLocalVersions.TryGetValue(version.ToString(), out string newVersion)
? new SemanticVersion(newVersion)
: version;
}
/// <summary>Get a semantic remote version for update checks.</summary>
/// <param name="version">The remote version to normalise.</param>
public string GetRemoteVersionForUpdateChecks(string version)
{
// normalise version if possible
if (SemanticVersion.TryParse(version, out ISemanticVersion parsed))
version = parsed.ToString();
// fetch remote version
return this.MapRemoteVersions != null && this.MapRemoteVersions.TryGetValue(version, out string newVersion)
? newVersion
: version;
}
/// <summary>Get a parsed representation of the <see cref="ModDataRecord.Fields"/> which match a given manifest.</summary>
/// <param name="manifest">The manifest to match.</param>
public ModDataRecordVersionedFields GetVersionedFields(IManifest manifest)
{
ModDataRecordVersionedFields parsed = new ModDataRecordVersionedFields { DisplayName = this.DisplayName, DataRecord = this };
foreach (ModDataField field in this.Fields.Where(field => field.IsMatch(manifest)))
{
switch (field.Key)
{
// update key
case ModDataFieldKey.UpdateKey:
parsed.UpdateKey = field.Value;
break;
// alternative URL
case ModDataFieldKey.AlternativeUrl:
parsed.AlternativeUrl = field.Value;
break;
// status
case ModDataFieldKey.Status:
parsed.Status = (ModStatus)Enum.Parse(typeof(ModStatus), field.Value, ignoreCase: true);
parsed.StatusUpperVersion = field.UpperVersion;
break;
// status reason phrase
case ModDataFieldKey.StatusReasonPhrase:
parsed.StatusReasonPhrase = field.Value;
break;
}
}
return parsed;
}
}
}
|