Files
SabreTools/SabreTools.Helper/Objects/GenerateTwo.cs

247 lines
7.3 KiB
C#
Raw Normal View History

2016-06-13 23:54:13 -07:00
using Mono.Data.Sqlite;
using SabreTools.Helper;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
2016-05-10 13:03:53 -07:00
using System.Security.Cryptography;
using System.Text.RegularExpressions;
namespace SabreTools
{
public class GenerateTwo : IGenerate
{
// 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;
/// <summary>
/// Initialize a Generate object with the given information
/// </summary>
/// <param name="systemid">String representing the system id (blank means all)</param>
/// <param name="sourceid">String representing the source id (blank means all) [CURRENTLY UNUSED]</param>
/// <param name="datroot">Root directory where all DAT files are held</param>
/// <param name="outroot">Root directory where new DAT files are output</param>
/// <param name="connectionString">Connection string for SQLite</param>
/// <param name="logger">Logger object for file or console output</param>
/// <param name="norename">True if files should not be renamed with system and/or source in merged mode (default false)</param>
/// <param name="old">True if the output file should be in ClrMamePro format (default false)</param>
public GenerateTwo(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;
}
/// <summary>
/// Generate a DAT file that is represented by the data in the Generate object.
/// </summary>
/// <returns>True if the file could be created, false otherwise</returns>
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;
}
name = system.Trim();
2016-06-16 22:17:58 -07:00
path = Path.Combine(path, name);
}
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
2016-05-10 15:42:26 -07:00
Dictionary<int, string> sources = new Dictionary<int, string>();
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<string, string> sourcemap = new Dictionary<string, string>();
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
{
dbc.Open();
2016-05-10 13:03:53 -07:00
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())
{
2016-05-10 13:03:53 -07:00
string tempsha1 = sldr.GetString(0);
string tempval = sldr.GetString(1);
2016-05-10 13:03:53 -07:00
if (!sourcemap.ContainsKey(tempsha1))
{
2016-05-10 13:03:53 -07:00
sourcemap.Add(tempsha1, tempval);
}
}
}
}
}
2016-05-16 13:42:21 -07:00
// Create the output DatData object
Dat datdata = new Dat
2016-05-16 13:42:21 -07:00
{
FileName = description,
2016-05-16 13:42:21 -07:00
Name = name,
Description = description,
Version = "",
Date = date,
Category = "SabreTools",
Author = "SabreTools",
ForcePacking = ForcePacking.None,
OutputFormat = (_old ? OutputFormat.ClrMamePro : OutputFormat.Xml),
2016-05-16 13:42:21 -07:00
MergeRoms = true,
};
// Now read in all of the files
2016-05-10 13:03:53 -07:00
SHA1 sha1 = SHA1.Create();
foreach (string file in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
{
2016-05-10 13:03:53 -07:00
string hash = "";
using (FileStream fs = File.Open(file, FileMode.Open))
2016-05-10 13:03:53 -07:00
{
hash = BitConverter.ToString(sha1.ComputeHash(fs)).Replace("-", "");
}
int tempSrcId = 0;
2016-05-10 13:03:53 -07:00
if (sourcemap.ContainsKey(hash))
{
2016-05-10 13:03:53 -07:00
Int32.TryParse(sourcemap[hash], out tempSrcId);
}
DatTools.Parse(file, 0, tempSrcId, ref datdata, _logger);
}
// If the dictionary is empty for any reason, tell the user and exit
if (datdata.Files.Keys.Count == 0 || datdata.Files.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<string> keys = datdata.Files.Keys.ToList();
foreach (string key in keys)
{
List<DatItem> temp = new List<DatItem>();
List<DatItem> newroms = datdata.Files[key];
for (int i = 0; i < newroms.Count; i++)
{
Rom rom = (Rom)newroms[i];
// In the case that the RomData is incomplete, skip it
if (rom.Name == null || rom.MachineName == 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");
2016-05-13 14:45:17 -07:00
// Run the name through the filters to make sure that it's correct
rom.MachineName = Style.NormalizeChars(rom.MachineName);
rom.MachineName = Style.RussianToLatin(rom.MachineName);
rom.MachineName = Style.SearchPattern(rom.MachineName);
2016-05-13 14:45:17 -07:00
// 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.MachineName);
rom.MachineName = stripMatch.Groups[1].Value;
rom.MachineName = rom.MachineName.TrimEnd().TrimStart();
if (!_norename)
{
rom.MachineName += " [" + 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);
}
datdata.Files[key] = temp;
}
// Then write out the file
DatTools.WriteDatfile(datdata, _outroot, _logger, _norename);
return true;
}
}
}