diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..8c23067
--- /dev/null
+++ b/.github/dependabot.yml
@@ -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"
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..6d9f542
--- /dev/null
+++ b/.vscode/launch.json
@@ -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"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..04fd839
--- /dev/null
+++ b/.vscode/tasks.json
@@ -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"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Gaseous.sln b/Gaseous.sln
index d15120a..f7adb01 100644
--- a/Gaseous.sln
+++ b/Gaseous.sln
@@ -13,6 +13,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-signature-ingestor"
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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -47,6 +51,14 @@ Global
{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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/gaseous-server/Controllers/SignaturesController.cs b/gaseous-server/Controllers/SignaturesController.cs
new file mode 100644
index 0000000..7f69893
--- /dev/null
+++ b/gaseous-server/Controllers/SignaturesController.cs
@@ -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
+ {
+ ///
+ /// Get the current signature counts from the database
+ ///
+ /// Number of sources, publishers, games, and rom signatures in the database
+ [HttpGet]
+ public Models.Signatures_Status Status()
+ {
+ return new Models.Signatures_Status();
+ }
+
+ [HttpGet]
+ [Route("api/[controller]/[action]")]
+ public List 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 _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 dbDict = new Dictionary();
+ dbDict.Add("searchString", searchString);
+
+ DataTable sigDb = db.ExecuteCMD(sql, dbDict);
+
+ List GamesList = new List();
+
+ 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>((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;
+ }
+ }
+}
+
diff --git a/gaseous-server/Models/Signatures_Games.cs b/gaseous-server/Models/Signatures_Games.cs
new file mode 100644
index 0000000..9765714
--- /dev/null
+++ b/gaseous-server/Models/Signatures_Games.cs
@@ -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 flags { get; set; } = new List();
+
+ public RomTypes RomType { get; set; }
+ public string? RomTypeMedia { get; set; }
+ public string? MediaLabel { get; set; }
+
+ public enum RomTypes
+ {
+ ///
+ /// Media type is unknown
+ ///
+ Unknown = 0,
+
+ ///
+ /// Optical media
+ ///
+ Disc = 1,
+
+ ///
+ /// Magnetic media
+ ///
+ Disk = 2,
+
+ ///
+ /// Individual files
+ ///
+ File = 3,
+
+ ///
+ /// Individual pars
+ ///
+ Part = 4,
+
+ ///
+ /// Tape base media
+ ///
+ Tape = 5,
+
+ ///
+ /// Side of the media
+ ///
+ Side = 6
+ }
+ }
+ }
+}
+
diff --git a/gaseous-server/Models/Signatures_Status.cs b/gaseous-server/Models/Signatures_Status.cs
new file mode 100644
index 0000000..8d2c904
--- /dev/null
+++ b/gaseous-server/Models/Signatures_Status.cs
@@ -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;
+ }
+ }
+ }
+}
+
diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs
new file mode 100644
index 0000000..6fd856e
--- /dev/null
+++ b/gaseous-server/Program.cs
@@ -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();
+
diff --git a/gaseous-server/Properties/launchSettings.json b/gaseous-server/Properties/launchSettings.json
new file mode 100644
index 0000000..6cb3fd1
--- /dev/null
+++ b/gaseous-server/Properties/launchSettings.json
@@ -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"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/gaseous-server/appsettings.Development.json b/gaseous-server/appsettings.Development.json
new file mode 100644
index 0000000..ce16a2e
--- /dev/null
+++ b/gaseous-server/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
+
diff --git a/gaseous-server/appsettings.json b/gaseous-server/appsettings.json
new file mode 100644
index 0000000..af0538f
--- /dev/null
+++ b/gaseous-server/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
+
diff --git a/gaseous-server/gaseous-server.csproj b/gaseous-server/gaseous-server.csproj
new file mode 100644
index 0000000..35f78b0
--- /dev/null
+++ b/gaseous-server/gaseous-server.csproj
@@ -0,0 +1,34 @@
+
+
+
+ net7.0
+ enable
+ enable
+ gaseous_server
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gaseous-tools/Database.cs b/gaseous-tools/Database.cs
index 9f87e3c..db1f2c6 100644
--- a/gaseous-tools/Database.cs
+++ b/gaseous-tools/Database.cs
@@ -122,17 +122,33 @@ namespace gaseous_tools
}
}
+ public DataTable ExecuteCMD(string Command)
+ {
+ Dictionary dbDict = new Dictionary();
+ return _ExecuteCMD(Command, dbDict, 30, "");
+ }
+
+ public DataTable ExecuteCMD(string Command, Dictionary Parameters)
+ {
+ return _ExecuteCMD(Command, Parameters, 30, "");
+ }
+
public DataTable ExecuteCMD(string Command, Dictionary Parameters, int Timeout = 30, string ConnectionString = "")
{
- if (ConnectionString == "") { ConnectionString = _ConnectionString; }
+ return _ExecuteCMD(Command, Parameters, Timeout, ConnectionString);
+ }
+
+ private DataTable _ExecuteCMD(string Command, Dictionary Parameters, int Timeout = 30, string ConnectionString = "")
+ {
+ if (ConnectionString == "") { ConnectionString = _ConnectionString; }
switch (_ConnectorType)
- {
- case databaseType.MySql:
+ {
+ case databaseType.MySql:
MySQLServerConnector conn = new MySQLServerConnector(ConnectionString);
- return (DataTable)conn.ExecCMD(Command, Parameters, Timeout);
- default:
- return new DataTable();
- }
+ return (DataTable)conn.ExecCMD(Command, Parameters, Timeout);
+ default:
+ return new DataTable();
+ }
}
private partial class MySQLServerConnector