diff --git a/gaseous-server/Classes/ImportGames.cs b/gaseous-server/Classes/ImportGames.cs new file mode 100644 index 0000000..2cddbe9 --- /dev/null +++ b/gaseous-server/Classes/ImportGames.cs @@ -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 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); + } + } + } +} + diff --git a/gaseous-server/Classes/Platforms.cs b/gaseous-server/Classes/Platforms.cs new file mode 100644 index 0000000..eae183d --- /dev/null +++ b/gaseous-server/Classes/Platforms.cs @@ -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(0), + PlatformLogo = new IdentityOrValue(0), + Slug = "Unknown", + Summary = "", + UpdatedAt = DateTime.UtcNow, + Url = "", + Versions = new IdentitiesOrValues(), + Websites = new IdentitiesOrValues() + }; + + 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 RetVal = _GetPlatform(SearchUsing.id, Id); + return RetVal.Result; + } + } + + public static Platform GetPlatform(string Slug) + { + Task RetVal = _GetPlatform(SearchUsing.slug, Slug); + return RetVal.Result; + } + + private static async Task _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(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 dbDict = new Dictionary(); + 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 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((int?)PlatformDR["platform_family"]), + PlatformLogo = new IdentityOrValue((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>((string?)PlatformDR["versions"]), + Websites = Newtonsoft.Json.JsonConvert.DeserializeObject>((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 dbDict = new Dictionary(); + 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); + } + } +} + diff --git a/gaseous-server/Classes/SignatureIngestors/TOSEC.cs b/gaseous-server/Classes/SignatureIngestors/TOSEC.cs index f6b1a2a..c1c46b4 100644 --- a/gaseous-server/Classes/SignatureIngestors/TOSEC.cs +++ b/gaseous-server/Classes/SignatureIngestors/TOSEC.cs @@ -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(); @@ -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); + } } } } diff --git a/gaseous-server/Models/PlatformMapping.cs b/gaseous-server/Models/PlatformMapping.cs new file mode 100644 index 0000000..86a1614 --- /dev/null +++ b/gaseous-server/Models/PlatformMapping.cs @@ -0,0 +1,60 @@ +using System; +using System.Reflection; + +namespace gaseous_server.Models +{ + public class PlatformMapping + { + public PlatformMapping() + { + + } + + private static List _PlatformMaps = new List(); + public static List 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>(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 AlternateNames { get; set; } = new List(); + public List KnownFileExtensions { get; set; } = new List(); + } + } +} + diff --git a/gaseous-server/Models/Signatures_Games.cs b/gaseous-server/Models/Signatures_Games.cs index 9765714..8aec7a4 100644 --- a/gaseous-server/Models/Signatures_Games.cs +++ b/gaseous-server/Models/Signatures_Games.cs @@ -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 /// 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)) + { + 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; } } } } diff --git a/gaseous-server/ProcessQueue.cs b/gaseous-server/ProcessQueue.cs index 1dc60d0..07b01ad 100644 --- a/gaseous-server/ProcessQueue.cs +++ b/gaseous-server/ProcessQueue.cs @@ -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; diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs index cf33cca..dd471da 100644 --- a/gaseous-server/Program.cs +++ b/gaseous-server/Program.cs @@ -45,6 +45,9 @@ app.UseHttpsRedirection(); app.UseAuthorization(); +app.UseDefaultFiles(); +app.UseStaticFiles(); + app.MapControllers(); // setup library directories diff --git a/gaseous-server/Support/PlatformMap.json b/gaseous-server/Support/PlatformMap.json new file mode 100644 index 0000000..e403b63 --- /dev/null +++ b/gaseous-server/Support/PlatformMap.json @@ -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" + ] + } +] diff --git a/gaseous-server/gaseous-server.csproj b/gaseous-server/gaseous-server.csproj index 0383705..c66b20b 100644 --- a/gaseous-server/gaseous-server.csproj +++ b/gaseous-server/gaseous-server.csproj @@ -13,6 +13,7 @@ + @@ -21,12 +22,15 @@ + + + @@ -39,4 +43,18 @@ + + + + + + + + true + PreserveNewest + + + + + diff --git a/gaseous-server/wwwroot/index.html b/gaseous-server/wwwroot/index.html new file mode 100644 index 0000000..045404b --- /dev/null +++ b/gaseous-server/wwwroot/index.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gaseous-tools/Common.cs b/gaseous-tools/Common.cs index 00bc713..ef95b17 100644 --- a/gaseous-tools/Common.cs +++ b/gaseous-tools/Common.cs @@ -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 = ""; diff --git a/gaseous-tools/Config.cs b/gaseous-tools/Config.cs index 95553bd..941ee47 100644 --- a/gaseous-tools/Config.cs +++ b/gaseous-tools/Config.cs @@ -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; diff --git a/gaseous-tools/Database/MySQL/gaseous-1003.sql b/gaseous-tools/Database/MySQL/gaseous-1003.sql new file mode 100644 index 0000000..38f81ee --- /dev/null +++ b/gaseous-tools/Database/MySQL/gaseous-1003.sql @@ -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; \ No newline at end of file diff --git a/gaseous-tools/gaseous-tools.csproj b/gaseous-tools/gaseous-tools.csproj index 5f6b960..351f32e 100644 --- a/gaseous-tools/gaseous-tools.csproj +++ b/gaseous-tools/gaseous-tools.csproj @@ -17,6 +17,7 @@ + @@ -26,5 +27,6 @@ +