Separated TOSEC signature scanner to it's own class and enhanced
This commit is contained in:
368
gaseous-identifier/Classes/TosecParser.cs
Normal file
368
gaseous-identifier/Classes/TosecParser.cs
Normal file
@@ -0,0 +1,368 @@
|
|||||||
|
using System;
|
||||||
|
using System.Xml;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace gaseous_identifier.classes
|
||||||
|
{
|
||||||
|
public class TosecParser
|
||||||
|
{
|
||||||
|
public objects.RomSignatureObject Parse(string XMLFile)
|
||||||
|
{
|
||||||
|
// load resources
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
// load systems list
|
||||||
|
List<string> TOSECSystems = new List<string>();
|
||||||
|
var resourceName = "gaseous_identifier.Support.Parsers.TOSEC.Systems.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
TOSECSystems = reader.ReadToEnd().Split(Environment.NewLine).ToList<string>();
|
||||||
|
}
|
||||||
|
// load video list
|
||||||
|
List<string> TOSECVideo = new List<string>();
|
||||||
|
resourceName = "gaseous_identifier.Support.Parsers.TOSEC.Video.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
TOSECVideo = reader.ReadToEnd().Split(Environment.NewLine).ToList<string>();
|
||||||
|
}
|
||||||
|
// load country list
|
||||||
|
Dictionary<string, string> TOSECCountry = new Dictionary<string, string>();
|
||||||
|
resourceName = "gaseous_identifier.Support.Parsers.TOSEC.Country.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
string[] line = reader.ReadLine().Split(",");
|
||||||
|
TOSECCountry.Add(line[0], line[1]);
|
||||||
|
} while (reader.EndOfStream == false);
|
||||||
|
}
|
||||||
|
// load language list
|
||||||
|
Dictionary<string, string> TOSECLanguage = new Dictionary<string, string>();
|
||||||
|
resourceName = "gaseous_identifier.Support.Parsers.TOSEC.Language.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
string[] line = reader.ReadLine().Split(",");
|
||||||
|
TOSECLanguage.Add(line[0], line[1]);
|
||||||
|
} while (reader.EndOfStream == false);
|
||||||
|
}
|
||||||
|
// load copyright list
|
||||||
|
Dictionary<string, string> TOSECCopyright = new Dictionary<string, string>();
|
||||||
|
resourceName = "gaseous_identifier.Support.Parsers.TOSEC.Copyright.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
string[] line = reader.ReadLine().Split(",");
|
||||||
|
TOSECCopyright.Add(line[0], line[1]);
|
||||||
|
} while (reader.EndOfStream == false);
|
||||||
|
}
|
||||||
|
// load development status list
|
||||||
|
Dictionary<string, string> TOSECDevelopment = new Dictionary<string, string>();
|
||||||
|
resourceName = "gaseous_identifier.Support.Parsers.TOSEC.DevelopmentStatus.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
string[] line = reader.ReadLine().Split(",");
|
||||||
|
TOSECDevelopment.Add(line[0], line[1]);
|
||||||
|
} while (reader.EndOfStream == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load TOSEC file
|
||||||
|
XmlDocument tosecXmlDoc = new XmlDocument();
|
||||||
|
tosecXmlDoc.Load(XMLFile);
|
||||||
|
|
||||||
|
objects.RomSignatureObject tosecObject = new objects.RomSignatureObject();
|
||||||
|
|
||||||
|
// get header
|
||||||
|
XmlNode xmlHeader = tosecXmlDoc.DocumentElement.SelectSingleNode("/datafile/header");
|
||||||
|
foreach (XmlNode childNode in xmlHeader.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (childNode.Name.ToLower())
|
||||||
|
{
|
||||||
|
case "name":
|
||||||
|
tosecObject.Name = childNode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "description":
|
||||||
|
tosecObject.Description = childNode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "category":
|
||||||
|
tosecObject.Category = childNode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "version":
|
||||||
|
tosecObject.Version = childNode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "author":
|
||||||
|
tosecObject.Author = childNode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "email":
|
||||||
|
tosecObject.Email = childNode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "homepage":
|
||||||
|
tosecObject.Homepage = childNode.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "url":
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tosecObject.Url = new Uri(childNode.InnerText);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
tosecObject.Url = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get games
|
||||||
|
tosecObject.Games = new List<gaseous_identifier.objects.RomSignatureObject.Game>();
|
||||||
|
XmlNodeList xmlGames = tosecXmlDoc.DocumentElement.SelectNodes("/datafile/game");
|
||||||
|
foreach (XmlNode xmlGame in xmlGames)
|
||||||
|
{
|
||||||
|
objects.RomSignatureObject.Game gameObject = new objects.RomSignatureObject.Game();
|
||||||
|
|
||||||
|
// parse game name
|
||||||
|
string gameName = xmlGame.Attributes["name"].Value;
|
||||||
|
|
||||||
|
// before split, save and remove the demo tag if present
|
||||||
|
if (gameName.Contains("(demo) ", StringComparison.CurrentCulture))
|
||||||
|
{
|
||||||
|
gameObject.Demo = objects.RomSignatureObject.Game.DemoTypes.demo;
|
||||||
|
gameName.Replace("(demo) ", "");
|
||||||
|
}
|
||||||
|
else if (gameName.Contains("(demo-kiosk) ", StringComparison.CurrentCulture))
|
||||||
|
{
|
||||||
|
gameObject.Demo = objects.RomSignatureObject.Game.DemoTypes.demo_kiosk;
|
||||||
|
gameName.Replace("(demo-kiosk) ", "");
|
||||||
|
}
|
||||||
|
else if (gameName.Contains("(demo-playable) ", StringComparison.CurrentCulture))
|
||||||
|
{
|
||||||
|
gameObject.Demo = objects.RomSignatureObject.Game.DemoTypes.demo_playable;
|
||||||
|
gameName.Replace("(demo-playable) ", "");
|
||||||
|
}
|
||||||
|
else if (gameName.Contains("(demo-rolling) ", StringComparison.CurrentCulture))
|
||||||
|
{
|
||||||
|
gameObject.Demo = objects.RomSignatureObject.Game.DemoTypes.demo_rolling;
|
||||||
|
gameName.Replace("(demo-rolling) ", "");
|
||||||
|
}
|
||||||
|
else if (gameName.Contains("(demo-slideshow) ", StringComparison.CurrentCulture))
|
||||||
|
{
|
||||||
|
gameObject.Demo = objects.RomSignatureObject.Game.DemoTypes.demo_slideshow;
|
||||||
|
gameName.Replace("(demo-slideshow) ", "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameObject.Demo = objects.RomSignatureObject.Game.DemoTypes.NotDemo;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] gameNameTokens = gameName.Split("(");
|
||||||
|
// game title should be first item
|
||||||
|
gameObject.Name = gameNameTokens[0].Trim();
|
||||||
|
|
||||||
|
// game year should be second item
|
||||||
|
if (gameNameTokens.Length >= 2)
|
||||||
|
{
|
||||||
|
gameObject.Year = gameNameTokens[1].Replace(")", "").Trim();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameObject.Year = "";
|
||||||
|
}
|
||||||
|
// game publisher should be third item
|
||||||
|
if (gameNameTokens.Length >= 3)
|
||||||
|
{
|
||||||
|
gameObject.Publisher = gameNameTokens[2].Replace(")", "").Trim();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameObject.Publisher = "";
|
||||||
|
}
|
||||||
|
// process remaining tokens
|
||||||
|
// set default values
|
||||||
|
gameObject.System = tosecObject.Name.Split(" - ")[0];
|
||||||
|
// process title values
|
||||||
|
UInt16 StartToken = 0;
|
||||||
|
foreach (string rawToken in gameNameTokens)
|
||||||
|
{
|
||||||
|
if (StartToken > 2)
|
||||||
|
{
|
||||||
|
string[] tokenSplit = rawToken.Split("[");
|
||||||
|
|
||||||
|
// replace the extra closing bracket
|
||||||
|
string token = tokenSplit[0].Replace(")", "").Trim();
|
||||||
|
|
||||||
|
// perform tests on the token to see what it is
|
||||||
|
// exclude strings that start with [ in this part
|
||||||
|
if (!(token.StartsWith("[") && token.EndsWith("]")))
|
||||||
|
{
|
||||||
|
// check for systems
|
||||||
|
if (TOSECSystems.Contains(token, StringComparer.CurrentCulture))
|
||||||
|
{
|
||||||
|
// this is a system token
|
||||||
|
gameObject.SystemVariant = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for video
|
||||||
|
if (TOSECVideo.Contains(token, StringComparer.CurrentCulture))
|
||||||
|
{
|
||||||
|
// this is a system token
|
||||||
|
gameObject.Video = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for country
|
||||||
|
if (TOSECCountry.ContainsKey(token))
|
||||||
|
{
|
||||||
|
gameObject.Country = new KeyValuePair<string, string>(token, TOSECCountry[token]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for language
|
||||||
|
if (TOSECLanguage.ContainsKey(token))
|
||||||
|
{
|
||||||
|
gameObject.Language = new KeyValuePair<string, string>(token, TOSECLanguage[token]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for copyright
|
||||||
|
if (TOSECCopyright.ContainsKey(token))
|
||||||
|
{
|
||||||
|
gameObject.Copyright = new KeyValuePair<string, string>(token, TOSECCopyright[token]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for copyright
|
||||||
|
if (TOSECDevelopment.ContainsKey(token))
|
||||||
|
{
|
||||||
|
gameObject.DevelopmentStatus = new KeyValuePair<string, string>(token, TOSECDevelopment[token]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// handle the square bracket tokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StartToken += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gameObject.Roms = new List<objects.RomSignatureObject.Game.Rom>();
|
||||||
|
|
||||||
|
// get the roms
|
||||||
|
foreach (XmlNode xmlGameDetail in xmlGame.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (xmlGameDetail.Name.ToLower())
|
||||||
|
{
|
||||||
|
case "description":
|
||||||
|
gameObject.Description = xmlGameDetail.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "rom":
|
||||||
|
objects.RomSignatureObject.Game.Rom romObject = new objects.RomSignatureObject.Game.Rom();
|
||||||
|
romObject.Name = xmlGameDetail.Attributes["name"]?.Value;
|
||||||
|
romObject.Size = UInt64.Parse(xmlGameDetail.Attributes["size"]?.Value);
|
||||||
|
romObject.Crc = xmlGameDetail.Attributes["crc"]?.Value;
|
||||||
|
romObject.Md5 = xmlGameDetail.Attributes["md5"]?.Value;
|
||||||
|
romObject.Sha1 = xmlGameDetail.Attributes["sha1"]?.Value;
|
||||||
|
|
||||||
|
// parse name
|
||||||
|
string[] romNameTokens = romObject.Name.Split("(");
|
||||||
|
foreach (string rawToken in gameNameTokens) {
|
||||||
|
string[] tokenSplit = rawToken.Split("[");
|
||||||
|
|
||||||
|
// replace the extra closing bracket
|
||||||
|
string token = tokenSplit[0].Replace(")", "").Trim();
|
||||||
|
|
||||||
|
// check for media type
|
||||||
|
if (token.StartsWith("Disc") ||
|
||||||
|
token.StartsWith("Disk") ||
|
||||||
|
token.StartsWith("File") ||
|
||||||
|
token.StartsWith("Part") ||
|
||||||
|
token.StartsWith("Side") ||
|
||||||
|
token.StartsWith("Tape"))
|
||||||
|
{
|
||||||
|
string[] tokens = token.Split(" ");
|
||||||
|
switch (tokens[0])
|
||||||
|
{
|
||||||
|
case "Disc":
|
||||||
|
romObject.RomType = objects.RomSignatureObject.Game.Rom.RomTypes.Disc;
|
||||||
|
break;
|
||||||
|
case "Disk":
|
||||||
|
romObject.RomType = objects.RomSignatureObject.Game.Rom.RomTypes.Disk;
|
||||||
|
break;
|
||||||
|
case "File":
|
||||||
|
romObject.RomType = objects.RomSignatureObject.Game.Rom.RomTypes.File;
|
||||||
|
break;
|
||||||
|
case "Part":
|
||||||
|
romObject.RomType = objects.RomSignatureObject.Game.Rom.RomTypes.Part;
|
||||||
|
break;
|
||||||
|
case "Side":
|
||||||
|
romObject.RomType = objects.RomSignatureObject.Game.Rom.RomTypes.Side;
|
||||||
|
break;
|
||||||
|
case "Tape":
|
||||||
|
romObject.RomType = objects.RomSignatureObject.Game.Rom.RomTypes.Tape;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
romObject.RomTypeMedia = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for media label
|
||||||
|
if (token.Length > 0 &&
|
||||||
|
token == gameNameTokens.Last() &&
|
||||||
|
gameNameTokens.Length > 2 &&
|
||||||
|
(
|
||||||
|
token != romObject.RomTypeMedia &&
|
||||||
|
token != gameObject.Publisher &&
|
||||||
|
token != gameObject.Country.Key)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// likely the media label?
|
||||||
|
romObject.MediaLabel = token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gameObject.Roms.Add(romObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// search for existing gameObject to update
|
||||||
|
bool existingGameFound = false;
|
||||||
|
foreach (gaseous_identifier.objects.RomSignatureObject.Game existingGame in tosecObject.Games)
|
||||||
|
{
|
||||||
|
if (existingGame.Name == gameObject.Name && existingGame.Year == gameObject.Year && existingGame.Publisher == gameObject.Publisher)
|
||||||
|
{
|
||||||
|
existingGame.Roms.AddRange(gameObject.Roms);
|
||||||
|
existingGameFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (existingGameFound == false)
|
||||||
|
{
|
||||||
|
tosecObject.Games.Add(gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tosecObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
106
gaseous-identifier/Objects/RomSignatureObject.cs
Normal file
106
gaseous-identifier/Objects/RomSignatureObject.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace gaseous_identifier.objects
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Object returned by all signature engines containing metadata about the ROM's in the data files
|
||||||
|
///
|
||||||
|
/// This class was based on the TOSEC dataset, so may need to be expanded as new signature engines are added
|
||||||
|
/// </summary>
|
||||||
|
public class RomSignatureObject
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Category { get; set; }
|
||||||
|
public string Version { get; set; }
|
||||||
|
public string Author { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string Homepage { get; set; }
|
||||||
|
public Uri? Url { get; set; }
|
||||||
|
|
||||||
|
public List<Game> Games { get; set; }
|
||||||
|
|
||||||
|
public class Game
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Year { get; set; }
|
||||||
|
public string Publisher { get; set; }
|
||||||
|
public DemoTypes Demo { get; set; }
|
||||||
|
public string System { get; set; }
|
||||||
|
public string SystemVariant { get; set; }
|
||||||
|
public string Video { get; set; }
|
||||||
|
public KeyValuePair<string, string> Country { get; set; }
|
||||||
|
public KeyValuePair<string, string> Language { get; set; }
|
||||||
|
public KeyValuePair<string, string> Copyright { get; set; }
|
||||||
|
public KeyValuePair<string, string> DevelopmentStatus { get; set; }
|
||||||
|
public List<Rom> Roms { get; set; }
|
||||||
|
|
||||||
|
public enum DemoTypes
|
||||||
|
{
|
||||||
|
NotDemo = 0,
|
||||||
|
demo = 1,
|
||||||
|
demo_kiosk = 2,
|
||||||
|
demo_playable = 3,
|
||||||
|
demo_rolling = 4,
|
||||||
|
demo_slideshow = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Rom
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public UInt64 Size { get; set; }
|
||||||
|
public string Crc { get; set; }
|
||||||
|
public string Md5 { get; set; }
|
||||||
|
public string Sha1 { get; set; }
|
||||||
|
|
||||||
|
public string flags { get; set; }
|
||||||
|
|
||||||
|
public RomTypes RomType { get; set; }
|
||||||
|
public string RomTypeMedia { get; set; }
|
||||||
|
public string MediaLabel { get; set; }
|
||||||
|
|
||||||
|
public enum RomTypes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Media type is unknown
|
||||||
|
/// </summary>
|
||||||
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optical media
|
||||||
|
/// </summary>
|
||||||
|
Disc = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Magnetic media
|
||||||
|
/// </summary>
|
||||||
|
Disk = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Individual files
|
||||||
|
/// </summary>
|
||||||
|
File = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Individual pars
|
||||||
|
/// </summary>
|
||||||
|
Part = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tape base media
|
||||||
|
/// </summary>
|
||||||
|
Tape = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Side of the media
|
||||||
|
/// </summary>
|
||||||
|
Side = 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -50,8 +50,7 @@ scanPath = Path.GetFullPath(scanPath);
|
|||||||
Console.WriteLine("ROM search path: " + scanPath);
|
Console.WriteLine("ROM search path: " + scanPath);
|
||||||
|
|
||||||
System.Collections.ArrayList TOSEC = new System.Collections.ArrayList();
|
System.Collections.ArrayList TOSEC = new System.Collections.ArrayList();
|
||||||
List<gaseous_identifier.classes.tosecXML> tosecLists = new List<gaseous_identifier.classes.tosecXML>();
|
List<gaseous_identifier.objects.RomSignatureObject> tosecLists = new List<gaseous_identifier.objects.RomSignatureObject>();
|
||||||
UInt32 GameCounter = 0;
|
|
||||||
if (tosecXML != null && tosecXML.Length > 0)
|
if (tosecXML != null && tosecXML.Length > 0)
|
||||||
{
|
{
|
||||||
tosecXML = Path.GetFullPath(tosecXML);
|
tosecXML = Path.GetFullPath(tosecXML);
|
||||||
@@ -61,127 +60,8 @@ if (tosecXML != null && tosecXML.Length > 0)
|
|||||||
string[] tosecPathContents = Directory.GetFiles(tosecXML);
|
string[] tosecPathContents = Directory.GetFiles(tosecXML);
|
||||||
foreach (string tosecXMLFile in tosecPathContents)
|
foreach (string tosecXMLFile in tosecPathContents)
|
||||||
{
|
{
|
||||||
XmlDocument tosecXmlDoc = new XmlDocument();
|
gaseous_identifier.classes.TosecParser tosecParser = new gaseous_identifier.classes.TosecParser();
|
||||||
tosecXmlDoc.Load(tosecXMLFile);
|
gaseous_identifier.objects.RomSignatureObject tosecObject = tosecParser.Parse(tosecXMLFile);
|
||||||
|
|
||||||
gaseous_identifier.classes.tosecXML tosecObject = new gaseous_identifier.classes.tosecXML();
|
|
||||||
|
|
||||||
// get header
|
|
||||||
XmlNode xmlHeader = tosecXmlDoc.DocumentElement.SelectSingleNode("/datafile/header");
|
|
||||||
foreach (XmlNode childNode in xmlHeader.ChildNodes)
|
|
||||||
{
|
|
||||||
switch (childNode.Name.ToLower())
|
|
||||||
{
|
|
||||||
case "name":
|
|
||||||
tosecObject.Name = childNode.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "description":
|
|
||||||
tosecObject.Description = childNode.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "category":
|
|
||||||
tosecObject.Category = childNode.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "version":
|
|
||||||
tosecObject.Version = childNode.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "author":
|
|
||||||
tosecObject.Author = childNode.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "email":
|
|
||||||
tosecObject.Email = childNode.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "homepage":
|
|
||||||
tosecObject.Homepage = childNode.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "url":
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tosecObject.Url = new Uri(childNode.InnerText);
|
|
||||||
} catch
|
|
||||||
{
|
|
||||||
tosecObject.Url = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get games
|
|
||||||
tosecObject.Games = new List<gaseous_identifier.classes.tosecXML.Game>();
|
|
||||||
XmlNodeList xmlGames = tosecXmlDoc.DocumentElement.SelectNodes("/datafile/game");
|
|
||||||
foreach (XmlNode xmlGame in xmlGames)
|
|
||||||
{
|
|
||||||
gaseous_identifier.classes.tosecXML.Game gameObject = new gaseous_identifier.classes.tosecXML.Game();
|
|
||||||
|
|
||||||
// parse game name
|
|
||||||
string gameName = xmlGame.Attributes["name"].Value;
|
|
||||||
string[] gameNameTokens = gameName.Split("(");
|
|
||||||
// game title should be first item
|
|
||||||
gameObject.Name = gameNameTokens[0].Trim();
|
|
||||||
// game year should be second item
|
|
||||||
if (gameNameTokens.Length == 2)
|
|
||||||
{
|
|
||||||
gameObject.Year = gameNameTokens[1].Replace(")", "").Trim();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
gameObject.Year = "";
|
|
||||||
}
|
|
||||||
// game publisher should be third item
|
|
||||||
if (gameNameTokens.Length == 3)
|
|
||||||
{
|
|
||||||
gameObject.Publisher = gameNameTokens[2].Replace(")", "").Trim();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
gameObject.Publisher = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
gameObject.Roms = new List<gaseous_identifier.classes.tosecXML.Game.Rom>();
|
|
||||||
|
|
||||||
// get the roms
|
|
||||||
foreach (XmlNode xmlGameDetail in xmlGame.ChildNodes)
|
|
||||||
{
|
|
||||||
switch (xmlGameDetail.Name.ToLower())
|
|
||||||
{
|
|
||||||
case "description":
|
|
||||||
gameObject.Description = xmlGameDetail.InnerText;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "rom":
|
|
||||||
gaseous_identifier.classes.tosecXML.Game.Rom romObject = new gaseous_identifier.classes.tosecXML.Game.Rom();
|
|
||||||
romObject.Name = xmlGameDetail.Attributes["name"]?.Value;
|
|
||||||
romObject.Size = UInt64.Parse(xmlGameDetail.Attributes["size"]?.Value);
|
|
||||||
romObject.Crc = xmlGameDetail.Attributes["crc"]?.Value;
|
|
||||||
romObject.Md5 = xmlGameDetail.Attributes["md5"]?.Value;
|
|
||||||
romObject.Sha1 = xmlGameDetail.Attributes["sha1"]?.Value;
|
|
||||||
|
|
||||||
gameObject.Roms.Add(romObject);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// search for existing gameObject to update
|
|
||||||
bool existingGameFound = false;
|
|
||||||
foreach (gaseous_identifier.classes.tosecXML.Game existingGame in tosecObject.Games)
|
|
||||||
{
|
|
||||||
if (existingGame.Name == gameObject.Name && existingGame.Year == gameObject.Year && existingGame.Publisher == gameObject.Publisher)
|
|
||||||
{
|
|
||||||
existingGame.Roms.AddRange(gameObject.Roms);
|
|
||||||
existingGameFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (existingGameFound == false)
|
|
||||||
{
|
|
||||||
tosecObject.Games.Add(gameObject);
|
|
||||||
GameCounter += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.Write(".");
|
Console.Write(".");
|
||||||
tosecLists.Add(tosecObject);
|
tosecLists.Add(tosecObject);
|
||||||
@@ -191,12 +71,12 @@ if (tosecXML != null && tosecXML.Length > 0)
|
|||||||
{
|
{
|
||||||
Console.WriteLine("TOSEC is disabled, title matching will be by file name only.");
|
Console.WriteLine("TOSEC is disabled, title matching will be by file name only.");
|
||||||
}
|
}
|
||||||
Console.WriteLine(tosecLists.Count + " TOSEC files loaded - " + GameCounter + " games cataloged");
|
Console.WriteLine(tosecLists.Count + " TOSEC files loaded");
|
||||||
|
|
||||||
if (tosecLists.Count > 0)
|
if (tosecLists.Count > 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine("TOSEC lists available:");
|
Console.WriteLine("TOSEC lists available:");
|
||||||
foreach (gaseous_identifier.classes.tosecXML tosecList in tosecLists)
|
foreach (gaseous_identifier.objects.RomSignatureObject tosecList in tosecLists)
|
||||||
{
|
{
|
||||||
Console.WriteLine(" * " + tosecList.Name);
|
Console.WriteLine(" * " + tosecList.Name);
|
||||||
}
|
}
|
||||||
@@ -219,11 +99,11 @@ foreach (string romFile in romPathContents)
|
|||||||
string sha1Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
|
string sha1Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
|
||||||
|
|
||||||
bool gameFound = false;
|
bool gameFound = false;
|
||||||
foreach (gaseous_identifier.classes.tosecXML tosecList in tosecLists)
|
foreach (gaseous_identifier.objects.RomSignatureObject tosecList in tosecLists)
|
||||||
{
|
{
|
||||||
foreach (gaseous_identifier.classes.tosecXML.Game gameObject in tosecList.Games)
|
foreach (gaseous_identifier.objects.RomSignatureObject.Game gameObject in tosecList.Games)
|
||||||
{
|
{
|
||||||
foreach (gaseous_identifier.classes.tosecXML.Game.Rom romObject in gameObject.Roms)
|
foreach (gaseous_identifier.objects.RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
||||||
{
|
{
|
||||||
if (md5Hash == romObject.Md5)
|
if (md5Hash == romObject.Md5)
|
||||||
{
|
{
|
||||||
|
9
gaseous-identifier/Support/Parsers/TOSEC/Copyright.txt
Normal file
9
gaseous-identifier/Support/Parsers/TOSEC/Copyright.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
CW,Cardware
|
||||||
|
CW-R,Cardware-Registered
|
||||||
|
FW,Freeware
|
||||||
|
GW,Giftware
|
||||||
|
GW-R,Giftware-Registered
|
||||||
|
LW,Licenceware
|
||||||
|
PD,Public Domain
|
||||||
|
SW,Shareware
|
||||||
|
SW-R,Shareware-Registered
|
68
gaseous-identifier/Support/Parsers/TOSEC/Country.txt
Normal file
68
gaseous-identifier/Support/Parsers/TOSEC/Country.txt
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
AE,United Arab Emirates
|
||||||
|
AL,Albania
|
||||||
|
AS,Asia
|
||||||
|
AT,Austria
|
||||||
|
AU,Australia
|
||||||
|
BA,Bosnia and Herzegovina
|
||||||
|
BE,Belgium
|
||||||
|
BG,Bulgaria
|
||||||
|
BR,Brazil
|
||||||
|
CA,Canada
|
||||||
|
CH,Switzerland
|
||||||
|
CL,Chile
|
||||||
|
CN,China
|
||||||
|
CS,Serbia and Montenegro
|
||||||
|
CY,Cyprus
|
||||||
|
CZ,Czech Republic
|
||||||
|
DE,Germany
|
||||||
|
DK,Denmark
|
||||||
|
EE,Estonia
|
||||||
|
EG,Egypt
|
||||||
|
ES,Spain
|
||||||
|
EU,Europe
|
||||||
|
FI,Finland
|
||||||
|
FR,France
|
||||||
|
GB,United Kingdom
|
||||||
|
GR,Greece
|
||||||
|
HK,Hong Kong
|
||||||
|
HR,Croatia
|
||||||
|
HU,Hungary
|
||||||
|
ID,Indonesia
|
||||||
|
IE,Ireland
|
||||||
|
IL,Israel
|
||||||
|
IN,India
|
||||||
|
IR,Iran
|
||||||
|
IS,Iceland
|
||||||
|
IT,Italy
|
||||||
|
JO,Jordan
|
||||||
|
JP,Japan
|
||||||
|
KR,South Korea
|
||||||
|
LT,Lithuania
|
||||||
|
LU,Luxembourg
|
||||||
|
LV,Latvia
|
||||||
|
MN,Mongolia
|
||||||
|
MX,Mexico
|
||||||
|
MY,Malaysia
|
||||||
|
NL,Netherlands
|
||||||
|
NO,Norway
|
||||||
|
NP,Nepal
|
||||||
|
NZ,New Zealand
|
||||||
|
OM,Oman
|
||||||
|
PE,Peru
|
||||||
|
PH,Philippines
|
||||||
|
PL,Poland
|
||||||
|
PT,Portugal
|
||||||
|
QA,Qatar
|
||||||
|
RO,Romania
|
||||||
|
RU,Russia
|
||||||
|
SE,Sweden
|
||||||
|
SG,Singapore
|
||||||
|
SI,Slovenia
|
||||||
|
SK,Slovakia
|
||||||
|
TH,Thailand
|
||||||
|
TR,Turkey
|
||||||
|
TW,Taiwan
|
||||||
|
US,United States
|
||||||
|
VN,Vietnam
|
||||||
|
YU,Yugoslavia
|
||||||
|
ZA,South Africa
|
@@ -0,0 +1,5 @@
|
|||||||
|
alpha,Early test build
|
||||||
|
beta,Later; feature complete test build
|
||||||
|
preview,Near complete build
|
||||||
|
pre-release,Near complete build
|
||||||
|
proto,Unreleased; prototype software
|
45
gaseous-identifier/Support/Parsers/TOSEC/Language.txt
Normal file
45
gaseous-identifier/Support/Parsers/TOSEC/Language.txt
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
ar,Arabic
|
||||||
|
bg,Bulgarian
|
||||||
|
bs,Bosnian
|
||||||
|
cs,Czech
|
||||||
|
cy,Welsh
|
||||||
|
da,Danish
|
||||||
|
de,German
|
||||||
|
el,Greek
|
||||||
|
en,English
|
||||||
|
eo,Esperanto
|
||||||
|
es,Spanish
|
||||||
|
et,Estonian
|
||||||
|
fa,Persian
|
||||||
|
fi,Finnish
|
||||||
|
fr,French
|
||||||
|
ga,Irish
|
||||||
|
gu,Gujarati
|
||||||
|
he,Hebrew
|
||||||
|
hi,Hindi
|
||||||
|
hr,Croatian
|
||||||
|
hu,Hungarian
|
||||||
|
is,Icelandic
|
||||||
|
it,Italian
|
||||||
|
ja,Japanese
|
||||||
|
ko,Korean
|
||||||
|
lt,Lithuanian
|
||||||
|
lv,Latvian
|
||||||
|
ms,Malay
|
||||||
|
nl,Dutch
|
||||||
|
no,Norwegian
|
||||||
|
pl,Polish
|
||||||
|
pt,Portuguese
|
||||||
|
ro,Romanian
|
||||||
|
ru,Russian
|
||||||
|
sk,Slovakian
|
||||||
|
sl,Slovenian
|
||||||
|
sq,Albanian
|
||||||
|
sr,Serbian
|
||||||
|
sv,Swedish
|
||||||
|
th,Thai
|
||||||
|
tr,Turkish
|
||||||
|
ur,Urdu
|
||||||
|
vi,Vietnamese
|
||||||
|
yi,Yiddish
|
||||||
|
zh,Chinese
|
57
gaseous-identifier/Support/Parsers/TOSEC/Systems.txt
Normal file
57
gaseous-identifier/Support/Parsers/TOSEC/Systems.txt
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
+2
|
||||||
|
+2a
|
||||||
|
+3
|
||||||
|
130XE
|
||||||
|
A1000
|
||||||
|
A1200
|
||||||
|
A1200-A4000
|
||||||
|
A2000
|
||||||
|
A2000-A3000
|
||||||
|
A2024
|
||||||
|
A2500-A3000UX
|
||||||
|
A3000
|
||||||
|
A4000
|
||||||
|
A4000T
|
||||||
|
A500
|
||||||
|
A500+
|
||||||
|
A500-A1000-A2000
|
||||||
|
A500-A1000-A2000-CDTV
|
||||||
|
A500-A1200
|
||||||
|
A500-A1200-A2000-A4000
|
||||||
|
A500-A2000
|
||||||
|
A500-A600-A2000
|
||||||
|
A570
|
||||||
|
A600
|
||||||
|
A600HD
|
||||||
|
AGA
|
||||||
|
AGA-CD32
|
||||||
|
Aladdin Deck Enhancer
|
||||||
|
CD32
|
||||||
|
CDTV
|
||||||
|
Computrainer
|
||||||
|
Doctor PC Jr.
|
||||||
|
ECS
|
||||||
|
ECS-AGA
|
||||||
|
Executive
|
||||||
|
Mega ST
|
||||||
|
Mega-STE
|
||||||
|
OCS
|
||||||
|
OCS-AGA
|
||||||
|
ORCH80
|
||||||
|
Osbourne 1
|
||||||
|
PIANO90
|
||||||
|
PlayChoice-10
|
||||||
|
Plus4
|
||||||
|
Primo-A
|
||||||
|
Primo-A64
|
||||||
|
Primo-B
|
||||||
|
Primo-B64
|
||||||
|
Pro-Primo
|
||||||
|
ST
|
||||||
|
STE
|
||||||
|
STE-Falcon
|
||||||
|
TT
|
||||||
|
TURBO-R GT
|
||||||
|
TURBO-R ST
|
||||||
|
VS DualSystem
|
||||||
|
VS UniSystem
|
13
gaseous-identifier/Support/Parsers/TOSEC/Video.txt
Normal file
13
gaseous-identifier/Support/Parsers/TOSEC/Video.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CGA
|
||||||
|
EGA
|
||||||
|
HGC
|
||||||
|
MCGA
|
||||||
|
MDA
|
||||||
|
NTSC
|
||||||
|
NTSC-PAL
|
||||||
|
PAL
|
||||||
|
PAL-60
|
||||||
|
PAL-NTSC
|
||||||
|
SVGA
|
||||||
|
VGA
|
||||||
|
XGA
|
@@ -1,55 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace gaseous_identifier.classes
|
|
||||||
{
|
|
||||||
public class tosecXML
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Description { get; set; }
|
|
||||||
public string Category { get; set; }
|
|
||||||
public string Version { get; set; }
|
|
||||||
public string Author { get; set; }
|
|
||||||
public string Email { get; set; }
|
|
||||||
public string Homepage { get; set; }
|
|
||||||
public Uri? Url { get; set; }
|
|
||||||
|
|
||||||
public List<Game> Games { get; set; }
|
|
||||||
|
|
||||||
public class Game
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Description { get; set; }
|
|
||||||
public string Year { get; set; }
|
|
||||||
public string Publisher { get; set; }
|
|
||||||
public List<Rom> Roms { get; set; }
|
|
||||||
|
|
||||||
public class Rom
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public UInt64 Size { get; set; }
|
|
||||||
public string Crc { get; set; }
|
|
||||||
public string Md5 { get; set; }
|
|
||||||
public string Sha1 { get; set; }
|
|
||||||
|
|
||||||
public string flags { get; set; }
|
|
||||||
|
|
||||||
public RomTypes RomType { get; set; }
|
|
||||||
public UInt16 DiskNumber { get; set; }
|
|
||||||
public string DiskSide { get; set; }
|
|
||||||
|
|
||||||
public enum RomTypes
|
|
||||||
{
|
|
||||||
Cartridge = 0,
|
|
||||||
Cassette = 1,
|
|
||||||
Floppy = 2,
|
|
||||||
CD = 3,
|
|
||||||
DVD = 4,
|
|
||||||
Unknown = 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -9,9 +9,29 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="classes\" />
|
<None Remove="Classes\" />
|
||||||
|
<None Remove="Support\" />
|
||||||
|
<None Remove="Support\Parsers\" />
|
||||||
|
<None Remove="Support\Parsers\TOSEC\" />
|
||||||
|
<None Remove="Support\Parsers\TOSEC\Systems.txt" />
|
||||||
|
<None Remove="Support\Parsers\TOSEC\Video.txt" />
|
||||||
|
<None Remove="Support\Parsers\TOSEC\Country.txt" />
|
||||||
|
<None Remove="Support\Parsers\TOSEC\Language.txt" />
|
||||||
|
<None Remove="Support\Parsers\TOSEC\Copyright.txt" />
|
||||||
|
<None Remove="Support\Parsers\TOSEC\DevelopmentStatus.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="classes\" />
|
<Folder Include="Classes\" />
|
||||||
|
<Folder Include="Support\" />
|
||||||
|
<Folder Include="Support\Parsers\" />
|
||||||
|
<Folder Include="Support\Parsers\TOSEC\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Support\Parsers\TOSEC\Systems.txt" />
|
||||||
|
<EmbeddedResource Include="Support\Parsers\TOSEC\Video.txt" />
|
||||||
|
<EmbeddedResource Include="Support\Parsers\TOSEC\Country.txt" />
|
||||||
|
<EmbeddedResource Include="Support\Parsers\TOSEC\Language.txt" />
|
||||||
|
<EmbeddedResource Include="Support\Parsers\TOSEC\Copyright.txt" />
|
||||||
|
<EmbeddedResource Include="Support\Parsers\TOSEC\DevelopmentStatus.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
Reference in New Issue
Block a user