WIP - Images are now pulled via Hasheous proxy

This commit is contained in:
Michael Green
2024-10-20 01:25:25 +11:00
parent f25b3d0eaa
commit 478044a5a1
6 changed files with 216 additions and 187 deletions

View File

@@ -1,9 +1,11 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Drawing;
using System.IO.Compression; using System.IO.Compression;
using System.Reflection; using System.Reflection;
using System.Security.Cryptography; using System.Security.Cryptography;
using static gaseous_server.Classes.Metadata.Communications;
namespace gaseous_server.Classes namespace gaseous_server.Classes
{ {
@@ -126,6 +128,27 @@ namespace gaseous_server.Classes
typeof(DescriptionAttribute)))?.Description ?? value.ToString(); typeof(DescriptionAttribute)))?.Description ?? value.ToString();
} }
public static Point GetResolution(this Enum value)
{
string width = ((ResolutionAttribute)Attribute.GetCustomAttribute(
value.GetType().GetFields(BindingFlags.Public | BindingFlags.Static)
.Single(x => x.GetValue(null).Equals(value)),
typeof(ResolutionAttribute)))?.width.ToString() ?? value.ToString();
string height = ((ResolutionAttribute)Attribute.GetCustomAttribute(
value.GetType().GetFields(BindingFlags.Public | BindingFlags.Static)
.Single(x => x.GetValue(null).Equals(value)),
typeof(ResolutionAttribute)))?.height.ToString() ?? value.ToString();
return new Point(int.Parse(width), int.Parse(height));
}
public static bool IsNullableEnum(this Type t)
{
Type u = Nullable.GetUnderlyingType(t);
return u != null && u.IsEnum;
}
// compression // compression
public static byte[] Compress(byte[] data) public static byte[] Compress(byte[] data)
{ {

View File

@@ -213,30 +213,37 @@ namespace gaseous_server.Classes
{ {
Logging.Log(Logging.LogType.Information, "Import Game", " Search type: " + searchType.ToString()); Logging.Log(Logging.LogType.Information, "Import Game", " Search type: " + searchType.ToString());
IGDB.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType); IGDB.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
if (games.Length == 1) if (games != null)
{ {
// exact match! if (games.Length == 1)
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
Logging.Log(Logging.LogType.Information, "Import Game", " IGDB game: " + determinedGame.Name);
GameFound = true;
break;
}
else if (games.Length > 0)
{
Logging.Log(Logging.LogType.Information, "Import Game", " " + games.Length + " search results found");
// quite likely we've found sequels and alternate types
foreach (Game game in games)
{ {
if (game.Name == SearchCandidate) // exact match!
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
Logging.Log(Logging.LogType.Information, "Import Game", " IGDB game: " + determinedGame.Name);
GameFound = true;
break;
}
else if (games.Length > 0)
{
Logging.Log(Logging.LogType.Information, "Import Game", " " + games.Length + " search results found");
// quite likely we've found sequels and alternate types
foreach (Game game in games)
{ {
// found game title matches the search candidate if (game.Name == SearchCandidate)
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false); {
Logging.Log(Logging.LogType.Information, "Import Game", "Found exact match!"); // found game title matches the search candidate
GameFound = true; determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
break; Logging.Log(Logging.LogType.Information, "Import Game", "Found exact match!");
GameFound = true;
break;
}
} }
} }
else
{
Logging.Log(Logging.LogType.Information, "Import Game", " No search results found");
}
} }
else else
{ {

View File

@@ -1,6 +1,7 @@
using System.Collections; using System.Collections;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Drawing; using System.Drawing;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
@@ -666,73 +667,73 @@ namespace gaseous_server.Classes.Metadata
switch (typeName) switch (typeName)
{ {
case "agerating": case "agerating":
HasheousClient.Models.Metadata.IGDB.AgeRating ageRatingResult = new AgeRating(); HasheousClient.Models.Metadata.IGDB.AgeRating ageRatingResult = new HasheousClient.Models.Metadata.IGDB.AgeRating();
ageRatingResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.AgeRating>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); ageRatingResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.AgeRating>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(ageRatingResult) }; return new T[] { ConvertToIGDBModel<T>(ageRatingResult) };
case "ageratingcontentdescription": case "ageratingcontentdescription":
HasheousClient.Models.Metadata.IGDB.AgeRatingContentDescription ageRatingContentDescriptionResult = new AgeRatingContentDescription(); HasheousClient.Models.Metadata.IGDB.AgeRatingContentDescription ageRatingContentDescriptionResult = new HasheousClient.Models.Metadata.IGDB.AgeRatingContentDescription();
ageRatingContentDescriptionResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.AgeRatingContentDescription>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); ageRatingContentDescriptionResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.AgeRatingContentDescription>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(ageRatingContentDescriptionResult) }; return new T[] { ConvertToIGDBModel<T>(ageRatingContentDescriptionResult) };
case "alternativename": case "alternativename":
HasheousClient.Models.Metadata.IGDB.AlternativeName alternativeNameResult = new AlternativeName(); HasheousClient.Models.Metadata.IGDB.AlternativeName alternativeNameResult = new HasheousClient.Models.Metadata.IGDB.AlternativeName();
alternativeNameResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.AlternativeName>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); alternativeNameResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.AlternativeName>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(alternativeNameResult) }; return new T[] { ConvertToIGDBModel<T>(alternativeNameResult) };
case "artwork": case "artwork":
HasheousClient.Models.Metadata.IGDB.Artwork artworkResult = new Artwork(); HasheousClient.Models.Metadata.IGDB.Artwork artworkResult = new HasheousClient.Models.Metadata.IGDB.Artwork();
artworkResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Artwork>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); artworkResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Artwork>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(artworkResult) }; return new T[] { ConvertToIGDBModel<T>(artworkResult) };
case "collection": case "collection":
HasheousClient.Models.Metadata.IGDB.Collection collectionResult = new Collection(); HasheousClient.Models.Metadata.IGDB.Collection collectionResult = new HasheousClient.Models.Metadata.IGDB.Collection();
collectionResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Collection>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); collectionResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Collection>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(collectionResult) }; return new T[] { ConvertToIGDBModel<T>(collectionResult) };
case "company": case "company":
HasheousClient.Models.Metadata.IGDB.Company companyResult = new Company(); HasheousClient.Models.Metadata.IGDB.Company companyResult = new HasheousClient.Models.Metadata.IGDB.Company();
companyResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Company>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); companyResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Company>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(companyResult) }; return new T[] { ConvertToIGDBModel<T>(companyResult) };
case "companylogo": case "companylogo":
HasheousClient.Models.Metadata.IGDB.CompanyLogo companyLogoResult = new CompanyLogo(); HasheousClient.Models.Metadata.IGDB.CompanyLogo companyLogoResult = new HasheousClient.Models.Metadata.IGDB.CompanyLogo();
companyLogoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.CompanyLogo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); companyLogoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.CompanyLogo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(companyLogoResult) }; return new T[] { ConvertToIGDBModel<T>(companyLogoResult) };
case "companywebsite": case "companywebsite":
HasheousClient.Models.Metadata.IGDB.CompanyWebsite companyWebsiteResult = new CompanyWebsite(); HasheousClient.Models.Metadata.IGDB.CompanyWebsite companyWebsiteResult = new HasheousClient.Models.Metadata.IGDB.CompanyWebsite();
companyWebsiteResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.CompanyWebsite>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); companyWebsiteResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.CompanyWebsite>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(companyWebsiteResult) }; return new T[] { ConvertToIGDBModel<T>(companyWebsiteResult) };
case "cover": case "cover":
HasheousClient.Models.Metadata.IGDB.Cover coverResult = new Cover(); HasheousClient.Models.Metadata.IGDB.Cover coverResult = new HasheousClient.Models.Metadata.IGDB.Cover();
coverResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Cover>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); coverResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Cover>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(coverResult) }; return new T[] { ConvertToIGDBModel<T>(coverResult) };
case "externalgame": case "externalgame":
HasheousClient.Models.Metadata.IGDB.ExternalGame externalGameResult = new ExternalGame(); HasheousClient.Models.Metadata.IGDB.ExternalGame externalGameResult = new HasheousClient.Models.Metadata.IGDB.ExternalGame();
externalGameResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.ExternalGame>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); externalGameResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.ExternalGame>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(externalGameResult) }; return new T[] { ConvertToIGDBModel<T>(externalGameResult) };
case "franchise": case "franchise":
HasheousClient.Models.Metadata.IGDB.Franchise franchiseResult = new Franchise(); HasheousClient.Models.Metadata.IGDB.Franchise franchiseResult = new HasheousClient.Models.Metadata.IGDB.Franchise();
franchiseResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Franchise>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); franchiseResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Franchise>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(franchiseResult) }; return new T[] { ConvertToIGDBModel<T>(franchiseResult) };
case "game": case "game":
HasheousClient.Models.Metadata.IGDB.Game gameResult = new Game(); HasheousClient.Models.Metadata.IGDB.Game gameResult = new HasheousClient.Models.Metadata.IGDB.Game();
if (Fields == "slug") if (Fields == "slug")
{ {
gameResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Game>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, Query.ToString()); gameResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Game>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, Query.ToString());
@@ -745,61 +746,61 @@ namespace gaseous_server.Classes.Metadata
return new T[] { ConvertToIGDBModel<T>(gameResult) }; return new T[] { ConvertToIGDBModel<T>(gameResult) };
case "gameengine": case "gameengine":
HasheousClient.Models.Metadata.IGDB.GameEngine gameEngineResult = new GameEngine(); HasheousClient.Models.Metadata.IGDB.GameEngine gameEngineResult = new HasheousClient.Models.Metadata.IGDB.GameEngine();
gameEngineResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameEngine>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); gameEngineResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameEngine>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(gameEngineResult) }; return new T[] { ConvertToIGDBModel<T>(gameEngineResult) };
case "gameenginelogo": case "gameenginelogo":
HasheousClient.Models.Metadata.IGDB.GameEngineLogo gameEngineLogoResult = new GameEngineLogo(); HasheousClient.Models.Metadata.IGDB.GameEngineLogo gameEngineLogoResult = new HasheousClient.Models.Metadata.IGDB.GameEngineLogo();
gameEngineLogoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameEngineLogo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); gameEngineLogoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameEngineLogo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(gameEngineLogoResult) }; return new T[] { ConvertToIGDBModel<T>(gameEngineLogoResult) };
case "gamelocalization": case "gamelocalization":
HasheousClient.Models.Metadata.IGDB.GameLocalization gameLocalizationResult = new GameLocalization(); HasheousClient.Models.Metadata.IGDB.GameLocalization gameLocalizationResult = new HasheousClient.Models.Metadata.IGDB.GameLocalization();
gameLocalizationResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameLocalization>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); gameLocalizationResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameLocalization>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(gameLocalizationResult) }; return new T[] { ConvertToIGDBModel<T>(gameLocalizationResult) };
case "gamemode": case "gamemode":
HasheousClient.Models.Metadata.IGDB.GameMode gameModeResult = new GameMode(); HasheousClient.Models.Metadata.IGDB.GameMode gameModeResult = new HasheousClient.Models.Metadata.IGDB.GameMode();
gameModeResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameMode>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); gameModeResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameMode>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(gameModeResult) }; return new T[] { ConvertToIGDBModel<T>(gameModeResult) };
case "gamevideo": case "gamevideo":
HasheousClient.Models.Metadata.IGDB.GameVideo gameVideoResult = new GameVideo(); HasheousClient.Models.Metadata.IGDB.GameVideo gameVideoResult = new HasheousClient.Models.Metadata.IGDB.GameVideo();
gameVideoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameVideo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); gameVideoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.GameVideo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(gameVideoResult) }; return new T[] { ConvertToIGDBModel<T>(gameVideoResult) };
case "genre": case "genre":
HasheousClient.Models.Metadata.IGDB.Genre genreResult = new Genre(); HasheousClient.Models.Metadata.IGDB.Genre genreResult = new HasheousClient.Models.Metadata.IGDB.Genre();
genreResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Genre>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); genreResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Genre>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(genreResult) }; return new T[] { ConvertToIGDBModel<T>(genreResult) };
case "involvedcompany": case "involvedcompany":
HasheousClient.Models.Metadata.IGDB.InvolvedCompany involvedCompanyResult = new InvolvedCompany(); HasheousClient.Models.Metadata.IGDB.InvolvedCompany involvedCompanyResult = new HasheousClient.Models.Metadata.IGDB.InvolvedCompany();
involvedCompanyResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.InvolvedCompany>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); involvedCompanyResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.InvolvedCompany>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(involvedCompanyResult) }; return new T[] { ConvertToIGDBModel<T>(involvedCompanyResult) };
case "multiplayermode": case "multiplayermode":
HasheousClient.Models.Metadata.IGDB.MultiplayerMode multiplayerModeResult = new MultiplayerMode(); HasheousClient.Models.Metadata.IGDB.MultiplayerMode multiplayerModeResult = new HasheousClient.Models.Metadata.IGDB.MultiplayerMode();
multiplayerModeResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.MultiplayerMode>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); multiplayerModeResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.MultiplayerMode>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(multiplayerModeResult) }; return new T[] { ConvertToIGDBModel<T>(multiplayerModeResult) };
case "platformlogo": case "platformlogo":
HasheousClient.Models.Metadata.IGDB.PlatformLogo platformLogoResult = new PlatformLogo(); HasheousClient.Models.Metadata.IGDB.PlatformLogo platformLogoResult = new HasheousClient.Models.Metadata.IGDB.PlatformLogo();
platformLogoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.PlatformLogo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); platformLogoResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.PlatformLogo>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(platformLogoResult) }; return new T[] { ConvertToIGDBModel<T>(platformLogoResult) };
case "platform": case "platform":
HasheousClient.Models.Metadata.IGDB.Platform platformResult = new Platform(); HasheousClient.Models.Metadata.IGDB.Platform platformResult = new HasheousClient.Models.Metadata.IGDB.Platform();
if (Fields == "slug") if (Fields == "slug")
{ {
platformResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Platform>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, Query.ToString()); platformResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Platform>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, Query.ToString());
@@ -812,31 +813,31 @@ namespace gaseous_server.Classes.Metadata
return new T[] { ConvertToIGDBModel<T>(platformResult) }; return new T[] { ConvertToIGDBModel<T>(platformResult) };
case "platformversion": case "platformversion":
HasheousClient.Models.Metadata.IGDB.PlatformVersion platformVersionResult = new PlatformVersion(); HasheousClient.Models.Metadata.IGDB.PlatformVersion platformVersionResult = new HasheousClient.Models.Metadata.IGDB.PlatformVersion();
platformVersionResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.PlatformVersion>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); platformVersionResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.PlatformVersion>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(platformVersionResult) }; return new T[] { ConvertToIGDBModel<T>(platformVersionResult) };
case "playerperspective": case "playerperspective":
HasheousClient.Models.Metadata.IGDB.PlayerPerspective playerPerspectiveResult = new PlayerPerspective(); HasheousClient.Models.Metadata.IGDB.PlayerPerspective playerPerspectiveResult = new HasheousClient.Models.Metadata.IGDB.PlayerPerspective();
playerPerspectiveResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.PlayerPerspective>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); playerPerspectiveResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.PlayerPerspective>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(playerPerspectiveResult) }; return new T[] { ConvertToIGDBModel<T>(playerPerspectiveResult) };
case "releasedate": case "releasedate":
HasheousClient.Models.Metadata.IGDB.ReleaseDate releaseDateResult = new ReleaseDate(); HasheousClient.Models.Metadata.IGDB.ReleaseDate releaseDateResult = new HasheousClient.Models.Metadata.IGDB.ReleaseDate();
releaseDateResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.ReleaseDate>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); releaseDateResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.ReleaseDate>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(releaseDateResult) }; return new T[] { ConvertToIGDBModel<T>(releaseDateResult) };
case "screenshot": case "screenshot":
HasheousClient.Models.Metadata.IGDB.Screenshot screenshotResult = new Screenshot(); HasheousClient.Models.Metadata.IGDB.Screenshot screenshotResult = new HasheousClient.Models.Metadata.IGDB.Screenshot();
screenshotResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Screenshot>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); screenshotResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Screenshot>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(screenshotResult) }; return new T[] { ConvertToIGDBModel<T>(screenshotResult) };
case "theme": case "theme":
HasheousClient.Models.Metadata.IGDB.Theme themeResult = new Theme(); HasheousClient.Models.Metadata.IGDB.Theme themeResult = new HasheousClient.Models.Metadata.IGDB.Theme();
themeResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Theme>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString())); themeResult = hasheous.GetMetadataProxy<HasheousClient.Models.Metadata.IGDB.Theme>(Endpoint, HasheousClient.Hasheous.MetadataProvider.IGDB, long.Parse(Query.ToString()));
return new T[] { ConvertToIGDBModel<T>(themeResult) }; return new T[] { ConvertToIGDBModel<T>(themeResult) };
@@ -872,12 +873,29 @@ namespace gaseous_server.Classes.Metadata
// check if the property is an enum // check if the property is an enum
if (property.PropertyType.IsEnum) if (property.PropertyType.IsEnum)
{ {
// get the enum type // check if property is null
Type enumType = property.PropertyType; if (input.GetType().GetProperty(property.Name).GetValue(input) != null)
// get the enum value {
object enumValue = Enum.Parse(enumType, input.GetType().GetProperty(property.Name).GetValue(input).ToString()); // get the enum type
// set the enum value Type enumType = property.PropertyType;
property.SetValue(output, enumValue); // get the enum value
object enumValue = Enum.Parse(enumType, input.GetType().GetProperty(property.Name).GetValue(input).ToString());
// set the enum value
property.SetValue(output, enumValue);
}
}
else if (Common.IsNullableEnum(property.PropertyType))
{
// check if property is null
if (input.GetType().GetProperty(property.Name).GetValue(input) != null)
{
// get the enum type
Type enumType = property.PropertyType;
// get the enum value
object enumValue = Enum.Parse(enumType.GenericTypeArguments[0], input.GetType().GetProperty(property.Name).GetValue(input).ToString());
// set the enum value
property.SetValue(output, enumValue);
}
} }
else else
{ {
@@ -886,17 +904,6 @@ namespace gaseous_server.Classes.Metadata
{ {
switch (propertyTypeName) switch (propertyTypeName)
{ {
case "string":
case "int":
case "int32":
case "int64":
case "long":
case "datetime":
case "datetimeoffset":
case "bool":
property.SetValue(output, inputProperty.GetValue(input));
break;
case "identityorvalue`1": case "identityorvalue`1":
// create new identityorvalue object, set the id property to the input property value // create new identityorvalue object, set the id property to the input property value
@@ -943,6 +950,10 @@ namespace gaseous_server.Classes.Metadata
property.SetValue(output, identitiesOrValues); property.SetValue(output, identitiesOrValues);
} }
break; break;
default:
property.SetValue(output, inputProperty.GetValue(input));
break;
} }
} }
} }
@@ -967,6 +978,8 @@ namespace gaseous_server.Classes.Metadata
private async Task<bool?> _DownloadFile(Uri uri, string DestinationFile) private async Task<bool?> _DownloadFile(Uri uri, string DestinationFile)
{ {
ConfigureHasheousClient();
string DestinationDirectory = new FileInfo(DestinationFile).Directory.FullName; string DestinationDirectory = new FileInfo(DestinationFile).Directory.FullName;
if (!Directory.Exists(DestinationDirectory)) if (!Directory.Exists(DestinationDirectory))
{ {
@@ -1036,121 +1049,69 @@ namespace gaseous_server.Classes.Metadata
public async Task<string> GetSpecificImageFromServer(string ImagePath, string ImageId, IGDBAPI_ImageSize size, List<IGDBAPI_ImageSize>? FallbackSizes = null) public async Task<string> GetSpecificImageFromServer(string ImagePath, string ImageId, IGDBAPI_ImageSize size, List<IGDBAPI_ImageSize>? FallbackSizes = null)
{ {
string returnPath = ""; string originalPath = Path.Combine(ImagePath, IGDBAPI_ImageSize.original.ToString(), ImageId + ".jpg");
string requestedPath = Path.Combine(ImagePath, size.ToString(), ImageId + ".jpg");
// check for artificial sizes first // create the directory if it doesn't exist
switch (size) if (!Directory.Exists(Path.GetDirectoryName(originalPath)))
{ {
case IGDBAPI_ImageSize.screenshot_small: Directory.CreateDirectory(Path.GetDirectoryName(originalPath));
case IGDBAPI_ImageSize.screenshot_thumb: }
string BasePath = Path.Combine(ImagePath, size.ToString()); if (!Directory.Exists(Path.GetDirectoryName(requestedPath)))
if (!Directory.Exists(BasePath)) {
{ Directory.CreateDirectory(Path.GetDirectoryName(originalPath));
Directory.CreateDirectory(BasePath);
}
returnPath = Path.Combine(BasePath, ImageId + ".jpg");
if (!File.Exists(returnPath))
{
// get original size image and resize
string originalSizePath = await GetSpecificImageFromServer(ImagePath, ImageId, IGDBAPI_ImageSize.original, null);
int width = 0;
int height = 0;
switch (size)
{
case IGDBAPI_ImageSize.screenshot_small:
// 235x128
width = 235;
height = 128;
break;
case IGDBAPI_ImageSize.screenshot_thumb:
// 165x90
width = 165;
height = 90;
break;
}
using (var image = new ImageMagick.MagickImage(originalSizePath))
{
image.Resize(width, height);
image.Strip();
image.Write(returnPath);
}
}
break;
default:
// these sizes are IGDB native
if (RateLimitResumeTime > DateTime.UtcNow)
{
Logging.Log(Logging.LogType.Information, "API Connection", "Metadata source rate limit hit. Pausing API communications until " + RateLimitResumeTime.ToString() + ". Attempt " + RetryAttempts + " of " + RetryAttemptsMax + " retries.");
Thread.Sleep(RateLimitRecoveryWaitTime);
}
if (InRateLimitAvoidanceMode == true)
{
// sleep for a moment to help avoid hitting the rate limiter
Logging.Log(Logging.LogType.Information, "API Connection: Fetch Image", "Metadata source rate limit hit. Pausing API communications for " + RateLimitAvoidanceWait + " milliseconds to avoid rate limiter.");
Thread.Sleep(RateLimitAvoidanceWait);
}
Communications comms = new Communications();
List<IGDBAPI_ImageSize> imageSizes = new List<IGDBAPI_ImageSize>
{
size
};
// get the image
try
{
returnPath = Path.Combine(ImagePath, size.ToString(), ImageId + ".jpg");
// fail early if the file is already downloaded
if (!File.Exists(returnPath))
{
switch (_MetadataSource)
{
case HasheousClient.Models.MetadataModel.MetadataSources.IGDB:
await comms.IGDBAPI_GetImage(imageSizes, ImageId, ImagePath);
break;
case HasheousClient.Models.MetadataModel.MetadataSources.Hasheous:
await comms.HasheousAPI_GetImage(imageSizes, ImageId, ImagePath);
break;
default:
break;
}
}
}
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);
}
}
}
}
// increment rate limiter avoidance call count
RateLimitAvoidanceCallCount += 1;
break;
} }
return returnPath; // get the resolution attribute for enum size
Point resolution = Common.GetResolution(size);
// check if the original image exists
if (!File.Exists(originalPath))
{
// sleep if the rate limiter is active
if (RateLimitResumeTime > DateTime.UtcNow)
{
Logging.Log(Logging.LogType.Information, "API Connection", "Metadata source rate limit hit. Pausing API communications until " + RateLimitResumeTime.ToString() + ". Attempt " + RetryAttempts + " of " + RetryAttemptsMax + " retries.");
Thread.Sleep(RateLimitRecoveryWaitTime);
}
if (InRateLimitAvoidanceMode == true)
{
// sleep for a moment to help avoid hitting the rate limiter
Logging.Log(Logging.LogType.Information, "API Connection: Fetch Image", "Metadata source rate limit hit. Pausing API communications for " + RateLimitAvoidanceWait + " milliseconds to avoid rate limiter.");
Thread.Sleep(RateLimitAvoidanceWait);
}
// get the original image
Communications comms = new Communications();
switch (_MetadataSource)
{
case HasheousClient.Models.MetadataModel.MetadataSources.IGDB:
await comms.IGDBAPI_GetImage(ImageId, ImagePath);
break;
case HasheousClient.Models.MetadataModel.MetadataSources.Hasheous:
await comms.HasheousAPI_GetImage(ImageId, ImagePath);
break;
default:
break;
}
}
// check if the requested image exists
if (!File.Exists(requestedPath))
{
// get the original image
using (var image = new ImageMagick.MagickImage(originalPath))
{
image.Resize(resolution.X, resolution.Y);
image.Strip();
image.Write(requestedPath);
}
}
return requestedPath;
} }
public static T? GetSearchCache<T>(string SearchFields, string SearchString) public static T? GetSearchCache<T>(string SearchFields, string SearchString)
@@ -1208,22 +1169,19 @@ namespace gaseous_server.Classes.Metadata
/// </summary> /// </summary>
/// <param name="ImageId"></param> /// <param name="ImageId"></param>
/// <param name="outputPath">The path to save the downloaded files to /// <param name="outputPath">The path to save the downloaded files to
public async Task IGDBAPI_GetImage(List<IGDBAPI_ImageSize> ImageSizes, string ImageId, string OutputPath) public async Task IGDBAPI_GetImage(string ImageId, string OutputPath)
{ {
string urlTemplate = "https://images.igdb.com/igdb/image/upload/t_{size}/{hash}.jpg"; string urlTemplate = "https://images.igdb.com/igdb/image/upload/t_{size}/{hash}.jpg";
foreach (IGDBAPI_ImageSize ImageSize in ImageSizes) string url = urlTemplate.Replace("{size}", "original").Replace("{hash}", ImageId);
{ string newOutputPath = Path.Combine(OutputPath, "original");
string url = urlTemplate.Replace("{size}", Common.GetDescription(ImageSize)).Replace("{hash}", ImageId); string OutputFile = ImageId + ".jpg";
string newOutputPath = Path.Combine(OutputPath, Common.GetDescription(ImageSize)); string fullPath = Path.Combine(newOutputPath, OutputFile);
string OutputFile = ImageId + ".jpg";
string fullPath = Path.Combine(newOutputPath, OutputFile);
await _DownloadFile(new Uri(url), fullPath); await _DownloadFile(new Uri(url), fullPath);
}
} }
public async Task HasheousAPI_GetImage(List<IGDBAPI_ImageSize> ImageSizes, string ImageId, string OutputPath) public async Task HasheousAPI_GetImage(string ImageId, string OutputPath)
{ {
string urlTemplate = HasheousClient.WebApp.HttpHelper.BaseUri + "api/v1/MetadataProxy/IGDB/Image/{hash}.jpg"; string urlTemplate = HasheousClient.WebApp.HttpHelper.BaseUri + "api/v1/MetadataProxy/IGDB/Image/{hash}.jpg";
@@ -1241,79 +1199,118 @@ namespace gaseous_server.Classes.Metadata
/// 90x128 Fit /// 90x128 Fit
/// </summary> /// </summary>
[Description("cover_small")] [Description("cover_small")]
[Resolution(90, 128)]
cover_small, cover_small,
/// <summary> /// <summary>
/// 264x374 Fit /// 264x374 Fit
/// </summary> /// </summary>
[Description("cover_big")] [Description("cover_big")]
[Resolution(264, 374)]
cover_big, cover_big,
/// <summary> /// <summary>
/// 165x90 Lfill, Centre gravity - resized by Gaseous and is not a real IGDB size /// 165x90 Lfill, Centre gravity - resized by Gaseous and is not a real IGDB size
/// </summary> /// </summary>
[Description("screenshot_thumb")] [Description("screenshot_thumb")]
[Resolution(165, 90)]
screenshot_thumb, screenshot_thumb,
/// <summary> /// <summary>
/// 235x128 Lfill, Centre gravity - resized by Gaseous and is not a real IGDB size /// 235x128 Lfill, Centre gravity - resized by Gaseous and is not a real IGDB size
/// </summary> /// </summary>
[Description("screenshot_small")] [Description("screenshot_small")]
[Resolution(235, 128)]
screenshot_small, screenshot_small,
/// <summary> /// <summary>
/// 589x320 Lfill, Centre gravity /// 589x320 Lfill, Centre gravity
/// </summary> /// </summary>
[Description("screenshot_med")] [Description("screenshot_med")]
[Resolution(589, 320)]
screenshot_med, screenshot_med,
/// <summary> /// <summary>
/// 889x500 Lfill, Centre gravity /// 889x500 Lfill, Centre gravity
/// </summary> /// </summary>
[Description("screenshot_big")] [Description("screenshot_big")]
[Resolution(889, 500)]
screenshot_big, screenshot_big,
/// <summary> /// <summary>
/// 1280x720 Lfill, Centre gravity /// 1280x720 Lfill, Centre gravity
/// </summary> /// </summary>
[Description("screenshot_huge")] [Description("screenshot_huge")]
[Resolution(1280, 720)]
screenshot_huge, screenshot_huge,
/// <summary> /// <summary>
/// 284x160 Fit /// 284x160 Fit
/// </summary> /// </summary>
[Description("logo_med")] [Description("logo_med")]
[Resolution(284, 160)]
logo_med, logo_med,
/// <summary> /// <summary>
/// 90x90 Thumb, Centre gravity /// 90x90 Thumb, Centre gravity
/// </summary> /// </summary>
[Description("thumb")] [Description("thumb")]
[Resolution(90, 90)]
thumb, thumb,
/// <summary> /// <summary>
/// 35x35 Thumb, Centre gravity /// 35x35 Thumb, Centre gravity
/// </summary> /// </summary>
[Description("micro")] [Description("micro")]
[Resolution(35, 35)]
micro, micro,
/// <summary> /// <summary>
/// 1280x720 Fit, Centre gravity /// 1280x720 Fit, Centre gravity
/// </summary> /// </summary>
[Description("720p")] [Description("720p")]
[Resolution(1280, 720)]
r720p, r720p,
/// <summary> /// <summary>
/// 1920x1080 Fit, Centre gravity /// 1920x1080 Fit, Centre gravity
/// </summary> /// </summary>
[Description("1080p")] [Description("1080p")]
[Resolution(1920, 1080)]
r1080p, r1080p,
/// <summary> /// <summary>
/// The originally uploaded image /// The originally uploaded image
/// </summary> /// </summary>
[Description("original")] [Description("original")]
[Resolution(0, 0)]
original original
} }
/// <summary>
/// Specifies a resolution for an image size enum
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class ResolutionAttribute : Attribute
{
public static readonly ResolutionAttribute Default = new ResolutionAttribute();
public ResolutionAttribute() : this(0, 0)
{
}
public ResolutionAttribute(int width, int height)
{
ResolutionWidth = width;
ResolutionHeight = height;
}
public virtual int width => ResolutionWidth;
public virtual int height => ResolutionHeight;
protected int ResolutionWidth { get; set; }
protected int ResolutionHeight { get; set; }
}
} }
} }

View File

@@ -271,7 +271,7 @@ namespace gaseous_server.Classes
PlatformId = (long)romDR["platformid"], PlatformId = (long)romDR["platformid"],
Platform = (string)romDR["platformname"], Platform = (string)romDR["platformname"],
GameId = (long)romDR["gameid"], GameId = (long)romDR["gameid"],
Game = (string)romDR["gamename"], Game = (string)Common.ReturnValueIfNull(romDR["gamename"], ""),
Name = (string)romDR["name"], Name = (string)romDR["name"],
Size = (long)romDR["size"], Size = (long)romDR["size"],
Crc = ((string)romDR["crc"]).ToLower(), Crc = ((string)romDR["crc"]).ToLower(),

View File

@@ -182,11 +182,12 @@ class PreferencesWindow {
]; ];
for (let j = 0; j < ratingGroupsOrder.length; j++) { for (let j = 0; j < ratingGroupsOrder.length; j++) {
let ageGroupValue = AgeRatingGroups[ratingGroupsOrder[j]]; let ageGroupValue = AgeRatingGroups[ratingGroupsOrder[j]];
let iconIdList = ageGroupValue[key]; let iconIdList = ageGroupValue[key.toLowerCase()];
// loop the age rating icons // loop the age rating icons
for (let i = 0; i < iconIdList.length; i++) { for (let i = 0; i < iconIdList.length; i++) {
let icon = document.createElement('img'); let icon = document.createElement('img');
icon.src = "/images/Ratings/" + key + "/" + AgeRatingStrings[iconIdList[i]] + ".svg"; // icon.src = "/images/Ratings/" + key + "/" + AgeRatingStrings[iconIdList[i]] + ".svg";
icon.src = "/images/Ratings/" + key + "/" + iconIdList[i] + ".svg";
icon.title = AgeRatingStrings[iconIdList[i]]; icon.title = AgeRatingStrings[iconIdList[i]];
icon.classList.add("rating_image_mini"); icon.classList.add("rating_image_mini");
classificationIcons.appendChild(icon); classificationIcons.appendChild(icon);

View File

@@ -2594,6 +2594,7 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
} }
.section-header { .section-header {
position: relative;
background-color: var(--section-header-background); background-color: var(--section-header-background);
padding: 10px; padding: 10px;
font-weight: bold; font-weight: bold;