Ejemplo n.º 1
0
        /*********
        ** Public methods
        *********/
        /// <summary>Parse SMAPI log text.</summary>
        /// <param name="logText">The SMAPI log text.</param>
        public ParsedLog Parse(string logText)
        {
            try
            {
                // skip if empty
                if (string.IsNullOrWhiteSpace(logText))
                {
                    return(new ParsedLog
                    {
                        IsValid = false,
                        RawText = logText,
                        Error = "The log is empty."
                    });
                }

                // init log
                ParsedLog log = new ParsedLog
                {
                    IsValid  = true,
                    RawText  = logText,
                    Messages = this.CollapseRepeats(this.GetMessages(logText)).ToArray()
                };

                // parse log messages
                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
                    if (message.Level == LogLevel.Error)
                    {
                        switch (message.Mod)
                        {
                        case "SMAPI":
                            smapiMod.Errors++;
                            break;

                        case "game":
                            gameMod.Errors++;
                            break;

                        default:
                            if (mods.ContainsKey(message.Mod))
                            {
                                mods[message.Mod].Errors++;
                            }
                            break;
                        }
                    }

                    // collect SMAPI metadata
                    if (message.Mod == "SMAPI")
                    {
                        // update flags
                        if (inModList && !this.ModListEntryPattern.IsMatch(message.Text))
                        {
                            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))
                        {
                            inModList = true;
                            message.IsStartOfSection = true;
                            message.Section          = LogSection.ModsList;
                        }
                        else if (inModList)
                        {
                            Match  match       = this.ModListEntryPattern.Match(message.Text);
                            string name        = match.Groups["name"].Value;
                            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, Loaded = true
                            };

                            message.Section = LogSection.ModsList;
                        }

                        // content pack list
                        else if (!inContentPackList && message.Level == LogLevel.Info && this.ContentPackListStartPattern.IsMatch(message.Text))
                        {
                            inContentPackList        = true;
                            message.IsStartOfSection = true;
                            message.Section          = LogSection.ContentPackList;
                        }
                        else if (inContentPackList)
                        {
                            Match  match       = this.ContentPackListEntryPattern.Match(message.Text);
                            string name        = match.Groups["name"].Value;
                            string version     = match.Groups["version"].Value;
                            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, Loaded = true
                            };

                            message.Section = LogSection.ContentPackList;
                        }

                        // mod update list
                        else if (!inModUpdateList && message.Level == LogLevel.Alert && this.ModUpdateListStartPattern.IsMatch(message.Text))
                        {
                            inModUpdateList          = true;
                            message.IsStartOfSection = true;
                            message.Section          = LogSection.ModUpdateList;
                        }
                        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
                                };
                            }

                            message.Section = LogSection.ModUpdateList;
                        }

                        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
                        else if (message.Level == LogLevel.Info && this.InfoLinePattern.IsMatch(message.Text))
                        {
                            Match match = this.InfoLinePattern.Match(message.Text);
                            log.ApiVersion      = match.Groups["apiVersion"].Value;
                            log.GameVersion     = match.Groups["gameVersion"].Value;
                            log.OperatingSystem = match.Groups["os"].Value;
                            smapiMod.Version    = log.ApiVersion;
                        }

                        // mod path line
                        else if (message.Level == LogLevel.Debug && this.ModPathPattern.IsMatch(message.Text))
                        {
                            Match match = this.ModPathPattern.Match(message.Text);
                            log.ModPath = match.Groups["path"].Value;
                            int lastDelimiterPos = log.ModPath.LastIndexOfAny(new char[] { '/', '\\' });
                            log.GamePath = lastDelimiterPos >= 0
                                ? log.ModPath.Substring(0, lastDelimiterPos)
                                : log.ModPath;
                        }

                        // log UTC timestamp line
                        else if (message.Level == LogLevel.Trace && this.LogStartedAtPattern.IsMatch(message.Text))
                        {
                            Match match = this.LogStartedAtPattern.Match(message.Text);
                            log.Timestamp = DateTime.Parse(match.Groups["timestamp"].Value + "Z");
                        }
                    }
                }

                // finalize log
                gameMod.Version = log.GameVersion;
                log.Mods        = new[] { gameMod, smapiMod }.Concat(mods.Values.OrderBy(p => p.Name)).ToArray();
                return(log);
            }
            catch (LogParseException ex)
            {
                return(new ParsedLog
                {
                    IsValid = false,
                    Error = ex.Message,
                    RawText = logText
                });
            }
            catch (Exception ex)
            {
                return(new ParsedLog
                {
                    IsValid = false,
                    Error = $"Parsing the log file failed. Technical details:\n{ex}",
                    RawText = logText
                });
            }
        }
Ejemplo n.º 2
0
        /*********
        ** Public methods
        *********/
        /// <summary>Parse SMAPI log text.</summary>
        /// <param name="logText">The SMAPI log text.</param>
        public ParsedLog Parse(string logText)
        {
            try
            {
                // skip if empty
                if (string.IsNullOrWhiteSpace(logText))
                {
                    return(new ParsedLog
                    {
                        IsValid = false,
                        RawText = logText,
                        Error = "The log is empty."
                    });
                }

                // init log
                ParsedLog log = new ParsedLog
                {
                    IsValid  = true,
                    RawText  = logText,
                    Messages = this.CollapseRepeats(this.GetMessages(logText)).ToArray()
                };

                // parse log messages
                LogModInfo smapiMod = new LogModInfo {
                    Name = "SMAPI", Author = "Pathoschild", Description = ""
                };
                IDictionary <string, LogModInfo> mods = new Dictionary <string, LogModInfo>();
                bool inModList         = false;
                bool inContentPackList = false;
                foreach (LogMessage message in log.Messages)
                {
                    // collect stats
                    if (message.Level == LogLevel.Error)
                    {
                        if (message.Mod == "SMAPI")
                        {
                            smapiMod.Errors++;
                        }
                        else if (mods.ContainsKey(message.Mod))
                        {
                            mods[message.Mod].Errors++;
                        }
                    }

                    // collect SMAPI metadata
                    if (message.Mod == "SMAPI")
                    {
                        // update flags
                        if (inModList && !this.ModListEntryPattern.IsMatch(message.Text))
                        {
                            inModList = false;
                        }
                        if (inContentPackList && !this.ContentPackListEntryPattern.IsMatch(message.Text))
                        {
                            inContentPackList = false;
                        }

                        // mod list
                        if (!inModList && message.Level == LogLevel.Info && this.ModListStartPattern.IsMatch(message.Text))
                        {
                            inModList = true;
                        }
                        else if (inModList)
                        {
                            Match  match       = this.ModListEntryPattern.Match(message.Text);
                            string name        = match.Groups["name"].Value;
                            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
                            };
                        }

                        // content pack list
                        else if (!inContentPackList && message.Level == LogLevel.Info && this.ContentPackListStartPattern.IsMatch(message.Text))
                        {
                            inContentPackList = true;
                        }
                        else if (inContentPackList)
                        {
                            Match  match       = this.ContentPackListEntryPattern.Match(message.Text);
                            string name        = match.Groups["name"].Value;
                            string version     = match.Groups["version"].Value;
                            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
                            };
                        }

                        // platform info line
                        else if (message.Level == LogLevel.Info && this.InfoLinePattern.IsMatch(message.Text))
                        {
                            Match match = this.InfoLinePattern.Match(message.Text);
                            log.ApiVersion      = match.Groups["apiVersion"].Value;
                            log.GameVersion     = match.Groups["gameVersion"].Value;
                            log.OperatingSystem = match.Groups["os"].Value;
                            smapiMod.Version    = log.ApiVersion;
                        }

                        // mod path line
                        else if (message.Level == LogLevel.Debug && this.ModPathPattern.IsMatch(message.Text))
                        {
                            Match match = this.ModPathPattern.Match(message.Text);
                            log.ModPath = match.Groups["path"].Value;
                        }

                        // log UTC timestamp line
                        else if (message.Level == LogLevel.Trace && this.LogStartedAtPattern.IsMatch(message.Text))
                        {
                            Match match = this.LogStartedAtPattern.Match(message.Text);
                            log.Timestamp = DateTime.Parse(match.Groups["timestamp"].Value + "Z");
                        }
                    }
                }

                // finalise log
                log.Mods = new[] { smapiMod }.Concat(mods.Values.OrderBy(p => p.Name)).ToArray();
                return(log);
            }
            catch (LogParseException ex)
            {
                return(new ParsedLog
                {
                    IsValid = false,
                    Error = ex.Message,
                    RawText = logText
                });
            }
            catch (Exception ex)
            {
                return(new ParsedLog
                {
                    IsValid = false,
                    Error = $"Parsing the log file failed. Technical details:\n{ex}",
                    RawText = logText
                });
            }
        }