chore: separated components into separate projects

This commit is contained in:
Michael Green
2023-02-22 21:09:13 +11:00
parent 44f1beaf69
commit e2e98ddc2a
14 changed files with 100 additions and 79 deletions

View File

@@ -0,0 +1,514 @@
using System;
using System.Xml;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using gaseous_romsignatureobject;
namespace gaseous_signature_parser.parsers
{
public class TosecParser
{
public RomSignatureObject Parse(string XMLFile)
{
// load resources
var assembly = Assembly.GetExecutingAssembly();
// load systems list
List<string> TOSECSystems = new List<string>();
var resourceName = "gaseous_signature_parser.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_signature_parser.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_signature_parser.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_signature_parser.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_signature_parser.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_signature_parser.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);
}
// get hashes of TOSEC file
var xmlStream = File.OpenRead(XMLFile);
var md5 = MD5.Create();
byte[] md5HashByte = md5.ComputeHash(xmlStream);
string md5Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
var sha1 = SHA1.Create();
byte[] sha1HashByte = sha1.ComputeHash(xmlStream);
string sha1Hash = BitConverter.ToString(sha1HashByte).Replace("-", "").ToLowerInvariant();
// load TOSEC file
XmlDocument tosecXmlDoc = new XmlDocument();
tosecXmlDoc.Load(XMLFile);
RomSignatureObject tosecObject = new RomSignatureObject();
// get header
XmlNode xmlHeader = tosecXmlDoc.DocumentElement.SelectSingleNode("/datafile/header");
tosecObject.SourceType = "TOSEC";
tosecObject.SourceMd5 = md5Hash;
tosecObject.SourceSHA1 = sha1Hash;
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<RomSignatureObject.Game>();
XmlNodeList xmlGames = tosecXmlDoc.DocumentElement.SelectNodes("/datafile/game");
foreach (XmlNode xmlGame in xmlGames)
{
RomSignatureObject.Game gameObject = new RomSignatureObject.Game();
// parse game name
string[] gameNameTitleParts = xmlGame.Attributes["name"].Value.Split("[");
string gameName = gameNameTitleParts[0];
// before split, save and remove the demo tag if present
if (gameName.Contains("(demo) ", StringComparison.CurrentCulture))
{
gameObject.Demo = RomSignatureObject.Game.DemoTypes.demo;
gameName = gameName.Replace("(demo) ", "");
}
else if (gameName.Contains("(demo-kiosk) ", StringComparison.CurrentCulture))
{
gameObject.Demo = RomSignatureObject.Game.DemoTypes.demo_kiosk;
gameName = gameName.Replace("(demo-kiosk) ", "");
}
else if (gameName.Contains("(demo-playable) ", StringComparison.CurrentCulture))
{
gameObject.Demo = RomSignatureObject.Game.DemoTypes.demo_playable;
gameName = gameName.Replace("(demo-playable) ", "");
}
else if (gameName.Contains("(demo-rolling) ", StringComparison.CurrentCulture))
{
gameObject.Demo = RomSignatureObject.Game.DemoTypes.demo_rolling;
gameName = gameName.Replace("(demo-rolling) ", "");
}
else if (gameName.Contains("(demo-slideshow) ", StringComparison.CurrentCulture))
{
gameObject.Demo = RomSignatureObject.Game.DemoTypes.demo_slideshow;
gameName = gameName.Replace("(demo-slideshow) ", "");
}
else
{
gameObject.Demo = 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)
{
bool dateFound = false;
// verify the value
string dateToken = gameNameTokens[1].Replace(")", "");
if (dateToken.Length >= 4)
{
// test for possible year values
// first up - centuries
if (dateToken == "19xx" || dateToken == "20xx")
{
// date is a century
gameObject.Year = dateToken;
dateFound = true;
} else
{
// check for decades
for (UInt16 i = 0; i < 10; i++)
{
if (dateToken == "19" + i + "x" || dateToken == "20" + i + "x")
{
// date is a decade
gameObject.Year = dateToken;
dateFound = true;
break;
}
}
if (dateFound == false)
{
// check if the year is a four digit number
DateTime dateTime = new DateTime();
if (DateTime.TryParse(string.Format("1/1/{0}", dateToken), out dateTime))
{
// is a valid year!
gameObject.Year = dateToken;
dateFound = true;
}
// if we still haven't found a valid date, check if the whole string is a valid date object
if (dateFound == false)
{
if (DateTime.TryParse(dateToken, out dateTime))
{
// is a valid year!
gameObject.Year = dateToken;
dateFound = true;
}
}
// if we still haven't found a valid date, check if the whole string is a valid date object, but with x's
// example: 19xx-12-2x
if (dateFound == false)
{
if (DateTime.TryParse(dateToken.Replace("x", "0"), out dateTime))
{
// is a valid year!
gameObject.Year = dateToken;
dateFound = true;
}
}
// if we still haven't found a valid date, perhaps it a year and month?
// example: 19xx-12
if (dateFound == false)
{
if (DateTime.TryParse(dateToken.Replace("x", "0") + "-01", out dateTime))
{
// is a valid year!
gameObject.Year = dateToken;
dateFound = true;
}
}
}
}
}
}
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 = token;
}
// check for language
if (TOSECLanguage.ContainsKey(token))
{
gameObject.Language = token;
}
// check for copyright
if (TOSECCopyright.ContainsKey(token))
{
gameObject.Copyright = token;
}
}
}
StartToken += 1;
}
gameObject.Roms = new List<RomSignatureObject.Game.Rom>();
// get the roms
string romDescription = "";
foreach (XmlNode xmlGameDetail in xmlGame.ChildNodes)
{
switch (xmlGameDetail.Name.ToLower())
{
case "description":
romDescription = xmlGameDetail.InnerText;
break;
case "rom":
RomSignatureObject.Game.Rom romObject = new 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 = romDescription.Split("(");
foreach (string rawToken in romNameTokens) {
string[] tokenSplit = rawToken.Split("[");
// replace the extra closing bracket
string token = tokenSplit[0].Replace(")", "").Trim();
// check for copyright
if (TOSECDevelopment.ContainsKey(token))
{
romObject.DevelopmentStatus = token;
}
// 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 = RomSignatureObject.Game.Rom.RomTypes.Disc;
break;
case "Disk":
romObject.RomType = RomSignatureObject.Game.Rom.RomTypes.Disk;
break;
case "File":
romObject.RomType = RomSignatureObject.Game.Rom.RomTypes.File;
break;
case "Part":
romObject.RomType = RomSignatureObject.Game.Rom.RomTypes.Part;
break;
case "Side":
romObject.RomType = RomSignatureObject.Game.Rom.RomTypes.Side;
break;
case "Tape":
romObject.RomType = RomSignatureObject.Game.Rom.RomTypes.Tape;
break;
}
romObject.RomTypeMedia = token;
}
// check for media label
if (token.Length > 0 &&
(token + ")") == gameNameTokens.Last() &&
(
token != romObject.RomTypeMedia &&
token != gameObject.Publisher &&
token != gameObject.SystemVariant &&
token != gameObject.Video &&
token != gameObject.Country &&
token != gameObject.Copyright &&
token != gameObject.Language &&
token != romObject.DevelopmentStatus
)
)
{
// likely the media label?
romObject.MediaLabel = token;
}
// process dump flags
if (rawToken.IndexOf("[") > 0)
{
// has dump flags
string rawDumpFlags = rawToken.Substring(rawToken.IndexOf("["));
string[] dumpFlags = rawDumpFlags.Split("[");
foreach (string dumpFlag in dumpFlags)
{
string dToken = dumpFlag.Replace("]", "");
if (dToken.Length > 0)
{
string[] dTokenCompare = dToken.Split(" ");
if (dTokenCompare[0].Trim().ToLower().StartsWith("a"))
{
romObject.flags.Add(dTokenCompare[0].Trim());
}
else
{
switch (dTokenCompare[0].Trim().ToLower())
{
case "cr":
// cracked
case "f":
// fixed
case "h":
// hacked
case "m":
// modified
case "p":
// pirated
case "t":
// trained
case "tr":
// translated
case "o":
// overdump
case "u":
// underdump
case "v":
// virus
case "b":
// bad dump
case "a":
// alternate
case "!":
// known verified dump
// -------------------
romObject.flags.Add(dToken);
break;
}
}
}
}
}
}
gameObject.Roms.Add(romObject);
break;
}
}
// search for existing gameObject to update
bool existingGameFound = false;
foreach (RomSignatureObject.Game existingGame in tosecObject.Games)
{
if (existingGame.Name == gameObject.Name &&
existingGame.Year == gameObject.Year &&
existingGame.Publisher == gameObject.Publisher &&
existingGame.Country == gameObject.Country &&
existingGame.Language == gameObject.Language)
{
existingGame.Roms.AddRange(gameObject.Roms);
existingGameFound = true;
break;
}
}
if (existingGameFound == false)
{
tosecObject.Games.Add(gameObject);
}
}
return tosecObject;
}
}
}

View 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

View 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

View File

@@ -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

View 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

View 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

View File

@@ -0,0 +1,13 @@
CGA
EGA
HGC
MCGA
MDA
NTSC
NTSC-PAL
PAL
PAL-60
PAL-NTSC
SVGA
VGA
XGA

View File

@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>gaseous_signature_parser</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<None Remove="Support\Parsers\TOSEC\Copyright.txt" />
<None Remove="Support\Parsers\TOSEC\Country.txt" />
<None Remove="Support\Parsers\TOSEC\DevelopmentStatus.txt" />
<None Remove="Support\Parsers\TOSEC\Language.txt" />
<None Remove="Support\Parsers\TOSEC\Systems.txt" />
<None Remove="Support\Parsers\TOSEC\Video.txt" />
<None Remove="Support\" />
<None Remove="Classes\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Support\Parsers\TOSEC\Copyright.txt" />
<EmbeddedResource Include="Support\Parsers\TOSEC\Country.txt" />
<EmbeddedResource Include="Support\Parsers\TOSEC\DevelopmentStatus.txt" />
<EmbeddedResource Include="Support\Parsers\TOSEC\Language.txt" />
<EmbeddedResource Include="Support\Parsers\TOSEC\Systems.txt" />
<EmbeddedResource Include="Support\Parsers\TOSEC\Video.txt" />
</ItemGroup>
<ItemGroup>
<Folder Include="Support\" />
<Folder Include="Classes\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\gaseous-romsignatureobject\gaseous-romsignatureobject.csproj" />
</ItemGroup>
</Project>