From a23261106ea454ab2e264007f27ca11ddbb7e44b Mon Sep 17 00:00:00 2001 From: danvolchek Date: Sun, 17 Feb 2019 20:39:36 -0600 Subject: [PATCH] add update info in suggested fixes section --- .../Framework/LogParsing/LogParser.cs | 49 +++++++++++++-- .../Models/{ModInfo.cs => LogModInfo.cs} | 12 ++++ src/SMAPI.Web/Views/LogParser/Index.cshtml | 61 +++++++++++++++++-- .../wwwroot/Content/css/log-parser.css | 33 +++++++--- 4 files changed, 138 insertions(+), 17 deletions(-) rename src/SMAPI.Web/Framework/LogParsing/Models/{ModInfo.cs => LogModInfo.cs} (64%) diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs index 6f848469..5cdc501f 100644 --- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs +++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs @@ -39,6 +39,15 @@ namespace StardewModdingAPI.Web.Framework.LogParsing /// A regex pattern matching an entry in SMAPI's content pack list. private readonly Regex ContentPackListEntryPattern = new Regex(@"^ (?.+) (?.+) by (?.+) \| for (?.+?)(?: \| (?.+))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + /// A regex pattern matching the start of SMAPI's mod update list. + private readonly Regex ModUpdateListStartPattern = new Regex(@"^You can update \d+ mods?:$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + /// A regex pattern matching an entry in SMAPI's mod update list. + private readonly Regex ModUpdateListEntryPattern = new Regex(@"^ (?.+?) (?" + SemanticVersion.UnboundedVersionPattern + @"): (?.+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + /// A regex pattern matching SMAPI's update line. + private readonly Regex SMAPIUpdatePattern = new Regex(@"^You can update SMAPI to (?" + SemanticVersion.UnboundedVersionPattern + @"): (?.+)$", 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 mods = new Dictionary(); 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 diff --git a/src/SMAPI.Web/Framework/LogParsing/Models/ModInfo.cs b/src/SMAPI.Web/Framework/LogParsing/Models/LogModInfo.cs similarity index 64% rename from src/SMAPI.Web/Framework/LogParsing/Models/ModInfo.cs rename to src/SMAPI.Web/Framework/LogParsing/Models/LogModInfo.cs index 8c84ab38..067e4df4 100644 --- a/src/SMAPI.Web/Framework/LogParsing/Models/ModInfo.cs +++ b/src/SMAPI.Web/Framework/LogParsing/Models/LogModInfo.cs @@ -12,6 +12,12 @@ namespace StardewModdingAPI.Web.Framework.LogParsing.Models /// The mod author. public string Author { get; set; } + /// The update version. + public string UpdateVersion { get; set; } + + /// The update link. + public string UpdateLink { get; set; } + /// The mod version. public string Version { get; set; } @@ -23,5 +29,11 @@ namespace StardewModdingAPI.Web.Framework.LogParsing.Models /// The number of errors logged by this mod. public int Errors { get; set; } + + /// Whether the mod was loaded into the game. + public bool Loaded { get; set; } + + /// Whether the mod has an update available. + public bool HasUpdate => this.UpdateVersion != null && this.Version != this.UpdateVersion; } } diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index 58830d64..07b413b1 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -117,9 +117,60 @@ else if (Model.ParsedLog?.IsValid == true) @* parsed log *@ @if (Model.ParsedLog?.IsValid == true) { -

Log info

- + @if (Model.ParsedLog.Mods.Any(mod => mod.HasUpdate)) + { +

Suggested fixes

+ +

You have some mods that aren't fully up to date. Updating them can fix problems.

+
+ + @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)))) + { + + + + + } +
+ Updates Available: +
+ @mod.Name + @if (contentPacks != null && contentPacks.TryGetValue(mod.Name, out LogModInfo[] contentPackList)) + { +
+ @foreach (LogModInfo contentPack in contentPackList.Where(pack => pack.HasUpdate)) + { + + @contentPack.Name
+ } +
+ } +
+ @if (mod.HasUpdate) + { + + @(mod.Version == null ? @mod.UpdateVersion : $"{mod.Version} → {mod.UpdateVersion}") + + } + else + { + + } + + @if (contentPacks != null && contentPacks.TryGetValue(mod.Name, out contentPackList)) + { +
+ @foreach (LogModInfo contentPack in contentPackList.Where(pack => pack.HasUpdate)) + { + @contentPack.Version → @contentPack.UpdateVersion
+ } +
+ } +
+ } + +

Log info

+ @@ -138,8 +189,8 @@ else if (Model.ParsedLog?.IsValid == true)
Game info:
Stardew Valley:@Model.ParsedLog.Timestamp.UtcDateTime.ToString("yyyy-MM-dd HH:mm") UTC ({{localTimeStarted}} your time)
-
- +
+
- @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)) { diff --git a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css index 2f3dd0a1..5e7ccb79 100644 --- a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css +++ b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css @@ -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 }
Installed mods: @if (!Model.ShowRaw) @@ -149,7 +200,7 @@ else if (Model.ParsedLog?.IsValid == true) hide all }