Ejemplo n.º 1
0
        /// <summary>
        /// Clean a DatItem according to the cleaner
        /// </summary>
        /// <param name="datItem">DatItem to clean</param>
        internal void CleanDatItem(DatItem datItem)
        {
            // If we're stripping unicode characters, strip machine name and description
            if (RemoveUnicode)
            {
                datItem.Machine.Name        = RemoveUnicodeCharacters(datItem.Machine.Name);
                datItem.Machine.Description = RemoveUnicodeCharacters(datItem.Machine.Description);
                datItem.SetName(RemoveUnicodeCharacters(datItem.GetName()));
            }

            // If we're in cleaning mode, sanitize machine name and description
            if (Clean)
            {
                datItem.Machine.Name        = CleanGameName(datItem.Machine.Name);
                datItem.Machine.Description = CleanGameName(datItem.Machine.Description);
            }

            // If we are in single game mode, rename the machine
            if (Single)
            {
                datItem.Machine.Name = "!";
            }

            // If we are in NTFS trim mode, trim the item name
            if (Trim && datItem.GetName() != null)
            {
                // Windows max name length is 260
                int usableLength = 260 - datItem.Machine.Name.Length - (Root?.Length ?? 0);
                if (datItem.GetName().Length > usableLength)
                {
                    string ext = Path.GetExtension(datItem.GetName());
                    datItem.SetName(datItem.GetName().Substring(0, usableLength - ext.Length) + ext);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Apply SuperDAT naming logic to a merged DatFile
        /// </summary>
        /// <param name="datFile">Current DatFile object to run operations on</param>
        /// <param name="inputs">List of inputs to use for renaming</param>
        public static void ApplySuperDAT(DatFile datFile, List <ParentablePath> inputs)
        {
            List <string> keys = datFile.Items.Keys.ToList();

            Parallel.ForEach(keys, Globals.ParallelOptions, key =>
            {
                ConcurrentList <DatItem> items    = datFile.Items[key];
                ConcurrentList <DatItem> newItems = new ConcurrentList <DatItem>();
                foreach (DatItem item in items)
                {
                    DatItem newItem = item;
                    string filename = inputs[newItem.Source.Index].CurrentPath;
                    string rootpath = inputs[newItem.Source.Index].ParentPath;

                    if (!string.IsNullOrWhiteSpace(rootpath))
                    {
                        rootpath += Path.DirectorySeparatorChar.ToString();
                    }

                    filename             = filename.Remove(0, rootpath.Length);
                    newItem.Machine.Name = Path.GetDirectoryName(filename) + Path.DirectorySeparatorChar
                                           + Path.GetFileNameWithoutExtension(filename) + Path.DirectorySeparatorChar
                                           + newItem.Machine.Name;

                    newItems.Add(newItem);
                }

                datFile.Items.Remove(key);
                datFile.Items.AddRange(key, newItems);
            });
        }
Ejemplo n.º 3
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a Adjuster, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a Adjuster
            Adjuster newOther = other as Adjuster;

            // If the Adjuster information matches
            bool match = (Name == newOther.Name && Default == newOther.Default);

            if (!match)
            {
                return(match);
            }

            // If the conditions match
            if (ConditionsSpecified)
            {
                foreach (Condition condition in Conditions)
                {
                    match &= newOther.Conditions.Contains(condition);
                }
            }

            return(match);
        }
Ejemplo n.º 4
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a Display, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a Display
            Display newOther = other as Display;

            // If the Display information matches
            return(Tag == newOther.Tag &&
                   DisplayType == newOther.DisplayType &&
                   Rotate == newOther.Rotate &&
                   FlipX == newOther.FlipX &&
                   Width == newOther.Width &&
                   Height == newOther.Height &&
                   Refresh == newOther.Refresh &&
                   PixClock == newOther.PixClock &&
                   HTotal == newOther.HTotal &&
                   HBEnd == newOther.HBEnd &&
                   HBStart == newOther.HBStart &&
                   VTotal == newOther.VTotal &&
                   VBEnd == newOther.VBEnd &&
                   VBStart == newOther.VBStart);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Write out Game start using the supplied StreamWriter
        /// </summary>
        /// <param name="sw">StreamWriter to output to</param>
        /// <param name="rom">DatItem object to be output</param>
        /// <returns>True if the data was written, false on error</returns>
        private bool WriteStartGame(StreamWriter sw, DatItem rom)
        {
            try
            {
                // No game should start with a path separator
                if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    rom.MachineName = rom.MachineName.Substring(1);
                }

                string state = "<software>\n"
                               + "\t<title>" + (!ExcludeFields[(int)Field.MachineName] ? WebUtility.HtmlEncode(rom.MachineName) : "") + "</title>\n"
                               // + "\t<genmsxid>" + msxid + "</genmsxid>\n"
                               // + "\t<system>" + system + "</system>\n"
                               + "\t<company>" + (!ExcludeFields[(int)Field.Manufacturer] ? rom.Manufacturer : "") + "</company>\n"
                               + "\t<year>" + (!ExcludeFields[(int)Field.Year] ? rom.Year : "") + "</year>\n";
                // + "\t<country>" + country + "</country>\n";

                sw.Write(state);
                sw.Flush();
            }
            catch (Exception ex)
            {
                Globals.Logger.Error(ex.ToString());
                return(false);
            }

            return(true);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Strip the dates from the beginning of scene-style set names
        /// </summary>
        /// <param name="datFile">Current DatFile object to run operations on</param>
        internal void StripSceneDatesFromItems(DatFile datFile)
        {
            // Output the logging statement
            logger.User("Stripping scene-style dates");

            // Set the regex pattern to use
            string pattern = @"([0-9]{2}\.[0-9]{2}\.[0-9]{2}-)(.*?-.*?)";

            // Now process all of the roms
            Parallel.ForEach(datFile.Items.Keys, Globals.ParallelOptions, key =>
            {
                ConcurrentList <DatItem> items = datFile.Items[key];
                for (int j = 0; j < items.Count; j++)
                {
                    DatItem item = items[j];
                    if (Regex.IsMatch(item.Machine.Name, pattern))
                    {
                        item.Machine.Name = Regex.Replace(item.Machine.Name, pattern, "$2");
                    }

                    if (Regex.IsMatch(item.Machine.Description, pattern))
                    {
                        item.Machine.Description = Regex.Replace(item.Machine.Description, pattern, "$2");
                    }

                    items[j] = item;
                }

                datFile.Items.Remove(key);
                datFile.Items.AddRange(key, items);
            });
        }
Ejemplo n.º 7
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a Slot, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a Slot
            Slot newOther = other as Slot;

            // If the Slot information matches
            bool match = (Name == newOther.Name);

            if (!match)
            {
                return(match);
            }

            // If the slot options match
            if (SlotOptionsSpecified)
            {
                foreach (SlotOption slotOption in SlotOptions)
                {
                    match &= newOther.SlotOptions.Contains(slotOption);
                }
            }

            return(match);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Output duplicate item diff
        /// </summary>
        /// <param name="datFile">Current DatFile object to use for updating</param>
        /// <param name="inputs">List of inputs to write out from</param>
        public static DatFile DiffDuplicates(DatFile datFile, List <ParentablePath> inputs)
        {
            InternalStopwatch watch = new InternalStopwatch("Initializing duplicate DAT");

            // Fill in any information not in the base DAT
            if (string.IsNullOrWhiteSpace(datFile.Header.FileName))
            {
                datFile.Header.FileName = "All DATs";
            }

            if (string.IsNullOrWhiteSpace(datFile.Header.Name))
            {
                datFile.Header.Name = "datFile.All DATs";
            }

            if (string.IsNullOrWhiteSpace(datFile.Header.Description))
            {
                datFile.Header.Description = "datFile.All DATs";
            }

            string  post     = " (Duplicates)";
            DatFile dupeData = DatFile.Create(datFile.Header);

            dupeData.Header.FileName    += post;
            dupeData.Header.Name        += post;
            dupeData.Header.Description += post;
            dupeData.Items = new ItemDictionary();

            watch.Stop();

            // Now, loop through the dictionary and populate the correct DATs
            watch.Start("Populating duplicate DAT");

            Parallel.ForEach(datFile.Items.Keys, Globals.ParallelOptions, key =>
            {
                ConcurrentList <DatItem> items = DatItem.Merge(datFile.Items[key]);

                // If the rom list is empty or null, just skip it
                if (items == null || items.Count == 0)
                {
                    return;
                }

                // Loop through and add the items correctly
                foreach (DatItem item in items)
                {
                    if (item.DupeType.HasFlag(DupeType.External))
                    {
                        DatItem newrom       = item.Clone() as DatItem;
                        newrom.Machine.Name += $" ({Path.GetFileNameWithoutExtension(inputs[item.Source.Index].CurrentPath)})";

                        dupeData.Items.Add(key, newrom);
                    }
                }
            });

            watch.Stop();

            return(dupeData);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Write out Game start using the supplied StreamWriter
        /// </summary>
        /// <param name="sw">StreamWriter to output to</param>
        /// <param name="rom">DatItem object to be output</param>
        /// <returns>True if the data was written, false on error</returns>
        private bool WriteStartGame(StreamWriter sw, DatItem rom)
        {
            try
            {
                // No game should start with a path separator
                if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    rom.MachineName = rom.MachineName.Substring(1);
                }

                string state = (rom.MachineType == MachineType.Bios ? "resource" : "game") + " (\n\tname \"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + "\"\n" +
                               (!ExcludeFields[(int)Field.RomOf] && String.IsNullOrWhiteSpace(rom.RomOf) ? "" : "\tromof \"" + rom.RomOf + "\"\n") +
                               (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? "" : "\tcloneof \"" + rom.CloneOf + "\"\n") +
                               (!ExcludeFields[(int)Field.SampleOf] && String.IsNullOrWhiteSpace(rom.SampleOf) ? "" : "\tsampleof \"" + rom.SampleOf + "\"\n") +
                               (!ExcludeFields[(int)Field.Description] ? "\tdescription \"" + (String.IsNullOrWhiteSpace(rom.MachineDescription) ? rom.MachineName : rom.MachineDescription) + "\"\n" : "") +
                               (!ExcludeFields[(int)Field.Year] && String.IsNullOrWhiteSpace(rom.Year) ? "" : "\tyear " + rom.Year + "\n") +
                               (!ExcludeFields[(int)Field.Manufacturer] && String.IsNullOrWhiteSpace(rom.Manufacturer) ? "" : "\tmanufacturer \"" + rom.Manufacturer + "\"\n");

                sw.Write(state);
                sw.Flush();
            }
            catch (Exception ex)
            {
                Globals.Logger.Error(ex.ToString());
                return(false);
            }

            return(true);
        }
Ejemplo n.º 10
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a Part, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a Part
            Part newOther = other as Part;

            // If the Part information matches
            bool match = (Name == newOther.Name &&
                          Interface == newOther.Interface);

            if (!match)
            {
                return(match);
            }

            // If the features match
            if (FeaturesSpecified)
            {
                foreach (PartFeature partFeature in Features)
                {
                    match &= newOther.Features.Contains(partFeature);
                }
            }

            return(match);
        }
Ejemplo n.º 11
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a Port, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a Port
            Port newOther = other as Port;

            // If the Port information matches
            bool match = (Tag == newOther.Tag);

            if (!match)
            {
                return(match);
            }

            // If the analogs match
            if (AnalogsSpecified)
            {
                foreach (Analog analog in Analogs)
                {
                    match &= newOther.Analogs.Contains(analog);
                }
            }

            return(match);
        }
Ejemplo n.º 12
0
        public override bool Equals(DatItem other)
        {
            bool dupefound = false;

            // If we don't have a rom, return false
            if (ItemType != other.ItemType)
            {
                return(dupefound);
            }

            // Otherwise, treat it as a Rom
            Rom newOther = other as Rom;

            // If all hashes are empty but they're both nodump and the names match, then they're dupes
            if ((ItemStatus == ItemStatus.Nodump && newOther.ItemStatus == ItemStatus.Nodump) &&
                Name == newOther.Name &&
                !HasHashes() && !newOther.HasHashes())
            {
                dupefound = true;
            }

            // If we have a file that has no known size, rely on the hashes only
            else if (Size == null && HashMatch(newOther))
            {
                dupefound = true;
            }

            // Otherwise if we get a partial match
            else if (Size == newOther.Size && HashMatch(newOther))
            {
                dupefound = true;
            }

            return(dupefound);
        }
Ejemplo n.º 13
0
        public override bool Equals(DatItem other)
        {
            bool dupefound = false;

            // If we don't have a rom, return false
            if (ItemType != other.ItemType)
            {
                return(dupefound);
            }

            // Otherwise, treat it as a Disk
            Disk newOther = other as Disk;

            // If all hashes are empty but they're both nodump and the names match, then they're dupes
            if ((ItemStatus == ItemStatus.Nodump && newOther.ItemStatus == ItemStatus.Nodump) &&
                Name == newOther.Name &&
                !HasHashes() && !newOther.HasHashes())
            {
                dupefound = true;
            }

            // Otherwise if we get a partial match
            else if (HashMatch(newOther))
            {
                dupefound = true;
            }

            return(dupefound);
        }
Ejemplo n.º 14
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a Control, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a Control
            Control newOther = other as Control;

            // If the Control information matches
            return(ControlType == newOther.ControlType &&
                   Player == newOther.Player &&
                   Buttons == newOther.Buttons &&
                   RequiredButtons == newOther.RequiredButtons &&
                   Minimum == newOther.Minimum &&
                   Maximum == newOther.Maximum &&
                   Sensitivity == newOther.Sensitivity &&
                   KeyDelta == newOther.KeyDelta &&
                   Reverse == newOther.Reverse &&
                   Ways == newOther.Ways &&
                   Ways2 == newOther.Ways2 &&
                   Ways3 == newOther.Ways3);
        }
Ejemplo n.º 15
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a Input, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a Input
            Input newOther = other as Input;

            // If the Input information matches
            bool match = (Service == newOther.Service &&
                          Tilt == newOther.Tilt &&
                          Players == newOther.Players &&
                          Coins == newOther.Coins);

            if (!match)
            {
                return(match);
            }

            // If the controls match
            if (ControlsSpecified)
            {
                foreach (Control control in Controls)
                {
                    match &= newOther.Controls.Contains(control);
                }
            }

            return(match);
        }
Ejemplo n.º 16
0
        public void CreateBaseFileTest(FileType fileType, ItemType?expected)
        {
            var baseFile = CreateBaseFile(fileType);
            var actual   = DatItem.Create(baseFile);

            Assert.Equal(expected, actual?.ItemType);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Get the Stream related to a file
        /// </summary>
        /// <param name="datItem">Information for the current file to rebuild from</param>
        /// <param name="file">Name of the file to process</param>
        /// <param name="isZip">Non-null if the input file is an archive</param>
        /// <param name="stream">Output stream representing the opened file</param>
        /// <returns>True if the stream opening succeeded, false otherwise</returns>
        private static bool GetFileStream(DatItem datItem, string file, bool?isZip, out Stream stream)
        {
            // Get a generic stream for the file
            stream = null;

            // If we have a zipfile, extract the stream to memory
            if (isZip != null)
            {
                BaseArchive archive = BaseArchive.Create(file);
                if (archive != null)
                {
                    (stream, _) = archive.CopyToStream(datItem.GetName() ?? datItem.ItemType.ToString());
                }
            }
            // Otherwise, just open the filestream
            else
            {
                stream = File.OpenRead(file);
            }

            // If the stream is null, then continue
            if (stream == null)
            {
                return(false);
            }

            // Seek to the beginning of the stream
            if (stream.CanSeek)
            {
                stream.Seek(0, SeekOrigin.Begin);
            }

            return(true);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Write out Game start using the supplied StreamWriter
        /// </summary>
        /// <param name="sw">StreamWriter to output to</param>
        /// <param name="rom">DatItem object to be output</param>
        /// <param name="newsplit">Split path representing the parent game (SabreDAT only)</param>
        /// <param name="lastgame">The name of the last game to be output</param>
        /// <param name="depth">Current depth to output file at (SabreDAT only)</param>
        /// <param name="last">Last known depth to cycle back from (SabreDAT only)</param>
        /// <returns>The new depth of the tag</returns>
        private int WriteStartGame(StreamWriter sw, DatItem rom, List <string> newsplit, string lastgame, int depth, int last)
        {
            try
            {
                // No game should start with a path separator
                if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    rom.MachineName = rom.MachineName.Substring(1);
                }

                string state = "";
                for (int i = (last == -1 ? 0 : last); i < newsplit.Count; i++)
                {
                    for (int j = 0; j < depth - last + i - (lastgame == null ? 1 : 0); j++)
                    {
                        state += "\t";
                    }
                    state += "<directory name=\"" + (!ExcludeFields[(int)Field.MachineName] ? HttpUtility.HtmlEncode(newsplit[i]) : "") + "\" description=\"" +
                             HttpUtility.HtmlEncode(newsplit[i]) + "\">\n";
                }
                depth = depth - (last == -1 ? 0 : last) + newsplit.Count;

                sw.Write(state);
                sw.Flush();
            }
            catch (Exception ex)
            {
                Globals.Logger.Error(ex.ToString());
                return(depth);
            }

            return(depth);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Write out Game start using the supplied StreamWriter
        /// </summary>
        /// <param name="svw">SeparatedValueWriter to output to</param>
        /// <param name="datItem">DatItem object to be output</param>
        private void WriteDatItem(SeparatedValueWriter svw, DatItem datItem)
        {
            // No game should start with a path separator
            datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);

            // Pre-process the item name
            ProcessItemName(datItem, true);

            // Build the state
            switch (datItem.ItemType)
            {
            case ItemType.Rom:
                var rom = datItem as Rom;

                string[] fields = new string[]
                {
                    rom.SHA256 ?? string.Empty,
                    $"{rom.Machine.Name ?? string.Empty}/",
                    rom.Name ?? string.Empty,
                    rom.SHA1 ?? string.Empty,
                    rom.MD5 ?? string.Empty,
                    rom.CRC ?? string.Empty,
                };

                svw.WriteValues(fields);

                break;
            }

            svw.Flush();
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Set proper Game and Rom names from user inputs
        /// </summary>
        /// <param name="datFile">Current DatFile object to add to</param>
        /// <param name="datItem">DatItem representing the input file</param>
        /// <param name="item">Item name to use</param>
        /// <param name="parent">Parent name to use</param>
        /// <param name="basepath">Base path to use</param>
        private static void SetDatItemInfo(DatFile datFile, DatItem datItem, string item, string parent, string basepath)
        {
            // Get the data to be added as game and item names
            string machineName, itemName;

            // If the parent is blank, then we have a non-archive file
            if (string.IsNullOrWhiteSpace(parent))
            {
                // If we have a SuperDAT, we want anything that's not the base path as the game, and the file as the rom
                if (datFile.Header.Type == "SuperDAT")
                {
                    machineName = Path.GetDirectoryName(item.Remove(0, basepath.Length));
                    itemName    = Path.GetFileName(item);
                }

                // Otherwise, we want just the top level folder as the game, and the file as everything else
                else
                {
                    machineName = item.Remove(0, basepath.Length).Split(Path.DirectorySeparatorChar)[0];
                    itemName    = item.Remove(0, (Path.Combine(basepath, machineName).Length));
                }
            }

            // Otherwise, we assume that we have an archive
            else
            {
                // If we have a SuperDAT, we want the archive name as the game, and the file as everything else (?)
                if (datFile.Header.Type == "SuperDAT")
                {
                    machineName = parent;
                    itemName    = datItem.GetName();
                }

                // Otherwise, we want the archive name as the game, and the file as everything else
                else
                {
                    machineName = parent;
                    itemName    = datItem.GetName();
                }
            }

            // Sanitize the names
            machineName = machineName.Trim(Path.DirectorySeparatorChar);
            itemName    = itemName?.Trim(Path.DirectorySeparatorChar) ?? string.Empty;

            if (!string.IsNullOrWhiteSpace(machineName) && string.IsNullOrWhiteSpace(itemName))
            {
                itemName    = machineName;
                machineName = "Default";
            }

            // Update machine information
            datItem.Machine.Name        = machineName;
            datItem.Machine.Description = machineName;

            // If we have a Disk, then the ".chd" extension needs to be removed
            if (datItem.ItemType == ItemType.Disk && itemName.EndsWith(".chd"))
            {
                itemName = itemName[0..^ 4];
Ejemplo n.º 21
0
        /// <inheritdoc/>
        public override void ParseFile(string filename, int indexId, bool keep, bool statsOnly = false, bool throwOnError = false)
        {
            // Open a file reader
            Encoding             enc = filename.GetEncoding();
            SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc)
            {
                Header           = true,
                Quotes           = true,
                Separator        = _delim,
                VerifyFieldCount = true,
            };

            // If we're somehow at the end of the stream already, we can't do anything
            if (svr.EndOfStream)
            {
                return;
            }

            // Read in the header
            svr.ReadHeader();

            // Loop through all of the data lines
            while (!svr.EndOfStream)
            {
                try
                {
                    // Get the current line, split and parse
                    svr.ReadNextLine();

                    // Create mapping dictionaries
                    Setter setter = new Setter();
                    setter.PopulateSettersFromList(svr.HeaderValues, svr.Line);

                    // Set DatHeader fields
                    DatHeader datHeader = new DatHeader();
                    setter.SetFields(datHeader);
                    Header.ConditionalCopy(datHeader);

                    // Set Machine and DatItem fields
                    if (setter.DatItemMappings.ContainsKey(DatItemField.Type))
                    {
                        DatItem datItem = DatItem.Create(setter.DatItemMappings[DatItemField.Type].AsItemType());
                        setter.SetFields(datItem);
                        datItem.Machine = new Machine();
                        setter.SetFields(datItem.Machine);
                        datItem.Source = new Source(indexId, filename);
                        ParseAddHelper(datItem, statsOnly);
                    }
                }
                catch (Exception ex) when(!throwOnError)
                {
                    string message = $"'{filename}' - There was an error parsing line {svr.LineNumber} '{svr.CurrentLine}'";

                    logger.Error(ex, message);
                }
            }

            svr.Dispose();
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Process a single file as a file
        /// </summary>
        /// <param name="datFile">Current DatFile object to add to</param>
        /// <param name="item">File to be added</param>
        /// <param name="basePath">Path the represents the parent directory</param>
        /// <param name="hashes">Hashes to include in the information</param>
        /// <param name="asFiles">TreatAsFiles representing CHD and Archive scanning</param>
        private static void ProcessFile(DatFile datFile, string item, string basePath, Hash hashes, TreatAsFile asFiles)
        {
            logger.Verbose($"'{Path.GetFileName(item)}' treated like a file");
            BaseFile baseFile = BaseFile.GetInfo(item, header: datFile.Header.HeaderSkipper, hashes: hashes, asFiles: asFiles);
            DatItem  datItem  = DatItem.Create(baseFile);

            ProcessFileHelper(datFile, item, datItem, basePath, string.Empty);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Write out DatItem using the supplied StreamWriter
        /// </summary>
        /// <param name="xtw">XmlTextWriter to output to</param>
        /// <param name="datItem">DatItem object to be output</param>
        private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
        {
            // Pre-process the item name
            ProcessItemName(datItem, true);

            // Build the state
            switch (datItem.ItemType)
            {
            case ItemType.Rom:
                var rom = datItem as Rom;
                xtw.WriteStartElement("dump");

                if (rom.Original != null)
                {
                    xtw.WriteStartElement("original");
                    xtw.WriteAttributeString("value", rom.Original.Value == true ? "true" : "false");
                    xtw.WriteString(rom.Original.Content);
                    xtw.WriteEndElement();
                }

                switch (rom.OpenMSXSubType)
                {
                // Default to Rom for converting from other formats
                case OpenMSXSubType.Rom:
                case OpenMSXSubType.NULL:
                    xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
                    xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
                    xtw.WriteOptionalElementString("start", rom.Offset);
                    xtw.WriteOptionalElementString("type", rom.OpenMSXType);
                    xtw.WriteOptionalElementString("remark", rom.Remark);
                    xtw.WriteEndElement();
                    break;

                case OpenMSXSubType.MegaRom:
                    xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
                    xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
                    xtw.WriteOptionalElementString("start", rom.Offset);
                    xtw.WriteOptionalElementString("type", rom.OpenMSXType);
                    xtw.WriteOptionalElementString("remark", rom.Remark);
                    xtw.WriteEndElement();
                    break;

                case OpenMSXSubType.SCCPlusCart:
                    xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType());
                    xtw.WriteOptionalElementString("boot", rom.Boot);
                    xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant());
                    xtw.WriteOptionalElementString("remark", rom.Remark);
                    xtw.WriteEndElement();
                    break;
                }

                // End dump
                xtw.WriteEndElement();
                break;
            }

            xtw.Flush();
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Write out DatItem using the supplied StreamWriter
        /// </summary>
        /// <param name="sw">StreamWriter to output to</param>
        /// <param name="rom">DatItem object to be output</param>
        /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param>
        /// <returns>True if the data was written, false on error</returns>
        private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false)
        {
            // If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
            if (ignoreblanks &&
                (rom.ItemType == ItemType.Rom &&
                 (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1)))
            {
                return(true);
            }

            try
            {
                string state = "";

                // Pre-process the item name
                ProcessItemName(rom, true);

                switch (rom.ItemType)
                {
                case ItemType.Archive:
                    break;

                case ItemType.BiosSet:
                    break;

                case ItemType.Disk:
                    break;

                case ItemType.Release:
                    break;

                case ItemType.Rom: // Currently this encapsulates rom, megarom, and sccpluscart
                    state += "\t\t<dump>"
                                   // + "<original value=\"true\">GoodMSX</original>"
                             + "<rom>"
                             + (!ExcludeFields[(int)Field.Offset] && !String.IsNullOrWhiteSpace(((Rom)rom).Offset) ? "<start>" + ((Rom)rom).Offset + "</start>" : "")
                             // + "<type>Normal</type>"
                             + "<hash>" + (!ExcludeFields[(int)Field.SHA1] ? ((Rom)rom).SHA1 : "") + "</hash>"
                             // + "<remark></remark>"
                             + "</rom></dump>\n";
                    break;

                case ItemType.Sample:
                    break;
                }

                sw.Write(state);
                sw.Flush();
            }
            catch (Exception ex)
            {
                Globals.Logger.Error(ex.ToString());
                return(false);
            }

            return(true);
        }
Ejemplo n.º 25
0
        public override bool Equals(DatItem other)
        {
            // If we don't have a DipSwitch, return false
            if (ItemType != other.ItemType)
            {
                return(false);
            }

            // Otherwise, treat it as a DipSwitch
            DipSwitch newOther = other as DipSwitch;

            // If the DipSwitch information matches
            bool match = (Name == newOther.Name &&
                          Tag == newOther.Tag &&
                          Mask == newOther.Mask);

            if (!match)
            {
                return(match);
            }

            // If the part matches
            if (PartSpecified)
            {
                match &= (Part == newOther.Part);
            }

            // If the conditions match
            if (ConditionsSpecified)
            {
                foreach (Condition condition in Conditions)
                {
                    match &= newOther.Conditions.Contains(condition);
                }
            }

            // If the locations match
            if (LocationsSpecified)
            {
                foreach (Location location in Locations)
                {
                    match &= newOther.Locations.Contains(location);
                }
            }

            // If the values match
            if (ValuesSpecified)
            {
                foreach (Setting value in Values)
                {
                    match &= newOther.Values.Contains(value);
                }
            }

            return(match);
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Write out Game end using the supplied StreamWriter
        /// </summary>
        /// <param name="cmpw">ClrMameProWriter to output to</param>
        /// <param name="datItem">DatItem object to be output</param>
        private void WriteEndGame(ClrMameProWriter cmpw, DatItem datItem)
        {
            // Build the state
            cmpw.WriteOptionalStandalone("sampleof", datItem.Machine.SampleOf);

            // End game
            cmpw.WriteEndElement();

            cmpw.Flush();
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Set internal names to match One Rom Per Game (ORPG) logic
        /// </summary>
        /// <param name="datItem">DatItem to run logic on</param>
        internal void SetOneRomPerGame(DatItem datItem)
        {
            if (datItem.GetName() == null)
            {
                return;
            }

            string[] splitname = datItem.GetName().Split('.');
            datItem.Machine.Name += $"/{string.Join(".", splitname.Take(splitname.Length > 1 ? splitname.Length - 1 : 1))}";
            datItem.SetName(Path.GetFileName(datItem.GetName()));
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Use cloneof tags to add roms to the children, setting the new romof tag in the process
        /// </summary>
        /// <param name="datFile">Current DatFile object to run operations on</param>
        internal static void AddRomsFromParent(DatFile datFile)
        {
            List <string> games = datFile.Items.Keys.OrderBy(g => g).ToList();

            foreach (string game in games)
            {
                // If the game has no items in it, we want to continue
                if (datFile.Items[game].Count == 0)
                {
                    continue;
                }

                // Determine if the game has a parent or not
                string parent = null;
                if (!string.IsNullOrWhiteSpace(datFile.Items[game][0].Machine.CloneOf))
                {
                    parent = datFile.Items[game][0].Machine.CloneOf;
                }

                // If the parent doesnt exist, we want to continue
                if (string.IsNullOrWhiteSpace(parent))
                {
                    continue;
                }

                // If the parent doesn't have any items, we want to continue
                if (datFile.Items[parent].Count == 0)
                {
                    continue;
                }

                // If the parent exists and has items, we copy the items from the parent to the current game
                DatItem copyFrom = datFile.Items[game][0];
                ConcurrentList <DatItem> parentItems = datFile.Items[parent];
                foreach (DatItem item in parentItems)
                {
                    DatItem datItem = (DatItem)item.Clone();
                    datItem.CopyMachineInformation(copyFrom);
                    if (datFile.Items[game].Where(i => i.GetName()?.ToLowerInvariant() == datItem.GetName()?.ToLowerInvariant()).Count() == 0 &&
                        !datFile.Items[game].Contains(datItem))
                    {
                        datFile.Items.Add(game, datItem);
                    }
                }

                // Now we want to get the parent romof tag and put it in each of the items
                ConcurrentList <DatItem> items = datFile.Items[game];
                string romof = datFile.Items[parent][0].Machine.RomOf;
                foreach (DatItem item in items)
                {
                    item.Machine.RomOf = romof;
                }
            }
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Write out Game start using the supplied StreamWriter
        /// </summary>
        /// <param name="cmpw">ClrMameProWriter to output to</param>
        /// <param name="datItem">DatItem object to be output</param>
        private void WriteStartGame(ClrMameProWriter cmpw, DatItem datItem)
        {
            // No game should start with a path separator
            datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);

            // Build the state
            cmpw.WriteStartElement("game");
            cmpw.WriteRequiredStandalone("name", $"{datItem.Machine.Name}.zip", true);

            cmpw.Flush();
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Write out Game start using the supplied StreamWriter
        /// </summary>
        /// <param name="sw">StreamWriter to output to</param>
        /// <param name="rom">DatItem object to be output</param>
        private void WriteStartGame(StreamWriter sw, DatItem rom)
        {
            // No game should start with a path separator
            rom.Machine.Name = rom.Machine.Name.TrimStart(Path.DirectorySeparatorChar);

            // Build the state
            sw.Write($"ROMs required for driver \"{rom.Machine.Name}\".\n");
            sw.Write("Name                                   Size Checksum\n");

            sw.Flush();
        }