add update info in suggested fixes section
This commit is contained in:
parent
4baad0ec8d
commit
a23261106e
|
@ -39,6 +39,15 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
|
|||
/// <summary>A regex pattern matching an entry in SMAPI's content pack list.</summary>
|
||||
private readonly Regex ContentPackListEntryPattern = new Regex(@"^ (?<name>.+) (?<version>.+) by (?<author>.+) \| for (?<for>.+?)(?: \| (?<description>.+))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
/// <summary>A regex pattern matching the start of SMAPI's mod update list.</summary>
|
||||
private readonly Regex ModUpdateListStartPattern = new Regex(@"^You can update \d+ mods?:$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
/// <summary>A regex pattern matching an entry in SMAPI's mod update list.</summary>
|
||||
private readonly Regex ModUpdateListEntryPattern = new Regex(@"^ (?<name>.+?) (?<version>" + SemanticVersion.UnboundedVersionPattern + @"): (?<link>.+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
/// <summary>A regex pattern matching SMAPI's update line.</summary>
|
||||
private readonly Regex SMAPIUpdatePattern = new Regex(@"^You can update SMAPI to (?<version>" + SemanticVersion.UnboundedVersionPattern + @"): (?<link>.+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
|
@ -69,11 +78,12 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
|
|||
};
|
||||
|
||||
// parse log messages
|
||||
LogModInfo smapiMod = new LogModInfo { Name = "SMAPI", Author = "Pathoschild", Description = "" };
|
||||
LogModInfo gameMod = new LogModInfo { Name = "game", Author = "", Description = "" };
|
||||
LogModInfo smapiMod = new LogModInfo { Name = "SMAPI", Author = "Pathoschild", Description = "", Loaded = true};
|
||||
LogModInfo gameMod = new LogModInfo { Name = "game", Author = "", Description = "", Loaded = true };
|
||||
IDictionary<string, LogModInfo> mods = new Dictionary<string, LogModInfo>();
|
||||
bool inModList = false;
|
||||
bool inContentPackList = false;
|
||||
bool inModUpdateList = false;
|
||||
foreach (LogMessage message in log.Messages)
|
||||
{
|
||||
// collect stats
|
||||
|
@ -106,6 +116,8 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
|
|||
inModList = false;
|
||||
if (inContentPackList && !this.ContentPackListEntryPattern.IsMatch(message.Text))
|
||||
inContentPackList = false;
|
||||
if (inModUpdateList && !this.ModUpdateListEntryPattern.IsMatch(message.Text))
|
||||
inModUpdateList = false;
|
||||
|
||||
// mod list
|
||||
if (!inModList && message.Level == LogLevel.Info && this.ModListStartPattern.IsMatch(message.Text))
|
||||
|
@ -117,7 +129,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
|
|||
string version = match.Groups["version"].Value;
|
||||
string author = match.Groups["author"].Value;
|
||||
string description = match.Groups["description"].Value;
|
||||
mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description };
|
||||
mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, Loaded = true };
|
||||
}
|
||||
|
||||
// content pack list
|
||||
|
@ -131,7 +143,36 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
|
|||
string author = match.Groups["author"].Value;
|
||||
string description = match.Groups["description"].Value;
|
||||
string forMod = match.Groups["for"].Value;
|
||||
mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, ContentPackFor = forMod };
|
||||
mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, ContentPackFor = forMod, Loaded = true };
|
||||
}
|
||||
|
||||
// mod update list
|
||||
else if (!inModUpdateList && message.Level == LogLevel.Alert && this.ModUpdateListStartPattern.IsMatch(message.Text))
|
||||
inModUpdateList = true;
|
||||
else if (inModUpdateList)
|
||||
{
|
||||
Match match = this.ModUpdateListEntryPattern.Match(message.Text);
|
||||
string name = match.Groups["name"].Value;
|
||||
string version = match.Groups["version"].Value;
|
||||
string link = match.Groups["link"].Value;
|
||||
if (mods.ContainsKey(name))
|
||||
{
|
||||
mods[name].UpdateLink = link;
|
||||
mods[name].UpdateVersion = version;
|
||||
}
|
||||
else
|
||||
{
|
||||
mods[name] = new LogModInfo {Name = name, UpdateVersion = version, UpdateLink = link, Loaded = false};
|
||||
}
|
||||
}
|
||||
|
||||
else if(message.Level == LogLevel.Alert && this.SMAPIUpdatePattern.IsMatch(message.Text))
|
||||
{
|
||||
Match match = this.SMAPIUpdatePattern.Match(message.Text);
|
||||
string version = match.Groups["version"].Value;
|
||||
string link = match.Groups["link"].Value;
|
||||
smapiMod.UpdateVersion = version;
|
||||
smapiMod.UpdateLink = link;
|
||||
}
|
||||
|
||||
// platform info line
|
||||
|
|
|
@ -12,6 +12,12 @@ namespace StardewModdingAPI.Web.Framework.LogParsing.Models
|
|||
/// <summary>The mod author.</summary>
|
||||
public string Author { get; set; }
|
||||
|
||||
/// <summary>The update version.</summary>
|
||||
public string UpdateVersion { get; set; }
|
||||
|
||||
/// <summary>The update link.</summary>
|
||||
public string UpdateLink { get; set; }
|
||||
|
||||
/// <summary>The mod version.</summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
|
@ -23,5 +29,11 @@ namespace StardewModdingAPI.Web.Framework.LogParsing.Models
|
|||
|
||||
/// <summary>The number of errors logged by this mod.</summary>
|
||||
public int Errors { get; set; }
|
||||
|
||||
/// <summary>Whether the mod was loaded into the game.</summary>
|
||||
public bool Loaded { get; set; }
|
||||
|
||||
/// <summary>Whether the mod has an update available.</summary>
|
||||
public bool HasUpdate => this.UpdateVersion != null && this.Version != this.UpdateVersion;
|
||||
}
|
||||
}
|
|
@ -117,9 +117,60 @@ else if (Model.ParsedLog?.IsValid == true)
|
|||
@* parsed log *@
|
||||
@if (Model.ParsedLog?.IsValid == true)
|
||||
{
|
||||
<h2>Log info</h2>
|
||||
<div id="output">
|
||||
<table id="metadata">
|
||||
@if (Model.ParsedLog.Mods.Any(mod => mod.HasUpdate))
|
||||
{
|
||||
<h2>Suggested fixes</h2>
|
||||
|
||||
<p>You have some mods that aren't fully up to date. Updating them can fix problems.</p>
|
||||
<table id="updates" class="table">
|
||||
<caption>
|
||||
Updates Available:
|
||||
</caption>
|
||||
@foreach (LogModInfo mod in Model.ParsedLog.Mods.Where(mod => (mod.HasUpdate && mod.ContentPackFor == null) || (contentPacks != null && contentPacks.TryGetValue(mod.Name, out LogModInfo[] contentPackList) && contentPackList.Any(pack => pack.HasUpdate))))
|
||||
{
|
||||
<tr class="mod-entry">
|
||||
<td>
|
||||
<strong class=@(!mod.HasUpdate ? "hidden": "")>@mod.Name</strong>
|
||||
@if (contentPacks != null && contentPacks.TryGetValue(mod.Name, out LogModInfo[] contentPackList))
|
||||
{
|
||||
<div class="content-packs">
|
||||
@foreach (LogModInfo contentPack in contentPackList.Where(pack => pack.HasUpdate))
|
||||
{
|
||||
<text>+ @contentPack.Name</text><br />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (mod.HasUpdate)
|
||||
{
|
||||
<a href="@mod.UpdateLink" target="_blank">
|
||||
@(mod.Version == null ? @mod.UpdateVersion : $"{mod.Version} → {mod.UpdateVersion}")
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="invisible">Okay</span>
|
||||
}
|
||||
|
||||
@if (contentPacks != null && contentPacks.TryGetValue(mod.Name, out contentPackList))
|
||||
{
|
||||
<div>
|
||||
@foreach (LogModInfo contentPack in contentPackList.Where(pack => pack.HasUpdate))
|
||||
{
|
||||
<a href="@contentPack.UpdateLink" target="_blank">@contentPack.Version → @contentPack.UpdateVersion</a><br />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
}
|
||||
|
||||
<h2>Log info</h2>
|
||||
<table id="metadata" class="table">
|
||||
<caption>Game info:</caption>
|
||||
<tr>
|
||||
<th>Stardew Valley:</th>
|
||||
|
@ -139,7 +190,7 @@ else if (Model.ParsedLog?.IsValid == true)
|
|||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
<table id="mods" class="@(Model.ShowRaw ? "filters-disabled" : null)">
|
||||
<table id="mods" class="@(Model.ShowRaw ? "filters-disabled" : null) table">
|
||||
<caption>
|
||||
Installed mods:
|
||||
@if (!Model.ShowRaw)
|
||||
|
@ -149,7 +200,7 @@ else if (Model.ParsedLog?.IsValid == true)
|
|||
<span class="notice btn txt" v-on:click="hideAllMods" v-bind:class="{ invisible: !anyModsShown || !anyModsHidden }">hide all</span>
|
||||
}
|
||||
</caption>
|
||||
@foreach (var mod in Model.ParsedLog.Mods.Where(p => p.ContentPackFor == null))
|
||||
@foreach (var mod in Model.ParsedLog.Mods.Where(p => p.Loaded && p.ContentPackFor == null))
|
||||
{
|
||||
<tr v-on:click="toggleMod('@Model.GetSlug(mod.Name)')" class="mod-entry" v-bind:class="{ hidden: !showMods['@Model.GetSlug(mod.Name)'] }">
|
||||
<td><input type="checkbox" v-bind:checked="showMods['@Model.GetSlug(mod.Name)']" v-bind:class="{ invisible: !anyModsHidden }" /></td>
|
||||
|
|
|
@ -13,6 +13,13 @@ caption {
|
|||
#output {
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#output h2 {
|
||||
margin: -10px 0 10px -10px;
|
||||
}
|
||||
|
||||
#output table {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
|
@ -43,7 +50,7 @@ table caption {
|
|||
/*********
|
||||
** Log metadata & filters
|
||||
*********/
|
||||
#metadata, #mods, #filters {
|
||||
.table, #filters {
|
||||
border-bottom: 1px dashed #888888;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
@ -53,7 +60,7 @@ table caption {
|
|||
padding-right: 0.7em;
|
||||
}
|
||||
|
||||
table#metadata, table#mods {
|
||||
.table {
|
||||
border: 1px solid #000000;
|
||||
background: #ffffff;
|
||||
border-radius: 5px;
|
||||
|
@ -63,6 +70,18 @@ table#metadata, table#mods {
|
|||
box-shadow: 1px 1px 1px 1px #dddddd;
|
||||
}
|
||||
|
||||
.mod-entry {
|
||||
height: 1.8em;
|
||||
}
|
||||
|
||||
.table > caption {
|
||||
min-height: 1.3em;
|
||||
}
|
||||
|
||||
#updates {
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
@ -87,8 +106,7 @@ table#metadata, table#mods {
|
|||
cursor: default;
|
||||
}
|
||||
|
||||
#metadata tr,
|
||||
#mods tr {
|
||||
.table tr {
|
||||
background: #eee
|
||||
}
|
||||
|
||||
|
@ -114,11 +132,11 @@ table#metadata, table#mods {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
#mods .mod-entry.hidden {
|
||||
.table .hidden {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#mods .content-packs {
|
||||
.table .content-packs {
|
||||
margin-left: 1em;
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
|
@ -128,8 +146,7 @@ table#metadata, table#mods {
|
|||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#metadata tr:nth-child(even),
|
||||
#mods tr:nth-child(even) {
|
||||
.table tr:nth-child(even) {
|
||||
background: #fff
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue