using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading.Tasks; using System.Windows.Forms; namespace Percent___Qualification_work.Classes { public class api_scrape_game { // IGDB API credentials string clientId = "isk0e8z2vpss2pzmgyctkgkaurfij3"; string clientSecret = "7qfim9q0qa93khn12fwm6lwjoo98iu"; // Method to retrieve the access token from the Twitch/IGDB OAuth2 endpoint public async Task GetToken() { string url = $"https://id.twitch.tv/oauth2/token?client_id={clientId}&client_secret={clientSecret}&grant_type=client_credentials"; using (HttpClient httpClient = new HttpClient()) { try { // Send a POST request to retrieve the access token HttpResponseMessage response = await httpClient.PostAsync(url, null); if (response.IsSuccessStatusCode) { // Deserialize the JSON response to extract the access token string responseContent = await response.Content.ReadAsStringAsync(); var tokenData = JsonSerializer.Deserialize(responseContent); string token = tokenData.GetProperty("access_token").GetString(); // Return the extracted access token return token; } else { // Handle errors by throwing an exception with the error response string errorContent = await response.Content.ReadAsStringAsync(); throw new Exception($"Error fetching token: {errorContent}"); } } catch (Exception ex) { // Catch any exceptions and rethrow with additional context throw new Exception($"Exception occurred: {ex.Message}"); } } } // Method to fetch game information by name from the IGDB API public async Task GetGame(string gameName) { // Retrieve the access token string token = await GetToken(); if (string.IsNullOrEmpty(token)) { // Notify the user if the token could not be retrieved MessageBox.Show("Failed to retrieve an access token."); return null; } // IGDB API endpoint for fetching game data string url = "https://api.igdb.com/v4/games"; using (HttpClient httpClient = new HttpClient()) { try { // Add necessary headers for authorization and client identification httpClient.DefaultRequestHeaders.Add("Client-ID", clientId); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}"); // Construct the query to fetch game data with the specified fields string query = $"fields id, name, genres.name, involved_companies.company.name, first_release_date, cover.image_id; " + $"search \"{gameName}\";"; // Send a POST request with the query as the content StringContent content = new StringContent(query, Encoding.UTF8, "application/json"); HttpResponseMessage response = await httpClient.PostAsync(url, content); if (response.IsSuccessStatusCode) { // Deserialize the JSON response into an array of JsonElement objects string jsonResponse = await response.Content.ReadAsStringAsync(); var gamesData = JsonSerializer.Deserialize(jsonResponse); if (gamesData != null && gamesData.Length > 0) { // Extract the first game from the response var gameData = gamesData[0]; // Extract game fields safely with proper error handling int? id = gameData.GetProperty("id").GetInt32(); string name = gameData.GetProperty("name").GetString(); string genre = gameData.TryGetProperty("genres", out var genres) && genres.GetArrayLength() > 0 ? genres[0].GetProperty("name").GetString() : "Unknown"; // Default to "Unknown" if no genre is provided string developer = gameData.TryGetProperty("involved_companies", out var companies) && companies.GetArrayLength() > 0 ? companies[0].GetProperty("company").GetProperty("name").GetString() : "Unknown"; // Default to "Unknown" if no developer is provided int releaseYear = gameData.TryGetProperty("first_release_date", out var releaseDate) ? DateTimeOffset.FromUnixTimeSeconds(releaseDate.GetInt64()).Year : 0; // Default to 0 if release date is missing byte[] coverImage = gameData.TryGetProperty("cover", out var cover) ? await GetCoverImage(cover.GetProperty("image_id").GetString()) : ImageToByteArray(Properties.Resources.no_image); // Map the extracted data to a Game object and return it return new Game(id, name, genre, developer, releaseYear, coverImage); } else { // return nothing if no game found return null; } } else { // Handle API errors string errorResponse = await response.Content.ReadAsStringAsync(); MessageBox.Show($"API Error: {errorResponse}"); return null; } } catch (Exception ex) { // Catch and handle any exceptions that occur during the request MessageBox.Show($"Exception occurred: {ex.Message}"); return null; } } } // Method to fetch a game's cover image from the IGDB private async Task GetCoverImage(string imageId) { if (string.IsNullOrEmpty(imageId)) return null; // Return null if the image ID is not provided // Construct the URL for fetching the cover image string coverUrl = $"https://images.igdb.com/igdb/image/upload/t_cover_big/{imageId}.jpg"; using (HttpClient httpClient = new HttpClient()) { try { // Fetch the cover image as a byte array return await httpClient.GetByteArrayAsync(coverUrl); } catch (Exception ex) { // Handle exceptions during the image fetch process return null; } } } byte[] ImageToByteArray(System.Drawing.Image image) { using (var ms = new MemoryStream()) { image.Save(ms, image.RawFormat); return ms.ToArray(); } } } }