feat: now pulls platform information and stores it in the database

This commit is contained in:
Michael Green
2023-04-09 01:19:50 +10:00
parent 1ad840750e
commit b36b3a8f57
14 changed files with 686 additions and 15 deletions

View File

@@ -0,0 +1,102 @@
using System;
using System.Data;
using System.Threading.Tasks;
using gaseous_tools;
namespace gaseous_server.Classes
{
public class ImportGames
{
public ImportGames(string ImportPath)
{
if (Directory.Exists(ImportPath))
{
string[] importContents_Files = Directory.GetFiles(ImportPath);
string[] importContents_Directories = Directory.GetDirectories(ImportPath);
// import files first
foreach (string importContent in importContents_Files) {
ImportGame importGame = new ImportGame();
importGame.ImportGameFile(importContent);
}
}
else
{
Logging.Log(Logging.LogType.Critical, "Import Games", "The import directory " + ImportPath + " does not exist.");
throw new DirectoryNotFoundException("Invalid path: " + ImportPath);
}
}
}
public class ImportGame
{
private Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
public void ImportGameFile(string GameFileImportPath, bool IsDirectory = false)
{
Logging.Log(Logging.LogType.Information, "Import Game", "Processing item " + GameFileImportPath);
if (IsDirectory == false)
{
FileInfo fi = new FileInfo(GameFileImportPath);
// process as a single file
// check 1: do we have a signature for it?
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
gaseous_server.Controllers.SignaturesController sc = new Controllers.SignaturesController();
List<Models.Signatures_Games> signatures = sc.GetSignature(hash.md5hash);
if (signatures.Count == 0)
{
// no md5 signature found - try sha1
signatures = sc.GetSignature("", hash.sha1hash);
}
Models.Signatures_Games discoveredSignature = new Models.Signatures_Games();
if (signatures.Count == 1)
{
// only 1 signature found!
discoveredSignature = signatures.ElementAt(0);
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
}
else if (signatures.Count > 1)
{
// more than one signature found - find one with highest score
foreach(Models.Signatures_Games Sig in signatures)
{
if (Sig.Score > discoveredSignature.Score)
{
discoveredSignature = Sig;
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
}
}
}
else
{
// no signature match found - try alternate methods
Models.Signatures_Games.GameItem gi = new Models.Signatures_Games.GameItem();
Models.Signatures_Games.RomItem ri = new Models.Signatures_Games.RomItem();
// game title is the file name without the extension or path
gi.Name = Path.GetFileNameWithoutExtension(GameFileImportPath);
// guess platform
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, true);
// get rom data
ri.Name = Path.GetFileName(GameFileImportPath);
ri.Md5 = hash.md5hash;
ri.Sha1 = hash.sha1hash;
discoveredSignature.Game = gi;
discoveredSignature.Rom = ri;
}
//Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(discoveredSignature));
IGDB.Models.Platform determinedPlatform = Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
}
}
}
}

View File

@@ -0,0 +1,229 @@
using System;
using System.Data;
using gaseous_tools;
using IGDB;
using IGDB.Models;
namespace gaseous_server.Classes
{
public class Platforms
{
public Platforms()
{
}
public static Platform UnknownPlatform
{
get
{
Platform unkownPlatform = new Platform
{
Id = 0,
Abbreviation = "",
AlternativeName = "",
Category = PlatformCategory.Computer,
Checksum = "",
CreatedAt = DateTime.UtcNow,
Generation = 1,
Name = "Unknown",
PlatformFamily = new IdentityOrValue<PlatformFamily>(0),
PlatformLogo = new IdentityOrValue<PlatformLogo>(0),
Slug = "Unknown",
Summary = "",
UpdatedAt = DateTime.UtcNow,
Url = "",
Versions = new IdentitiesOrValues<PlatformVersion>(),
Websites = new IdentitiesOrValues<PlatformWebsite>()
};
return unkownPlatform;
}
}
private static IGDBClient igdb = new IGDBClient(
// Found in Twitch Developer portal for your app
Config.IGDB.ClientId,
Config.IGDB.Secret
);
public static Platform GetPlatform(int Id)
{
if (Id == 0)
{
return UnknownPlatform;
}
else
{
Task<Platform> RetVal = _GetPlatform(SearchUsing.id, Id);
return RetVal.Result;
}
}
public static Platform GetPlatform(string Slug)
{
Task<Platform> RetVal = _GetPlatform(SearchUsing.slug, Slug);
return RetVal.Result;
}
private static async Task<Platform> _GetPlatform(SearchUsing searchUsing, object searchValue)
{
// check database first
Platform? platform = DBGetPlatform(searchUsing, searchValue);
// set up where clause
string WhereClause = "";
switch (searchUsing)
{
case SearchUsing.id:
WhereClause = "where id = " + searchValue;
break;
case SearchUsing.slug:
WhereClause = "where slug = " + searchValue;
break;
default:
throw new Exception("Invalid search type");
}
if (platform == null)
{
var results = await igdb.QueryAsync<Platform>(IGDBClient.Endpoints.Platforms, query: "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites; " + WhereClause + ";");
var result = results.First();
DBInsertPlatform(result, true);
return result;
}
else
{
return platform;
}
}
private static Platform? DBGetPlatform(SearchUsing searchUsing, object searchValue)
{
Dictionary<string, object> dbDict = new Dictionary<string, object>();
switch (searchUsing)
{
case SearchUsing.id:
dbDict.Add("id", searchValue);
return _DBGetPlatform("SELECT * FROM platforms WHERE id = @id", dbDict);
case SearchUsing.slug:
dbDict.Add("slug", searchValue);
return _DBGetPlatform("SELECT * FROM platforms WHERE slug = @slug", dbDict);
default:
throw new Exception("Invalid Search Type");
}
}
private enum SearchUsing
{
id,
slug
}
private static Platform? _DBGetPlatform(string sql, Dictionary<string, object> searchParams)
{
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
DataTable dbResponse = db.ExecuteCMD(sql, searchParams);
if (dbResponse.Rows.Count > 0)
{
return ConvertDataRowToPlatform(dbResponse.Rows[0]);
}
else
{
return null;
}
}
private static Platform ConvertDataRowToPlatform(DataRow PlatformDR)
{
Platform returnPlatform = new Platform
{
Id = (long)(UInt64)PlatformDR["id"],
Abbreviation = (string?)PlatformDR["abbreviation"],
AlternativeName = (string?)PlatformDR["alternative_name"],
Category = (PlatformCategory)PlatformDR["category"],
Checksum = (string?)PlatformDR["checksum"],
CreatedAt = (DateTime?)PlatformDR["created_at"],
Generation = (int?)PlatformDR["generation"],
Name = (string?)PlatformDR["name"],
PlatformFamily = new IdentityOrValue<PlatformFamily>((int?)PlatformDR["platform_family"]),
PlatformLogo = new IdentityOrValue<PlatformLogo>((int?)PlatformDR["platform_logo"]),
Slug = (string?)PlatformDR["slug"],
Summary = (string?)PlatformDR["summary"],
UpdatedAt = (DateTime?)PlatformDR["updated_at"],
Url = (string?)PlatformDR["url"],
Versions = Newtonsoft.Json.JsonConvert.DeserializeObject<IdentitiesOrValues<PlatformVersion>>((string?)PlatformDR["versions"]),
Websites = Newtonsoft.Json.JsonConvert.DeserializeObject<IdentitiesOrValues<PlatformWebsite>>((string?)PlatformDR["websites"])
};
return returnPlatform;
}
private static void DBInsertPlatform(Platform PlatformItem, bool Insert)
{
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "INSERT INTO platforms (id, abbreviation, alternative_name, category, checksum, created_at, generation, name, platform_family, platform_logo, slug, summary, updated_at, url, versions, websites, dateAdded, lastUpdated) VALUES (@id, @abbreviation, @alternative_name, @category, @checksum, @created_at, @generation, @name, @platform_family, @platform_logo, @slug, @summary, @updated_at, @url, @versions, @websites, @lastUpdated, @lastUpdated)";
if (Insert == false)
{
sql = "UPDATE platforms SET abbreviation=@abbreviation, alternative_name=@alternative_name, category=@category, checksum=@checksum, created_at=@created_at, generation=@generation, name=@name, platform_family=@platform_family, platform_logo=@platform_logo, slug=@slug, summary=@summary, updated_at=@updated_at, url=@url, versions=@versions, websites=@websites, lastUpdated=@lastUpdated WHERE id=@id";
}
Dictionary<string, object> dbDict = new Dictionary<string, object>();
dbDict.Add("id", PlatformItem.Id);
dbDict.Add("abbreviation", Common.ReturnValueIfNull(PlatformItem.Abbreviation, ""));
dbDict.Add("alternative_name", Common.ReturnValueIfNull(PlatformItem.AlternativeName, ""));
dbDict.Add("category", Common.ReturnValueIfNull(PlatformItem.Category, PlatformCategory.Computer));
dbDict.Add("checksum", Common.ReturnValueIfNull(PlatformItem.Checksum, ""));
dbDict.Add("created_at", Common.ReturnValueIfNull(PlatformItem.CreatedAt, DateTime.UtcNow));
dbDict.Add("generation", Common.ReturnValueIfNull(PlatformItem.Generation, 1));
dbDict.Add("name", Common.ReturnValueIfNull(PlatformItem.Name, ""));
if (PlatformItem.PlatformFamily == null)
{
dbDict.Add("platform_family", 0);
}
else
{
dbDict.Add("platform_family", Common.ReturnValueIfNull(PlatformItem.PlatformFamily.Id, 0));
}
if (PlatformItem.PlatformLogo == null)
{
dbDict.Add("platform_logo", 0);
}
else
{
dbDict.Add("platform_logo", Common.ReturnValueIfNull(PlatformItem.PlatformLogo.Id, 0));
}
dbDict.Add("slug", Common.ReturnValueIfNull(PlatformItem.Slug, ""));
dbDict.Add("summary", Common.ReturnValueIfNull(PlatformItem.Summary, ""));
dbDict.Add("updated_at", Common.ReturnValueIfNull(PlatformItem.UpdatedAt, DateTime.UtcNow));
dbDict.Add("url", Common.ReturnValueIfNull(PlatformItem.Url, ""));
dbDict.Add("lastUpdated", DateTime.UtcNow);
string EmptyJson = "{\"Ids\": [], \"Values\": null}";
if (PlatformItem.Versions == null)
{
dbDict.Add("versions", EmptyJson);
}
else
{
dbDict.Add("versions", Newtonsoft.Json.JsonConvert.SerializeObject(PlatformItem.Versions));
}
if (PlatformItem.Websites == null)
{
dbDict.Add("websites", EmptyJson);
}
else
{
dbDict.Add("websites", Newtonsoft.Json.JsonConvert.SerializeObject(PlatformItem.Websites));
}
db.ExecuteCMD(sql, dbDict);
}
}
}

View File

@@ -31,7 +31,6 @@ namespace gaseous_server.SignatureIngestors.TOSEC
string tosecXMLFile = tosecPathContents[i];
// check tosec file md5
Logging.Log(Logging.LogType.Information, "Signature Ingestor - TOSEC", "Checking file: " + tosecXMLFile);
Common.hashObject hashObject = new Common.hashObject(tosecXMLFile);
sql = "SELECT * FROM signatures_sources WHERE sourcemd5=@sourcemd5";
dbDict = new Dictionary<string, object>();
@@ -40,6 +39,8 @@ namespace gaseous_server.SignatureIngestors.TOSEC
if (sigDB.Rows.Count == 0)
{
Logging.Log(Logging.LogType.Information, "Signature Ingestor - TOSEC", "Importing file: " + tosecXMLFile);
// start parsing file
TosecParser tosecParser = new TosecParser();
RomSignatureObject tosecObject = tosecParser.Parse(tosecXMLFile);
@@ -214,6 +215,10 @@ namespace gaseous_server.SignatureIngestors.TOSEC
}
}
}
else
{
Logging.Log(Logging.LogType.Debug, "Signature Ingestor - TOSEC", "Rejecting already imported file: " + tosecXMLFile);
}
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Reflection;
namespace gaseous_server.Models
{
public class PlatformMapping
{
public PlatformMapping()
{
}
private static List<PlatformMapItem> _PlatformMaps = new List<PlatformMapItem>();
public static List<PlatformMapItem> PlatformMap
{
get
{
if (_PlatformMaps.Count == 0)
{
// load platform maps from: gaseous_server.Support.PlatformMap.json
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "gaseous_server.Support.PlatformMap.json";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string rawJson = reader.ReadToEnd();
_PlatformMaps.Clear();
_PlatformMaps = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem>>(rawJson);
}
}
return _PlatformMaps;
}
}
public static void GetIGDBPlatformMapping(ref Models.Signatures_Games Signature, FileInfo RomFileInfo, bool SetSystemName)
{
foreach (Models.PlatformMapping.PlatformMapItem PlatformMapping in Models.PlatformMapping.PlatformMap)
{
if (PlatformMapping.KnownFileExtensions.Contains(RomFileInfo.Extension, StringComparer.OrdinalIgnoreCase))
{
if (SetSystemName == true)
{
if (Signature.Game != null) { Signature.Game.System = PlatformMapping.IGDBName; }
}
Signature.Flags.IGDBPlatformId = PlatformMapping.IGDBId;
}
}
}
public class PlatformMapItem
{
public int IGDBId { get; set; }
public string IGDBName { get; set; }
public List<string> AlternateNames { get; set; } = new List<string>();
public List<string> KnownFileExtensions { get; set; } = new List<string>();
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Text.Json.Serialization;
using static gaseous_romsignatureobject.RomSignatureObject.Game;
namespace gaseous_server.Models
@@ -12,6 +13,29 @@ namespace gaseous_server.Models
public GameItem? Game { get; set; }
public RomItem? Rom { get; set; }
//[JsonIgnore]
public int Score
{
get
{
int _score = 0;
if (Game != null)
{
_score = _score + Game.Score;
}
if (Rom != null)
{
_score = _score + Rom.Score;
}
return _score;
}
}
public SignatureFlags Flags = new SignatureFlags();
public class GameItem
{
public Int32? Id { get; set; }
@@ -36,6 +60,60 @@ namespace gaseous_server.Models
demo_rolling = 4,
demo_slideshow = 5
}
[JsonIgnore]
public int Score
{
get
{
// calculate a score based on the availablility of data
int _score = 0;
var properties = this.GetType().GetProperties();
foreach (var prop in properties)
{
if (prop.GetGetMethod() != null)
{
switch (prop.Name.ToLower())
{
case "id":
case "score":
break;
case "name":
case "year":
case "publisher":
case "system":
if (prop.PropertyType == typeof(string))
{
if (prop.GetValue(this) != null)
{
string propVal = prop.GetValue(this).ToString();
if (propVal.Length > 0)
{
_score = _score + 10;
}
}
}
break;
default:
if (prop.PropertyType == typeof(string))
{
if (prop.GetValue(this) != null)
{
string propVal = prop.GetValue(this).ToString();
if (propVal.Length > 0)
{
_score = _score + 1;
}
}
}
break;
}
}
}
return _score;
}
}
}
public class RomItem
@@ -92,6 +170,65 @@ namespace gaseous_server.Models
/// </summary>
Side = 6
}
[JsonIgnore]
public int Score
{
get
{
// calculate a score based on the availablility of data
int _score = 0;
var properties = this.GetType().GetProperties();
foreach (var prop in properties)
{
if (prop.GetGetMethod() != null)
{
switch (prop.Name.ToLower())
{
case "name":
case "size":
case "crc":
case "developmentstatus":
case "flags":
case "romtypemedia":
case "medialabel":
if (prop.PropertyType == typeof(string) || prop.PropertyType == typeof(Int64) || prop.PropertyType == typeof(List<string>))
{
if (prop.GetValue(this) != null)
{
string propVal = prop.GetValue(this).ToString();
if (propVal.Length > 0)
{
_score = _score + 10;
}
}
}
break;
default:
if (prop.PropertyType == typeof(string))
{
if (prop.GetValue(this) != null)
{
string propVal = prop.GetValue(this).ToString();
if (propVal.Length > 0)
{
_score = _score + 1;
}
}
}
break;
}
}
}
return _score;
}
}
}
public class SignatureFlags
{
public int IGDBPlatformId { get; set; }
}
}
}

View File

@@ -23,7 +23,7 @@ namespace gaseous_server
private DateTime _LastFinishTime = DateTime.UtcNow;
private int _Interval = 0;
private string _LastResult = "";
private Exception? _LastError = null;
private string? _LastError = null;
private bool _ForceExecute = false;
public QueueItemType ItemType => _ItemType;
@@ -38,7 +38,7 @@ namespace gaseous_server
}
public int Interval => _Interval;
public string LastResult => _LastResult;
public Exception? LastError => _LastError;
public string? LastError => _LastError;
public bool Force => _ForceExecute;
public void Execute()
@@ -67,6 +67,7 @@ namespace gaseous_server
case QueueItemType.TitleIngestor:
Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Title Ingestor");
Classes.ImportGames importGames = new Classes.ImportGames(Config.LibraryConfiguration.LibraryImportDirectory);
break;
}
}
@@ -74,7 +75,7 @@ namespace gaseous_server
{
Logging.Log(Logging.LogType.Warning, "Timered Event", "An error occurred", ex);
_LastResult = "";
_LastError = ex;
_LastError = ex.ToString();
}
_ForceExecute = false;

View File

@@ -45,6 +45,9 @@ app.UseHttpsRedirection();
app.UseAuthorization();
app.UseDefaultFiles();
app.UseStaticFiles();
app.MapControllers();
// setup library directories

View File

@@ -0,0 +1,66 @@
[
{
"IGDBId": 15,
"IGDBName": "Commodore C64/128/MAX",
"AlternateNames": [
"C64",
"Commodore C64",
"Commodore C128",
"Commodore C64DTV",
"Commodore C64/128/MAX"
],
"KnownFileExtensions": [
".C64",
".CRT",
".D64",
".D71",
".D81",
".G64",
".PRG",
".T64",
".TAP",
".Z64"
]
},
{
"IGDBId": 16,
"IGDBName": "Amiga",
"AlternateNames": [
"Amiga",
"Commodore Amiga"
],
"KnownFileExtensions": [
".ADF",
".ADZ",
".DMS"
]
},
{
"IGDBId": 64,
"IGDBName": "Sega Master System/Mark III",
"AlternateNames": [
"Sega Master System/Mark III",
"Sega Master System",
"Sega Mark III & Master System"
],
"KnownFileExtensions": [
".SMS"
]
},
{
"IGDBId": 29,
"IGDBName": "Sega Mega Drive/Genesis",
"AlternateNames": [
"Sega Mega Drive/Genesis",
"Sega Mega Drive",
"Sega Genesis",
"Sega Mega Drive & Genesis"
],
"KnownFileExtensions": [
".GEN",
".MD",
".SG",
".SMD"
]
}
]

View File

@@ -13,6 +13,7 @@
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.5" />
<PackageReference Include="IGDB" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
@@ -21,12 +22,15 @@
<None Remove="Models\Signatures.Status" />
<None Remove="Classes\" />
<None Remove="Classes\SignatureIngestors\" />
<None Remove="Support\" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\" />
<Folder Include="Models\" />
<Folder Include="Classes\" />
<Folder Include="Classes\SignatureIngestors\" />
<Folder Include="Support\" />
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\gaseous-tools\gaseous-tools.csproj">
@@ -39,4 +43,18 @@
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Remove="Support\PlatformMap.json" />
<Content Remove="wwwroot\" />
<Content Remove="wwwroot\index.html" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Support\PlatformMap.json" Condition="'$(ExcludeConfigFilesFromBuildOutput)'!='true'">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="wwwroot\index.html" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
</body>
</html>

View File

@@ -22,6 +22,13 @@ namespace gaseous_tools
}
}
static public DateTime ConvertUnixToDateTime(double UnixTimeStamp)
{
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
dateTime = dateTime.AddSeconds(UnixTimeStamp).ToLocalTime();
return dateTime;
}
public class hashObject
{
public hashObject(string FileName)
@@ -31,12 +38,12 @@ namespace gaseous_tools
var md5 = MD5.Create();
byte[] md5HashByte = md5.ComputeHash(xmlStream);
string md5Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
_md5hash = md5hash;
_md5hash = md5Hash;
var sha1 = SHA1.Create();
byte[] sha1HashByte = sha1.ComputeHash(xmlStream);
string sha1Hash = BitConverter.ToString(sha1HashByte).Replace("-", "").ToLowerInvariant();
_sha1hash = sha1hash;
_sha1hash = sha1Hash;
}
string _md5hash = "";

View File

@@ -49,6 +49,14 @@ namespace gaseous_tools
}
}
public static ConfigFile.IGDB IGDB
{
get
{
return _config.IGDBConfiguration;
}
}
public static string LogPath
{
get
@@ -185,6 +193,8 @@ namespace gaseous_tools
[JsonIgnore]
public Library LibraryConfiguration = new Library();
public IGDB IGDBConfiguration = new IGDB();
public Logging LoggingConfiguration = new Logging();
public class Database
@@ -220,14 +230,6 @@ namespace gaseous_tools
}
}
public string LibraryUploadDirectory
{
get
{
return Path.Combine(LibraryRootDirectory, "Upload");
}
}
public string LibraryImportDirectory
{
get
@@ -263,7 +265,6 @@ namespace gaseous_tools
public void InitLibrary()
{
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
if (!Directory.Exists(LibraryUploadDirectory)) { Directory.CreateDirectory(LibraryUploadDirectory); }
if (!Directory.Exists(LibraryImportDirectory)) { Directory.CreateDirectory(LibraryImportDirectory); }
if (!Directory.Exists(LibraryDataDirectory)) { Directory.CreateDirectory(LibraryDataDirectory); }
if (!Directory.Exists(LibrarySignatureImportDirectory)) { Directory.CreateDirectory(LibrarySignatureImportDirectory); }
@@ -271,6 +272,12 @@ namespace gaseous_tools
}
}
public class IGDB
{
public string ClientId = "";
public string Secret = "";
}
public class Logging
{
public bool DebugLogging = false;

View File

@@ -0,0 +1,24 @@

CREATE TABLE `platforms` (
`id` bigint unsigned NOT NULL,
`abbreviation` varchar(45) DEFAULT NULL,
`alternative_name` varchar(45) DEFAULT NULL,
`category` int DEFAULT NULL,
`checksum` varchar(45) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`generation` int DEFAULT NULL,
`name` varchar(45) DEFAULT NULL,
`platform_family` int DEFAULT NULL,
`platform_logo` int DEFAULT NULL,
`slug` varchar(45) DEFAULT NULL,
`summary` varchar(255) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
`versions` json DEFAULT NULL,
`websites` json DEFAULT NULL,
`dateAdded` datetime DEFAULT NULL,
`lastUpdated` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
SELECT * FROM gaseous.platforms;

View File

@@ -17,6 +17,7 @@
<None Remove="Database\MySQL\gaseous-1000.sql" />
<None Remove="Database\MySQL\gaseous-1001.sql" />
<None Remove="Database\MySQL\gaseous-1002.sql" />
<None Remove="Database\MySQL\gaseous-1003.sql" />
</ItemGroup>
<ItemGroup>
<Folder Include="Database\" />
@@ -26,5 +27,6 @@
<EmbeddedResource Include="Database\MySQL\gaseous-1000.sql" />
<EmbeddedResource Include="Database\MySQL\gaseous-1001.sql" />
<EmbeddedResource Include="Database\MySQL\gaseous-1002.sql" />
<EmbeddedResource Include="Database\MySQL\gaseous-1003.sql" />
</ItemGroup>
</Project>