11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "nuget" # See documentation for possible values
|
||||||
|
directory: "/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
35
.vscode/launch.json
vendored
Normal file
35
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
|
// Use hover for the description of the existing attributes
|
||||||
|
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||||
|
"name": ".NET Core Launch (web)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
|
"program": "${workspaceFolder}/gaseous-server/bin/Debug/net7.0/gaseous-server.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/gaseous-server",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"sourceFileMap": {
|
||||||
|
"/Views": "${workspaceFolder}/Views"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
41
.vscode/tasks.json
vendored
Normal file
41
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/gaseous-server/gaseous-server.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/gaseous-server/gaseous-server.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run",
|
||||||
|
"--project",
|
||||||
|
"${workspaceFolder}/gaseous-server/gaseous-server.csproj"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
48
Gaseous.sln
48
Gaseous.sln
@@ -1,9 +1,21 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 25.0.1704.4
|
VisualStudioVersion = 25.0.1704.4
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-identifier", "gaseous-identifier\gaseous-identifier.csproj", "{F5C42134-5372-430A-A9AE-1871981850DB}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-identifier-testapp", "gaseous-identifier\gaseous-identifier-testapp.csproj", "{F5C42134-5372-430A-A9AE-1871981850DB}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-signature-parser", "gaseous-signature-parser\gaseous-signature-parser.csproj", "{DAEBBB82-5051-43FD-A406-F9D64A38F468}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-romsignatureobject", "gaseous-romsignatureobject\gaseous-romsignatureobject.csproj", "{9DCD243D-37CE-4562-8411-B5242B687D4F}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-signature-ingestor", "gaseous-signature-ingestor\gaseous-signature-ingestor.csproj", "{86DF6E45-2C2B-4C30-AEC1-E7EF8C5CEA7D}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-tools", "gaseous-tools\gaseous-tools.csproj", "{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-server", "gaseous-server\gaseous-server.csproj", "{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{B07A4655-A003-416B-A790-ADAA5B548E1A}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -15,6 +27,38 @@ Global
|
|||||||
{F5C42134-5372-430A-A9AE-1871981850DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F5C42134-5372-430A-A9AE-1871981850DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{F5C42134-5372-430A-A9AE-1871981850DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F5C42134-5372-430A-A9AE-1871981850DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F5C42134-5372-430A-A9AE-1871981850DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
{F5C42134-5372-430A-A9AE-1871981850DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{08699C93-15CD-4E39-9053-D3C8056CE938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{08699C93-15CD-4E39-9053-D3C8056CE938}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{08699C93-15CD-4E39-9053-D3C8056CE938}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{08699C93-15CD-4E39-9053-D3C8056CE938}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{DAEBBB82-5051-43FD-A406-F9D64A38F468}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DAEBBB82-5051-43FD-A406-F9D64A38F468}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DAEBBB82-5051-43FD-A406-F9D64A38F468}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DAEBBB82-5051-43FD-A406-F9D64A38F468}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9DCD243D-37CE-4562-8411-B5242B687D4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9DCD243D-37CE-4562-8411-B5242B687D4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9DCD243D-37CE-4562-8411-B5242B687D4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9DCD243D-37CE-4562-8411-B5242B687D4F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{86DF6E45-2C2B-4C30-AEC1-E7EF8C5CEA7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{86DF6E45-2C2B-4C30-AEC1-E7EF8C5CEA7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{86DF6E45-2C2B-4C30-AEC1-E7EF8C5CEA7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{86DF6E45-2C2B-4C30-AEC1-E7EF8C5CEA7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@@ -3,6 +3,9 @@ using System.Security.Cryptography;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using gaseous_romsignatureobject;
|
||||||
|
using gaseous_signature_parser.parsers;
|
||||||
|
|
||||||
string[] commandLineArgs = Environment.GetCommandLineArgs();
|
string[] commandLineArgs = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
@@ -49,9 +52,10 @@ foreach (string commandLineArg in commandLineArgs)
|
|||||||
scanPath = Path.GetFullPath(scanPath);
|
scanPath = Path.GetFullPath(scanPath);
|
||||||
Console.WriteLine("ROM search path: " + scanPath);
|
Console.WriteLine("ROM search path: " + scanPath);
|
||||||
|
|
||||||
System.Collections.ArrayList TOSEC = new System.Collections.ArrayList();
|
List<RomSignatureObject> romSignatures = new List<RomSignatureObject>();
|
||||||
List<gaseous_identifier.classes.tosecXML> tosecLists = new List<gaseous_identifier.classes.tosecXML>();
|
System.Collections.ArrayList availablePlatforms = new System.Collections.ArrayList();
|
||||||
UInt32 GameCounter = 0;
|
|
||||||
|
// load TOSEC XML files
|
||||||
if (tosecXML != null && tosecXML.Length > 0)
|
if (tosecXML != null && tosecXML.Length > 0)
|
||||||
{
|
{
|
||||||
tosecXML = Path.GetFullPath(tosecXML);
|
tosecXML = Path.GetFullPath(tosecXML);
|
||||||
@@ -59,146 +63,43 @@ if (tosecXML != null && tosecXML.Length > 0)
|
|||||||
Console.WriteLine("TOSEC XML search path: " + tosecXML);
|
Console.WriteLine("TOSEC XML search path: " + tosecXML);
|
||||||
|
|
||||||
string[] tosecPathContents = Directory.GetFiles(tosecXML);
|
string[] tosecPathContents = Directory.GetFiles(tosecXML);
|
||||||
foreach (string tosecXMLFile in tosecPathContents)
|
int lastCLILineLength = 0;
|
||||||
|
for (UInt16 i = 0; i < tosecPathContents.Length; ++i)
|
||||||
{
|
{
|
||||||
XmlDocument tosecXmlDoc = new XmlDocument();
|
string tosecXMLFile = tosecPathContents[i];
|
||||||
tosecXmlDoc.Load(tosecXMLFile);
|
|
||||||
|
|
||||||
gaseous_identifier.classes.tosecXML tosecObject = new gaseous_identifier.classes.tosecXML();
|
TosecParser tosecParser = new TosecParser();
|
||||||
|
RomSignatureObject tosecObject = tosecParser.Parse(tosecXMLFile);
|
||||||
|
|
||||||
// get header
|
string statusOutput = i + " / " + tosecPathContents.Length + " : " + Path.GetFileName(tosecXMLFile);
|
||||||
XmlNode xmlHeader = tosecXmlDoc.DocumentElement.SelectSingleNode("/datafile/header");
|
Console.Write("\r " + statusOutput.PadRight(lastCLILineLength, ' ') + "\r");
|
||||||
foreach (XmlNode childNode in xmlHeader.ChildNodes)
|
lastCLILineLength = statusOutput.Length;
|
||||||
|
|
||||||
|
foreach (RomSignatureObject.Game gameRom in tosecObject.Games)
|
||||||
{
|
{
|
||||||
switch (childNode.Name.ToLower())
|
if (!availablePlatforms.Contains(gameRom.System))
|
||||||
{
|
{
|
||||||
case "name":
|
availablePlatforms.Add(gameRom.System);
|
||||||
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
|
romSignatures.Add(tosecObject);
|
||||||
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(".");
|
|
||||||
tosecLists.Add(tosecObject);
|
|
||||||
}
|
}
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
Console.WriteLine("TOSEC is disabled, title matching will be by file name only.");
|
Console.WriteLine("TOSEC is disabled.");
|
||||||
}
|
}
|
||||||
Console.WriteLine(tosecLists.Count + " TOSEC files loaded - " + GameCounter + " games cataloged");
|
Console.WriteLine(romSignatures.Count + " TOSEC files loaded");
|
||||||
|
|
||||||
if (tosecLists.Count > 0)
|
// Summarise signatures
|
||||||
|
if (availablePlatforms.Count > 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine("TOSEC lists available:");
|
availablePlatforms.Sort();
|
||||||
foreach (gaseous_identifier.classes.tosecXML tosecList in tosecLists)
|
Console.WriteLine("Platforms loaded:");
|
||||||
|
foreach (string platform in availablePlatforms)
|
||||||
{
|
{
|
||||||
Console.WriteLine(" * " + tosecList.Name);
|
Console.WriteLine(" * " + platform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,20 +117,43 @@ foreach (string romFile in romPathContents)
|
|||||||
|
|
||||||
var sha1 = SHA1.Create();
|
var sha1 = SHA1.Create();
|
||||||
byte[] sha1HashByte = sha1.ComputeHash(stream);
|
byte[] sha1HashByte = sha1.ComputeHash(stream);
|
||||||
string sha1Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
|
string sha1Hash = BitConverter.ToString(sha1HashByte).Replace("-", "").ToLowerInvariant();
|
||||||
|
|
||||||
bool gameFound = false;
|
bool gameFound = false;
|
||||||
foreach (gaseous_identifier.classes.tosecXML tosecList in tosecLists)
|
foreach (RomSignatureObject tosecList in romSignatures)
|
||||||
{
|
{
|
||||||
foreach (gaseous_identifier.classes.tosecXML.Game gameObject in tosecList.Games)
|
foreach (RomSignatureObject.Game gameObject in tosecList.Games)
|
||||||
{
|
{
|
||||||
foreach (gaseous_identifier.classes.tosecXML.Game.Rom romObject in gameObject.Roms)
|
foreach (RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
||||||
{
|
{
|
||||||
if (md5Hash == romObject.Md5)
|
if (romObject.Md5 != null)
|
||||||
|
{
|
||||||
|
if (md5Hash == romObject.Md5.ToLowerInvariant())
|
||||||
|
{
|
||||||
|
// match
|
||||||
|
gameFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (romObject.Sha1 != null)
|
||||||
|
{
|
||||||
|
if (md5Hash == romObject.Sha1.ToLowerInvariant())
|
||||||
|
{
|
||||||
|
// match
|
||||||
|
gameFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gameFound == true)
|
||||||
{
|
{
|
||||||
// match
|
|
||||||
gameFound = true;
|
|
||||||
Console.WriteLine(romObject.Name);
|
Console.WriteLine(romObject.Name);
|
||||||
|
|
||||||
|
RomSignatureObject.Game gameSignature = gameObject;
|
||||||
|
gameSignature.Roms.Clear();
|
||||||
|
gameSignature.Roms.Add(romObject);
|
||||||
|
|
||||||
|
var jsonSerializerSettings = new JsonSerializerSettings();
|
||||||
|
jsonSerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||||
|
jsonSerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||||
|
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(gameSignature, Newtonsoft.Json.Formatting.Indented, jsonSerializerSettings));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,3 +166,18 @@ foreach (string romFile in romPathContents)
|
|||||||
Console.WriteLine("File not found in TOSEC library");
|
Console.WriteLine("File not found in TOSEC library");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string SearchTitle = "California Games";
|
||||||
|
foreach (RomSignatureObject romSignatureObject in romSignatures)
|
||||||
|
{
|
||||||
|
foreach (RomSignatureObject.Game gameObject in romSignatureObject.Games)
|
||||||
|
{
|
||||||
|
if (gameObject.Name == SearchTitle)
|
||||||
|
{
|
||||||
|
var jsonSerializerSettings = new JsonSerializerSettings();
|
||||||
|
jsonSerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||||
|
jsonSerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||||
|
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(gameObject, Newtonsoft.Json.Formatting.Indented, jsonSerializerSettings));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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,13 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="classes\" />
|
<None Remove="Newtonsoft.Json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="classes\" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\gaseous-romsignatureobject\gaseous-romsignatureobject.csproj" />
|
||||||
|
<ProjectReference Include="..\gaseous-signature-parser\gaseous-signature-parser.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
117
gaseous-romsignatureobject/RomSignatureObject.cs
Normal file
117
gaseous-romsignatureobject/RomSignatureObject.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace gaseous_romsignatureobject
|
||||||
|
{
|
||||||
|
/// <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 string? SourceType { get; set; }
|
||||||
|
public string SourceMd5 { get; set; } = "";
|
||||||
|
public string SourceSHA1 { get; set; } = "";
|
||||||
|
|
||||||
|
public List<Game> Games { get; set; } = new List<Game>();
|
||||||
|
|
||||||
|
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 string? Country { get; set; }
|
||||||
|
public string? Language { get; set; }
|
||||||
|
public string? Copyright { get; set; }
|
||||||
|
public List<Rom> Roms { get; set; } = new List<Rom>();
|
||||||
|
public int RomCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Roms.Count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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? DevelopmentStatus { get; set; }
|
||||||
|
|
||||||
|
public List<string> flags { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
13
gaseous-romsignatureobject/gaseous-romsignatureobject.csproj
Normal file
13
gaseous-romsignatureobject/gaseous-romsignatureobject.csproj
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<RootNamespace>gaseous_romsignatureobject</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
92
gaseous-server/Controllers/SignaturesController.cs
Normal file
92
gaseous-server/Controllers/SignaturesController.cs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using gaseous_tools;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
||||||
|
|
||||||
|
namespace gaseous_server.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
public class SignaturesController : ControllerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get the current signature counts from the database
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Number of sources, publishers, games, and rom signatures in the database</returns>
|
||||||
|
[HttpGet]
|
||||||
|
public Models.Signatures_Status Status()
|
||||||
|
{
|
||||||
|
return new Models.Signatures_Status();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
public List<Models.Signatures_Games> GetSignature(string md5 = "", string sha1 = "")
|
||||||
|
{
|
||||||
|
if (md5.Length > 0)
|
||||||
|
{
|
||||||
|
return _GetSignature("signatures_roms.md5 = @searchstring", md5);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return _GetSignature("signatures_roms.sha1 = @searchstring", sha1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Models.Signatures_Games> _GetSignature(string sqlWhere, string searchString)
|
||||||
|
{
|
||||||
|
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT \n view_signatures_games.*,\n signatures_roms.id AS romid,\n signatures_roms.name AS romname,\n signatures_roms.size,\n signatures_roms.crc,\n signatures_roms.md5,\n signatures_roms.sha1,\n signatures_roms.developmentstatus,\n signatures_roms.flags,\n signatures_roms.romtype,\n signatures_roms.romtypemedia,\n signatures_roms.medialabel\nFROM\n signatures_roms\n INNER JOIN\n view_signatures_games ON signatures_roms.gameid = view_signatures_games.id WHERE " + sqlWhere;
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("searchString", searchString);
|
||||||
|
|
||||||
|
DataTable sigDb = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
List<Models.Signatures_Games> GamesList = new List<Models.Signatures_Games>();
|
||||||
|
|
||||||
|
foreach (DataRow sigDbRow in sigDb.Rows)
|
||||||
|
{
|
||||||
|
Models.Signatures_Games gameItem = new Models.Signatures_Games
|
||||||
|
{
|
||||||
|
Game = new Models.Signatures_Games.GameItem
|
||||||
|
{
|
||||||
|
Id = (Int32)sigDbRow["id"],
|
||||||
|
Name = (string)sigDbRow["name"],
|
||||||
|
Description = (string)sigDbRow["description"],
|
||||||
|
Year = (string)sigDbRow["year"],
|
||||||
|
Publisher = (string)sigDbRow["publisher"],
|
||||||
|
Demo = (Models.Signatures_Games.GameItem.DemoTypes)(int)sigDbRow["demo"],
|
||||||
|
System = (string)sigDbRow["platform"],
|
||||||
|
SystemVariant = (string)sigDbRow["systemvariant"],
|
||||||
|
Video = (string)sigDbRow["video"],
|
||||||
|
Country = (string)sigDbRow["country"],
|
||||||
|
Language = (string)sigDbRow["language"],
|
||||||
|
Copyright = (string)sigDbRow["copyright"]
|
||||||
|
},
|
||||||
|
Rom = new Models.Signatures_Games.RomItem
|
||||||
|
{
|
||||||
|
Id = (Int32)sigDbRow["romid"],
|
||||||
|
Name = (string)sigDbRow["romname"],
|
||||||
|
Size = (Int64)sigDbRow["size"],
|
||||||
|
Crc = (string)sigDbRow["crc"],
|
||||||
|
Md5 = (string)sigDbRow["md5"],
|
||||||
|
Sha1 = (string)sigDbRow["sha1"],
|
||||||
|
DevelopmentStatus = (string)sigDbRow["developmentstatus"],
|
||||||
|
flags = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>((string)sigDbRow["flags"]),
|
||||||
|
RomType = (Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["romtype"],
|
||||||
|
RomTypeMedia = (string)sigDbRow["romtypemedia"],
|
||||||
|
MediaLabel = (string)sigDbRow["medialabel"]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
GamesList.Add(gameItem);
|
||||||
|
}
|
||||||
|
return GamesList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
98
gaseous-server/Models/Signatures_Games.cs
Normal file
98
gaseous-server/Models/Signatures_Games.cs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
using static gaseous_romsignatureobject.RomSignatureObject.Game;
|
||||||
|
|
||||||
|
namespace gaseous_server.Models
|
||||||
|
{
|
||||||
|
public class Signatures_Games
|
||||||
|
{
|
||||||
|
public Signatures_Games()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameItem? Game { get; set; }
|
||||||
|
public RomItem? Rom { get; set; }
|
||||||
|
|
||||||
|
public class GameItem
|
||||||
|
{
|
||||||
|
public Int32? Id { get; set; }
|
||||||
|
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 string? Country { get; set; }
|
||||||
|
public string? Language { get; set; }
|
||||||
|
public string? Copyright { get; set; }
|
||||||
|
|
||||||
|
public enum DemoTypes
|
||||||
|
{
|
||||||
|
NotDemo = 0,
|
||||||
|
demo = 1,
|
||||||
|
demo_kiosk = 2,
|
||||||
|
demo_playable = 3,
|
||||||
|
demo_rolling = 4,
|
||||||
|
demo_slideshow = 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RomItem
|
||||||
|
{
|
||||||
|
public Int32? Id { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public Int64? Size { get; set; }
|
||||||
|
public string? Crc { get; set; }
|
||||||
|
public string? Md5 { get; set; }
|
||||||
|
public string? Sha1 { get; set; }
|
||||||
|
|
||||||
|
public string? DevelopmentStatus { get; set; }
|
||||||
|
|
||||||
|
public List<string> flags { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
63
gaseous-server/Models/Signatures_Status.cs
Normal file
63
gaseous-server/Models/Signatures_Status.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using gaseous_tools;
|
||||||
|
|
||||||
|
namespace gaseous_server.Models
|
||||||
|
{
|
||||||
|
public class Signatures_Status
|
||||||
|
{
|
||||||
|
|
||||||
|
private Int64 _SourceCount = 0;
|
||||||
|
private Int64 _PlatformCount = 0;
|
||||||
|
private Int64 _GameCount = 0;
|
||||||
|
private Int64 _RomCount = 0;
|
||||||
|
|
||||||
|
public Signatures_Status()
|
||||||
|
{
|
||||||
|
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "select (select count(*) from signatures_sources) as SourceCount, (select count(*) from signatures_platforms) as PlatformCount, (select count(*) from signatures_games) as GameCount, (select count(*) from signatures_roms) as RomCount;";
|
||||||
|
|
||||||
|
DataTable sigDb = db.ExecuteCMD(sql);
|
||||||
|
if (sigDb.Rows.Count > 0)
|
||||||
|
{
|
||||||
|
_SourceCount = (Int64)sigDb.Rows[0]["SourceCount"];
|
||||||
|
_PlatformCount = (Int64)sigDb.Rows[0]["PlatformCount"];
|
||||||
|
_GameCount = (Int64)sigDb.Rows[0]["GameCount"];
|
||||||
|
_RomCount = (Int64)sigDb.Rows[0]["RomCount"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Int64 Sources
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _SourceCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Int64 Platforms
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _PlatformCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Int64 Games
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _GameCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Int64 Roms
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _RomCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
38
gaseous-server/Program.cs
Normal file
38
gaseous-server/Program.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using gaseous_tools;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
|
||||||
|
builder.Services.AddControllers().AddJsonOptions(x =>
|
||||||
|
{
|
||||||
|
// serialize enums as strings in api responses (e.g. Role)
|
||||||
|
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||||
|
});
|
||||||
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
// set up db
|
||||||
|
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
db.InitDB();
|
||||||
|
|
||||||
|
// start the app
|
||||||
|
app.Run();
|
||||||
|
|
41
gaseous-server/Properties/launchSettings.json
Normal file
41
gaseous-server/Properties/launchSettings.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:38715",
|
||||||
|
"sslPort": 44314
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5198",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7282;http://localhost:5198",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
gaseous-server/appsettings.Development.json
Normal file
9
gaseous-server/appsettings.Development.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
10
gaseous-server/appsettings.json
Normal file
10
gaseous-server/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
|
|
34
gaseous-server/gaseous-server.csproj
Normal file
34
gaseous-server/gaseous-server.csproj
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<RootNamespace>gaseous_server</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(RunConfiguration)' == 'https' " />
|
||||||
|
<PropertyGroup Condition=" '$(RunConfiguration)' == 'http' " />
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.3" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\gaseous-tools\gaseous-tools.csproj">
|
||||||
|
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\gaseous-romsignatureobject\gaseous-romsignatureobject.csproj">
|
||||||
|
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Controllers\" />
|
||||||
|
<None Remove="Models\" />
|
||||||
|
<None Remove="Models\Signatures.Status" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Controllers\" />
|
||||||
|
<Folder Include="Models\" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
284
gaseous-signature-ingestor/Program.cs
Normal file
284
gaseous-signature-ingestor/Program.cs
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
using gaseous_romsignatureobject;
|
||||||
|
using gaseous_signature_parser.parsers;
|
||||||
|
using gaseous_tools;
|
||||||
|
using MySqlX.XDevAPI;
|
||||||
|
|
||||||
|
// process command line
|
||||||
|
string[] commandLineArgs = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
|
string tosecXML = "";
|
||||||
|
bool showGames = false;
|
||||||
|
string inArgument = "";
|
||||||
|
foreach (string commandLineArg in commandLineArgs)
|
||||||
|
{
|
||||||
|
if (commandLineArg != commandLineArgs[0])
|
||||||
|
{
|
||||||
|
if (inArgument == "")
|
||||||
|
{
|
||||||
|
switch (commandLineArg.ToLower())
|
||||||
|
{
|
||||||
|
case "-tosecpath":
|
||||||
|
inArgument = commandLineArg.ToLower();
|
||||||
|
break;
|
||||||
|
case "-showgames":
|
||||||
|
showGames = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (inArgument)
|
||||||
|
{
|
||||||
|
case "-tosecpath":
|
||||||
|
tosecXML = commandLineArg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inArgument = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if Config.ConfigurationPath is valid and create it if not
|
||||||
|
if (!Directory.Exists(Config.ConfigurationPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Config.ConfigurationPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect to database
|
||||||
|
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
// initialise the db
|
||||||
|
db.InitDB();
|
||||||
|
|
||||||
|
// process provided files
|
||||||
|
Console.WriteLine("Processing input files:");
|
||||||
|
if (Directory.Exists(tosecXML))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Processing TOSEC data files", ConsoleColor.Green);
|
||||||
|
Console.WriteLine("");
|
||||||
|
Console.WriteLine("");
|
||||||
|
|
||||||
|
tosecXML = Path.GetFullPath(tosecXML);
|
||||||
|
string[] tosecPathContents = Directory.GetFiles(tosecXML);
|
||||||
|
int lineFileNameLength = 0;
|
||||||
|
int lineGameNameLength = 0;
|
||||||
|
|
||||||
|
string sql = "";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
System.Data.DataTable sigDB;
|
||||||
|
|
||||||
|
for (UInt16 i = 0; i < tosecPathContents.Length; ++i)
|
||||||
|
{
|
||||||
|
string tosecXMLFile = tosecPathContents[i];
|
||||||
|
|
||||||
|
string statusOutput = (i + 1).ToString().PadLeft(7, ' ') + " / " + tosecPathContents.Length.ToString().PadLeft(7, ' ') + " : " + Path.GetFileName(tosecXMLFile);
|
||||||
|
Console.SetCursorPosition(0, Console.CursorTop - 2);
|
||||||
|
Console.WriteLine("\r " + statusOutput.PadRight(lineFileNameLength, ' ') + "\r");
|
||||||
|
lineFileNameLength = statusOutput.Length;
|
||||||
|
|
||||||
|
// check tosec file md5
|
||||||
|
Console.WriteLine(" ==> Checking input file ");
|
||||||
|
Common.hashObject hashObject = new Common.hashObject(tosecXMLFile);
|
||||||
|
sql = "SELECT * FROM signatures_sources WHERE sourcemd5=@sourcemd5";
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("sourcemd5", hashObject.md5hash);
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// start parsing file
|
||||||
|
Console.SetCursorPosition(0, Console.CursorTop - 1);
|
||||||
|
Console.WriteLine(" ==> Parsing file ");
|
||||||
|
TosecParser tosecParser = new TosecParser();
|
||||||
|
RomSignatureObject tosecObject = tosecParser.Parse(tosecXMLFile);
|
||||||
|
|
||||||
|
// store in database
|
||||||
|
|
||||||
|
// store source object
|
||||||
|
bool processGames = false;
|
||||||
|
if (tosecObject.SourceMd5 != null)
|
||||||
|
{
|
||||||
|
Console.SetCursorPosition(0, Console.CursorTop - 1);
|
||||||
|
Console.WriteLine(" ==> Storing file in database ");
|
||||||
|
|
||||||
|
sql = "SELECT * FROM signatures_sources WHERE sourcemd5=@sourcemd5";
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(tosecObject.Name, ""));
|
||||||
|
dbDict.Add("description", Common.ReturnValueIfNull(tosecObject.Description, ""));
|
||||||
|
dbDict.Add("category", Common.ReturnValueIfNull(tosecObject.Category, ""));
|
||||||
|
dbDict.Add("version", Common.ReturnValueIfNull(tosecObject.Version, ""));
|
||||||
|
dbDict.Add("author", Common.ReturnValueIfNull(tosecObject.Author, ""));
|
||||||
|
dbDict.Add("email", Common.ReturnValueIfNull(tosecObject.Email, ""));
|
||||||
|
dbDict.Add("homepage", Common.ReturnValueIfNull(tosecObject.Homepage, ""));
|
||||||
|
dbDict.Add("uri", Common.ReturnValueIfNull(tosecObject.Url, ""));
|
||||||
|
dbDict.Add("sourcetype", Common.ReturnValueIfNull(tosecObject.SourceType, ""));
|
||||||
|
dbDict.Add("sourcemd5", tosecObject.SourceMd5);
|
||||||
|
dbDict.Add("sourcesha1", tosecObject.SourceSHA1);
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO signatures_sources (name, description, category, version, author, email, homepage, url, sourcetype, sourcemd5, sourcesha1) VALUES (@name, @description, @category, @version, @author, @email, @homepage, @uri, @sourcetype, @sourcemd5, @sourcesha1)";
|
||||||
|
|
||||||
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
processGames = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processGames == true)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < tosecObject.Games.Count; ++x)
|
||||||
|
{
|
||||||
|
RomSignatureObject.Game gameObject = tosecObject.Games[x];
|
||||||
|
|
||||||
|
// update display
|
||||||
|
if (showGames == true)
|
||||||
|
{
|
||||||
|
Console.SetCursorPosition(0, Console.CursorTop - 1);
|
||||||
|
string statusGameOutput = " ==> " + (x + 1).ToString().PadLeft(7, ' ') + " / " + tosecObject.Games.Count.ToString().PadLeft(7, ' ') + " : " + gameObject.Name;
|
||||||
|
Console.WriteLine("\r " + statusGameOutput.PadRight(lineGameNameLength, ' ') + "\r");
|
||||||
|
lineGameNameLength = statusGameOutput.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up game dictionary
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Name, ""));
|
||||||
|
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Description, ""));
|
||||||
|
dbDict.Add("year", Common.ReturnValueIfNull(gameObject.Year, ""));
|
||||||
|
dbDict.Add("publisher", Common.ReturnValueIfNull(gameObject.Publisher, ""));
|
||||||
|
dbDict.Add("demo", (int)gameObject.Demo);
|
||||||
|
dbDict.Add("system", Common.ReturnValueIfNull(gameObject.System, ""));
|
||||||
|
dbDict.Add("platform", Common.ReturnValueIfNull(gameObject.System, ""));
|
||||||
|
dbDict.Add("systemvariant", Common.ReturnValueIfNull(gameObject.SystemVariant, ""));
|
||||||
|
dbDict.Add("video", Common.ReturnValueIfNull(gameObject.Video, ""));
|
||||||
|
dbDict.Add("country", Common.ReturnValueIfNull(gameObject.Country, ""));
|
||||||
|
dbDict.Add("language", Common.ReturnValueIfNull(gameObject.Language, ""));
|
||||||
|
dbDict.Add("copyright", Common.ReturnValueIfNull(gameObject.Copyright, ""));
|
||||||
|
|
||||||
|
// store platform
|
||||||
|
int gameSystem = 0;
|
||||||
|
if (gameObject.System != null)
|
||||||
|
{
|
||||||
|
sql = "SELECT id FROM signatures_platforms WHERE platform=@platform";
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO signatures_platforms (platform) VALUES (@platform); SELECT LAST_INSERT_ID()";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
gameSystem = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameSystem = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbDict.Add("systemid", gameSystem);
|
||||||
|
|
||||||
|
// store publisher
|
||||||
|
int gamePublisher = 0;
|
||||||
|
if (gameObject.Publisher != null)
|
||||||
|
{
|
||||||
|
sql = "SELECT * FROM signatures_publishers WHERE publisher=@publisher";
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO signatures_publishers (publisher) VALUES (@publisher); SELECT LAST_INSERT_ID()";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
gamePublisher = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gamePublisher = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbDict.Add("publisherid", gamePublisher);
|
||||||
|
|
||||||
|
// store game
|
||||||
|
int gameId = 0;
|
||||||
|
sql = "SELECT * FROM signatures_games WHERE name=@name AND year=@year AND publisherid=@publisher AND systemid=@systemid AND country=@country AND language=@language";
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO signatures_games " +
|
||||||
|
"(name, description, year, publisherid, demo, systemid, systemvariant, video, country, language, copyright) VALUES " +
|
||||||
|
"(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @country, @language, @copyright); SELECT LAST_INSERT_ID()";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
gameId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// store rom
|
||||||
|
foreach (RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
||||||
|
{
|
||||||
|
if (romObject.Md5 != null)
|
||||||
|
{
|
||||||
|
int romId = 0;
|
||||||
|
sql = "SELECT * FROM signatures_roms WHERE gameid=@gameid AND md5=@md5";
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("gameid", gameId);
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(romObject.Name, ""));
|
||||||
|
dbDict.Add("size", Common.ReturnValueIfNull(romObject.Size, ""));
|
||||||
|
dbDict.Add("crc", Common.ReturnValueIfNull(romObject.Crc, ""));
|
||||||
|
dbDict.Add("md5", romObject.Md5);
|
||||||
|
dbDict.Add("sha1", Common.ReturnValueIfNull(romObject.Sha1, ""));
|
||||||
|
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(romObject.DevelopmentStatus, ""));
|
||||||
|
|
||||||
|
if (romObject.flags != null)
|
||||||
|
{
|
||||||
|
if (romObject.flags.Count > 0)
|
||||||
|
{
|
||||||
|
dbDict.Add("flags", Newtonsoft.Json.JsonConvert.SerializeObject(romObject.flags));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("flags", "[ ]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("flags", "[ ]");
|
||||||
|
}
|
||||||
|
dbDict.Add("romtype", (int)romObject.RomType);
|
||||||
|
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(romObject.RomTypeMedia, ""));
|
||||||
|
dbDict.Add("medialabel", Common.ReturnValueIfNull(romObject.MediaLabel, ""));
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO signatures_roms (gameid, name, size, crc, md5, sha1, developmentstatus, flags, romtype, romtypemedia, medialabel) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @flags, @romtype, @romtypemedia, @medialabel); SELECT LAST_INSERT_ID()";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
|
||||||
|
romId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
romId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
gaseous-signature-ingestor/gaseous-signature-ingestor.csproj
Normal file
20
gaseous-signature-ingestor/gaseous-signature-ingestor.csproj
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<RootNamespace>gaseous_signature_ingestor</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\gaseous-romsignatureobject\gaseous-romsignatureobject.csproj" />
|
||||||
|
<ProjectReference Include="..\gaseous-signature-parser\gaseous-signature-parser.csproj" />
|
||||||
|
<ProjectReference Include="..\gaseous-tools\gaseous-tools.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MySql.Data" Version="8.0.32" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
525
gaseous-signature-parser/Parsers/TosecParser.cs
Normal file
525
gaseous-signature-parser/Parsers/TosecParser.cs
Normal file
@@ -0,0 +1,525 @@
|
|||||||
|
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();
|
||||||
|
if (xmlGameDetail != null)
|
||||||
|
{
|
||||||
|
romObject.Name = xmlGameDetail.Attributes["name"]?.Value;
|
||||||
|
if (xmlGameDetail.Attributes["size"]?.Value != null)
|
||||||
|
{
|
||||||
|
romObject.Size = UInt64.Parse(xmlGameDetail.Attributes["size"]?.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
romObject.Size = 0;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -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-signature-parser/Support/Parsers/TOSEC/Country.txt
Normal file
68
gaseous-signature-parser/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-signature-parser/Support/Parsers/TOSEC/Language.txt
Normal file
45
gaseous-signature-parser/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-signature-parser/Support/Parsers/TOSEC/Systems.txt
Normal file
57
gaseous-signature-parser/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-signature-parser/Support/Parsers/TOSEC/Video.txt
Normal file
13
gaseous-signature-parser/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
|
38
gaseous-signature-parser/gaseous-signature-parser.csproj
Normal file
38
gaseous-signature-parser/gaseous-signature-parser.csproj
Normal 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>
|
63
gaseous-tools/Common.cs
Normal file
63
gaseous-tools/Common.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
namespace gaseous_tools
|
||||||
|
{
|
||||||
|
public class Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns IfNullValue if the ObjectToCheck is null
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ObjectToCheck">Any nullable object to check for null</param>
|
||||||
|
/// <param name="IfNullValue">Any object to return if ObjectToCheck is null</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
static public object ReturnValueIfNull(object? ObjectToCheck, object IfNullValue)
|
||||||
|
{
|
||||||
|
if (ObjectToCheck == null)
|
||||||
|
{
|
||||||
|
return IfNullValue;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return ObjectToCheck;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class hashObject
|
||||||
|
{
|
||||||
|
public hashObject(string FileName)
|
||||||
|
{
|
||||||
|
var xmlStream = File.OpenRead(FileName);
|
||||||
|
|
||||||
|
var md5 = MD5.Create();
|
||||||
|
byte[] md5HashByte = md5.ComputeHash(xmlStream);
|
||||||
|
string md5Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
|
||||||
|
_md5hash = md5hash;
|
||||||
|
|
||||||
|
var sha1 = SHA1.Create();
|
||||||
|
byte[] sha1HashByte = sha1.ComputeHash(xmlStream);
|
||||||
|
string sha1Hash = BitConverter.ToString(sha1HashByte).Replace("-", "").ToLowerInvariant();
|
||||||
|
_sha1hash = sha1hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
string _md5hash = "";
|
||||||
|
string _sha1hash = "";
|
||||||
|
|
||||||
|
public string md5hash
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _md5hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string sha1hash
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _sha1hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
112
gaseous-tools/Config.cs
Normal file
112
gaseous-tools/Config.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace gaseous_tools
|
||||||
|
{
|
||||||
|
public static class Config
|
||||||
|
{
|
||||||
|
static ConfigFile _config;
|
||||||
|
|
||||||
|
public static string ConfigurationPath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".gaseous-server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string ConfigurationFilePath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".gaseous-server", "config.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string ConfigurationFilePath_Backup
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".gaseous-server", "config.json.backup");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfigFile.Database DatabaseConfiguration
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _config.DatabaseConfiguration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Config()
|
||||||
|
{
|
||||||
|
if (_config == null)
|
||||||
|
{
|
||||||
|
// load the config file
|
||||||
|
if (File.Exists(ConfigurationFilePath))
|
||||||
|
{
|
||||||
|
string configRaw = File.ReadAllText(ConfigurationFilePath);
|
||||||
|
ConfigFile? _tempConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<ConfigFile>(configRaw);
|
||||||
|
if (_tempConfig != null)
|
||||||
|
{
|
||||||
|
_config = _tempConfig;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
throw new Exception("There was an error reading the config file: Json returned null");
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// no config file!
|
||||||
|
// use defaults and save
|
||||||
|
_config = new ConfigFile();
|
||||||
|
string configRaw = Newtonsoft.Json.JsonConvert.SerializeObject(_config, Newtonsoft.Json.Formatting.Indented);
|
||||||
|
File.WriteAllText(ConfigurationFilePath, configRaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Using configuration:");
|
||||||
|
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(_config, Formatting.Indented));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateConfig()
|
||||||
|
{
|
||||||
|
// save any updates to the configuration
|
||||||
|
string configRaw = Newtonsoft.Json.JsonConvert.SerializeObject(_config, Newtonsoft.Json.Formatting.Indented);
|
||||||
|
if (File.Exists(ConfigurationFilePath_Backup))
|
||||||
|
{
|
||||||
|
File.Delete(ConfigurationFilePath_Backup);
|
||||||
|
}
|
||||||
|
if (File.Exists(ConfigurationFilePath))
|
||||||
|
{
|
||||||
|
File.Move(ConfigurationFilePath, ConfigurationFilePath_Backup);
|
||||||
|
}
|
||||||
|
File.WriteAllText(ConfigurationFilePath, configRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConfigFile
|
||||||
|
{
|
||||||
|
public Database DatabaseConfiguration = new Database();
|
||||||
|
|
||||||
|
public class Database
|
||||||
|
{
|
||||||
|
public string HostName = "localhost";
|
||||||
|
public string UserName = "gaseous";
|
||||||
|
public string Password = "gaseous";
|
||||||
|
public string DatabaseName = "gaseous";
|
||||||
|
public int Port = 3306;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string ConnectionString
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string dbConnString = "server=" + HostName + ";port=" + Port + ";userid=" + UserName + ";password=" + Password + ";database=" + DatabaseName + "";
|
||||||
|
return dbConnString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
192
gaseous-tools/Database.cs
Normal file
192
gaseous-tools/Database.cs
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Reflection;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace gaseous_tools
|
||||||
|
{
|
||||||
|
public class Database
|
||||||
|
{
|
||||||
|
public Database()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Database(databaseType Type, string ConnectionString)
|
||||||
|
{
|
||||||
|
_ConnectorType = Type;
|
||||||
|
_ConnectionString = ConnectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum databaseType
|
||||||
|
{
|
||||||
|
MySql
|
||||||
|
}
|
||||||
|
|
||||||
|
string _ConnectionString = "";
|
||||||
|
|
||||||
|
public string ConnectionString
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _ConnectionString;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ConnectionString = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
databaseType? _ConnectorType = null;
|
||||||
|
|
||||||
|
public databaseType? ConnectorType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _ConnectorType;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ConnectorType = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitDB()
|
||||||
|
{
|
||||||
|
// load resources
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
|
switch (_ConnectorType)
|
||||||
|
{
|
||||||
|
case databaseType.MySql:
|
||||||
|
// check if the database exists first - first run must have permissions to create a database
|
||||||
|
string sql = "CREATE DATABASE IF NOT EXISTS `" + Config.DatabaseConfiguration.DatabaseName + "`;";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
ExecuteCMD(sql, dbDict, 30, "server=" + Config.DatabaseConfiguration.HostName + ";port=" + Config.DatabaseConfiguration.Port + ";userid=" + Config.DatabaseConfiguration.UserName + ";password=" + Config.DatabaseConfiguration.Password);
|
||||||
|
|
||||||
|
// check if schema version table is in place - if not, create the schema version table
|
||||||
|
sql = "SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'gaseous' AND TABLE_NAME = 'schema_version';";
|
||||||
|
DataTable SchemaVersionPresent = ExecuteCMD(sql, dbDict);
|
||||||
|
if (SchemaVersionPresent.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// no schema table present - create it
|
||||||
|
sql = "CREATE TABLE `schema_version` (`schema_version` INT NOT NULL, PRIMARY KEY (`schema_version`)); INSERT INTO `schema_version` (`schema_version`) VALUES (0);";
|
||||||
|
ExecuteCMD(sql, dbDict);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1000; i < 10000; i++)
|
||||||
|
{
|
||||||
|
string resourceName = "gaseous_tools.Database.MySQL.gaseous-" + i + ".sql";
|
||||||
|
string dbScript = "";
|
||||||
|
|
||||||
|
string[] resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();
|
||||||
|
if (resources.Contains(resourceName))
|
||||||
|
{
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
dbScript = reader.ReadToEnd();
|
||||||
|
|
||||||
|
// apply script
|
||||||
|
sql = "SELECT schema_version FROM schema_version;";
|
||||||
|
DataTable SchemaVersion = ExecuteCMD(sql, dbDict);
|
||||||
|
if (SchemaVersion.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// something is broken here... where's the table?
|
||||||
|
throw new Exception("schema_version table is missing!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int SchemaVer = (int)SchemaVersion.Rows[0][0];
|
||||||
|
if (SchemaVer < i)
|
||||||
|
{
|
||||||
|
// apply schema!
|
||||||
|
ExecuteCMD(dbScript, dbDict);
|
||||||
|
|
||||||
|
sql = "UPDATE schema_version SET schema_version=@schemaver";
|
||||||
|
dbDict.Add("schemaver", i);
|
||||||
|
ExecuteCMD(sql, dbDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable ExecuteCMD(string Command)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
return _ExecuteCMD(Command, dbDict, 30, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters)
|
||||||
|
{
|
||||||
|
return _ExecuteCMD(Command, Parameters, 30, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
||||||
|
{
|
||||||
|
return _ExecuteCMD(Command, Parameters, Timeout, ConnectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataTable _ExecuteCMD(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
||||||
|
{
|
||||||
|
if (ConnectionString == "") { ConnectionString = _ConnectionString; }
|
||||||
|
switch (_ConnectorType)
|
||||||
|
{
|
||||||
|
case databaseType.MySql:
|
||||||
|
MySQLServerConnector conn = new MySQLServerConnector(ConnectionString);
|
||||||
|
return (DataTable)conn.ExecCMD(Command, Parameters, Timeout);
|
||||||
|
default:
|
||||||
|
return new DataTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private partial class MySQLServerConnector
|
||||||
|
{
|
||||||
|
private string DBConn = "";
|
||||||
|
|
||||||
|
public MySQLServerConnector(string ConnectionString)
|
||||||
|
{
|
||||||
|
DBConn = ConnectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable ExecCMD(string SQL, Dictionary<string, object> Parameters, int Timeout)
|
||||||
|
{
|
||||||
|
DataTable RetTable = new DataTable();
|
||||||
|
|
||||||
|
MySqlConnection conn = new MySqlConnection(DBConn);
|
||||||
|
conn.Open();
|
||||||
|
|
||||||
|
MySqlCommand cmd = new MySqlCommand
|
||||||
|
{
|
||||||
|
Connection = conn,
|
||||||
|
CommandText = SQL,
|
||||||
|
CommandTimeout = Timeout
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (string Parameter in Parameters.Keys)
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue(Parameter, Parameters[Parameter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RetTable.Load(cmd.ExecuteReader());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Trace.WriteLine("Error executing " + SQL);
|
||||||
|
Trace.WriteLine("Full exception: " + ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Close();
|
||||||
|
|
||||||
|
return RetTable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
146
gaseous-tools/Database/MySQL/gaseous-1000.sql
Normal file
146
gaseous-tools/Database/MySQL/gaseous-1000.sql
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
-- MySQL dump 10.13 Distrib 8.0.32, for macos13.0 (arm64)
|
||||||
|
--
|
||||||
|
-- Host: localhost Database: gaseous
|
||||||
|
-- ------------------------------------------------------
|
||||||
|
-- Server version 8.0.32
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!50503 SET NAMES utf8mb4 */;
|
||||||
|
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||||
|
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||||
|
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `signatures_games`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `signatures_games`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `signatures_games` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`description` varchar(255) DEFAULT NULL,
|
||||||
|
`year` varchar(15) DEFAULT NULL,
|
||||||
|
`publisherid` int DEFAULT NULL,
|
||||||
|
`demo` int DEFAULT NULL,
|
||||||
|
`systemid` int DEFAULT NULL,
|
||||||
|
`systemvariant` varchar(100) DEFAULT NULL,
|
||||||
|
`video` varchar(10) DEFAULT NULL,
|
||||||
|
`country` varchar(5) DEFAULT NULL,
|
||||||
|
`language` varchar(5) DEFAULT NULL,
|
||||||
|
`copyright` varchar(15) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `id_UNIQUE` (`id`),
|
||||||
|
KEY `publisher_idx` (`publisherid`),
|
||||||
|
KEY `system_idx` (`systemid`),
|
||||||
|
KEY `ingest_idx` (`name`,`year`,`publisherid`,`systemid`,`country`,`language`) USING BTREE,
|
||||||
|
CONSTRAINT `publisher` FOREIGN KEY (`publisherid`) REFERENCES `signatures_publishers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT `system` FOREIGN KEY (`systemid`) REFERENCES `signatures_platforms` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1466355 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `signatures_platforms`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `signatures_platforms`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `signatures_platforms` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`platform` varchar(100) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `idsignatures_platforms_UNIQUE` (`id`),
|
||||||
|
KEY `platforms_idx` (`platform`,`id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1231 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `signatures_publishers`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `signatures_publishers`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `signatures_publishers` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`publisher` varchar(100) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `id_UNIQUE` (`id`),
|
||||||
|
KEY `publisher_idx` (`publisher`,`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=97693 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `signatures_roms`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `signatures_roms`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `signatures_roms` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`gameid` int DEFAULT NULL,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`size` bigint DEFAULT NULL,
|
||||||
|
`crc` varchar(20) DEFAULT NULL,
|
||||||
|
`md5` varchar(100) DEFAULT NULL,
|
||||||
|
`sha1` varchar(100) DEFAULT NULL,
|
||||||
|
`developmentstatus` varchar(100) DEFAULT NULL,
|
||||||
|
`flags` json DEFAULT NULL,
|
||||||
|
`romtype` int DEFAULT NULL,
|
||||||
|
`romtypemedia` varchar(100) DEFAULT NULL,
|
||||||
|
`medialabel` varchar(100) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `id_UNIQUE` (`id`,`gameid`) USING BTREE,
|
||||||
|
KEY `gameid_idx` (`gameid`),
|
||||||
|
KEY `md5_idx` (`md5`) USING BTREE,
|
||||||
|
KEY `sha1_idx` (`sha1`) USING BTREE,
|
||||||
|
KEY `flags_idx` ((cast(`flags` as char(255) array))),
|
||||||
|
CONSTRAINT `gameid` FOREIGN KEY (`gameid`) REFERENCES `signatures_games` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=3350963 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `signatures_sources`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `signatures_sources`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `signatures_sources` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`description` varchar(255) DEFAULT NULL,
|
||||||
|
`category` varchar(45) DEFAULT NULL,
|
||||||
|
`version` varchar(45) DEFAULT NULL,
|
||||||
|
`author` varchar(255) DEFAULT NULL,
|
||||||
|
`email` varchar(45) DEFAULT NULL,
|
||||||
|
`homepage` varchar(45) DEFAULT NULL,
|
||||||
|
`url` varchar(45) DEFAULT NULL,
|
||||||
|
`sourcetype` varchar(45) DEFAULT NULL,
|
||||||
|
`sourcemd5` varchar(45) DEFAULT NULL,
|
||||||
|
`sourcesha1` varchar(45) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `id_UNIQUE` (`id`),
|
||||||
|
KEY `sourcemd5_idx` (`sourcemd5`,`id`) USING BTREE,
|
||||||
|
KEY `sourcesha1_idx` (`sourcesha1`,`id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=7573 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||||
|
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
|
-- Dump completed on 2023-02-27 8:54:22
|
25
gaseous-tools/Database/MySQL/gaseous-1001.sql
Normal file
25
gaseous-tools/Database/MySQL/gaseous-1001.sql
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
CREATE
|
||||||
|
ALGORITHM = UNDEFINED
|
||||||
|
DEFINER = `root`@`localhost`
|
||||||
|
SQL SECURITY DEFINER
|
||||||
|
VIEW `view_signatures_games` AS
|
||||||
|
SELECT
|
||||||
|
`signatures_games`.`id` AS `id`,
|
||||||
|
`signatures_games`.`name` AS `name`,
|
||||||
|
`signatures_games`.`description` AS `description`,
|
||||||
|
`signatures_games`.`year` AS `year`,
|
||||||
|
`signatures_games`.`publisherid` AS `publisherid`,
|
||||||
|
`signatures_publishers`.`publisher` AS `publisher`,
|
||||||
|
`signatures_games`.`demo` AS `demo`,
|
||||||
|
`signatures_games`.`systemid` AS `platformid`,
|
||||||
|
`signatures_platforms`.`platform` AS `platform`,
|
||||||
|
`signatures_games`.`systemvariant` AS `systemvariant`,
|
||||||
|
`signatures_games`.`video` AS `video`,
|
||||||
|
`signatures_games`.`country` AS `country`,
|
||||||
|
`signatures_games`.`language` AS `language`,
|
||||||
|
`signatures_games`.`copyright` AS `copyright`
|
||||||
|
FROM
|
||||||
|
((`signatures_games`
|
||||||
|
JOIN `signatures_publishers` ON ((`signatures_games`.`publisherid` = `signatures_publishers`.`id`)))
|
||||||
|
JOIN `signatures_platforms` ON ((`signatures_games`.`systemid` = `signatures_platforms`.`id`)));
|
||||||
|
|
28
gaseous-tools/gaseous-tools.csproj
Normal file
28
gaseous-tools/gaseous-tools.csproj
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<RootNamespace>gaseous_tools</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MySql.Data" Version="8.0.32" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Database\" />
|
||||||
|
<None Remove="Database\MySQL\" />
|
||||||
|
<None Remove="Database\MySQL\gaseous-1000.sql" />
|
||||||
|
<None Remove="Database\MySQL\gaseous-1001.sql" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Database\" />
|
||||||
|
<Folder Include="Database\MySQL\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Database\MySQL\gaseous-1000.sql" />
|
||||||
|
<EmbeddedResource Include="Database\MySQL\gaseous-1001.sql" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
Reference in New Issue
Block a user