diff --git a/gaseous-server/Classes/Config.cs b/gaseous-server/Classes/Config.cs index f33004c..d5eb24e 100644 --- a/gaseous-server/Classes/Config.cs +++ b/gaseous-server/Classes/Config.cs @@ -2,6 +2,7 @@ using System.Data; using Newtonsoft.Json; using IGDB.Models; +using gaseous_server.Classes.Metadata; namespace gaseous_server.Classes { @@ -57,6 +58,14 @@ namespace gaseous_server.Classes } } + public static ConfigFile.MetadataAPI MetadataConfiguration + { + get + { + return _config.MetadataConfiguration; + } + } + public static ConfigFile.IGDB IGDB { get @@ -247,6 +256,8 @@ namespace gaseous_server.Classes [JsonIgnore] public Library LibraryConfiguration = new Library(); + public MetadataAPI MetadataConfiguration = new MetadataAPI(); + public IGDB IGDBConfiguration = new IGDB(); public Logging LoggingConfiguration = new Logging(); @@ -460,6 +471,26 @@ namespace gaseous_server.Classes } } + public class MetadataAPI + { + private static Communications.MetadataSources _Source + { + get + { + if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("metadatasource"))) + { + return (Communications.MetadataSources)Enum.Parse(typeof(Communications.MetadataSources), Environment.GetEnvironmentVariable("metadatasource")); + } + else + { + return Communications.MetadataSources.IGDB; + } + } + } + + public Communications.MetadataSources Source = _Source; + } + public class IGDB { private static string _DefaultIGDBClientId diff --git a/gaseous-server/Classes/Metadata/AgeRating.cs b/gaseous-server/Classes/Metadata/AgeRating.cs index 9c6fcd9..0d35bdb 100644 --- a/gaseous-server/Classes/Metadata/AgeRating.cs +++ b/gaseous-server/Classes/Metadata/AgeRating.cs @@ -15,12 +15,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static AgeRating? GetAgeRatings(long? Id) { if ((Id == 0) || (Id == null)) @@ -117,7 +111,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get AgeRatings metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.AgeRating, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.AgeRating, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs b/gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs index f9b15aa..d27df81 100644 --- a/gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs +++ b/gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static AgeRatingContentDescription? GetAgeRatingContentDescriptions(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get AgeRatingContentDescriptionContentDescriptions metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.AgeRatingContentDescriptions, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.AgeRatingContentDescriptions, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/AlternativeNames.cs b/gaseous-server/Classes/Metadata/AlternativeNames.cs index a64b873..be5a7bf 100644 --- a/gaseous-server/Classes/Metadata/AlternativeNames.cs +++ b/gaseous-server/Classes/Metadata/AlternativeNames.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static AlternativeName? GetAlternativeNames(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get AlternativeNames metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.AlternativeNames, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.AlternativeNames, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/Artworks.cs b/gaseous-server/Classes/Metadata/Artworks.cs index d3c7680..5f7bc94 100644 --- a/gaseous-server/Classes/Metadata/Artworks.cs +++ b/gaseous-server/Classes/Metadata/Artworks.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Artwork? GetArtwork(long? Id, string LogoPath) { if ((Id == 0) || (Id == null)) @@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause, string LogoPath) { // get Artwork metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Artworks, query: fieldList + " " + WhereClause + ";"); + 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); diff --git a/gaseous-server/Classes/Metadata/Collections.cs b/gaseous-server/Classes/Metadata/Collections.cs index aabb400..f59fc1d 100644 --- a/gaseous-server/Classes/Metadata/Collections.cs +++ b/gaseous-server/Classes/Metadata/Collections.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Collection? GetCollections(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Collections metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Collections, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Collections, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/Communications.cs b/gaseous-server/Classes/Metadata/Communications.cs new file mode 100644 index 0000000..fff1227 --- /dev/null +++ b/gaseous-server/Classes/Metadata/Communications.cs @@ -0,0 +1,238 @@ +using System.Net; +using IGDB; +using RestEase; + +namespace gaseous_server.Classes.Metadata +{ + /// + /// Handles all metadata API communications + /// + public class Communications + { + private static IGDBClient igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + /// + /// Configure metadata API communications + /// + public static MetadataSources MetadataSource + { + get + { + return _MetadataSource; + } + set + { + _MetadataSource = value; + + switch (value) + { + case MetadataSources.IGDB: + // set rate limiter avoidance values + RateLimitAvoidanceWait = 1500; + RateLimitAvoidanceThreshold = 3; + RateLimitAvoidancePeriod = 1; + + // set rate limiter recovery values + RateLimitRecoveryWaitTime = 10000; + + break; + default: + // leave all values at default + break; + } + } + } + private static MetadataSources _MetadataSource = MetadataSources.None; + + // rate limit avoidance - what can we do to ensure that rate limiting is avoided? + // these values affect all communications + + /// + /// How long to wait to avoid hitting an API rate limiter + /// + private static int RateLimitAvoidanceWait = 2000; + + /// + /// How many API calls in the period are allowed before we start introducing a wait + /// + private static int RateLimitAvoidanceThreshold = 80; + + /// + /// A counter of API calls since the beginning of the period + /// + private static int RateLimitAvoidanceCallCount = 0; + + /// + /// How large the period (in seconds) to measure API call counts against + /// + private static int RateLimitAvoidancePeriod = 60; + + /// + /// The start of the rate limit avoidance period + /// + private static DateTime RateLimitAvoidanceStartTime = DateTime.UtcNow; + + /// + /// Used to determine if we're already in rate limit avoidance mode - always query "InRateLimitAvoidanceMode" + /// for up to date mode status. + /// This bool is used to track status changes and should not be relied upon for current status. + /// + private static bool InRateLimitAvoidanceModeStatus = false; + + /// + /// Determine if we're in rate limit avoidance mode. + /// + private static bool InRateLimitAvoidanceMode + { + get + { + if (RateLimitAvoidanceStartTime.AddSeconds(RateLimitAvoidancePeriod) <= DateTime.UtcNow) + { + // avoidance period has expired - reset + RateLimitAvoidanceCallCount = 0; + RateLimitAvoidanceStartTime = DateTime.UtcNow; + + return false; + } + else + { + // we're in the avoidance period + if (RateLimitAvoidanceCallCount > RateLimitAvoidanceThreshold) + { + // the number of call counts indicates we should throttle things a bit + if (InRateLimitAvoidanceModeStatus == false) + { + Logging.Log(Logging.LogType.Information, "API Connection", "Entered rate limit avoidance period, API calls will be throttled by " + RateLimitAvoidanceWait + " milliseconds."); + InRateLimitAvoidanceModeStatus = true; + } + return true; + } + else + { + // still in full speed mode - no throttle required + if (InRateLimitAvoidanceModeStatus == true) + { + Logging.Log(Logging.LogType.Information, "API Connection", "Exited rate limit avoidance period, API call rate is returned to full speed."); + InRateLimitAvoidanceModeStatus = false; + } + return false; + } + } + } + } + + // rate limit handling - how long to wait to allow the server to recover and try again + // these values affect ALL communications if a 429 response code is received + + /// + /// How long to wait (in milliseconds) if a 429 status code is received before trying again + /// + private static int RateLimitRecoveryWaitTime = 10000; + + /// + /// The time when normal communications can attempt to be resumed + /// + private static DateTime RateLimitResumeTime = DateTime.UtcNow.AddMinutes(5 * -1); + + // rate limit retry - how many times to retry before aborting + 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 + /// + /// Type of object to return + /// API endpoint segment to use + /// Fields to request from the API + /// Selection criteria for data to request + /// + public async Task APIComm(string Endpoint, string Fields, string Query) + { + switch (_MetadataSource) + { + case MetadataSources.None: + return null; + case MetadataSources.IGDB: + return await IGDBAPI(Endpoint, Fields, Query); + default: + return null; + } + } + + private async Task IGDBAPI(string Endpoint, string Fields, string Query) + { + Logging.Log(Logging.LogType.Debug, "API Connection", "Accessing API for endpoint: " + Endpoint); + + if (RateLimitResumeTime > DateTime.UtcNow) + { + Logging.Log(Logging.LogType.Information, "API Connection", "IGDB rate limit hit. Pausing API communications until " + RateLimitResumeTime.ToString() + ". Attempt " + RetryAttempts + " of " + RetryAttemptsMax + " retries."); + Thread.Sleep(RateLimitRecoveryWaitTime); + } + + try + { + if (InRateLimitAvoidanceMode == true) + { + // sleep for a moment to help avoid hitting the rate limiter + Thread.Sleep(RateLimitAvoidanceWait); + } + + // perform the actual API call + var results = await igdb.QueryAsync(Endpoint, query: Fields + " " + Query + ";"); + + // increment rate limiter avoidance call count + RateLimitAvoidanceCallCount += 1; + + return results; + } + catch (ApiException apiEx) + { + switch (apiEx.StatusCode) + { + case HttpStatusCode.TooManyRequests: + if (RetryAttempts >= RetryAttemptsMax) + { + Logging.Log(Logging.LogType.Warning, "API Connection", "IGDB rate limiter attempts expired. Aborting.", apiEx); + throw; + } + else + { + Logging.Log(Logging.LogType.Information, "API Connection", "IGDB API rate limit hit while accessing endpoint " + Endpoint, apiEx); + + RetryAttempts += 1; + + return await IGDBAPI(Endpoint, Fields, Query); + } + default: + Logging.Log(Logging.LogType.Warning, "API Connection", "Exception when accessing endpoint " + Endpoint, apiEx); + throw; + } + } + catch(Exception ex) + { + Logging.Log(Logging.LogType.Warning, "API Connection", "Exception when accessing endpoint " + Endpoint, ex); + throw; + } + } + } +} \ No newline at end of file diff --git a/gaseous-server/Classes/Metadata/Company.cs b/gaseous-server/Classes/Metadata/Company.cs index 73276f6..288bb7b 100644 --- a/gaseous-server/Classes/Metadata/Company.cs +++ b/gaseous-server/Classes/Metadata/Company.cs @@ -12,12 +12,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Company? GetCompanies(long? Id) { if ((Id == 0) || (Id == null)) @@ -111,7 +105,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Companies metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Companies, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Companies, fieldList, WhereClause); if (results.Length > 0) { var result = results.First(); diff --git a/gaseous-server/Classes/Metadata/CompanyLogos.cs b/gaseous-server/Classes/Metadata/CompanyLogos.cs index 2b83d70..3f56165 100644 --- a/gaseous-server/Classes/Metadata/CompanyLogos.cs +++ b/gaseous-server/Classes/Metadata/CompanyLogos.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static CompanyLogo? GetCompanyLogo(long? Id, string LogoPath) { if ((Id == 0) || (Id == null)) @@ -118,7 +112,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause, string LogoPath) { // get CompanyLogo metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.CompanyLogos, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.CompanyLogos, fieldList, WhereClause); if (results.Length > 0) { var result = results.First(); diff --git a/gaseous-server/Classes/Metadata/Covers.cs b/gaseous-server/Classes/Metadata/Covers.cs index 1e7dc12..6f9a8ae 100644 --- a/gaseous-server/Classes/Metadata/Covers.cs +++ b/gaseous-server/Classes/Metadata/Covers.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Cover? GetCover(long? Id, string LogoPath) { if ((Id == 0) || (Id == null)) @@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause, string LogoPath) { // get Cover metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Covers, query: fieldList + " " + WhereClause + ";"); + 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); diff --git a/gaseous-server/Classes/Metadata/ExternalGames.cs b/gaseous-server/Classes/Metadata/ExternalGames.cs index a36969f..9f2b612 100644 --- a/gaseous-server/Classes/Metadata/ExternalGames.cs +++ b/gaseous-server/Classes/Metadata/ExternalGames.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static ExternalGame? GetExternalGames(long? Id) { if ((Id == 0) || (Id == null)) @@ -106,7 +100,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get ExternalGames metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.ExternalGames, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.ExternalGames, fieldList, WhereClause); if (results.Length > 0) { var result = results.First(); diff --git a/gaseous-server/Classes/Metadata/Franchises.cs b/gaseous-server/Classes/Metadata/Franchises.cs index 191981f..6e57ceb 100644 --- a/gaseous-server/Classes/Metadata/Franchises.cs +++ b/gaseous-server/Classes/Metadata/Franchises.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Franchise? GetFranchises(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get FranchiseContentDescriptions metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Franchies, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Franchies, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/GameModes.cs b/gaseous-server/Classes/Metadata/GameModes.cs index d059082..37697cc 100644 --- a/gaseous-server/Classes/Metadata/GameModes.cs +++ b/gaseous-server/Classes/Metadata/GameModes.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static GameMode? GetGame_Modes(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Game_Modes metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.GameModes, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.GameModes, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/GameVideos.cs b/gaseous-server/Classes/Metadata/GameVideos.cs index dec63fb..b4bf4d8 100644 --- a/gaseous-server/Classes/Metadata/GameVideos.cs +++ b/gaseous-server/Classes/Metadata/GameVideos.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static GameVideo? GetGame_Videos(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Game_Videos metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.GameVideos, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.GameVideos, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/Games.cs b/gaseous-server/Classes/Metadata/Games.cs index 35f4e41..0bfcd95 100644 --- a/gaseous-server/Classes/Metadata/Games.cs +++ b/gaseous-server/Classes/Metadata/Games.cs @@ -20,12 +20,6 @@ namespace gaseous_server.Classes.Metadata {} } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh) { if (Id == 0) @@ -295,7 +289,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Game metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Games, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Games, fieldList, WhereClause); var result = results.First(); return result; @@ -310,7 +305,7 @@ namespace gaseous_server.Classes.Metadata private static async Task _SearchForGame(string SearchString, long PlatformId, SearchType searchType) { string searchBody = ""; - searchBody += "fields id,name,slug,platforms,summary; "; + string searchFields = "fields id,name,slug,platforms,summary; "; switch (searchType) { case SearchType.searchNoPlatform: @@ -330,7 +325,8 @@ namespace gaseous_server.Classes.Metadata // get Game metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Games, query: searchBody); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Games, searchFields, searchBody); return results; } diff --git a/gaseous-server/Classes/Metadata/Genres.cs b/gaseous-server/Classes/Metadata/Genres.cs index 47c630b..e386be6 100644 --- a/gaseous-server/Classes/Metadata/Genres.cs +++ b/gaseous-server/Classes/Metadata/Genres.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Genre? GetGenres(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Genres metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Genres, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Genres, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/InvolvedCompany.cs b/gaseous-server/Classes/Metadata/InvolvedCompany.cs index 9c01074..0d75035 100644 --- a/gaseous-server/Classes/Metadata/InvolvedCompany.cs +++ b/gaseous-server/Classes/Metadata/InvolvedCompany.cs @@ -12,12 +12,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static InvolvedCompany? GetInvolvedCompanies(long? Id) { if ((Id == 0) || (Id == null)) @@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata // get InvolvedCompanies metadata try { - var results = await igdb.QueryAsync(IGDBClient.Endpoints.InvolvedCompanies, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.InvolvedCompanies, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/MultiplayerModes.cs b/gaseous-server/Classes/Metadata/MultiplayerModes.cs index e77072b..e89f945 100644 --- a/gaseous-server/Classes/Metadata/MultiplayerModes.cs +++ b/gaseous-server/Classes/Metadata/MultiplayerModes.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static MultiplayerMode? GetGame_MultiplayerModes(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Game_MultiplayerModes metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.MultiplayerModes, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.MultiplayerModes, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/PlatformLogos.cs b/gaseous-server/Classes/Metadata/PlatformLogos.cs index 08d855a..cbf9b3e 100644 --- a/gaseous-server/Classes/Metadata/PlatformLogos.cs +++ b/gaseous-server/Classes/Metadata/PlatformLogos.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static PlatformLogo? GetPlatformLogo(long? Id, string LogoPath) { if ((Id == 0) || (Id == null)) @@ -118,7 +112,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause, string LogoPath) { // get PlatformLogo metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.PlatformLogos, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.PlatformLogos, fieldList, WhereClause); if (results.Length > 0) { var result = results.First(); diff --git a/gaseous-server/Classes/Metadata/PlatformVersions.cs b/gaseous-server/Classes/Metadata/PlatformVersions.cs index ecb7890..7afe668 100644 --- a/gaseous-server/Classes/Metadata/PlatformVersions.cs +++ b/gaseous-server/Classes/Metadata/PlatformVersions.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static PlatformVersion? GetPlatformVersion(long Id, Platform ParentPlatform) { if (Id == 0) @@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get PlatformVersion metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.PlatformVersions, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.PlatformVersions, fieldList, WhereClause); if (results.Length > 0) { var result = results.First(); diff --git a/gaseous-server/Classes/Metadata/Platforms.cs b/gaseous-server/Classes/Metadata/Platforms.cs index 7cf5af4..2b6f06d 100644 --- a/gaseous-server/Classes/Metadata/Platforms.cs +++ b/gaseous-server/Classes/Metadata/Platforms.cs @@ -15,12 +15,6 @@ namespace gaseous_server.Classes.Metadata } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Platform? GetPlatform(long Id, bool forceRefresh = false) { if (Id == 0) @@ -168,7 +162,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get platform metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Platforms, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Platforms, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/PlayerPerspectives.cs b/gaseous-server/Classes/Metadata/PlayerPerspectives.cs index f9310a6..6455e2a 100644 --- a/gaseous-server/Classes/Metadata/PlayerPerspectives.cs +++ b/gaseous-server/Classes/Metadata/PlayerPerspectives.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static PlayerPerspective? GetGame_PlayerPerspectives(long? Id) { if ((Id == 0) || (Id == null)) @@ -105,7 +99,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Game_PlayerPerspectives metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.PlayerPerspectives, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.PlayerPerspectives, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/ReleaseDates.cs b/gaseous-server/Classes/Metadata/ReleaseDates.cs index 1869d43..20c8e06 100644 --- a/gaseous-server/Classes/Metadata/ReleaseDates.cs +++ b/gaseous-server/Classes/Metadata/ReleaseDates.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static ReleaseDate? GetReleaseDates(long? Id) { if ((Id == 0) || (Id == null)) @@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get ReleaseDates metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.ReleaseDates, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.ReleaseDates, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Classes/Metadata/Screenshots.cs b/gaseous-server/Classes/Metadata/Screenshots.cs index 32e59e9..7978b28 100644 --- a/gaseous-server/Classes/Metadata/Screenshots.cs +++ b/gaseous-server/Classes/Metadata/Screenshots.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Screenshot? GetScreenshot(long? Id, string LogoPath) { if ((Id == 0) || (Id == null)) @@ -114,7 +108,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause, string LogoPath) { // get Screenshot metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Screenshots, query: fieldList + " " + WhereClause + ";"); + 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); diff --git a/gaseous-server/Classes/Metadata/Storage.cs b/gaseous-server/Classes/Metadata/Storage.cs index 76c10bd..f6998ac 100644 --- a/gaseous-server/Classes/Metadata/Storage.cs +++ b/gaseous-server/Classes/Metadata/Storage.cs @@ -414,6 +414,12 @@ namespace gaseous_server.Classes.Metadata case "[igdb.models.startdatecategory": property.SetValue(EndpointType, (StartDateCategory)dataRow[property.Name]); break; + case "[igdb.models.releasedateregion": + property.SetValue(EndpointType, (ReleaseDateRegion)dataRow[property.Name]); + break; + case "[igdb.models.releasedatecategory": + property.SetValue(EndpointType, (ReleaseDateCategory)dataRow[property.Name]); + break; default: property.SetValue(EndpointType, dataRow[property.Name]); break; diff --git a/gaseous-server/Classes/Metadata/Themes.cs b/gaseous-server/Classes/Metadata/Themes.cs index 7059770..c4d1e7d 100644 --- a/gaseous-server/Classes/Metadata/Themes.cs +++ b/gaseous-server/Classes/Metadata/Themes.cs @@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata { } - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - public static Theme? GetGame_Themes(long? Id) { if ((Id == 0) || (Id == null)) @@ -105,7 +99,8 @@ namespace gaseous_server.Classes.Metadata private static async Task GetObjectFromServer(string WhereClause) { // get Game_Themes metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Themes, query: fieldList + " " + WhereClause + ";"); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Themes, fieldList, WhereClause); var result = results.First(); return result; diff --git a/gaseous-server/Controllers/V1.0/SearchController.cs b/gaseous-server/Controllers/V1.0/SearchController.cs index 2321fa6..a3b506f 100644 --- a/gaseous-server/Controllers/V1.0/SearchController.cs +++ b/gaseous-server/Controllers/V1.0/SearchController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using gaseous_server.Classes; +using gaseous_server.Classes.Metadata; using IGDB; using IGDB.Models; using Microsoft.AspNetCore.Authorization; @@ -19,12 +20,6 @@ namespace gaseous_server.Controllers [Authorize] public class SearchController : Controller { - private static IGDBClient igdb = new IGDBClient( - // Found in Twitch Developer portal for your app - Config.IGDB.ClientId, - Config.IGDB.Secret - ); - [MapToApiVersion("1.0")] [MapToApiVersion("1.1")] [HttpGet] @@ -39,11 +34,12 @@ namespace gaseous_server.Controllers private static async Task> _SearchForPlatform(string SearchString) { string searchBody = ""; - searchBody += "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites; "; + string searchFields = "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites; "; searchBody += "where name ~ *\"" + SearchString + "\"*;"; // get Platform metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Platforms, query: searchBody); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Platforms, searchFields, searchBody); return results.ToList(); } @@ -62,12 +58,13 @@ namespace gaseous_server.Controllers private static async Task> _SearchForGame(long PlatformId, string SearchString) { string searchBody = ""; - searchBody += "fields cover.*,first_release_date,name,platforms,slug; "; + string searchFields = "fields cover.*,first_release_date,name,platforms,slug; "; searchBody += "search \"" + SearchString + "\";"; searchBody += "where platforms = (" + PlatformId + ");"; // get Platform metadata - var results = await igdb.QueryAsync(IGDBClient.Endpoints.Games, query: searchBody); + Communications comms = new Communications(); + var results = await comms.APIComm(IGDBClient.Endpoints.Games, searchFields, searchBody); return results.ToList(); } diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs index ad6a1be..26c9134 100644 --- a/gaseous-server/Program.cs +++ b/gaseous-server/Program.cs @@ -49,6 +49,9 @@ Config.InitSettings(); // write updated settings back to the config file Config.UpdateConfig(); +// set api metadata source from config +Communications.MetadataSource = Config.MetadataConfiguration.Source; + // set initial values Guid APIKey = Guid.NewGuid(); if (Config.ReadSetting("API Key", "Test API Key") == "Test API Key")