Exemple #1
0
        /// <summary>
        /// Constructs based on XML game.
        /// </summary>
        /// <param name="xmlGame">Parsed game from PinballX XML database</param>
        public AggregatedGame([NotNull] PinballXGame xmlGame) : this(Locator.Current)
        {
            Update(xmlGame);
            FileId = Path.Combine(xmlGame.System.TablePath, xmlGame.FileName);

            // Unlink local file when table path changes.
            XmlGame.WhenAnyValue(g => g.System.TablePath).Subscribe(newPath => ClearLocalFile());
        }
Exemple #2
0
 /// <summary>
 /// Updates XML game.
 /// </summary>
 /// <param name="xmlGame">Parsed game from PinballX XML database</param>
 /// <returns>This instance</returns>
 public AggregatedGame Update(PinballXGame xmlGame)
 {
     if (XmlGame == null)
     {
         XmlGame = xmlGame;
     }
     else
     {
         XmlGame.Update(xmlGame);
     }
     return(this);
 }
Exemple #3
0
 /// <summary>
 /// Renames the file ID of the game.
 /// </summary>
 ///
 /// <remarks>
 /// This happens when a local file with a mapping has been renamed. In
 /// this case we want to keep the mapping linked to the game. The
 /// mapping is renamed as well.
 /// </remarks>
 ///
 /// <param name="filePath">Absolute path to new file name</param>
 /// <param name="newXmlGame">If set, link to this XML game. This means that an entry with the new file name exists already and its mapping will be overwritten existing.</param>
 public void Rename(string filePath, PinballXGame newXmlGame = null)
 {
     if (!HasMapping || !HasLocalFile)
     {
         throw new InvalidOperationException("Can only rename games with mapping and local file.");
     }
     Update(filePath);
     if (newXmlGame != null)
     {
         XmlGame = newXmlGame;
     }
     Mapping.Rename(filePath);
 }
Exemple #4
0
        public void RemoveGame(PinballXGame game)
        {
            // read current xml
            var xmlPath = Path.Combine(game.System.DatabasePath, _settingsManager.Settings.XmlFile[game.System.Type] + ".xml");

            _logger.Info("Removing \"{0}\" from PinballX database at {1}", game.Description, xmlPath);

            if (_settingsManager.Settings.ReformatXml)
            {
                var menu = _marshallManager.UnmarshallXml(xmlPath);

                var gameToRemove = menu.Games.FirstOrDefault(g => g.Description == game.Description && g.FileName == game.FileName);
                if (gameToRemove == null)
                {
                    _logger.Warn("Could not find game in existing XML, aborting.");
                    return;
                }

                // remove game
                menu.Games.Remove(gameToRemove);

                // save xml
                _marshallManager.MarshallXml(menu, xmlPath);
            }
            else
            {
                // match with regex
                var xml       = _file.ReadAllText(xmlPath);
                var gameBlock = new Regex("<game\\s[^>]*name=\"" + Regex.Escape(game.FileName) + "\".*?<\\/game> *[\\n\\r]?", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                _logger.Info("Trying to match {0}", gameBlock);
                var match  = gameBlock.Match(xml);
                var offset = 0;
                while (match.Success)
                {
                    if (match.Groups[0].Value.Contains("<description>" + game.Description + "</description>"))
                    {
                        _logger.Info("Got match: {0}", match.Groups[0]);
                        xml     = xml.Substring(0, match.Index - offset) + xml.Substring(match.Index + match.Length - offset);
                        offset += match.Length;
                    }
                    match = match.NextMatch();
                }

                // write back to disk
                _file.WriteAllText(xmlPath, xml);
            }
        }
Exemple #5
0
        public void AddGame(AggregatedGame game)
        {
            if (game.HasXmlGame)
            {
                throw new InvalidOperationException("Game already in XML database.");
            }
            if (game.MappedRelease == null || game.MappedTableFile == null)
            {
                throw new InvalidOperationException("Cannot add game without release mapping.");
            }
            var xmlGame = new PinballXGame {
                FileName     = Path.GetFileNameWithoutExtension(game.FileDisplayName),
                Description  = $"{game.MappedRelease.Game.Title} ({game.MappedRelease.Game.Manufacturer} {game.MappedRelease.Game.Year})",
                Manufacturer = game.MappedRelease.Game.Manufacturer,
                Year         = game.MappedRelease.Game.Year.ToString(),
                System       = game.System
            };

            _pinballXManager.AddGame(xmlGame);
        }
Exemple #6
0
        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);
        }
Exemple #7
0
 /// <summary>
 /// Checks if the XML game is equal, i.e. the data is equal (to
 /// check if it should be updated).
 /// </summary>
 /// <param name="xmlGame">XML game to compare</param>
 /// <returns>True if equal, false otherwise</returns>
 public bool EqualsXmlGame(PinballXGame xmlGame)
 {
     return(XmlGame != null && XmlGame.Equals(xmlGame));
 }