From 311c7733fa925a70ed4cc96eff9b9e00c3fcfef6 Mon Sep 17 00:00:00 2001 From: Michael Green <84688932+michael-j-green@users.noreply.github.com> Date: Sat, 30 Dec 2023 20:28:23 +1100 Subject: [PATCH] Assorted bug fixes (#242) * Fixed DBNull error when updating metadata * Fixed platform id bug with media group launching * Updates to support Hasheous - testing only * Refactored alot of code, initial support for Hasheous --- gaseous-server/Classes/Collections.cs | 6 +- gaseous-server/Classes/Common.cs | 12 +- gaseous-server/Classes/Config.cs | 42 ++- gaseous-server/Classes/FileSignature.cs | 286 ++++++++++++++++++ gaseous-server/Classes/ImportGames.cs | 173 ++--------- gaseous-server/Classes/Metadata/Artworks.cs | 82 ++--- .../Classes/Metadata/Communications.cs | 232 ++++++++++++-- .../Classes/Metadata/CompanyLogos.cs | 87 ++---- gaseous-server/Classes/Metadata/Covers.cs | 91 ++---- gaseous-server/Classes/Metadata/Games.cs | 8 +- .../Classes/Metadata/PlatformLogos.cs | 90 ++---- .../Classes/Metadata/Screenshots.cs | 80 ++--- gaseous-server/Classes/MetadataManagement.cs | 4 +- gaseous-server/Classes/Roms.cs | 151 ++------- gaseous-server/Classes/SignatureManagement.cs | 81 +++++ .../Controllers/V1.0/GamesController.cs | 78 ++--- .../Controllers/V1.0/SignaturesController.cs | 67 +--- gaseous-server/Models/PlatformMapping.cs | 2 +- gaseous-server/Models/Signatures_Games.cs | 182 +---------- gaseous-server/Program.cs | 10 +- gaseous-server/gaseous-server.csproj | 6 + gaseous-server/wwwroot/pages/EmulatorJS.html | 2 + .../wwwroot/pages/dialogs/rominfo.html | 6 +- gaseous-server/wwwroot/pages/game.html | 12 +- .../wwwroot/scripts/gamesformating.js | 2 +- gaseous-server/wwwroot/scripts/main.js | 2 +- 26 files changed, 898 insertions(+), 896 deletions(-) create mode 100644 gaseous-server/Classes/FileSignature.cs create mode 100644 gaseous-server/Classes/SignatureManagement.cs diff --git a/gaseous-server/Classes/Collections.cs b/gaseous-server/Classes/Collections.cs index c89685b..da47792 100644 --- a/gaseous-server/Classes/Collections.cs +++ b/gaseous-server/Classes/Collections.cs @@ -304,7 +304,7 @@ namespace gaseous_server.Classes // calculate total rom size for the game long GameRomSize = 0; foreach (Roms.GameRomItem gameRom in gameRoms) { - GameRomSize += gameRom.Size; + GameRomSize += (long)gameRom.Size; } if (collectionItem.MaximumBytesPerPlatform > 0) { if ((TotalRomSize + GameRomSize) < collectionItem.MaximumBytesPerPlatform) { @@ -749,7 +749,7 @@ namespace gaseous_server.Classes long Size = 0; foreach (CollectionGameItem Game in Games) { foreach (Roms.GameRomItem Rom in Game.Roms) { - Size += Rom.Size; + Size += (long)Rom.Size; } } @@ -801,7 +801,7 @@ namespace gaseous_server.Classes get { long Size = 0; foreach (Roms.GameRomItem Rom in Roms) { - Size += Rom.Size; + Size += (long)Rom.Size; } return Size; diff --git a/gaseous-server/Classes/Common.cs b/gaseous-server/Classes/Common.cs index 519776b..9ba5d2f 100644 --- a/gaseous-server/Classes/Common.cs +++ b/gaseous-server/Classes/Common.cs @@ -1,9 +1,11 @@ using System.Collections.Concurrent; +using System.ComponentModel; +using System.Reflection; using System.Security.Cryptography; namespace gaseous_server.Classes { - public class Common + public static class Common { /// /// Returns IfNullValue if the ObjectToCheck is null @@ -110,6 +112,14 @@ namespace gaseous_server.Classes return Path.GetFullPath(new Uri(path).LocalPath) .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); } + + public static string GetDescription(this Enum value) + { + return ((DescriptionAttribute)Attribute.GetCustomAttribute( + value.GetType().GetFields(BindingFlags.Public | BindingFlags.Static) + .Single(x => x.GetValue(null).Equals(value)), + typeof(DescriptionAttribute)))?.Description ?? value.ToString(); + } } /// diff --git a/gaseous-server/Classes/Config.cs b/gaseous-server/Classes/Config.cs index d5eb24e..5c887fd 100644 --- a/gaseous-server/Classes/Config.cs +++ b/gaseous-server/Classes/Config.cs @@ -473,22 +473,56 @@ namespace gaseous_server.Classes public class MetadataAPI { - private static Communications.MetadataSources _Source + private static HasheousClient.Models.MetadataModel.MetadataSources _MetadataSource { get { if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("metadatasource"))) { - return (Communications.MetadataSources)Enum.Parse(typeof(Communications.MetadataSources), Environment.GetEnvironmentVariable("metadatasource")); + return (HasheousClient.Models.MetadataModel.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.MetadataSources), Environment.GetEnvironmentVariable("metadatasource")); } else { - return Communications.MetadataSources.IGDB; + return HasheousClient.Models.MetadataModel.MetadataSources.IGDB; } } } - public Communications.MetadataSources Source = _Source; + private static HasheousClient.Models.MetadataModel.SignatureSources _SignatureSource + { + get + { + if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("signaturesource"))) + { + return (HasheousClient.Models.MetadataModel.SignatureSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.SignatureSources), Environment.GetEnvironmentVariable("signaturesource")); + } + else + { + return HasheousClient.Models.MetadataModel.SignatureSources.LocalOnly; + } + } + } + + private static string _HasheousHost + { + get + { + if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("hasheoushoust"))) + { + return Environment.GetEnvironmentVariable("hasheoushoust"); + } + else + { + return "https://hasheous.org/"; + } + } + } + + public HasheousClient.Models.MetadataModel.MetadataSources MetadataSource = _MetadataSource; + + public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource; + + public string HasheousHost = _HasheousHost; } public class IGDB diff --git a/gaseous-server/Classes/FileSignature.cs b/gaseous-server/Classes/FileSignature.cs new file mode 100644 index 0000000..d4d7673 --- /dev/null +++ b/gaseous-server/Classes/FileSignature.cs @@ -0,0 +1,286 @@ +using System.IO.Compression; +using HasheousClient.Models; +using SharpCompress.Archives; +using SharpCompress.Archives.Rar; +using SharpCompress.Common; + +namespace gaseous_server.Classes +{ + public class FileSignature + { + public static gaseous_server.Models.Signatures_Games GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath) + { + gaseous_server.Models.Signatures_Games discoveredSignature = new gaseous_server.Models.Signatures_Games(); + discoveredSignature = _GetFileSignature(hash, fi, GameFileImportPath, false); + + string[] CompressionExts = { ".zip", ".rar", ".7z" }; + string ImportedFileExtension = Path.GetExtension(GameFileImportPath); + + if (CompressionExts.Contains(ImportedFileExtension) && (fi.Length < 1073741824)) + { + // file is a zip and less than 1 GiB + // extract the zip file and search the contents + Logging.Log(Logging.LogType.Information, "Get Signature", "Decompressing " + GameFileImportPath + " to examine contents"); + + string ExtractPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, Path.GetRandomFileName()); + if (!Directory.Exists(ExtractPath)) { Directory.CreateDirectory(ExtractPath); } + try + { + switch(ImportedFileExtension) + { + case ".zip": + ZipFile.ExtractToDirectory(GameFileImportPath, ExtractPath); + break; + + case ".rar": + using (var archive = RarArchive.Open(GameFileImportPath)) + { + foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) + { + entry.WriteToDirectory(ExtractPath, new ExtractionOptions() + { + ExtractFullPath = true, + Overwrite = true + }); + } + } + break; + + case ".7z": + using (var archive = SharpCompress.Archives.SevenZip.SevenZipArchive.Open(GameFileImportPath)) + { + foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) + { + entry.WriteToDirectory(ExtractPath, new ExtractionOptions() + { + ExtractFullPath = true, + Overwrite = true + }); + } + } + break; + } + + // loop through contents until we find the first signature match + foreach (string file in Directory.GetFiles(ExtractPath, "*.*", SearchOption.AllDirectories)) + { + FileInfo zfi = new FileInfo(file); + Common.hashObject zhash = new Common.hashObject(file); + + gaseous_server.Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi, file, true); + zDiscoveredSignature.Rom.Name = Path.ChangeExtension(zDiscoveredSignature.Rom.Name, ImportedFileExtension); + + if (zDiscoveredSignature.Score > discoveredSignature.Score) + { + if ( + zDiscoveredSignature.Rom.SignatureSource == gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.MAMEArcade || + zDiscoveredSignature.Rom.SignatureSource == gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.MAMEMess + ) + { + zDiscoveredSignature.Rom.Name = zDiscoveredSignature.Game.Description + ImportedFileExtension; + } + zDiscoveredSignature.Rom.Crc = discoveredSignature.Rom.Crc; + zDiscoveredSignature.Rom.Md5 = discoveredSignature.Rom.Md5; + zDiscoveredSignature.Rom.Sha1 = discoveredSignature.Rom.Sha1; + zDiscoveredSignature.Rom.Size = discoveredSignature.Rom.Size; + discoveredSignature = zDiscoveredSignature; + + break; + } + } + } + catch (Exception ex) + { + Logging.Log(Logging.LogType.Critical, "Get Signature", "Error processing zip file: " + GameFileImportPath, ex); + } + + if (Directory.Exists(ExtractPath)) { Directory.Delete(ExtractPath, true); } + } + + return discoveredSignature; + } + + private static gaseous_server.Models.Signatures_Games _GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath, bool IsInZip) + { + gaseous_server.Models.Signatures_Games discoveredSignature = new gaseous_server.Models.Signatures_Games(); + + // do database search first + gaseous_server.Models.Signatures_Games? dbSignature = _GetFileSignatureFromDatabase(hash, fi, GameFileImportPath); + + if (dbSignature != null) + { + // local signature found + discoveredSignature = dbSignature; + } + else + { + // no local signature attempt to pull from Hasheous + dbSignature = _GetFileSignatureFromHasheous(hash, fi, GameFileImportPath); + + if (dbSignature != null) + { + // signature retrieved from Hasheous + discoveredSignature = dbSignature; + } + else + { + // construct a signature from file data + dbSignature = _GetFileSignatureFromFileData(hash, fi, GameFileImportPath); + discoveredSignature = dbSignature; + } + } + + Logging.Log(Logging.LogType.Information, "Import Game", " Determined import file as: " + discoveredSignature.Game.Name + " (" + discoveredSignature.Game.Year + ") " + discoveredSignature.Game.System); + + return discoveredSignature; + } + + private static gaseous_server.Models.Signatures_Games? _GetFileSignatureFromDatabase(Common.hashObject hash, FileInfo fi, string GameFileImportPath) + { + // check 1: do we have a signature for it? + gaseous_server.Classes.SignatureManagement sc = new SignatureManagement(); + List signatures = sc.GetSignature(hash.md5hash); + if (signatures.Count == 0) + { + // no md5 signature found - try sha1 + signatures = sc.GetSignature("", hash.sha1hash); + } + + gaseous_server.Models.Signatures_Games? discoveredSignature = null; + if (signatures.Count == 1) + { + // only 1 signature found! + discoveredSignature = signatures.ElementAt(0); + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false); + + return discoveredSignature; + } + else if (signatures.Count > 1) + { + // more than one signature found - find one with highest score + foreach (gaseous_server.Models.Signatures_Games Sig in signatures) + { + if (Sig.Score > discoveredSignature.Score) + { + discoveredSignature = Sig; + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false); + } + } + + return discoveredSignature; + } + + return null; + } + + private static gaseous_server.Models.Signatures_Games? _GetFileSignatureFromHasheous(Common.hashObject hash, FileInfo fi, string GameFileImportPath) + { + // check if hasheous is enabled, and if so use it's signature database + if (Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous) + { + HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous(); + SignatureLookupItem? HasheousResult = hasheous.RetrieveFromHasheousAsync(new HashLookupModel{ + MD5 = hash.md5hash, + SHA1 = hash.sha1hash + }); + + if (HasheousResult != null) + { + if (HasheousResult.Signature != null) + { + gaseous_server.Models.Signatures_Games signature = new Models.Signatures_Games(); + signature.Game = HasheousResult.Signature.Game; + signature.Rom = HasheousResult.Signature.Rom; + + if (HasheousResult.MetadataResults != null) + { + if (HasheousResult.MetadataResults.Count > 0) + { + foreach (SignatureLookupItem.MetadataResult metadataResult in HasheousResult.MetadataResults) + { + if (metadataResult.Source == MetadataModel.MetadataSources.IGDB) + { + signature.Flags.IGDBPlatformId = (long)metadataResult.PlatformId; + signature.Flags.IGDBGameId = (long)metadataResult.GameId; + } + } + } + } + + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref signature, fi, false); + + return signature; + } + } + } + + return null; + } + + private static gaseous_server.Models.Signatures_Games _GetFileSignatureFromFileData(Common.hashObject hash, FileInfo fi, string GameFileImportPath) + { + SignatureManagement signatureManagement = new SignatureManagement(); + + gaseous_server.Models.Signatures_Games discoveredSignature = new gaseous_server.Models.Signatures_Games(); + + // no signature match found - try name search + List signatures = signatureManagement.GetByTosecName(fi.Name); + + if (signatures.Count == 1) + { + // only 1 signature found! + discoveredSignature = signatures.ElementAt(0); + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false); + + return discoveredSignature; + } + else if (signatures.Count > 1) + { + // more than one signature found - find one with highest score + foreach (gaseous_server.Models.Signatures_Games Sig in signatures) + { + if (Sig.Score > discoveredSignature.Score) + { + discoveredSignature = Sig; + gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false); + } + } + + return discoveredSignature; + } + else + { + // still no search - try alternate method + gaseous_server.Models.Signatures_Games.GameItem gi = new gaseous_server.Models.Signatures_Games.GameItem(); + gaseous_server.Models.Signatures_Games.RomItem ri = new gaseous_server.Models.Signatures_Games.RomItem(); + + discoveredSignature.Game = gi; + discoveredSignature.Rom = ri; + + // game title is the file name without the extension or path + gi.Name = Path.GetFileNameWithoutExtension(GameFileImportPath); + + // remove everything after brackets - leaving (hopefully) only the name + if (gi.Name.Contains("(")) + { + gi.Name = gi.Name.Substring(0, gi.Name.IndexOf("(")).Trim(); + } + + // remove special characters like dashes + gi.Name = gi.Name.Replace("-", "").Trim(); + + // 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; + ri.Size = fi.Length; + ri.SignatureSource = gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.None; + + return discoveredSignature; + } + } + } +} \ No newline at end of file diff --git a/gaseous-server/Classes/ImportGames.cs b/gaseous-server/Classes/ImportGames.cs index 843be99..99ae49c 100644 --- a/gaseous-server/Classes/ImportGames.cs +++ b/gaseous-server/Classes/ImportGames.cs @@ -6,10 +6,13 @@ using System.Security.Policy; using System.Text.RegularExpressions; using System.Threading.Tasks; using gaseous_server.Classes.Metadata; +using gaseous_server.Models; using IGDB.Models; using NuGet.Common; using NuGet.LibraryModel; using static gaseous_server.Classes.Metadata.Games; +using static gaseous_server.Classes.FileSignature; +using HasheousClient.Models; namespace gaseous_server.Classes { @@ -102,7 +105,7 @@ namespace gaseous_server.Classes { Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " not in database - processing"); - Models.Signatures_Games discoveredSignature = GetFileSignature(hash, fi, GameFileImportPath); + gaseous_server.Models.Signatures_Games discoveredSignature = GetFileSignature(hash, fi, GameFileImportPath); // get discovered platform IGDB.Models.Platform? determinedPlatform = null; @@ -121,7 +124,7 @@ namespace gaseous_server.Classes discoveredSignature.Flags.IGDBPlatformName = determinedPlatform.Name; } - IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature.Game.Name, discoveredSignature.Flags.IGDBPlatformId); + IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId); // add to database StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath); @@ -152,155 +155,29 @@ namespace gaseous_server.Classes } } - public static Models.Signatures_Games GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath) + public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId) { - Models.Signatures_Games discoveredSignature = _GetFileSignature(hash, fi, GameFileImportPath); - - if ((Path.GetExtension(GameFileImportPath) == ".zip") && (fi.Length < 1073741824)) + if (Signature.Flags != null) { - // file is a zip and less than 1 GiB - // extract the zip file and search the contents - string ExtractPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, Path.GetRandomFileName()); - if (!Directory.Exists(ExtractPath)) { Directory.CreateDirectory(ExtractPath); } - try + if (Signature.Flags.IGDBGameId != null) { - ZipFile.ExtractToDirectory(GameFileImportPath, ExtractPath); - - // loop through contents until we find the first signature match - foreach (string file in Directory.GetFiles(ExtractPath)) + // game was determined elsewhere - probably a Hasheous server + try { - FileInfo zfi = new FileInfo(file); - Common.hashObject zhash = new Common.hashObject(file); - - Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi, file); - zDiscoveredSignature.Rom.Name = Path.ChangeExtension(zDiscoveredSignature.Rom.Name, ".zip"); - - if (zDiscoveredSignature.Score > discoveredSignature.Score) - { - if ( - zDiscoveredSignature.Rom.SignatureSource == gaseous_signature_parser.models.RomSignatureObject.RomSignatureObject.Game.Rom.SignatureSourceType.MAMEArcade || - zDiscoveredSignature.Rom.SignatureSource == gaseous_signature_parser.models.RomSignatureObject.RomSignatureObject.Game.Rom.SignatureSourceType.MAMEMess - ) - { - zDiscoveredSignature.Rom.Name = zDiscoveredSignature.Game.Description + ".zip"; - } - zDiscoveredSignature.Rom.Crc = discoveredSignature.Rom.Crc; - zDiscoveredSignature.Rom.Md5 = discoveredSignature.Rom.Md5; - zDiscoveredSignature.Rom.Sha1 = discoveredSignature.Rom.Sha1; - zDiscoveredSignature.Rom.Size = discoveredSignature.Rom.Size; - discoveredSignature = zDiscoveredSignature; - - break; - } + return Games.GetGame(Signature.Flags.IGDBGameId, false, false, false); } - } - catch (Exception ex) - { - Logging.Log(Logging.LogType.Critical, "Get Signature", "Error processing zip file: " + GameFileImportPath, ex); - } - - if (Directory.Exists(ExtractPath)) { Directory.Delete(ExtractPath, true); } - } - - return discoveredSignature; - } - - private static Models.Signatures_Games _GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath) - { - // check 1: do we have a signature for it? - 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) + catch (Exception ex) { - discoveredSignature = Sig; - gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false); + Logging.Log(Logging.LogType.Warning, "Import Game", "Provided game id resulted in a failed game lookup", ex); } } } - else - { - // no signature match found - try name search - signatures = sc.GetByTosecName(fi.Name); - 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 - { - // still no search - try alternate method - Models.Signatures_Games.GameItem gi = new Models.Signatures_Games.GameItem(); - Models.Signatures_Games.RomItem ri = new Models.Signatures_Games.RomItem(); - - discoveredSignature.Game = gi; - discoveredSignature.Rom = ri; - - // game title is the file name without the extension or path - gi.Name = Path.GetFileNameWithoutExtension(GameFileImportPath); - - // remove everything after brackets - leaving (hopefully) only the name - if (gi.Name.Contains("(")) - { - gi.Name = gi.Name.Substring(0, gi.Name.IndexOf("(")); - } - - // remove special characters like dashes - gi.Name = gi.Name.Replace("-", ""); - - // 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; - ri.Size = fi.Length; - ri.SignatureSource = gaseous_signature_parser.models.RomSignatureObject.RomSignatureObject.Game.Rom.SignatureSourceType.None; - } - } - - Logging.Log(Logging.LogType.Information, "Import Game", " Determined import file as: " + discoveredSignature.Game.Name + " (" + discoveredSignature.Game.Year + ") " + discoveredSignature.Game.System); - - return discoveredSignature; - } - - public static IGDB.Models.Game SearchForGame(string GameName, long PlatformId) - { // search discovered game - case insensitive exact match first IGDB.Models.Game determinedGame = new IGDB.Models.Game(); + string GameName = Signature.Game.Name; + List SearchCandidates = GetSearchCandidates(GameName); foreach (string SearchCandidate in SearchCandidates) @@ -423,7 +300,7 @@ namespace gaseous_server.Classes return SearchCandidates; } - public static long StoreROM(GameLibrary.LibraryItem library, Common.hashObject hash, IGDB.Models.Game determinedGame, IGDB.Models.Platform determinedPlatform, Models.Signatures_Games discoveredSignature, string GameFileImportPath, long UpdateId = 0) + public static long StoreROM(GameLibrary.LibraryItem library, Common.hashObject hash, IGDB.Models.Game determinedGame, IGDB.Models.Platform determinedPlatform, gaseous_server.Models.Signatures_Games discoveredSignature, string GameFileImportPath, long UpdateId = 0) { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); @@ -682,7 +559,7 @@ namespace gaseous_server.Classes Common.hashObject hash = new Common.hashObject(LibraryFile); FileInfo fi = new FileInfo(LibraryFile); - Models.Signatures_Games sig = GetFileSignature(hash, fi, LibraryFile); + gaseous_server.Models.Signatures_Games sig = GetFileSignature(hash, fi, LibraryFile); Logging.Log(Logging.LogType.Information, "Library Scan", " Orphaned file found in library: " + LibraryFile); @@ -697,17 +574,17 @@ namespace gaseous_server.Classes if (library.DefaultPlatformId == 0) { determinedPlatform = new IGDB.Models.Platform(); - determinedGame = SearchForGame(sig.Game.Name, sig.Flags.IGDBPlatformId); + determinedGame = SearchForGame(sig, sig.Flags.IGDBPlatformId); } else { determinedPlatform = Platforms.GetPlatform(library.DefaultPlatformId); - determinedGame = SearchForGame(sig.Game.Name, library.DefaultPlatformId); + determinedGame = SearchForGame(sig, library.DefaultPlatformId); } } else { - determinedGame = SearchForGame(sig.Game.Name, (long)determinedPlatform.Id); + determinedGame = SearchForGame(sig, (long)determinedPlatform.Id); } StoreROM(library, hash, determinedGame, determinedPlatform, sig, LibraryFile); @@ -734,7 +611,7 @@ namespace gaseous_server.Classes { long romId = (long)dtRoms.Rows[i]["Id"]; string romPath = (string)dtRoms.Rows[i]["Path"]; - gaseous_signature_parser.models.RomSignatureObject.RomSignatureObject.Game.Rom.SignatureSourceType romMetadataSource = (gaseous_signature_parser.models.RomSignatureObject.RomSignatureObject.Game.Rom.SignatureSourceType)(int)dtRoms.Rows[i]["MetadataSource"]; + gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType romMetadataSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(int)dtRoms.Rows[i]["MetadataSource"]; SetStatus(StatusCount, dtRoms.Rows.Count, "Processing file " + romPath); Logging.Log(Logging.LogType.Information, "Library Scan", " Processing ROM at path " + romPath); @@ -778,11 +655,11 @@ namespace gaseous_server.Classes string sql = ""; if (ForceExecute == false) { - sql = "SELECT * FROM Games_Roms WHERE ((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) LIMIT 100;"; + sql = "SELECT * FROM Games_Roms WHERE (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) LIMIT 100;"; } else { - sql = "SELECT * FROM Games_Roms WHERE ((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0);"; + sql = "SELECT * FROM Games_Roms WHERE (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0));"; } Dictionary dbDict = new Dictionary(); dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7)); @@ -808,7 +685,7 @@ namespace gaseous_server.Classes Logging.Log(Logging.LogType.Information, "Rematch Scan", "Running rematch against " + romPath); // determine rom signature - Models.Signatures_Games sig = GetFileSignature(hash, fi, romPath); + gaseous_server.Models.Signatures_Games sig = GetFileSignature(hash, fi, romPath); // determine rom platform IGDB.Models.Platform determinedPlatform = Metadata.Platforms.GetPlatform(sig.Flags.IGDBPlatformId); @@ -817,7 +694,7 @@ namespace gaseous_server.Classes determinedPlatform = new IGDB.Models.Platform(); } - IGDB.Models.Game determinedGame = SearchForGame(sig.Game.Name, sig.Flags.IGDBPlatformId); + IGDB.Models.Game determinedGame = SearchForGame(sig, sig.Flags.IGDBPlatformId); StoreROM(library, hash, determinedGame, determinedPlatform, sig, romPath, romId); diff --git a/gaseous-server/Classes/Metadata/Artworks.cs b/gaseous-server/Classes/Metadata/Artworks.cs index 5f7bc94..efbbfd8 100644 --- a/gaseous-server/Classes/Metadata/Artworks.cs +++ b/gaseous-server/Classes/Metadata/Artworks.cs @@ -13,7 +13,7 @@ namespace gaseous_server.Classes.Metadata { } - public static Artwork? GetArtwork(long? Id, string LogoPath) + public static Artwork? GetArtwork(long? Id, string ImagePath) { if ((Id == 0) || (Id == null)) { @@ -21,18 +21,18 @@ namespace gaseous_server.Classes.Metadata } else { - Task RetVal = _GetArtwork(SearchUsing.id, Id, LogoPath); + Task RetVal = _GetArtwork(SearchUsing.id, Id, ImagePath); return RetVal.Result; } } - public static Artwork GetArtwork(string Slug, string LogoPath) + public static Artwork GetArtwork(string Slug, string ImagePath) { - Task RetVal = _GetArtwork(SearchUsing.slug, Slug, LogoPath); + Task RetVal = _GetArtwork(SearchUsing.slug, Slug, ImagePath); return RetVal.Result; } - private static async Task _GetArtwork(SearchUsing searchUsing, object searchValue, string LogoPath) + private static async Task _GetArtwork(SearchUsing searchUsing, object searchValue, string ImagePath) { // check database first Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); @@ -61,19 +61,20 @@ namespace gaseous_server.Classes.Metadata Artwork returnValue = new Artwork(); bool forceImageDownload = false; - LogoPath = Path.Combine(LogoPath, "Artwork"); + ImagePath = Path.Combine(ImagePath, "Artwork"); switch (cacheStatus) { case Storage.CacheStatus.NotPresent: - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue); forceImageDownload = true; break; case Storage.CacheStatus.Expired: try { - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue, true); + forceImageDownload = true; } catch (Exception ex) { @@ -88,11 +89,13 @@ namespace gaseous_server.Classes.Metadata throw new Exception("How did you get here?"); } - if ((!File.Exists(Path.Combine(LogoPath, returnValue.ImageId + ".jpg"))) || forceImageDownload == true) + // check for presence of "original" quality file - download if absent or force download is true + string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg"); + if ((!File.Exists(localFile)) || forceImageDownload == true) { - //GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_thumb, returnValue.ImageId); - //GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_logo_med, returnValue.ImageId); - GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_original, returnValue.ImageId); + Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Artwork download forced."); + + GetImageFromServer(ImagePath, returnValue.ImageId); } return returnValue; @@ -104,64 +107,23 @@ namespace gaseous_server.Classes.Metadata slug } - private static async Task GetObjectFromServer(string WhereClause, string LogoPath) + private static async Task GetObjectFromServer(string WhereClause, string ImagePath) { // get Artwork metadata Communications comms = new Communications(); var results = await comms.APIComm(IGDBClient.Endpoints.Artworks, fieldList, WhereClause); var result = results.First(); - //GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId); - //GetImageFromServer(result.Url, LogoPath, LogoSize.t_logo_med, result.ImageId); - GetImageFromServer(result.Url, LogoPath, LogoSize.t_original, result.ImageId); - return result; } - - private static void GetImageFromServer(string Url, string LogoPath, LogoSize logoSize, string ImageId) + + private static async void GetImageFromServer(string ImagePath, string ImageId) { - using (var client = new HttpClient()) - { - string fileName = "Artwork.jpg"; - string extension = "jpg"; - switch (logoSize) - { - case LogoSize.t_thumb: - fileName = "_Thumb"; - extension = "jpg"; - break; - case LogoSize.t_logo_med: - fileName = "_Medium"; - extension = "png"; - break; - case LogoSize.t_original: - fileName = ""; - extension = "png"; - break; - default: - fileName = "Artwork"; - extension = "jpg"; - break; - } - fileName = ImageId + fileName; - string imageUrl = Url.Replace(LogoSize.t_thumb.ToString(), logoSize.ToString()).Replace("jpg", extension); + Communications comms = new Communications(); + List imageSizes = new List(); + imageSizes.AddRange(Enum.GetValues(typeof(Communications.IGDBAPI_ImageSize)).Cast()); - using (var s = client.GetStreamAsync("https:" + imageUrl)) - { - if (!Directory.Exists(LogoPath)) { Directory.CreateDirectory(LogoPath); } - using (var fs = new FileStream(Path.Combine(LogoPath, fileName + "." + extension), FileMode.OpenOrCreate)) - { - s.Result.CopyTo(fs); - } - } - } - } - - private enum LogoSize - { - t_thumb, - t_logo_med, - t_original + await comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath); } } } diff --git a/gaseous-server/Classes/Metadata/Communications.cs b/gaseous-server/Classes/Metadata/Communications.cs index fff1227..4a89556 100644 --- a/gaseous-server/Classes/Metadata/Communications.cs +++ b/gaseous-server/Classes/Metadata/Communications.cs @@ -1,4 +1,6 @@ +using System.ComponentModel; using System.Net; +using Humanizer; using IGDB; using RestEase; @@ -15,10 +17,12 @@ namespace gaseous_server.Classes.Metadata Config.IGDB.Secret ); + private HttpClient client = new HttpClient(); + /// /// Configure metadata API communications /// - public static MetadataSources MetadataSource + public static HasheousClient.Models.MetadataModel.MetadataSources MetadataSource { get { @@ -30,7 +34,7 @@ namespace gaseous_server.Classes.Metadata switch (value) { - case MetadataSources.IGDB: + case HasheousClient.Models.MetadataModel.MetadataSources.IGDB: // set rate limiter avoidance values RateLimitAvoidanceWait = 1500; RateLimitAvoidanceThreshold = 3; @@ -46,7 +50,7 @@ namespace gaseous_server.Classes.Metadata } } } - private static MetadataSources _MetadataSource = MetadataSources.None; + private static HasheousClient.Models.MetadataModel.MetadataSources _MetadataSource = HasheousClient.Models.MetadataModel.MetadataSources.None; // rate limit avoidance - what can we do to ensure that rate limiting is avoided? // these values affect all communications @@ -142,22 +146,6 @@ namespace gaseous_server.Classes.Metadata private int RetryAttempts = 0; private int RetryAttemptsMax = 3; - /// - /// Supported metadata sources - /// - public enum MetadataSources - { - /// - /// None - always returns null for metadata requests - should not really be using this source - /// - None, - - /// - /// IGDB - queries the IGDB service for metadata - /// - IGDB - } - /// /// Request data from the metadata API /// @@ -170,9 +158,9 @@ namespace gaseous_server.Classes.Metadata { switch (_MetadataSource) { - case MetadataSources.None: + case HasheousClient.Models.MetadataModel.MetadataSources.None: return null; - case MetadataSources.IGDB: + case HasheousClient.Models.MetadataModel.MetadataSources.IGDB: return await IGDBAPI(Endpoint, Fields, Query); default: return null; @@ -234,5 +222,207 @@ namespace gaseous_server.Classes.Metadata throw; } } + + /// + /// Download from the specified uri + /// + /// The uri to download from + /// The file name and path the download should be stored as + public Task DownloadFile(Uri uri, string DestinationFile) + { + var result = _DownloadFile(uri, DestinationFile); + + return result; + } + + private async Task _DownloadFile(Uri uri, string DestinationFile) + { + string DestinationDirectory = new FileInfo(DestinationFile).Directory.FullName; + + Logging.Log(Logging.LogType.Information, "Communications", "Downloading from " + uri.ToString() + " to " + DestinationFile); + + try + { + using (var s = client.GetStreamAsync(uri)) + { + s.ConfigureAwait(false); + + if (!Directory.Exists(DestinationDirectory)) + { + Directory.CreateDirectory(DestinationDirectory); + } + + using (var fs = new FileStream(DestinationFile, FileMode.OpenOrCreate)) + { + s.Result.CopyTo(fs); + } + } + + if (File.Exists(DestinationFile)) + { + FileInfo fi = new FileInfo(DestinationFile); + if (fi.Length > 0) + { + return true; + } + else + { + File.Delete(DestinationFile); + throw new Exception("Zero length file"); + } + } + else + { + throw new Exception("Zero length file"); + } + } + catch (Exception ex) + { + Logging.Log(Logging.LogType.Critical, "Communications", "Error while downloading from " + uri.ToString(), ex); + + throw; + } + + return false; + } + + public static async Task GetSpecificImageFromServer(string ImagePath, string ImageId, IGDBAPI_ImageSize size, List? FallbackSizes = null) + { + Communications comms = new Communications(); + List imageSizes = new List + { + size + }; + + string returnPath = ""; + FileInfo? fi; + + // get the image + try + { + returnPath = Path.Combine(ImagePath, size.ToString(), ImageId + ".jpg"); + + if (!File.Exists(returnPath)) + { + await comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath); + } + + if (File.Exists(returnPath)) + { + fi = new FileInfo(returnPath); + if (fi.Length == 0 || fi.LastWriteTimeUtc.AddDays(7) < DateTime.UtcNow) + { + File.Delete(returnPath); + await comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath); + } + } + + } + catch (HttpRequestException ex) + { + if (ex.StatusCode == HttpStatusCode.NotFound) + { + Logging.Log(Logging.LogType.Information, "Image Download", "Image not found, trying a different size."); + + if (FallbackSizes != null) + { + foreach (Communications.IGDBAPI_ImageSize imageSize in FallbackSizes) + { + returnPath = await GetSpecificImageFromServer(ImagePath, ImageId, imageSize, null); + } + } + } + } + + return returnPath; + } + + /// + /// See https://api-docs.igdb.com/?javascript#images for more information about the image url structure + /// + /// + /// The path to save the downloaded files to + public async Task IGDBAPI_GetImage(List ImageSizes, string ImageId, string OutputPath) + { + string urlTemplate = "https://images.igdb.com/igdb/image/upload/t_{size}/{hash}.jpg"; + + foreach (IGDBAPI_ImageSize ImageSize in ImageSizes) + { + string url = urlTemplate.Replace("{size}", Common.GetDescription(ImageSize)).Replace("{hash}", ImageId); + string newOutputPath = Path.Combine(OutputPath, Common.GetDescription(ImageSize)); + string OutputFile = ImageId + ".jpg"; + + await _DownloadFile(new Uri(url), Path.Combine(newOutputPath, OutputFile)); + } + } + + public enum IGDBAPI_ImageSize + { + /// + /// 90x128 Fit + /// + [Description("cover_small")] + cover_small, + + /// + /// 264x374 Fit + /// + [Description("cover_big")] + cover_big, + + /// + /// 589x320 Lfill, Centre gravity + /// + [Description("screenshot_med")] + screenshot_med, + + /// + /// 889x500 Lfill, Centre gravity + /// + [Description("screenshot_big")] + screenshot_big, + + /// + /// 1280x720 Lfill, Centre gravity + /// + [Description("screenshot_huge")] + screenshot_huge, + + /// + /// 284x160 Fit + /// + [Description("logo_med")] + logo_med, + + /// + /// 90x90 Thumb, Centre gravity + /// + [Description("thumb")] + thumb, + + /// + /// 35x35 Thumb, Centre gravity + /// + [Description("micro")] + micro, + + /// + /// 1280x720 Fit, Centre gravity + /// + [Description("720p")] + r720p, + + /// + /// 1920x1080 Fit, Centre gravity + /// + [Description("1080p")] + r1080p, + + /// + /// The originally uploaded image + /// + [Description("original")] + original + } } } \ No newline at end of file diff --git a/gaseous-server/Classes/Metadata/CompanyLogos.cs b/gaseous-server/Classes/Metadata/CompanyLogos.cs index 3f56165..d200584 100644 --- a/gaseous-server/Classes/Metadata/CompanyLogos.cs +++ b/gaseous-server/Classes/Metadata/CompanyLogos.cs @@ -13,7 +13,7 @@ namespace gaseous_server.Classes.Metadata { } - public static CompanyLogo? GetCompanyLogo(long? Id, string LogoPath) + public static CompanyLogo? GetCompanyLogo(long? Id, string ImagePath) { if ((Id == 0) || (Id == null)) { @@ -21,18 +21,18 @@ namespace gaseous_server.Classes.Metadata } else { - Task RetVal = _GetCompanyLogo(SearchUsing.id, Id, LogoPath); + Task RetVal = _GetCompanyLogo(SearchUsing.id, Id, ImagePath); return RetVal.Result; } } - public static CompanyLogo GetCompanyLogo(string Slug, string LogoPath) + public static CompanyLogo GetCompanyLogo(string Slug, string ImagePath) { - Task RetVal = _GetCompanyLogo(SearchUsing.slug, Slug, LogoPath); + Task RetVal = _GetCompanyLogo(SearchUsing.slug, Slug, ImagePath); return RetVal.Result; } - private static async Task _GetCompanyLogo(SearchUsing searchUsing, object searchValue, string LogoPath) + private static async Task _GetCompanyLogo(SearchUsing searchUsing, object searchValue, string ImagePath) { // check database first Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); @@ -64,7 +64,7 @@ namespace gaseous_server.Classes.Metadata switch (cacheStatus) { case Storage.CacheStatus.NotPresent: - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); if (returnValue != null) { Storage.NewCacheValue(returnValue); @@ -74,7 +74,7 @@ namespace gaseous_server.Classes.Metadata case Storage.CacheStatus.Expired: try { - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue, true); forceImageDownload = true; } @@ -91,13 +91,13 @@ namespace gaseous_server.Classes.Metadata throw new Exception("How did you get here?"); } - if (returnValue != null) + // check for presence of "original" quality file - download if absent or force download is true + string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg"); + if ((!File.Exists(localFile)) || forceImageDownload == true) { - if ((!File.Exists(Path.Combine(LogoPath, "Logo.jpg"))) || forceImageDownload == true) - { - GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_thumb); - GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_logo_med); - } + Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Company logo download forced."); + + GetImageFromServer(ImagePath, returnValue.ImageId); } return returnValue; @@ -109,64 +109,23 @@ namespace gaseous_server.Classes.Metadata slug } - private static async Task GetObjectFromServer(string WhereClause, string LogoPath) + private static async Task GetObjectFromServer(string WhereClause, string ImagePath) { - // get CompanyLogo metadata + // get Artwork metadata Communications comms = new Communications(); var results = await comms.APIComm(IGDBClient.Endpoints.CompanyLogos, fieldList, WhereClause); - if (results.Length > 0) - { - var result = results.First(); + var result = results.First(); - GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb); - GetImageFromServer(result.Url, LogoPath, LogoSize.t_logo_med); - - return result; - } - else - { - return null; - } + return result; } - - private static void GetImageFromServer(string Url, string LogoPath, LogoSize logoSize) + + private static async void GetImageFromServer(string ImagePath, string ImageId) { - using (var client = new HttpClient()) - { - string fileName = "Logo.jpg"; - string extension = "jpg"; - switch (logoSize) - { - case LogoSize.t_thumb: - fileName = "Logo_Thumb"; - extension = "jpg"; - break; - case LogoSize.t_logo_med: - fileName = "Logo_Medium"; - extension = "png"; - break; - default: - fileName = "Logo"; - extension = "jpg"; - break; - } - string imageUrl = Url.Replace(LogoSize.t_thumb.ToString(), logoSize.ToString()).Replace("jpg", extension); + Communications comms = new Communications(); + List imageSizes = new List(); + imageSizes.AddRange(Enum.GetValues(typeof(Communications.IGDBAPI_ImageSize)).Cast()); - using (var s = client.GetStreamAsync("https:" + imageUrl)) - { - if (!Directory.Exists(LogoPath)) { Directory.CreateDirectory(LogoPath); } - using (var fs = new FileStream(Path.Combine(LogoPath, fileName + "." + extension), FileMode.OpenOrCreate)) - { - s.Result.CopyTo(fs); - } - } - } - } - - private enum LogoSize - { - t_thumb, - t_logo_med + await comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath); } } } diff --git a/gaseous-server/Classes/Metadata/Covers.cs b/gaseous-server/Classes/Metadata/Covers.cs index 6f9a8ae..16858c8 100644 --- a/gaseous-server/Classes/Metadata/Covers.cs +++ b/gaseous-server/Classes/Metadata/Covers.cs @@ -1,6 +1,8 @@ using System; +using System.Net; using IGDB; using IGDB.Models; +using Microsoft.CodeAnalysis.Elfie.Model.Strings; namespace gaseous_server.Classes.Metadata @@ -13,7 +15,7 @@ namespace gaseous_server.Classes.Metadata { } - public static Cover? GetCover(long? Id, string LogoPath) + public static Cover? GetCover(long? Id, string ImagePath, bool GetImages = true) { if ((Id == 0) || (Id == null)) { @@ -21,18 +23,18 @@ namespace gaseous_server.Classes.Metadata } else { - Task RetVal = _GetCover(SearchUsing.id, Id, LogoPath); + Task RetVal = _GetCover(SearchUsing.id, Id, ImagePath, GetImages); return RetVal.Result; } } - public static Cover GetCover(string Slug, string LogoPath) + public static Cover GetCover(string Slug, string ImagePath, bool GetImages = true) { - Task RetVal = _GetCover(SearchUsing.slug, Slug, LogoPath); + Task RetVal = _GetCover(SearchUsing.slug, Slug, ImagePath, GetImages); return RetVal.Result; } - private static async Task _GetCover(SearchUsing searchUsing, object searchValue, string LogoPath) + private static async Task _GetCover(SearchUsing searchUsing, object searchValue, string ImagePath, bool GetImages = true) { // check database first Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); @@ -61,19 +63,20 @@ namespace gaseous_server.Classes.Metadata Cover returnValue = new Cover(); bool forceImageDownload = false; + ImagePath = Path.Combine(ImagePath, "Covers"); switch (cacheStatus) { case Storage.CacheStatus.NotPresent: - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue); - forceImageDownload = true; + if (GetImages == true) { forceImageDownload = true; } break; case Storage.CacheStatus.Expired: try { - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue, true); - forceImageDownload = true; + if (GetImages == true) { forceImageDownload = true; } } catch (Exception ex) { @@ -88,11 +91,21 @@ namespace gaseous_server.Classes.Metadata throw new Exception("How did you get here?"); } - if ((!File.Exists(Path.Combine(LogoPath, "Cover.jpg"))) || forceImageDownload == true) + if (forceImageDownload == true) { - //GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_thumb, returnValue.ImageId); - //GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_logo_med, returnValue.ImageId); - GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_original, returnValue.ImageId); + Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Cover download forced."); + + // check for presence of image file - download if absent or force download is true + List imageSizes = new List(); + imageSizes.AddRange(Enum.GetValues(typeof(Communications.IGDBAPI_ImageSize)).Cast()); + foreach (Communications.IGDBAPI_ImageSize size in imageSizes) + { + string localFile = Path.Combine(ImagePath, size.ToString(), returnValue.ImageId + ".jpg"); + if ((!File.Exists(localFile)) || forceImageDownload == true) + { + Communications.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, size, null); + } + } } return returnValue; @@ -104,63 +117,23 @@ namespace gaseous_server.Classes.Metadata slug } - private static async Task GetObjectFromServer(string WhereClause, string LogoPath) + private static async Task GetObjectFromServer(string WhereClause, string ImagePath) { // get Cover metadata Communications comms = new Communications(); var results = await comms.APIComm(IGDBClient.Endpoints.Covers, fieldList, WhereClause); var result = results.First(); - //GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId); - //GetImageFromServer(result.Url, LogoPath, LogoSize.t_logo_med, result.ImageId); - GetImageFromServer(result.Url, LogoPath, LogoSize.t_original, result.ImageId); - return result; } - private static void GetImageFromServer(string Url, string LogoPath, LogoSize logoSize, string ImageId) + public static async void GetImageFromServer(string ImagePath, string ImageId) { - using (var client = new HttpClient()) - { - string fileName = "Cover.jpg"; - string extension = "jpg"; - switch (logoSize) - { - case LogoSize.t_thumb: - fileName = "Cover_Thumb"; - extension = "jpg"; - break; - case LogoSize.t_logo_med: - fileName = "Cover_Medium"; - extension = "png"; - break; - case LogoSize.t_original: - fileName = "Cover"; - extension = "png"; - break; - default: - fileName = "Cover"; - extension = "jpg"; - break; - } - string imageUrl = Url.Replace(LogoSize.t_thumb.ToString(), logoSize.ToString()).Replace("jpg", extension); + Communications comms = new Communications(); + List imageSizes = new List(); + imageSizes.AddRange(Enum.GetValues(typeof(Communications.IGDBAPI_ImageSize)).Cast()); - using (var s = client.GetStreamAsync("https:" + imageUrl)) - { - if (!Directory.Exists(LogoPath)) { Directory.CreateDirectory(LogoPath); } - using (var fs = new FileStream(Path.Combine(LogoPath, fileName + "." + extension), FileMode.OpenOrCreate)) - { - s.Result.CopyTo(fs); - } - } - } - } - - private enum LogoSize - { - t_thumb, - t_logo_med, - t_original + await comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath); } } } diff --git a/gaseous-server/Classes/Metadata/Games.cs b/gaseous-server/Classes/Metadata/Games.cs index d61543d..7c19eff 100644 --- a/gaseous-server/Classes/Metadata/Games.cs +++ b/gaseous-server/Classes/Metadata/Games.cs @@ -129,7 +129,7 @@ namespace gaseous_server.Classes.Metadata { try { - Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game)); + Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), false); } catch (Exception ex) { @@ -441,9 +441,9 @@ namespace gaseous_server.Classes.Metadata { Game game = new Game{ Id = (long)row["Id"], - Name = (string)row["Name"], - Slug = (string)row["Slug"], - Summary = (string)row["Summary"] + Name = (string)Common.ReturnValueIfNull(row["Name"], ""), + Slug = (string)Common.ReturnValueIfNull(row["Slug"], ""), + Summary = (string)Common.ReturnValueIfNull(row["Summary"], "") }; searchResults.Add(game); } diff --git a/gaseous-server/Classes/Metadata/PlatformLogos.cs b/gaseous-server/Classes/Metadata/PlatformLogos.cs index cbf9b3e..4fc30fe 100644 --- a/gaseous-server/Classes/Metadata/PlatformLogos.cs +++ b/gaseous-server/Classes/Metadata/PlatformLogos.cs @@ -13,7 +13,7 @@ namespace gaseous_server.Classes.Metadata { } - public static PlatformLogo? GetPlatformLogo(long? Id, string LogoPath) + public static PlatformLogo? GetPlatformLogo(long? Id, string ImagePath) { if ((Id == 0) || (Id == null)) { @@ -21,18 +21,18 @@ namespace gaseous_server.Classes.Metadata } else { - Task RetVal = _GetPlatformLogo(SearchUsing.id, Id, LogoPath); + Task RetVal = _GetPlatformLogo(SearchUsing.id, Id, ImagePath); return RetVal.Result; } } - public static PlatformLogo GetPlatformLogo(string Slug, string LogoPath) + public static PlatformLogo GetPlatformLogo(string Slug, string ImagePath) { - Task RetVal = _GetPlatformLogo(SearchUsing.slug, Slug, LogoPath); + Task RetVal = _GetPlatformLogo(SearchUsing.slug, Slug, ImagePath); return RetVal.Result; } - private static async Task _GetPlatformLogo(SearchUsing searchUsing, object searchValue, string LogoPath) + private static async Task _GetPlatformLogo(SearchUsing searchUsing, object searchValue, string ImagePath) { // check database first Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); @@ -64,7 +64,7 @@ namespace gaseous_server.Classes.Metadata switch (cacheStatus) { case Storage.CacheStatus.NotPresent: - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); if (returnValue != null) { Storage.NewCacheValue(returnValue); @@ -74,7 +74,7 @@ namespace gaseous_server.Classes.Metadata case Storage.CacheStatus.Expired: try { - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue, true); forceImageDownload = true; } @@ -93,11 +93,14 @@ namespace gaseous_server.Classes.Metadata if (returnValue != null) { - if ((!File.Exists(Path.Combine(LogoPath, "Logo.jpg"))) || forceImageDownload == true) - { - GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_thumb); - GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_logo_med); - } + // check for presence of "original" quality file - download if absent or force download is true + string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg"); + if ((!File.Exists(localFile)) || forceImageDownload == true) + { + Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Platform logo download forced."); + + GetImageFromServer(ImagePath, returnValue.ImageId); + } } return returnValue; @@ -109,64 +112,23 @@ namespace gaseous_server.Classes.Metadata slug } - private static async Task GetObjectFromServer(string WhereClause, string LogoPath) + private static async Task GetObjectFromServer(string WhereClause, string ImagePath) { - // get PlatformLogo metadata + // get Artwork metadata Communications comms = new Communications(); - var results = await comms.APIComm(IGDBClient.Endpoints.PlatformLogos, fieldList, WhereClause); - if (results.Length > 0) - { - var result = results.First(); + var results = await comms.APIComm(IGDBClient.Endpoints.Artworks, fieldList, WhereClause); + var result = results.First(); - GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb); - GetImageFromServer(result.Url, LogoPath, LogoSize.t_logo_med); - - return result; - } - else - { - return null; - } + return result; } - - private static void GetImageFromServer(string Url, string LogoPath, LogoSize logoSize) + + private static async void GetImageFromServer(string ImagePath, string ImageId) { - using (var client = new HttpClient()) - { - string fileName = "Logo.jpg"; - string extension = "jpg"; - switch (logoSize) - { - case LogoSize.t_thumb: - fileName = "Logo_Thumb"; - extension = "jpg"; - break; - case LogoSize.t_logo_med: - fileName = "Logo_Medium"; - extension = "png"; - break; - default: - fileName = "Logo"; - extension = "jpg"; - break; - } - string imageUrl = Url.Replace(LogoSize.t_thumb.ToString(), logoSize.ToString()).Replace("jpg", extension); + Communications comms = new Communications(); + List imageSizes = new List(); + imageSizes.AddRange(Enum.GetValues(typeof(Communications.IGDBAPI_ImageSize)).Cast()); - using (var s = client.GetStreamAsync("https:" + imageUrl)) - { - if (!Directory.Exists(LogoPath)) { Directory.CreateDirectory(LogoPath); } - using (var fs = new FileStream(Path.Combine(LogoPath, fileName + "." + extension), FileMode.OpenOrCreate)) - { - s.Result.CopyTo(fs); - } - } - } - } - - private enum LogoSize - { - t_thumb, - t_logo_med + comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath); } } } diff --git a/gaseous-server/Classes/Metadata/Screenshots.cs b/gaseous-server/Classes/Metadata/Screenshots.cs index 7978b28..9ece1ee 100644 --- a/gaseous-server/Classes/Metadata/Screenshots.cs +++ b/gaseous-server/Classes/Metadata/Screenshots.cs @@ -13,7 +13,7 @@ namespace gaseous_server.Classes.Metadata { } - public static Screenshot? GetScreenshot(long? Id, string LogoPath) + public static Screenshot? GetScreenshot(long? Id, string ImagePath) { if ((Id == 0) || (Id == null)) { @@ -21,18 +21,18 @@ namespace gaseous_server.Classes.Metadata } else { - Task RetVal = _GetScreenshot(SearchUsing.id, Id, LogoPath); + Task RetVal = _GetScreenshot(SearchUsing.id, Id, ImagePath); return RetVal.Result; } } - public static Screenshot GetScreenshot(string Slug, string LogoPath) + public static Screenshot GetScreenshot(string Slug, string ImagePath) { - Task RetVal = _GetScreenshot(SearchUsing.slug, Slug, LogoPath); + Task RetVal = _GetScreenshot(SearchUsing.slug, Slug, ImagePath); return RetVal.Result; } - private static async Task _GetScreenshot(SearchUsing searchUsing, object searchValue, string LogoPath) + private static async Task _GetScreenshot(SearchUsing searchUsing, object searchValue, string ImagePath) { // check database first Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); @@ -61,18 +61,18 @@ namespace gaseous_server.Classes.Metadata Screenshot returnValue = new Screenshot(); bool forceImageDownload = false; - LogoPath = Path.Combine(LogoPath, "Screenshots"); + ImagePath = Path.Combine(ImagePath, "Screenshots"); switch (cacheStatus) { case Storage.CacheStatus.NotPresent: - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue); forceImageDownload = true; break; case Storage.CacheStatus.Expired: try { - returnValue = await GetObjectFromServer(WhereClause, LogoPath); + returnValue = await GetObjectFromServer(WhereClause, ImagePath); Storage.NewCacheValue(returnValue, true); forceImageDownload = true; } @@ -89,11 +89,13 @@ namespace gaseous_server.Classes.Metadata throw new Exception("How did you get here?"); } - if ((!File.Exists(Path.Combine(LogoPath, "Screenshot.jpg"))) || forceImageDownload == true) + // check for presence of "original" quality file - download if absent or force download is true + string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg"); + if ((!File.Exists(localFile)) || forceImageDownload == true) { - //GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_thumb, returnValue.ImageId); - //GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_logo_med, returnValue.ImageId); - GetImageFromServer(returnValue.Url, LogoPath, LogoSize.t_original, returnValue.ImageId); + Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Screenshot download forced."); + + GetImageFromServer(ImagePath, returnValue.ImageId); } return returnValue; @@ -105,64 +107,24 @@ namespace gaseous_server.Classes.Metadata slug } - private static async Task GetObjectFromServer(string WhereClause, string LogoPath) + private static async Task GetObjectFromServer(string WhereClause, string ImagePath) { // get Screenshot metadata Communications comms = new Communications(); var results = await comms.APIComm(IGDBClient.Endpoints.Screenshots, fieldList, WhereClause); var result = results.First(); - //GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId); - //GetImageFromServer(result.Url, LogoPath, LogoSize.t_logo_med, result.ImageId); - GetImageFromServer(result.Url, LogoPath, LogoSize.t_original, result.ImageId); - return result; } - private static void GetImageFromServer(string Url, string LogoPath, LogoSize logoSize, string ImageId) + private static async void GetImageFromServer(string ImagePath, string ImageId) { - using (var client = new HttpClient()) - { - string fileName = "Artwork.jpg"; - string extension = "jpg"; - switch (logoSize) - { - case LogoSize.t_thumb: - fileName = "_Thumb"; - extension = "jpg"; - break; - case LogoSize.t_logo_med: - fileName = "_Medium"; - extension = "png"; - break; - case LogoSize.t_original: - fileName = ""; - extension = "png"; - break; - default: - fileName = "Artwork"; - extension = "jpg"; - break; - } - fileName = ImageId + fileName; - string imageUrl = Url.Replace(LogoSize.t_thumb.ToString(), logoSize.ToString()).Replace("jpg", extension); + Communications comms = new Communications(); + List imageSizes = new List(); + imageSizes.Add(Communications.IGDBAPI_ImageSize.original); + imageSizes.Add(Communications.IGDBAPI_ImageSize.thumb); - using (var s = client.GetStreamAsync("https:" + imageUrl)) - { - if (!Directory.Exists(LogoPath)) { Directory.CreateDirectory(LogoPath); } - using (var fs = new FileStream(Path.Combine(LogoPath, fileName + "." + extension), FileMode.OpenOrCreate)) - { - s.Result.CopyTo(fs); - } - } - } - } - - private enum LogoSize - { - t_thumb, - t_logo_med, - t_original + await comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath); } } } diff --git a/gaseous-server/Classes/MetadataManagement.cs b/gaseous-server/Classes/MetadataManagement.cs index 09ebe52..2865f33 100644 --- a/gaseous-server/Classes/MetadataManagement.cs +++ b/gaseous-server/Classes/MetadataManagement.cs @@ -13,7 +13,7 @@ namespace gaseous_server.Classes DataTable dt = new DataTable(); // disabling forceRefresh - forceRefresh = false; + forceRefresh = true; // update platforms sql = "SELECT Id, `Name` FROM Platform;"; @@ -59,7 +59,7 @@ namespace gaseous_server.Classes try { Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ")"); - Metadata.Games.GetGame((long)dr["id"], true, false, forceRefresh); + Metadata.Games.GetGame((long)dr["id"], true, false, true); } catch (Exception ex) { diff --git a/gaseous-server/Classes/Roms.cs b/gaseous-server/Classes/Roms.cs index f1ee137..39cfc7d 100644 --- a/gaseous-server/Classes/Roms.cs +++ b/gaseous-server/Classes/Roms.cs @@ -139,16 +139,16 @@ namespace gaseous_server.Classes GameId = (long)romDR["gameid"], Name = (string)romDR["name"], Size = (long)romDR["size"], - CRC = ((string)romDR["crc"]).ToLower(), - MD5 = ((string)romDR["md5"]).ToLower(), - SHA1 = ((string)romDR["sha1"]).ToLower(), + Crc = ((string)romDR["crc"]).ToLower(), + Md5 = ((string)romDR["md5"]).ToLower(), + Sha1 = ((string)romDR["sha1"]).ToLower(), DevelopmentStatus = (string)romDR["developmentstatus"], Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject>>((string)Common.ReturnValueIfNull(romDR["attributes"], "[ ]")), - RomType = (int)romDR["romtype"], + RomType = (HasheousClient.Models.LookupResponseModel.RomItem.RomTypes)(int)romDR["romtype"], RomTypeMedia = (string)romDR["romtypemedia"], MediaLabel = (string)romDR["medialabel"], Path = (string)romDR["path"], - Source = (gaseous_signature_parser.models.RomSignatureObject.RomSignatureObject.Game.Rom.SignatureSourceType)(Int32)romDR["metadatasource"], + SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)romDR["metadatasource"], SignatureSourceGameTitle = (string)Common.ReturnValueIfNull(romDR["MetadataGameName"], ""), Library = GameLibrary.GetLibrary((int)romDR["LibraryId"]) }; @@ -176,130 +176,43 @@ namespace gaseous_server.Classes public List> Platforms { get; set; } } - public class GameRomItem + public class GameRomItem : HasheousClient.Models.LookupResponseModel.RomItem { - public long Id { get; set; } + //public long Id { get; set; } public long PlatformId { get; set; } public string Platform { get; set; } //public Dictionary? Emulator { get; set; } public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; } public long GameId { get; set; } - public string? Name { get; set; } - public long Size { get; set; } - public string? CRC { get; set; } - public string? MD5 { get; set; } - public string? SHA1 { get; set; } - public string? DevelopmentStatus { get; set; } - public string[]? Flags { get; set; } - public List>? Attributes { get; set;} - public int RomType { get; set; } - public string? RomTypeMedia { get; set; } - public MediaType? MediaDetail { - get - { - if (RomTypeMedia != null) - { - return new MediaType(Source, RomTypeMedia); - } - else - { - return null; - } - } - } - public string? MediaLabel { get; set; } + //public string? Name { get; set; } + //public long Size { get; set; } + //public string? CRC { get; set; } + //public string? MD5 { get; set; } + //public string? SHA1 { get; set; } + //public string? DevelopmentStatus { get; set; } + //public string[]? Flags { get; set; } + //public List>? Attributes { get; set;} + //public int RomType { get; set; } + //public string? RomTypeMedia { get; set; } + // public MediaType? MediaDetail { + // get + // { + // if (RomTypeMedia != null) + // { + // return new MediaType(Source, RomTypeMedia); + // } + // else + // { + // return null; + // } + // } + // } + // public string? MediaLabel { get; set; } public string? Path { get; set; } - public RomSignatureObject.Game.Rom.SignatureSourceType Source { get; set; } + //public SignatureSourceType Source { get; set; } public string? SignatureSourceGameTitle { get; set;} public GameLibrary.LibraryItem Library { get; set; } } - - public class MediaType - { - public MediaType(RomSignatureObject.Game.Rom.SignatureSourceType Source, string MediaTypeString) - { - switch (Source) - { - case RomSignatureObject.Game.Rom.SignatureSourceType.TOSEC: - string[] typeString = MediaTypeString.Split(" "); - - string inType = ""; - foreach (string typeStringVal in typeString) - { - if (inType == "") - { - switch (typeStringVal.ToLower()) - { - case "disk": - Media = RomSignatureObject.Game.Rom.RomTypes.Disk; - - inType = typeStringVal; - break; - case "disc": - Media = RomSignatureObject.Game.Rom.RomTypes.Disc; - - inType = typeStringVal; - break; - case "file": - Media = RomSignatureObject.Game.Rom.RomTypes.File; - - inType = typeStringVal; - break; - case "part": - Media = RomSignatureObject.Game.Rom.RomTypes.Part; - - inType = typeStringVal; - break; - case "tape": - Media = RomSignatureObject.Game.Rom.RomTypes.Tape; - - inType = typeStringVal; - break; - case "of": - inType = typeStringVal; - break; - case "side": - inType = typeStringVal; - break; - } - } - else { - switch (inType.ToLower()) - { - case "disk": - case "disc": - case "file": - case "part": - case "tape": - Number = int.Parse(typeStringVal); - break; - case "of": - Count = int.Parse(typeStringVal); - break; - case "side": - Side = typeStringVal; - break; - } - inType = ""; - } - } - - break; - - default: - break; - - } - } - - public RomSignatureObject.Game.Rom.RomTypes? Media { get; set; } - - public int? Number { get; set; } - - public int? Count { get; set; } - - public string? Side { get; set; } - } } } diff --git a/gaseous-server/Classes/SignatureManagement.cs b/gaseous-server/Classes/SignatureManagement.cs new file mode 100644 index 0000000..2ef5cde --- /dev/null +++ b/gaseous-server/Classes/SignatureManagement.cs @@ -0,0 +1,81 @@ +using System.Data; +using gaseous_signature_parser.models.RomSignatureObject; + +namespace gaseous_server.Classes +{ + public class SignatureManagement + { + 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); + } + } + + public List GetByTosecName(string TosecName = "") + { + if (TosecName.Length > 0) + { + return _GetSignature("Signatures_Roms.name = @searchstring", TosecName); + } else + { + return null; + } + } + + private List _GetSignature(string sqlWhere, string searchString) + { + Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); + string sql = "SELECT view_Signatures_Games.*, Signatures_Roms.Id AS romid, Signatures_Roms.Name AS romname, Signatures_Roms.Size, Signatures_Roms.CRC, Signatures_Roms.MD5, Signatures_Roms.SHA1, Signatures_Roms.DevelopmentStatus, Signatures_Roms.Attributes, Signatures_Roms.RomType, Signatures_Roms.RomTypeMedia, Signatures_Roms.MediaLabel, Signatures_Roms.MetadataSource FROM Signatures_Roms INNER JOIN 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) + { + gaseous_server.Models.Signatures_Games gameItem = new gaseous_server.Models.Signatures_Games + { + Game = new gaseous_server.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 = (gaseous_server.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 gaseous_server.Models.Signatures_Games.RomItem + { + Id = (Int32)sigDbRow["romid"], + Name = (string)sigDbRow["romname"], + Size = (Int64)sigDbRow["Size"], + Crc = (string)sigDbRow["CRC"], + Md5 = ((string)sigDbRow["MD5"]).ToLower(), + Sha1 = ((string)sigDbRow["SHA1"]).ToLower(), + DevelopmentStatus = (string)sigDbRow["DevelopmentStatus"], + Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject>>((string)Common.ReturnValueIfNull(sigDbRow["Attributes"], "[]")), + RomType = (gaseous_server.Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["RomType"], + RomTypeMedia = (string)sigDbRow["RomTypeMedia"], + MediaLabel = (string)sigDbRow["MediaLabel"], + SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)sigDbRow["MetadataSource"] + } + }; + GamesList.Add(gameItem); + } + return GamesList; + } + } +} \ No newline at end of file diff --git a/gaseous-server/Controllers/V1.0/GamesController.cs b/gaseous-server/Controllers/V1.0/GamesController.cs index 094b6c1..e825814 100644 --- a/gaseous-server/Controllers/V1.0/GamesController.cs +++ b/gaseous-server/Controllers/V1.0/GamesController.cs @@ -525,10 +525,10 @@ namespace gaseous_server.Controllers [MapToApiVersion("1.0")] [MapToApiVersion("1.1")] [HttpGet] - [Route("{GameId}/artwork/{ArtworkId}/image")] + [Route("{GameId}/artwork/{ArtworkId}/image/{size}")] [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GameCoverImage(long GameId, long ArtworkId) + public ActionResult GameCoverImage(long GameId, long ArtworkId, Communications.IGDBAPI_ImageSize size) { try { @@ -538,13 +538,13 @@ namespace gaseous_server.Controllers { IGDB.Models.Artwork artworkObject = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); if (artworkObject != null) { - string coverFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Artwork", artworkObject.ImageId + ".png"); + string coverFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Artwork", size.ToString(), artworkObject.ImageId + ".jpg"); if (System.IO.File.Exists(coverFilePath)) { - string filename = artworkObject.ImageId + ".png"; + string filename = artworkObject.ImageId + ".jpg"; string filepath = coverFilePath; byte[] filedata = System.IO.File.ReadAllBytes(filepath); - string contentType = "image/png"; + string contentType = "image/jpg"; var cd = new System.Net.Mime.ContentDisposition { @@ -592,7 +592,7 @@ namespace gaseous_server.Controllers IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false); if (gameObject != null) { - IGDB.Models.Cover coverObject = Covers.GetCover(gameObject.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); + IGDB.Models.Cover coverObject = Covers.GetCover(gameObject.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), false); if (coverObject != null) { return Ok(coverObject); @@ -616,37 +616,47 @@ namespace gaseous_server.Controllers [MapToApiVersion("1.0")] [MapToApiVersion("1.1")] [HttpGet] - [Route("{GameId}/cover/image")] + [Route("{GameId}/cover/image/{size}")] [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GameCoverImage(long GameId) + [ResponseCache(CacheProfileName = "None")] + public ActionResult GameCoverImage(long GameId, Communications.IGDBAPI_ImageSize size) { try { IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false); - string coverFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Cover.png"); - if (System.IO.File.Exists(coverFilePath)) { - string filename = "Cover.png"; - string filepath = coverFilePath; - byte[] filedata = System.IO.File.ReadAllBytes(filepath); - string contentType = "image/png"; - - var cd = new System.Net.Mime.ContentDisposition - { - FileName = filename, - Inline = true, - }; - - Response.Headers.Add("Content-Disposition", cd.ToString()); - Response.Headers.Add("Cache-Control", "public, max-age=604800"); - - return File(filedata, contentType); - } - else + if (gameObject.Cover != null) { - return NotFound(); + if (gameObject.Cover.Id != null) + { + IGDB.Models.Cover cover = Classes.Metadata.Covers.GetCover(gameObject.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), false); + string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Covers"); + + Task ImgFetch = Communications.GetSpecificImageFromServer(basePath, cover.ImageId, size, new List{ Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original }); + + string coverFilePath = ImgFetch.Result; + + if (System.IO.File.Exists(coverFilePath)) { + string filename = cover.ImageId + ".jpg"; + string filepath = coverFilePath; + byte[] filedata = System.IO.File.ReadAllBytes(filepath); + string contentType = "image/jpg"; + + var cd = new System.Net.Mime.ContentDisposition + { + FileName = filename, + Inline = true, + }; + + Response.Headers.Add("Content-Disposition", cd.ToString()); + //Response.Headers.Add("Cache-Control", "public, max-age=604800"); + + return File(filedata, contentType); + } + } } + return NotFound(); } catch { @@ -1232,7 +1242,7 @@ namespace gaseous_server.Controllers { Classes.Roms.GameRomItem romItem = Classes.Roms.GetRom(RomId); Common.hashObject hash = new Common.hashObject(romItem.Path); - Models.Signatures_Games romSig = Classes.ImportGame.GetFileSignature(hash, new FileInfo(romItem.Path), romItem.Path); + gaseous_server.Models.Signatures_Games romSig = FileSignature.GetFileSignature(hash, new FileInfo(romItem.Path), romItem.Path); List searchResults = Classes.ImportGame.SearchForGame_GetAll(romSig.Game.Name, romSig.Flags.IGDBPlatformId); return Ok(searchResults); @@ -1325,10 +1335,10 @@ namespace gaseous_server.Controllers [MapToApiVersion("1.0")] [MapToApiVersion("1.1")] [HttpGet] - [Route("{GameId}/screenshots/{ScreenshotId}/image")] + [Route("{GameId}/screenshots/{ScreenshotId}/image/{size}")] [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GameScreenshotImage(long GameId, long ScreenshotId) + public ActionResult GameScreenshotImage(long GameId, long ScreenshotId, Communications.IGDBAPI_ImageSize Size) { try { @@ -1336,13 +1346,13 @@ namespace gaseous_server.Controllers IGDB.Models.Screenshot screenshotObject = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); - string coverFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Screenshots", screenshotObject.ImageId + ".png"); + string coverFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Screenshots", Size.ToString(), screenshotObject.ImageId + ".jpg"); if (System.IO.File.Exists(coverFilePath)) { - string filename = screenshotObject.ImageId + ".png"; + string filename = screenshotObject.ImageId + ".jpg"; string filepath = coverFilePath; byte[] filedata = System.IO.File.ReadAllBytes(filepath); - string contentType = "image/png"; + string contentType = "image/jpg"; var cd = new System.Net.Mime.ContentDisposition { diff --git a/gaseous-server/Controllers/V1.0/SignaturesController.cs b/gaseous-server/Controllers/V1.0/SignaturesController.cs index 4040125..9cb7046 100644 --- a/gaseous-server/Controllers/V1.0/SignaturesController.cs +++ b/gaseous-server/Controllers/V1.0/SignaturesController.cs @@ -37,82 +37,27 @@ namespace gaseous_server.Controllers [MapToApiVersion("1.1")] [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] - public List GetSignature(string md5 = "", string sha1 = "") + 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); - } + SignatureManagement signatureManagement = new SignatureManagement(); + return signatureManagement.GetSignature(md5, sha1); } [MapToApiVersion("1.0")] [MapToApiVersion("1.1")] [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] - public List GetByTosecName(string TosecName = "") + public List GetByTosecName(string TosecName = "") { if (TosecName.Length > 0) { - return _GetSignature("Signatures_Roms.name = @searchstring", TosecName); + SignatureManagement signatureManagement = new SignatureManagement(); + return signatureManagement.GetByTosecName(TosecName); } else { return null; } } - - private List _GetSignature(string sqlWhere, string searchString) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "SELECT view_Signatures_Games.*, Signatures_Roms.Id AS romid, Signatures_Roms.Name AS romname, Signatures_Roms.Size, Signatures_Roms.CRC, Signatures_Roms.MD5, Signatures_Roms.SHA1, Signatures_Roms.DevelopmentStatus, Signatures_Roms.Attributes, Signatures_Roms.RomType, Signatures_Roms.RomTypeMedia, Signatures_Roms.MediaLabel, Signatures_Roms.MetadataSource FROM Signatures_Roms INNER JOIN 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"]).ToLower(), - Sha1 = ((string)sigDbRow["SHA1"]).ToLower(), - DevelopmentStatus = (string)sigDbRow["DevelopmentStatus"], - Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject>>((string)Common.ReturnValueIfNull(sigDbRow["Attributes"], "[]")), - RomType = (RomSignatureObject.Game.Rom.RomTypes)(int)sigDbRow["RomType"], - RomTypeMedia = (string)sigDbRow["RomTypeMedia"], - MediaLabel = (string)sigDbRow["MediaLabel"], - SignatureSource = (gaseous_signature_parser.models.RomSignatureObject.RomSignatureObject.Game.Rom.SignatureSourceType)(Int32)sigDbRow["MetadataSource"] - } - }; - GamesList.Add(gameItem); - } - return GamesList; - } } } diff --git a/gaseous-server/Models/PlatformMapping.cs b/gaseous-server/Models/PlatformMapping.cs index e513e8e..e62ac6f 100644 --- a/gaseous-server/Models/PlatformMapping.cs +++ b/gaseous-server/Models/PlatformMapping.cs @@ -358,7 +358,7 @@ namespace gaseous_server.Models return mapItem; } - public static void GetIGDBPlatformMapping(ref Models.Signatures_Games Signature, FileInfo RomFileInfo, bool SetSystemName) + public static void GetIGDBPlatformMapping(ref gaseous_server.Models.Signatures_Games Signature, FileInfo RomFileInfo, bool SetSystemName) { bool PlatformFound = false; foreach (Models.PlatformMapping.PlatformMapItem PlatformMapping in Models.PlatformMapping.PlatformMap) diff --git a/gaseous-server/Models/Signatures_Games.cs b/gaseous-server/Models/Signatures_Games.cs index 9aadb21..b2fe9b7 100644 --- a/gaseous-server/Models/Signatures_Games.cs +++ b/gaseous-server/Models/Signatures_Games.cs @@ -4,197 +4,19 @@ using gaseous_signature_parser.models.RomSignatureObject; namespace gaseous_server.Models { - public class Signatures_Games + public class Signatures_Games : HasheousClient.Models.LookupResponseModel { public Signatures_Games() { } - 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; } - 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 - } - - [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 - { - 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> Attributes { get; set; } = new List>(); - - public RomSignatureObject.Game.Rom.RomTypes RomType { get; set; } - public string? RomTypeMedia { get; set; } - public string? MediaLabel { get; set; } - - public RomSignatureObject.Game.Rom.SignatureSourceType SignatureSource { get; set; } - - [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 "attributes": - 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 long IGDBPlatformId { get; set; } public string IGDBPlatformName { get; set; } + public long IGDBGameId { get; set; } } } } diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs index 5e80110..ca1477b 100644 --- a/gaseous-server/Program.cs +++ b/gaseous-server/Program.cs @@ -50,7 +50,10 @@ Config.InitSettings(); Config.UpdateConfig(); // set api metadata source from config -Communications.MetadataSource = Config.MetadataConfiguration.Source; +Communications.MetadataSource = Config.MetadataConfiguration.MetadataSource; + +// set up hasheous client +HasheousClient.WebApp.HttpHelper.BaseUri = Config.MetadataConfiguration.HasheousHost; // set initial values Guid APIKey = Guid.NewGuid(); @@ -106,6 +109,11 @@ builder.Services.AddControllers().AddJsonOptions(x => builder.Services.AddResponseCaching(); builder.Services.AddControllers(options => { + options.CacheProfiles.Add("None", + new CacheProfile() + { + Duration = 1 + }); options.CacheProfiles.Add("Default30", new CacheProfile() { diff --git a/gaseous-server/gaseous-server.csproj b/gaseous-server/gaseous-server.csproj index 81bddac..98c91d0 100644 --- a/gaseous-server/gaseous-server.csproj +++ b/gaseous-server/gaseous-server.csproj @@ -20,11 +20,14 @@ + + + @@ -187,4 +190,7 @@ + + + diff --git a/gaseous-server/wwwroot/pages/EmulatorJS.html b/gaseous-server/wwwroot/pages/EmulatorJS.html index 8d9f4f9..2f60ae5 100644 --- a/gaseous-server/wwwroot/pages/EmulatorJS.html +++ b/gaseous-server/wwwroot/pages/EmulatorJS.html @@ -28,5 +28,7 @@ EJS_backgroundBlur = true; EJS_gameName = emuGameTitle; + + EJS_threads = false; \ No newline at end of file diff --git a/gaseous-server/wwwroot/pages/dialogs/rominfo.html b/gaseous-server/wwwroot/pages/dialogs/rominfo.html index ad4212b..fd4d1e6 100644 --- a/gaseous-server/wwwroot/pages/dialogs/rominfo.html +++ b/gaseous-server/wwwroot/pages/dialogs/rominfo.html @@ -128,9 +128,9 @@ document.getElementById('rominfo_type').innerHTML = getRomType(result.romType); document.getElementById('rominfo_mediatype').innerHTML = result.romTypeMedia; document.getElementById('rominfo_medialabel').innerHTML = result.mediaLabel; - document.getElementById('rominfo_md5').innerHTML = result.mD5; - document.getElementById('rominfo_sha1').innerHTML = result.shA1; - document.getElementById('rominfo_signaturematch').innerHTML = result.source; + document.getElementById('rominfo_md5').innerHTML = result.md5; + document.getElementById('rominfo_sha1').innerHTML = result.sha1; + document.getElementById('rominfo_signaturematch').innerHTML = result.signatureSource; document.getElementById('rominfo_signaturetitle').innerHTML = result.signatureSourceGameTitle; document.getElementById('properties_fixplatform').innerHTML = ""; diff --git a/gaseous-server/wwwroot/pages/game.html b/gaseous-server/wwwroot/pages/game.html index 0db35ba..65803d9 100644 --- a/gaseous-server/wwwroot/pages/game.html +++ b/gaseous-server/wwwroot/pages/game.html @@ -168,7 +168,7 @@ } else { var bg = document.getElementById('bgImage'); if (result.cover) { - bg.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/cover/image"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);'); + bg.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/cover/image/original"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);'); } else { var randomInt = randomIntFromInterval(1, 3); bg.setAttribute('style', 'background-image: url("/images/gamebg' + randomInt + '.jpg"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);'); @@ -234,7 +234,7 @@ var gameImage = document.createElement('img'); gameImage.className = 'game_cover_image'; if (result.cover) { - gameImage.src = '/api/v1.1/Games/' + result.id + '/cover/image'; + gameImage.src = '/api/v1.1/Games/' + result.id + '/cover/image/cover_big'; } else { gameImage.src = '/images/unknowngame.png'; gameImage.className = 'game_cover_image unknown'; @@ -298,7 +298,7 @@ var screenshotItem = document.createElement('div'); screenshotItem.id = 'gamescreenshots_gallery_' + imageIndex; screenshotItem.setAttribute('name', 'gamescreenshots_gallery_item'); - screenshotItem.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/screenshots/' + result.screenshots.ids[i] + '/image"); background-position: center; background-repeat: no-repeat; background-size: contain;)'); + screenshotItem.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/screenshots/' + result.screenshots.ids[i] + '/image/thumb"); background-position: center; background-repeat: no-repeat; background-size: contain;)'); screenshotItem.setAttribute('imageid', imageIndex); screenshotItem.setAttribute('imagetype', 0); screenshotItem.className = 'gamescreenshots_gallery_item'; @@ -584,7 +584,7 @@ if (gameRomItem.platformId == mediaGroup.platformId) { if (gameRomItem.emulator) { if (gameRomItem.emulator.type.length > 0) { - launchButton = 'Launch'; + launchButton = 'Launch'; break; } } @@ -673,7 +673,7 @@ artworksPosition = 0; } var bg = document.getElementById('bgImage'); - bg.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/artwork/' + artworks[artworksPosition] + '/image"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);'); + bg.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/artwork/' + artworks[artworksPosition] + '/image/original"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);'); artworksTimer = setTimeout(rotateBackground, 60000); } } @@ -698,7 +698,7 @@ switch (gameScreenshots_Selected.getAttribute('imagetype')) { case "0": // screenshot - gameScreenshots_Main.setAttribute('style', gameScreenshots_Selected.getAttribute('style')); + gameScreenshots_Main.setAttribute('style', gameScreenshots_Selected.getAttribute('style').replace("/image/thumb", "/image/original")); break; case "1": // video diff --git a/gaseous-server/wwwroot/scripts/gamesformating.js b/gaseous-server/wwwroot/scripts/gamesformating.js index d4a0e7d..e04dd78 100644 --- a/gaseous-server/wwwroot/scripts/gamesformating.js +++ b/gaseous-server/wwwroot/scripts/gamesformating.js @@ -192,7 +192,7 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification, } gameImage.src = '/images/unknowngame.png'; if (gameObject.cover) { - gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameObject.id + '/cover/image'); + gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameObject.id + '/cover/image/cover_big'); } else { gameImage.className = 'game_tile_image unknown'; } diff --git a/gaseous-server/wwwroot/scripts/main.js b/gaseous-server/wwwroot/scripts/main.js index 05b2788..847ee3d 100644 --- a/gaseous-server/wwwroot/scripts/main.js +++ b/gaseous-server/wwwroot/scripts/main.js @@ -260,7 +260,7 @@ function DropDownRenderGameOption(state) { if (state.cover) { response = $( - '' + '' ); } else { response = $(