/// <summary> /// Parses all games for a given system. /// </summary> /// /// <remarks> /// "Parsing" means reading and unmarshalling the given XML file in the /// system's database folder. /// </remarks> /// /// <param name="databaseFile">XML file to parse</param> /// <returns>Parsed games</returns> private List <PinballXGame> ParseGames([NotNull] string databaseFile) { var xmlPath = Path.Combine(DatabasePath, databaseFile); var games = new List <PinballXGame>(); if (_dir.Exists(DatabasePath)) { var menu = _marshallManager.UnmarshallXml(xmlPath); var remainingExecutables = Executables.ToList(); menu.Games.ForEach(game => { // update links game.System = this; game.DatabaseFile = databaseFile; // update executables var executable = game.AlternateExe != null && game.AlternateExe.Trim() != "" ? game.AlternateExe : DefaultExecutableLabel; if (!Executables.Contains(executable)) { _logger.Debug("Adding new alternate executable \"{0}\" to system \"{1}\"", executable, Name); _threadManager.MainDispatcher.Invoke(() => Executables.Add(executable)); } else { if (remainingExecutables.Contains(executable)) { remainingExecutables.Remove(executable); } } }); _logger.Debug("Removing alternate executables [ \"{0}\" ] from system \"{1}\"", string.Join("\", \"", remainingExecutables), Name); _threadManager.MainDispatcher.Invoke(() => Executables.RemoveAll(remainingExecutables)); _threadManager.MainDispatcher.Invoke(() => Executables.Sort(string.Compare)); games.AddRange(menu.Games); } _logger.Debug("Parsed {0} games from {1}.", games.Count, xmlPath); return(games); }
public PinballXGame AddGame(PinballXGame game) { // read current xml var xmlPath = Path.Combine(game.System.DatabasePath, _settingsManager.Settings.XmlFile[game.System.Type] + ".xml"); _logger.Info("Adding \"{0}\" to PinballX database at {1}", game.Description, xmlPath); if (_settingsManager.Settings.ReformatXml || !_file.Exists(xmlPath)) { var menu = _marshallManager.UnmarshallXml(xmlPath); // add game menu.Games.Add(game); // save xml _marshallManager.MarshallXml(menu, xmlPath); } else { var xml = _file.ReadAllText(xmlPath); var ns = new XmlSerializerNamespaces(); ns.Add("", ""); using (var writer = new StringWriter()) { // find out how the xml is indented var match = Regex.Match(xml, "[\n\r]([ \t]+)<", RegexOptions.Multiline | RegexOptions.IgnoreCase); var indentChars = match.Success ? match.Groups[1].ToString() : " "; // find the position where to insert game if (xml.IndexOf("</menu", StringComparison.OrdinalIgnoreCase) < 0) { xml = "<menu>\n\n</menu>"; } // serialize game as xml using (var xw = XmlWriter.Create(writer, new XmlWriterSettings { IndentChars = indentChars, Indent = true })) { var serializer = new XmlSerializer(typeof(PinballXGame)); serializer.Serialize(xw, game, ns); var xmlGame = string.Join("\n", writer .ToString() .Split('\n') .Select(line => line.StartsWith("<?xml") ? "" : line) .Select(line => indentChars + line) .ToList()) + "\n"; var pos = xml.LastIndexOf("</menu", StringComparison.OrdinalIgnoreCase); // insert game xml = xml.Substring(0, pos) + xmlGame + xml.Substring(pos); // write back to disk _file.WriteAllText(xmlPath, xml); _logger.Info("Appended game \"{0}\" to {1}", game.Description, xmlPath); } } } return(game); }