/// <summary> /// Add a zipfile potentially containing roms to the database for later analysis /// </summary> public static void GetFromZipFile() { // Wipe tables Reporter.Tic("Wiping tables...", out int tic1); string query = @"DELETE FROM RomFile_Rom; DELETE FROM RomFile; DELETE FROM sqlite_sequence WHERE NAME = 'RomFile';" ; M.Data.Database.ExecuteSqlCommand(query); Reporter.Toc(tic1); Reporter.Tic("Refreshing DB...", out int tic2); M.Refresh(true); Reporter.Toc(tic2); RobinDataEntities RData = new RobinDataEntities(); Platform arcade = RData.Platforms.FirstOrDefault(x => x.ID == CONSTANTS.ARCADE_PLATFORM_ID); string[] files = Directory.GetFiles(arcade.RomDirectory); //try //{ Reporter.Tic("Creating dictionary...", out int tic3); //ConcurrentDictionary<string, RomFile> romFiles = new ConcurrentDictionary<string, RomFile>(); Dictionary <string, RomFile> romFiles = new Dictionary <string, RomFile>(); Dictionary <string, Rom> roms = M.Data.Roms.ToDictionary(x => x.CRCN, y => y); Dictionary <string, Machine> machines = M.Data.Machines.ToDictionary(x => x.Name, y => y); Reporter.Toc(tic3); Stopwatch Watch = Stopwatch.StartNew(); Stopwatch Watch1 = Stopwatch.StartNew(); int i = 0; foreach (string file in files.Where(x => x.EndsWith(".zip"))) { if (!romFiles.ContainsKey(file)) { RomFile romFile = new RomFile { FilePath = file }; romFiles.Add(file, romFile); using (Ionic.Zip.ZipFile zipFile = Ionic.Zip.ZipFile.Read(file)) { foreach (ZipEntry entry in zipFile) { if (roms.TryGetValue(entry.Crc.ToString("X"), out Rom rom)) { romFile.Roms.Add(rom); } else { rom = new Rom { Name = entry.FileName, CRC = entry.Crc.ToString("X"), Size = entry.UncompressedSize, Unknown = true }; } } } } if (++i % 1000 == 0) { Reporter.Report(i + " zipfiles scanned." + Watch.Elapsed.TotalSeconds.ToString("#.0")); } } //var zipFiles = files.Where(x => x.EndsWith(".zip")); //ParallelOptions opt = new ParallelOptions(); //opt.MaxDegreeOfParallelism = Math.Max(Environment.ProcessorCount / 2, 1); //Parallel.ForEach(zipFiles, opt, (file) => //{ // if (!romFiles.ContainsKey(file)) // { // RomFile romFile = new RomFile // { // FilePath = file // }; // romFiles.TryAdd(file, romFile); // string name = Path.GetFileNameWithoutExtension(file); // if (machines.TryGetValue(name, out Machine machine)) // { // romFile.Machine = machine; // } // using (Ionic.Zip.ZipFile zipFile = Ionic.Zip.ZipFile.Read(file)) // { // foreach (ZipEntry entry in zipFile) // { // Rom rom; // if (roms.TryGetValue(entry.Crc.ToString("X"), out rom)) // { // romFile.Roms.Add(rom); // } // else // { // rom = new Rom // { // Name = entry.FileName, // CRC = entry.Crc.ToString("X"), // Size = entry.UncompressedSize, // Unknown = true // }; // } // } // } // } // if (++i % 1000 == 0) // { // Reporter.Report(i + " zipfiles scanned." + Watch.Elapsed.TotalSeconds.ToString("#.0")); // } //}); Reporter.Tic("Adding romfiles", out int tic4); M.Data.RomFiles.AddRange(romFiles.Values); Reporter.Toc(tic4); M.Data.Save(); Debug.WriteLine("Finished: " + Watch1.ElapsedMilliseconds); //} //catch (Exception ex) //{ // int u = 0; //} }
/// <summary> /// Cache direct MAME output to local DB cache MAMe.db /// </summary> public void CacheDataBase3() { Stopwatch Watch = Stopwatch.StartNew(); Stopwatch Watch1 = Stopwatch.StartNew(); XmlReaderSettings settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse }; // Wipe tables Reporter.Tic("Wiping tables.", out int tic1); string query = @"DELETE FROM Machine_Disk; DELETE FROM Machine_Rom; DELETE FROM Machine; DELETE FROM Disk; DELETE FROM Rom; DELETE FROM sqlite_sequence;" ; M.Data.Database.ExecuteSqlCommand(query); Reporter.Toc(tic1); //Reload M.Data so it knows about the wipe M.Refresh(false); M.Data.Configuration.ValidateOnSaveEnabled = false; int machineCount = 0; int romCount = 0; int diskCount = 0; Dictionary <string, Machine> machines = new Dictionary <string, Machine>(); Dictionary <string, Rom> roms = new Dictionary <string, Rom>(); Dictionary <string, Disk> disks = new Dictionary <string, Disk>(); // Scan through xml file from MAME and store machines using (Process process = MAMEexe(@"-lx")) using (XmlReader reader = XmlReader.Create(process.StandardOutput, settings)) { Reporter.Tic("Getting xml file from MAME...", out int tic2); while (reader.Read()) { if (reader.Name == "machine") { XElement machineElement = XNode.ReadFrom(reader) as XElement; Machine machine = new Machine(machineElement); machines.Add(machine.Name, machine); machine.ID = machineCount; foreach (XElement romElement in machineElement.Elements("rom")) { string crc = romElement.Attribute("crc")?.Value ?? "NONE" + romCount; if (!roms.TryGetValue(crc, out Rom rom)) { rom = new Rom(romElement); roms.Add(crc, rom); } machine.Roms.Add(rom); rom.ID = ++romCount; } foreach (XElement diskElement in machineElement.Elements("disk")) { string sha1 = diskElement.Attribute("sha1")?.Value ?? "NONE" + diskCount; if (!disks.TryGetValue(sha1, out Disk disk)) { disk = new Disk(diskElement); disks.Add(sha1, disk); } machine.Disks.Add(disk); disk.ID = ++diskCount; } if (++machineCount % 5000 == 0) { Reporter.Report(machineCount + " machines, " + Watch1.Elapsed.TotalSeconds + " s."); Watch1.Restart(); } } } Reporter.Toc(tic2); } // Add machines to local db Cache Reporter.Tic("Adding machines...", out int tic3); M.Data.Machines.AddRange(machines.Select(x => x.Value)); Reporter.Toc(tic3); Reporter.Tic("Saving changes...", out int tic4); M.Data.Save(false); Reporter.Toc(tic4); Reporter.Tic("Storing clones...", out int tic5); int i = 0; foreach (Machine machine in machines.Values.Where(x => x.CloneOf != null)) { Debug.WriteLine($"{machine.Name}, parent = {machine.CloneOf}"); if (machines.TryGetValue(machine.CloneOf, out Machine parent)) { machine.Parent = parent; Debug.WriteLine($"-Parent assigned {i++}"); } } Reporter.Toc(tic5); // Find sample based on sampleof stored as temp value Reporter.Tic("Storing samples...", out int tic6); int j = 0; foreach (Machine machine in machines.Values.Where(x => x.SampleOf != null)) { Debug.WriteLine($"{machine.Name}, sample = {machine.SampleOf}"); if (machines.TryGetValue(machine.SampleOf, out Machine sampleof)) { machine.SampleParent = sampleof; Debug.WriteLine($"-Sample assigned {j++}."); } } Reporter.Toc(tic6); M.Data.Save(true); Reporter.Report("Finished: " + Watch.Elapsed.ToString(@"m\:ss")); }