using System; using System.Collections.Generic; using Mono.Data.Sqlite; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text.RegularExpressions; using SabreTools.Helper; namespace SabreTools { public class Generate { // Private instance variables private string _systemid; private string _sourceid; private string _datroot; private string _outroot; private string _connectionString; private bool _norename; private bool _old; // Private required variables private Logger _logger; /// /// Initialize a Generate object with the given information /// /// String representing the system id (blank means all) /// String representing the source id (blank means all) [CURRENTLY UNUSED] /// Root directory where all DAT files are held /// Root directory where new DAT files are output /// Connection string for SQLite /// Logger object for file or console output /// True if files should not be renamed with system and/or source in merged mode (default false) /// True if the output file should be in ClrMamePro format (default false) public Generate(string systemid, string sourceid, string datroot, string outroot, string connectionString, Logger logger, bool norename = false, bool old = false) { _systemid = systemid; _sourceid = sourceid; _datroot = datroot; _outroot = outroot; _connectionString = connectionString; _logger = logger; _norename = norename; _old = old; } /// /// Generate a DAT file that is represented by the data in the Generate object. /// /// True if the file could be created, false otherwise public bool Export() { string name = ""; string path = _datroot; // If the System ID isn't set, then we will merge everything if (_systemid != "") { string system = ""; // First get the name of the system, if possible string query = "SELECT manufacturer, name FROM system WHERE id=" + _systemid; using (SqliteConnection dbc = new SqliteConnection(_connectionString)) { dbc.Open(); using (SqliteCommand slc = new SqliteCommand(query, dbc)) { using (SqliteDataReader sldr = slc.ExecuteReader()) { if (sldr.Read()) { system = sldr.GetString(0) + " - " + sldr.GetString(1); } } } } // If we didn't find anything, then return if (system == "") { _logger.Warning("No system could be found with id " + _systemid); return false; } path += Path.DirectorySeparatorChar + system.Trim(); name = system.Trim(); } else { name = "ALL"; } // Get the rest of the info as well string date = DateTime.Now.ToString("yyyyMMddHHmmss"); string description = name + " (merged " + date + ")"; name += " (merged)"; // For good measure, get all sources Dictionary sources = new Dictionary();C:\Users\Matt\GitHub\DATabase\DATabaseTwo\Generate.cs sources.Add(0, "Default"); string squery = "SELECT id, name FROM source"; using (SqliteConnection dbc = new SqliteConnection(_connectionString)) { dbc.Open(); using (SqliteCommand slc = new SqliteCommand(squery, dbc)) { using (SqliteDataReader sldr = slc.ExecuteReader()) { while (sldr.Read()) { sources.Add(sldr.GetInt32(0), sldr.GetString(1)); } } } } // Get a list of files to sourceid mappings Dictionary sourcemap = new Dictionary(); using (SqliteConnection dbc = new SqliteConnection(_connectionString)) { dbc.Open(); string tquery = "SELECT DISTINCT dats.sha1, datsdata.value FROM dats JOIN datsdata ON dats.id=datsdata.id WHERE key='source'"; using (SqliteCommand slc = new SqliteCommand(tquery, dbc)) { using (SqliteDataReader sldr = slc.ExecuteReader()) { while (sldr.Read()) { string tempsha1 = sldr.GetString(0); string tempval = sldr.GetString(1); if (!sourcemap.ContainsKey(tempsha1)) { sourcemap.Add(tempsha1, tempval); } } } } } // Now read in all of the files SHA1 sha1 = SHA1.Create(); Dictionary> roms = new Dictionary>(); foreach (string file in Directory.GetFiles(path, "*", SearchOption.AllDirectories)) { string hash = ""; using (FileStream fs = File.Open(file, FileMode.Open)) { hash = BitConverter.ToString(sha1.ComputeHash(fs)).Replace("-", ""); } int tempSrcId = 0; if (sourcemap.ContainsKey(hash)) { Int32.TryParse(sourcemap[hash], out tempSrcId); } roms = RomManipulation.ParseDict(file, 0, tempSrcId, roms, _logger); } // If the dictionary is empty for any reason, tell the user and exit if (roms.Keys.Count == 0 || roms.Count == 0) { _logger.Log("No roms found for system ID " + _systemid); return false; } // Now process all of the roms _logger.User("Cleaning rom data"); List keys = roms.Keys.ToList(); foreach (string key in keys) { List temp = new List(); List newroms = roms[key]; for (int i = 0; i < newroms.Count; i++) { RomData rom = newroms[i]; // In the case that the RomData is incomplete, skip it if (rom.Name == null || rom.Game == null) { continue; } // WOD origninally stripped out any subdirs from the imported files, we do the same rom.Name = Path.GetFileName(rom.Name); // Run the name through the filters to make sure that it's correct rom.Name = Style.NormalizeChars(rom.Name); rom.Name = Style.RussianToLatin(rom.Name); rom.Name = Regex.Replace(rom.Name, @"(.*) \.(.*)", "$1.$2"); // WoD gets rid of anything past the first "(" or "[" as the name, we will do the same string stripPattern = @"(([[(].*[\)\]] )?([^([]+))"; Regex stripRegex = new Regex(stripPattern); Match stripMatch = stripRegex.Match(rom.Game); rom.Game = stripMatch.Groups[1].Value; // Run the name through the filters to make sure that it's correct rom.Game = Style.NormalizeChars(rom.Game); rom.Game = Style.RussianToLatin(rom.Game); rom.Game = Style.SearchPattern(rom.Game); rom.Game = rom.Game.TrimEnd().TrimStart(); if (!_norename) { rom.Game += " [" + sources[rom.SourceID] + "]"; } // If a game has source "0" it's Default. Make this Int32.MaxValue for sorting purposes if (rom.SourceID == 0) { rom.SourceID = Int32.MaxValue; } temp.Add(rom); } roms[key] = temp; } // Then write out the file Output.WriteToDatFromDict(name, description, "", date, "SabreTools", "SabreTools", false, _old, true, _outroot, roms, _logger, _norename); return true; } } }