DBMan: Remove DATTools (this now lives in it's own external tool)

This commit is contained in:
Asnivor 2021-06-07 12:27:57 +01:00
parent d189790918
commit 12c42c745a
7 changed files with 3 additions and 1319 deletions

View File

@ -57,32 +57,12 @@ namespace BizHawk.DBManTool
var tbDiscCMPArgs = CreateArgsTextBox();
#if false
btnDiscCMP.Click += (sender, e) => new DiscCmp().Run(tbDiscCMPArgs.Text.Split(' '));
#endif
var btnDATConv = CreateLaunchButton();
btnDATConv.Click += (sender, e) =>
{
try
{
new DATConverter().Show(this);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
};
#endif
SuspendLayout();
Controls.Add(new FlowLayoutPanel {
AutoSize = true,
Controls = {
new FlowLayoutPanel {
AutoSize = true,
Controls = {
btnDATConv,
CreateArgsLabel("DAT Converter")
}
},
Controls = {
new FlowLayoutPanel {
AutoSize = true,
Controls = {

View File

@ -1,215 +0,0 @@
namespace BizHawk.DBManTool
{
partial class DATConverter
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.comboBoxSystemSelect = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.groupImportTypes = new System.Windows.Forms.GroupBox();
this.radioTOSEC = new System.Windows.Forms.RadioButton();
this.listBoxFiles = new System.Windows.Forms.ListBox();
this.buttonAddFiles = new System.Windows.Forms.Button();
this.buttonRemove = new System.Windows.Forms.Button();
this.buttonStartProcessing = new System.Windows.Forms.Button();
this.textBoxOutputFolder = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
this.radioNOINTRO = new System.Windows.Forms.RadioButton();
this.groupImportTypes.SuspendLayout();
this.SuspendLayout();
//
// comboBoxSystemSelect
//
this.comboBoxSystemSelect.FormattingEnabled = true;
this.comboBoxSystemSelect.Location = new System.Drawing.Point(13, 13);
this.comboBoxSystemSelect.Name = "comboBoxSystemSelect";
this.comboBoxSystemSelect.Size = new System.Drawing.Size(121, 21);
this.comboBoxSystemSelect.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(141, 20);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(74, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Select System";
//
// groupImportTypes
//
this.groupImportTypes.Controls.Add(this.radioNOINTRO);
this.groupImportTypes.Controls.Add(this.radioTOSEC);
this.groupImportTypes.Location = new System.Drawing.Point(13, 50);
this.groupImportTypes.Name = "groupImportTypes";
this.groupImportTypes.Size = new System.Drawing.Size(200, 100);
this.groupImportTypes.TabIndex = 2;
this.groupImportTypes.TabStop = false;
this.groupImportTypes.Text = "Import Type";
//
// radioTOSEC
//
this.radioTOSEC.AutoSize = true;
this.radioTOSEC.Location = new System.Drawing.Point(7, 20);
this.radioTOSEC.Name = "radioTOSEC";
this.radioTOSEC.Size = new System.Drawing.Size(61, 17);
this.radioTOSEC.TabIndex = 0;
this.radioTOSEC.TabStop = true;
this.radioTOSEC.Text = "TOSEC";
this.radioTOSEC.UseVisualStyleBackColor = true;
//
// listBoxFiles
//
this.listBoxFiles.FormattingEnabled = true;
this.listBoxFiles.HorizontalScrollbar = true;
this.listBoxFiles.Location = new System.Drawing.Point(13, 180);
this.listBoxFiles.Name = "listBoxFiles";
this.listBoxFiles.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
this.listBoxFiles.Size = new System.Drawing.Size(328, 121);
this.listBoxFiles.TabIndex = 3;
this.listBoxFiles.UseTabStops = false;
//
// buttonAddFiles
//
this.buttonAddFiles.Location = new System.Drawing.Point(348, 180);
this.buttonAddFiles.Name = "buttonAddFiles";
this.buttonAddFiles.Size = new System.Drawing.Size(107, 23);
this.buttonAddFiles.TabIndex = 4;
this.buttonAddFiles.Text = "Browse";
this.buttonAddFiles.UseVisualStyleBackColor = true;
this.buttonAddFiles.Click += new System.EventHandler(this.buttonAddFiles_Click);
//
// buttonRemove
//
this.buttonRemove.Location = new System.Drawing.Point(348, 210);
this.buttonRemove.Name = "buttonRemove";
this.buttonRemove.Size = new System.Drawing.Size(107, 23);
this.buttonRemove.TabIndex = 5;
this.buttonRemove.Text = "Remove";
this.buttonRemove.UseVisualStyleBackColor = true;
this.buttonRemove.Click += new System.EventHandler(this.buttonRemove_Click);
//
// buttonStartProcessing
//
this.buttonStartProcessing.Location = new System.Drawing.Point(13, 356);
this.buttonStartProcessing.Name = "buttonStartProcessing";
this.buttonStartProcessing.Size = new System.Drawing.Size(101, 23);
this.buttonStartProcessing.TabIndex = 6;
this.buttonStartProcessing.Text = "Start Processing";
this.buttonStartProcessing.UseVisualStyleBackColor = true;
this.buttonStartProcessing.Click += new System.EventHandler(this.buttonStartProcessing_Click);
//
// textBoxOutputFolder
//
this.textBoxOutputFolder.Location = new System.Drawing.Point(13, 330);
this.textBoxOutputFolder.Name = "textBoxOutputFolder";
this.textBoxOutputFolder.Size = new System.Drawing.Size(328, 20);
this.textBoxOutputFolder.TabIndex = 7;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 164);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(75, 13);
this.label2.TabIndex = 8;
this.label2.Text = "Files to Import:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 314);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(87, 13);
this.label3.TabIndex = 9;
this.label3.Text = "Output Directory:";
//
// button2
//
this.button2.Location = new System.Drawing.Point(348, 328);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(107, 23);
this.button2.TabIndex = 10;
this.button2.Text = "Select Output DIR";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// radioNOINTRO
//
this.radioNOINTRO.AutoSize = true;
this.radioNOINTRO.Location = new System.Drawing.Point(7, 44);
this.radioNOINTRO.Name = "radioNOINTRO";
this.radioNOINTRO.Size = new System.Drawing.Size(172, 17);
this.radioNOINTRO.TabIndex = 1;
this.radioNOINTRO.TabStop = true;
this.radioNOINTRO.Text = "NOINTRO (standard DAT only)";
this.radioNOINTRO.UseVisualStyleBackColor = true;
//
// DATConverter
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(469, 391);
this.Controls.Add(this.button2);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.textBoxOutputFolder);
this.Controls.Add(this.buttonStartProcessing);
this.Controls.Add(this.buttonRemove);
this.Controls.Add(this.buttonAddFiles);
this.Controls.Add(this.listBoxFiles);
this.Controls.Add(this.groupImportTypes);
this.Controls.Add(this.label1);
this.Controls.Add(this.comboBoxSystemSelect);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "DATConverter";
this.Text = "DATConverter";
this.groupImportTypes.ResumeLayout(false);
this.groupImportTypes.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ComboBox comboBoxSystemSelect;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.GroupBox groupImportTypes;
private System.Windows.Forms.RadioButton radioTOSEC;
private System.Windows.Forms.ListBox listBoxFiles;
private System.Windows.Forms.Button buttonAddFiles;
private System.Windows.Forms.Button buttonRemove;
private System.Windows.Forms.Button buttonStartProcessing;
private System.Windows.Forms.TextBox textBoxOutputFolder;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.RadioButton radioNOINTRO;
}
}

View File

@ -1,150 +0,0 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using BizHawk.Common;
using System.IO;
namespace BizHawk.DBManTool
{
public partial class DATConverter : Form
{
public DATConverter()
{
InitializeComponent();
var systems = Enum.GetValues(typeof(SystemType)).Cast<SystemType>().OrderBy(a => a.ToString()).ToList();
comboBoxSystemSelect.DataSource = systems;
textBoxOutputFolder.Text = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
}
/// <summary>
/// Choose output directory
/// </summary>
private void button2_Click(object sender, EventArgs e)
{
var fbd = new FolderBrowserDialog();
fbd.ShowNewFolderButton = true;
fbd.Description = "Choose a new output folder";
if (fbd.ShowDialog() == DialogResult.OK)
{
textBoxOutputFolder.Text = fbd.SelectedPath;
}
}
/// <summary>
/// Add import files to the list box
/// </summary>
private void buttonAddFiles_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog();
ofd.CheckFileExists = true;
ofd.CheckPathExists = true;
ofd.InitialDirectory = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
ofd.Multiselect = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
foreach (var f in ofd.FileNames)
{
if (!listBoxFiles.Items.Contains((f)))
{
listBoxFiles.Items.Add(f);
}
}
}
}
/// <summary>
/// Removes selected input files from the listbox
/// </summary>
private void buttonRemove_Click(object sender, EventArgs e)
{
List<string> files = new List<string>();
foreach (var s in listBoxFiles.SelectedItems)
{
files.Add(s.ToString());
}
if (files.Count > 0)
{
foreach (var s in files)
listBoxFiles.Items.Remove(s);
}
}
/// <summary>
/// Attempt to process all selected files
/// </summary>
private void buttonStartProcessing_Click(object sender, EventArgs e)
{
// initial checks
var checkedBtn = groupImportTypes.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked);
if (checkedBtn == null)
{
MessageBox.Show("You need to select an import type.");
return;
}
if (!Directory.Exists(textBoxOutputFolder.Text))
{
MessageBox.Show("Chosen output folder is not valid");
return;
}
if (listBoxFiles.Items.Count == 0)
{
MessageBox.Show("No files chosen for input");
return;
}
List<string> files = new List<string>();
foreach (var s in listBoxFiles.Items)
{
if (s.ToString().Trim() == "")
{
MessageBox.Show($"The selected file: {s}Cannot be found.\n\nSort this out and try again");
return;
}
files.Add((string)s);
}
string res = "";
if (radioTOSEC.Checked)
{
DATParser tp = new TOSECParser((SystemType)Enum.Parse(typeof(SystemType), comboBoxSystemSelect.SelectedValue.ToString()));
res = tp.ParseDAT(files.ToArray());
}
else if (radioNOINTRO.Checked)
{
DATParser dp = new NOINTROParser((SystemType)Enum.Parse(typeof(SystemType), comboBoxSystemSelect.SelectedValue.ToString()));
res = dp.ParseDAT(files.ToArray());
}
string fName = $"gamedb_{GameDB.GetSystemCode((SystemType)Enum.Parse(typeof(SystemType), comboBoxSystemSelect.SelectedValue.ToString()))}_DevExport_{DateTime.UtcNow:yyyy-MM-dd_HH_mm_ss}.txt";
try
{
File.WriteAllText(Path.Combine(textBoxOutputFolder.Text, fName), res);
}
catch (Exception ex)
{
MessageBox.Show($"Error writing file: {fName}\n\n{ex.Message}");
}
}
}
}

View File

@ -1,227 +0,0 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace BizHawk.DBManTool
{
public abstract class DATParser
{
/// <summary>
/// Required to generate a GameDB file
/// </summary>
public abstract SystemType SysType { get; set; }
/// <summary>
/// Parses multiple DAT files and returns a single GamesDB format csv string
/// </summary>
public abstract string ParseDAT(string[] filePath);
protected List<string> IncomingData = new List<string>();
protected List<GameDB> Data = new List<GameDB>();
protected StringBuilder sb = new StringBuilder();
protected void AddCommentBlock(string comment)
{
sb.AppendLine(";;;;;;;;;;--------------------------------------------------;;;;;;;;;;");
sb.AppendLine(";;; " + comment.Replace("\r\n", "\r\n;;; "));
sb.AppendLine(";;;;;;;;;;--------------------------------------------------;;;;;;;;;;");
}
protected void AddCommentBlock(string[] comment)
{
sb.AppendLine(";;;;;;;;;;--------------------------------------------------;;;;;;;;;;");
for (int i = 0; i < comment.Length; i++)
{
sb.AppendLine(";;; " + comment[i]);
}
sb.AppendLine(";;;;;;;;;;--------------------------------------------------;;;;;;;;;;");
}
protected void AppendCSVData(List<GameDB> data)
{
if (data == null || data.Count == 0)
{
sb.AppendLine(";");
return;
}
foreach (var d in data)
{
// hash
sb.Append(d.HASH);
sb.Append("\t");
// status
sb.Append(d.Status);
sb.Append("\t");
// name
sb.Append(d.Name);
sb.Append("\t");
// system
sb.Append(d.System);
// additional optional fields
bool[] populated = new bool[4];
if (d.Notes != null)
populated[0] = true;
if (d.MetaData != null)
populated[1] = true;
if (d.Region != null)
populated[2] = true;
if (d.ForcedCore != null)
populated[3] = true;
int last = 0;
for (int i = 3; i >= 0; i--)
{
if (populated[i])
{
last = i;
break;
}
}
int cnt = 0;
// notes
if (d.Notes != null)
{
sb.Append("\t");
sb.Append(d.Notes);
}
else if (cnt++ <= last)
{
sb.Append("\t");
}
// metadata
if (d.MetaData != null)
{
sb.Append("\t");
sb.Append(d.MetaData);
}
else if (cnt++ <= last)
{
sb.Append("\t");
}
// region
if (d.Region != null)
{
sb.Append("\t");
sb.Append(d.Region);
}
else if (cnt++ <= last)
{
sb.Append("\t");
}
// force core
if (d.ForcedCore != null)
{
sb.Append("\t");
sb.Append(d.ForcedCore);
}
sb.Append("\r\n");
}
}
}
/// <summary>
/// DAT data is parsed into this object
/// (every field is not always used)
/// </summary>
public class GameDB
{
// COL0: Hash
public string SHA1 { get; set; }
public string MD5 { get; set; }
// COL1: Status code indicator
public string Status { get; set; }
// COL2: Game title
public string Name { get; set; }
// COL3: System code (must match what bizhawk uses in Emulation.Common/Database/Database.cs
public string System { get; set; }
// COL4: Unknown - not currently parsed in database.cs, but some gamedb files use this for publisher/genre/etc
public string Notes { get; set; }
// COL5: Metadata
public string MetaData { get; set; }
// COL6: Region
public string Region { get; set; }
// COL7: Forced Fore
public string ForcedCore { get; set; }
// prefer MD5 if available
public string HASH
{
get
{
if (MD5.Trim() == "")
return "sha1:" + SHA1;
return MD5;
}
}
/// <summary>
/// Used to get the correct system code (that each gamedb csv needs)
/// </summary>
public static string GetSystemCode(SystemType type)
{
switch (type)
{
case SystemType.P83:
return "83P";
case SystemType.X32:
return "32X";
default:
return type.ToString();
}
}
}
public enum SystemType
{
SAT,
PSP,
PSX,
GEN,
PCFX,
PCECD,
GB,
DGB,
AppleII,
C64,
ZXSpectrum,
AmstradCPC,
SNES,
NES,
P83,
GBC,
A78,
GBA,
X32,
GG,
SG,
SGX,
A26,
Coleco,
INTV,
N64,
WSWAN,
Lynx,
VB,
UZE,
NGP,
ChannelF,
VEC,
GB3x,
GB4x,
O2,
MSX
}
}

View File

@ -1,322 +0,0 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml;
using System.Windows.Forms;
namespace BizHawk.DBManTool
{
public class NOINTROParser : DATParser
{
/// <summary>
/// Required to generate a GameDB file
/// </summary>
public override SystemType SysType { get; set; }
private List<XDocument> xmls = new List<XDocument>();
public NOINTROParser(SystemType type)
{
SysType = type;
}
/// <summary>
/// Parses multiple DAT files and returns a single GamesDB format csv string
/// </summary>
public override string ParseDAT(string[] filePath)
{
foreach (var s in filePath)
{
try
{
xmls.Add(XDocument.Load(s));
}
catch
{
var res = MessageBox.Show("Could not parse document as valid XML:\n\n" + s + "\n\nDo you wish to continue any other processing?", "Parsing Error", MessageBoxButtons.YesNo);
if (res != DialogResult.Yes)
return "";
}
}
int startIndex = 0;
// actual tosec parsing
foreach (var obj in xmls)
{
startIndex = Data.Count > 0 ? Data.Count - 1 : 0;
// get header info
var header = obj.Root.Descendants("header").First();
var name = header.Element("name").Value;
var version = header.Element("version").Value;
var description = header.Element("description").Value + " - " + version;
// start comment block
List<string> comments = new List<string>
{
"Type:\tNO-INTRO",
$"Source:\t{description}",
$"FileGen:\t{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} (UTC)",
};
AddCommentBlock(comments.ToArray());
// process each entry
var query = obj.Root.Descendants("game");
foreach (var g in query)
{
GameDB item = new GameDB();
item.Name = g.Value;
item.SHA1 = g.Elements("rom").First().Attribute("sha1").Value.ToUpper();
item.MD5 = g.Elements("rom").First().Attribute("md5").Value.ToUpper();
item.System = GameDB.GetSystemCode(SysType);
ParseNOINTROFlags(item);
Data.Add(item);
}
// add this file's data to the stringbuilder
// first we will sort into various ROMSTATUS groups
var working = Data.Skip(startIndex).ToList();
var baddump = working.Where(st => st.Status == "B").OrderBy(na => na.Name).ToList();
AddCommentBlock("Bad Dumps");
AppendCSVData(baddump);
var hack = working.Where(st => st.Status == "H").OrderBy(na => na.Name).ToList();
AddCommentBlock("Hacks");
AppendCSVData(hack);
var over = working.Where(st => st.Status == "O").OrderBy(na => na.Name).ToList();
AddCommentBlock("Over Dumps");
AppendCSVData(over);
var trans = working.Where(st => st.Status == "T").OrderBy(na => na.Name).ToList();
AddCommentBlock("Translated");
AppendCSVData(trans);
var good = working.Where(st => st.Status == "" || st.Status == null).OrderBy(na => na.Name).ToList();
AddCommentBlock("Believed Good");
AppendCSVData(good);
}
string result = sb.ToString();
return sb.ToString();
}
/// <summary>
/// Parses all the weird TOSEC flags within the game field
/// Detailed info here: https://www.tosecdev.org/tosec-naming-convention
/// Guts of this has been reused from here: https://github.com/Asnivor/MedLaunch/blob/master/MedLaunch/_Debug/DATDB/Platforms/TOSEC/StringConverterToSec.cs
/// </summary>
private void ParseNOINTROFlags(GameDB g)
{
string nameString = g.Name;
// remove uninteresting options
string a = RemoveUnneededOptions(nameString);
// process data contained in ()
string[] d = a.ToString().Split('(', ')');
if (d.Length > 0)
{
// name field
}
if (d.Length > 1)
{
if (d[1].Length >= 3)
{
// country
g.Region = d[1].Trim();
}
}
if (d.Length > 2)
{
// parse all other () fields
// because these are not mandatory this can be a confusing process
for (int i = 4; i < d.Length; i++)
{
string f = d[i].Trim();
// check for language
if (IsLanguageFlag(f) == true)
{
g.Notes = f;
continue;
}
// version - ignore
// check development status (not currently implemented)
if (IsDevelopmenttStatus(f) == true)
{
continue;
}
// check copyright status (not currently implemented)
if (IsCopyrightStatus(f) == true)
{
continue;
}
// country flag(s)
if (IsCountryFlag(f) == true)
{
g.Region = f;
continue;
}
// language - if present add to notes
if (IsLanguageFlag(f) == true)
{
g.Notes = f;
continue;
}
// Media Type - ignore for now
// Media Label - ignore for now
}
// process dump info flags and other info contained in []
if (nameString.Contains("[") && nameString.Contains("]"))
{
var e = nameString.Split('[', ']')
.Skip(1) // remove first entry (this is the bit before the [] entries start)
.Where(s => !string.IsNullOrWhiteSpace(s)) // remove empty entries
.Distinct()
.ToList();
if (e.Count > 0)
{
// bizhawk currently only has a few different RomStatus values (not as many as TOSEC anyway)
// Parsing priority will be:
// RomStatus.BadDump
// RomStatus.Hack
// RomStatus.Overdump
// RomStatus.GoodDump
// RomStatus.TranslatedRom
// everything else
// all tosec cr, h, t etc.. will fall under RomStatus.Hack
if (e.Where(str =>
// bad dump
str == "b" || str.StartsWith("b ")).ToList().Count > 0)
{
// RomStatus.BadDump
g.Status = "B";
}
else if (e.Where(str =>
// BIOS
str == "BIOS" || str.StartsWith("BIOS ")).ToList().Count > 0)
{
// RomStatus.BIOS
g.Status = "I";
}
else
{
g.Status = "";
}
}
}
}
}
public static bool IsDevelopmenttStatus(string s)
{
List<string> DS = new List<string>
{
"alpha", "beta", "preview", "pre-release", "proto"
};
bool b = DS.Any(s.Contains);
return b;
}
public static bool IsCopyrightStatus(string s)
{
List<string> CS = new List<string>
{
"CW", "CW-R", "FW", "GW", "GW-R", "LW", "PD", "SW", "SW-R"
};
bool b = CS.Any(s.Contains);
return b;
}
public static bool IsLanguageFlag(string s)
{
List<string> LC = new List<string>
{
"En", "Ja", "Fr", "De", "Es", "It", "Nl", "Pt", "Sv", "No", "Da", "Fi", "Zh", "Ko", "Pl"
};
bool b = false;
if (!s.Contains("[") && !s.Contains("]"))
{
foreach (var x in LC)
{
if (s == x || s.StartsWith(x + ",") || s.EndsWith("," + x))
{
b = true;
break;
}
}
//b = LC.Any(s.Contains);
}
return b;
}
public static bool IsCountryFlag(string s)
{
List<string> CC = new List<string>
{
"World", "Australia", "Brazil", "Canada", "China", "France", "Germany", "Hong Kong", "Italy",
"Japan", "Korea", "Netherlands", "Spain", "Sweden", "USA", "Europe", "Asia"
};
bool b = false;
if (!s.Contains("[") && !s.Contains("]"))
{
foreach (var x in CC)
{
if (s == x || s.StartsWith(x) || s.EndsWith(x))
{
b = true;
break;
}
}
//b = CC.Any(s.Contains);
}
return b;
}
public static string RemoveUnneededOptions(string nameString)
{
// Remove unneeded entries
string n = nameString
.Replace(" (demo) ", " ")
.Replace(" (demo-kiosk) ", " ")
.Replace(" (demo-playable) ", " ")
.Replace(" (demo-rolling) ", " ")
.Replace(" (demo-slideshow) ", " ");
return n;
}
}
}

View File

@ -1,378 +0,0 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml;
using System.Windows.Forms;
namespace BizHawk.DBManTool
{
public class TOSECParser : DATParser
{
/// <summary>
/// Required to generate a GameDB file
/// </summary>
public override SystemType SysType { get; set; }
private List<XDocument> xmls = new List<XDocument>();
public TOSECParser(SystemType type)
{
SysType = type;
}
/// <summary>
/// Parses multiple DAT files and returns a single GamesDB format csv string
/// </summary>
public override string ParseDAT(string[] filePath)
{
foreach (var s in filePath)
{
try
{
xmls.Add(XDocument.Load(s));
}
catch
{
var res = MessageBox.Show("Could not parse document as valid XML:\n\n" + s + "\n\nDo you wish to continue any other processing?", "Parsing Error", MessageBoxButtons.YesNo);
if (res != DialogResult.Yes)
return "";
}
}
int startIndex = 0;
// actual tosec parsing
foreach (var obj in xmls)
{
startIndex = Data.Count > 0 ? Data.Count - 1 : 0;
// get header info
var header = obj.Root.Descendants("header").First();
var category = header.Element("category").Value;
var name = header.Element("name").Value;
var version = header.Element("version").Value;
var description = header.Element("description").Value;
// start comment block
List<string> comments = new List<string>
{
$"Type:\t{category}",
$"Source:\t{description}",
$"FileGen:\t{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} (UTC)",
};
AddCommentBlock(comments.ToArray());
// process each entry
var query = obj.Root.Descendants("game");
foreach (var g in query)
{
GameDB item = new GameDB();
item.Name = g.Value;
item.SHA1 = g.Elements("rom").First().Attribute("sha1").Value.ToUpper();
item.MD5 = g.Elements("rom").First().Attribute("md5").Value.ToUpper();
item.System = GameDB.GetSystemCode(SysType);
ParseTOSECFlags(item);
Data.Add(item);
}
// add this file's data to the stringbuilder
// first we will sort into various ROMSTATUS groups
var working = Data.Skip(startIndex).ToList();
var baddump = working.Where(st => st.Status == "B").OrderBy(na => na.Name).ToList();
AddCommentBlock("Bad Dumps");
AppendCSVData(baddump);
var hack = working.Where(st => st.Status == "H").OrderBy(na => na.Name).ToList();
AddCommentBlock("Hacks");
AppendCSVData(hack);
var over = working.Where(st => st.Status == "O").OrderBy(na => na.Name).ToList();
AddCommentBlock("Over Dumps");
AppendCSVData(over);
var trans = working.Where(st => st.Status == "T").OrderBy(na => na.Name).ToList();
AddCommentBlock("Translated");
AppendCSVData(trans);
var pd = working.Where(st => st.Status == "D").OrderBy(na => na.Name).ToList();
AddCommentBlock("Home Brew");
AppendCSVData(pd);
var good = working.Where(st => st.Status == "" || st.Status == null).OrderBy(na => na.Name).ToList();
AddCommentBlock("Believed Good");
AppendCSVData(good);
}
string result = sb.ToString();
return sb.ToString();
}
/// <summary>
/// Parses all the weird TOSEC flags within the game field
/// Detailed info here: https://www.tosecdev.org/tosec-naming-convention
/// Guts of this has been reused from here: https://github.com/Asnivor/MedLaunch/blob/master/MedLaunch/_Debug/DATDB/Platforms/TOSEC/StringConverterToSec.cs
/// </summary>
private void ParseTOSECFlags(GameDB g)
{
string nameString = g.Name;
// remove uninteresting options
string a = RemoveUnneededOptions(nameString);
// process data contained in ()
string[] d = a.ToString().Split('(', ')');
if (d.Length > 0)
{
// name field
}
if (d.Length > 1)
{
if (d[1].Length > 3)
{
// year field
}
}
if (d.Length > 3)
{
// publisher field
}
// public domain
if (nameString.Contains("(PD)"))
{
g.Status = "D";
}
if (d.Length > 4)
{
// parse all other () fields
// because these are not mandatory this can be a confusing process
for (int i = 4; i < d.Length; i++)
{
string f = d[i];
// system field
if (f == "Aladdin Deck Enhancer" ||
f == "PlayChoice-10" ||
f == "VS DualSystem" ||
f == "VS UniSystem")
{
// ignore for now (not currently implemented)
continue;
}
// country flag(s)
if (IsCountryFlag(f) == true)
{
g.Region = f;
continue;
}
// language - if present add to notes
if (IsLanguageFlag(f) == true)
{
g.Notes = f;
continue;
}
// check copyright status (not currently implemented)
if (IsCopyrightStatus(f) == true)
{
continue;
}
// check development status (not currently implemented)
if (IsDevelopmenttStatus(f) == true)
{
continue;
}
// Media Type - ignore for now
// Media Label - ignore for now
}
// process dump info flags and other info contained in []
if (nameString.Contains("[") && nameString.Contains("]"))
{
var e = nameString.Split('[', ']')
.Skip(1) // remove first entry (this is the bit before the [] entries start)
.Where(s => !string.IsNullOrWhiteSpace(s)) // remove empty entries
.Distinct()
.ToList();
if (e.Count > 0)
{
// bizhawk currently only has a few different RomStatus values (not as many as TOSEC anyway)
// Parsing priority will be:
// RomStatus.BadDump
// RomStatus.Hack
// RomStatus.Overdump
// RomStatus.GoodDump
// RomStatus.TranslatedRom
// everything else
// all tosec cr, h, t etc.. will fall under RomStatus.Hack
if (e.Where(str =>
// bad dump
str == "b" || str.StartsWith("b ") ||
// virus
str == "v" || str.StartsWith("v ") ||
// under dump
str == "u" || str.StartsWith("u ")).ToList().Count > 0)
{
// RomStatus.BadDump
g.Status = "B";
}
else if (e.Where(str =>
// cracked
str == "cr" || str.StartsWith("cr ") ||
// fixed
str == "f" || str.StartsWith("f ") ||
// hack
str == "h" || str.StartsWith("h ") ||
// modified
str == "m" || str.StartsWith("m ") ||
// pirated
str == "p" || str.StartsWith("p ") ||
// trained
str == "t" || str.StartsWith("t ")
).ToList().Count > 0)
{
// RomStatus.Hack
g.Status = "H";
}
else if (e.Where(str =>
// over dump
str == "o" || str.StartsWith("o ")).ToList().Count > 0)
{
// RomStatus.Overdump
g.Status = "O";
}
else if (e.Where(str =>
// known verified dump
str == "!").ToList().Count > 0)
{
// RomStatus.GoodDump
g.Status = "";
}
else if (e.Where(str =>
// translated
str == "tr" || str.StartsWith("tr ")).ToList().Count > 0)
{
// RomStatus.TranslatedRom
g.Status = "T";
}
}
}
}
}
public static bool IsDevelopmenttStatus(string s)
{
List<string> DS = new List<string>
{
"alpha", "beta", "preview", "pre-release", "proto"
};
bool b = DS.Any(s.Contains);
return b;
}
public static bool IsCopyrightStatus(string s)
{
List<string> CS = new List<string>
{
"CW", "CW-R", "FW", "GW", "GW-R", "LW", "PD", "SW", "SW-R"
};
bool b = CS.Any(s.Contains);
return b;
}
public static bool IsLanguageFlag(string s)
{
List<string> LC = new List<string>
{
"ar", "bg", "bs", "cs", "cy", "da", "de", "el", "en", "eo", "es", "et", "fa", "fi", "fr", "ga",
"gu", "he", "hi", "hr", "hu", "is", "it", "ja", "ko", "lt", "lv", "ms", "nl", "no", "pl", "pt",
"ro", "ru", "sk", "sl", "sq", "sr", "sv", "th", "tr", "ur", "vi", "yi", "zh", "M1", "M2", "M3",
"M4", "M5", "M6", "M7", "M8", "M9"
};
bool b = false;
if (!s.Contains("[") && !s.Contains("]"))
{
foreach (var x in LC)
{
if (s == x || s.StartsWith(x) || s.EndsWith(x))
{
b = true;
break;
}
}
//b = LC.Any(s.Contains);
}
return b;
}
public static bool IsCountryFlag(string s)
{
List<string> CC = new List<string>
{
"AE", "AL", "AS", "AT", "AU", "BA", "BE", "BG", "BR", "CA", "CH", "CL", "CN", "CS", "CY", "CZ",
"DE", "DK", "EE", "EG", "EU", "ES", "FI", "FR", "GB", "GR", "HK", "HR", "HU", "ID", "IE", "IL",
"IN", "IR", "IS", "IT", "JO", "JP", "KR", "LT", "LU", "LV", "MN", "MX", "MY", "NL", "NO", "NP",
"NZ", "OM", "PE", "PH", "PL", "PT", "QA", "RO", "RU", "SE", "SG", "SI", "SK", "TH", "TR", "TW",
"US", "VN", "YU", "ZA"
};
bool b = false;
if (!s.Contains("[") && !s.Contains("]"))
{
foreach (var x in CC)
{
if (s == x || s.StartsWith(x) || s.EndsWith(x))
{
b = true;
break;
}
}
//b = CC.Any(s.Contains);
}
return b;
}
public static string RemoveUnneededOptions(string nameString)
{
// Remove unneeded entries
string n = nameString
.Replace(" (demo) ", " ")
.Replace(" (demo-kiosk) ", " ")
.Replace(" (demo-playable) ", " ")
.Replace(" (demo-rolling) ", " ")
.Replace(" (demo-slideshow) ", " ");
return n;
}
}
}

View File

@ -9,14 +9,10 @@
<ItemGroup>
<PackageReference Include="System.Memory" Version="4.5.4" />
<NET48ExternalToolFormDependency Include="$(ProjectDir)CSharp-SQLite.dll" />
<Reference Include="CSharp-SQLite"
HintPath="$(ProjectDir)CSharp-SQLite.dll"
Private="true" />
<Reference Include="CSharp-SQLite" HintPath="$(ProjectDir)CSharp-SQLite.dll" Private="true" />
</ItemGroup>
<ItemGroup>
<Compile Update="CustomMainForm.cs" SubType="Form" />
<Compile Update="DATTools/DATConverter.cs" SubType="Form" />
<Compile Update="DATTools/DATConverter.Designer.cs" DependentUpon="DATConverter.cs" />
<Compile Update="DBMan.cs" SubType="Form" />
<Compile Update="DBMan.Designer.cs" DependentUpon="DBMan.cs" />
<EmbeddedResource Update="DBMan.resx" DependentUpon="DBMan.cs" />