diff --git a/gaseous-server/Assets/Ratings/ACB/ACB_G.png b/gaseous-server/Assets/Ratings/ACB/ACB_G.png new file mode 100644 index 0000000..93b5e5f Binary files /dev/null and b/gaseous-server/Assets/Ratings/ACB/ACB_G.png differ diff --git a/gaseous-server/Assets/Ratings/ACB/ACB_M.png b/gaseous-server/Assets/Ratings/ACB/ACB_M.png new file mode 100644 index 0000000..7bdaa1d Binary files /dev/null and b/gaseous-server/Assets/Ratings/ACB/ACB_M.png differ diff --git a/gaseous-server/Assets/Ratings/ACB/ACB_MA15.png b/gaseous-server/Assets/Ratings/ACB/ACB_MA15.png new file mode 100644 index 0000000..bec82bd Binary files /dev/null and b/gaseous-server/Assets/Ratings/ACB/ACB_MA15.png differ diff --git a/gaseous-server/Assets/Ratings/ACB/ACB_PG.png b/gaseous-server/Assets/Ratings/ACB/ACB_PG.png new file mode 100644 index 0000000..c505b3f Binary files /dev/null and b/gaseous-server/Assets/Ratings/ACB/ACB_PG.png differ diff --git a/gaseous-server/Assets/Ratings/ACB/ACB_R18.png b/gaseous-server/Assets/Ratings/ACB/ACB_R18.png new file mode 100644 index 0000000..62edcae Binary files /dev/null and b/gaseous-server/Assets/Ratings/ACB/ACB_R18.png differ diff --git a/gaseous-server/Assets/Ratings/ACB/ACB_RC.png b/gaseous-server/Assets/Ratings/ACB/ACB_RC.png new file mode 100644 index 0000000..1b0f511 Binary files /dev/null and b/gaseous-server/Assets/Ratings/ACB/ACB_RC.png differ diff --git a/gaseous-server/Assets/Ratings/ESRB/AO.svg b/gaseous-server/Assets/Ratings/ESRB/AO.svg new file mode 100644 index 0000000..c88be19 --- /dev/null +++ b/gaseous-server/Assets/Ratings/ESRB/AO.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gaseous-server/Assets/Ratings/ESRB/E.svg b/gaseous-server/Assets/Ratings/ESRB/E.svg new file mode 100644 index 0000000..e6f7695 --- /dev/null +++ b/gaseous-server/Assets/Ratings/ESRB/E.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gaseous-server/Assets/Ratings/ESRB/E10.svg b/gaseous-server/Assets/Ratings/ESRB/E10.svg new file mode 100644 index 0000000..664135f --- /dev/null +++ b/gaseous-server/Assets/Ratings/ESRB/E10.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gaseous-server/Assets/Ratings/ESRB/M.svg b/gaseous-server/Assets/Ratings/ESRB/M.svg new file mode 100644 index 0000000..3ae12f7 --- /dev/null +++ b/gaseous-server/Assets/Ratings/ESRB/M.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gaseous-server/Assets/Ratings/ESRB/RP-LM17-English.svg b/gaseous-server/Assets/Ratings/ESRB/RP-LM17-English.svg new file mode 100644 index 0000000..39deca5 --- /dev/null +++ b/gaseous-server/Assets/Ratings/ESRB/RP-LM17-English.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gaseous-server/Assets/Ratings/ESRB/RP.svg b/gaseous-server/Assets/Ratings/ESRB/RP.svg new file mode 100644 index 0000000..1cd0cc7 --- /dev/null +++ b/gaseous-server/Assets/Ratings/ESRB/RP.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gaseous-server/Assets/Ratings/ESRB/T.svg b/gaseous-server/Assets/Ratings/ESRB/T.svg new file mode 100644 index 0000000..31039e6 --- /dev/null +++ b/gaseous-server/Assets/Ratings/ESRB/T.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gaseous-server/Assets/Ratings/PEGI/Eighteen.jpg b/gaseous-server/Assets/Ratings/PEGI/Eighteen.jpg new file mode 100644 index 0000000..c4fc8f2 Binary files /dev/null and b/gaseous-server/Assets/Ratings/PEGI/Eighteen.jpg differ diff --git a/gaseous-server/Assets/Ratings/PEGI/PEGI_Parental_Guidance_Recommended.png b/gaseous-server/Assets/Ratings/PEGI/PEGI_Parental_Guidance_Recommended.png new file mode 100644 index 0000000..575c375 Binary files /dev/null and b/gaseous-server/Assets/Ratings/PEGI/PEGI_Parental_Guidance_Recommended.png differ diff --git a/gaseous-server/Assets/Ratings/PEGI/Seven.jpg b/gaseous-server/Assets/Ratings/PEGI/Seven.jpg new file mode 100644 index 0000000..264cac2 Binary files /dev/null and b/gaseous-server/Assets/Ratings/PEGI/Seven.jpg differ diff --git a/gaseous-server/Assets/Ratings/PEGI/Sixteen.jpg b/gaseous-server/Assets/Ratings/PEGI/Sixteen.jpg new file mode 100644 index 0000000..55fe2ec Binary files /dev/null and b/gaseous-server/Assets/Ratings/PEGI/Sixteen.jpg differ diff --git a/gaseous-server/Assets/Ratings/PEGI/Three.jpg b/gaseous-server/Assets/Ratings/PEGI/Three.jpg new file mode 100644 index 0000000..2d6c734 Binary files /dev/null and b/gaseous-server/Assets/Ratings/PEGI/Three.jpg differ diff --git a/gaseous-server/Assets/Ratings/PEGI/Twelve.jpg b/gaseous-server/Assets/Ratings/PEGI/Twelve.jpg new file mode 100644 index 0000000..40dc135 Binary files /dev/null and b/gaseous-server/Assets/Ratings/PEGI/Twelve.jpg differ diff --git a/gaseous-server/Classes/Metadata/AgeRating.cs b/gaseous-server/Classes/Metadata/AgeRating.cs index 7057fa6..47bd6df 100644 --- a/gaseous-server/Classes/Metadata/AgeRating.cs +++ b/gaseous-server/Classes/Metadata/AgeRating.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using gaseous_tools; using IGDB; using IGDB.Models; @@ -115,6 +116,37 @@ namespace gaseous_server.Classes.Metadata return result; } + + public static GameAgeRating GetConsolidatedAgeRating(long RatingId) + { + GameAgeRating gameAgeRating = new GameAgeRating(); + + AgeRating ageRating = GetAgeRatings(RatingId); + gameAgeRating.Id = (long)ageRating.Id; + gameAgeRating.RatingBoard = (AgeRatingCategory)ageRating.Category; + gameAgeRating.RatingTitle = (AgeRatingTitle)ageRating.Rating; + + List descriptions = new List(); + if (ageRating.ContentDescriptions != null) + { + foreach (long ContentId in ageRating.ContentDescriptions.Ids) + { + AgeRatingContentDescription ageRatingContentDescription = AgeRatingContentDescriptions.GetAgeRatingContentDescriptions(ContentId); + descriptions.Add(ageRatingContentDescription.Description); + } + } + gameAgeRating.Descriptions = descriptions.ToArray(); + + return gameAgeRating; + } + + public class GameAgeRating + { + public long Id { get; set; } + public AgeRatingCategory RatingBoard { get; set; } + public AgeRatingTitle RatingTitle { get; set; } + public string[] Descriptions { get; set; } + } } } diff --git a/gaseous-server/Classes/Metadata/Storage.cs b/gaseous-server/Classes/Metadata/Storage.cs index 792b2ec..bb26ccd 100644 --- a/gaseous-server/Classes/Metadata/Storage.cs +++ b/gaseous-server/Classes/Metadata/Storage.cs @@ -231,6 +231,9 @@ namespace gaseous_server.Classes.Metadata break; case "artwork": objectToStore = new IdentitiesOrValues(ids: fromJsonObject); + break; + case "ageratingcontentdescription": + objectToStore = new IdentitiesOrValues(ids: fromJsonObject); break; case "game": objectToStore = new IdentitiesOrValues(ids: fromJsonObject); @@ -313,6 +316,9 @@ namespace gaseous_server.Classes.Metadata case "[igdb.models.ageratingcategory": property.SetValue(EndpointType, (AgeRatingCategory)dataRow[property.Name]); break; + case "[igdb.models.ageratingcontentdescriptioncategory": + property.SetValue(EndpointType, (AgeRatingContentDescriptionCategory)dataRow[property.Name]); + break; case "[igdb.models.ageratingtitle": property.SetValue(EndpointType, (AgeRatingTitle)dataRow[property.Name]); break; diff --git a/gaseous-server/Controllers/GamesController.cs b/gaseous-server/Controllers/GamesController.cs index 04ee22a..3c62d3c 100644 --- a/gaseous-server/Controllers/GamesController.cs +++ b/gaseous-server/Controllers/GamesController.cs @@ -1,14 +1,18 @@ using System; using System.Collections.Generic; using System.Data; +using System.IO; using System.Linq; +using System.Reflection; using System.Threading.Tasks; using gaseous_server.Classes.Metadata; using gaseous_tools; using IGDB.Models; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; - +using Microsoft.CodeAnalysis.Scripting; +using static gaseous_server.Classes.Metadata.AgeRatings; + namespace gaseous_server.Controllers { [Route("api/v1/[controller]")] @@ -154,39 +158,23 @@ namespace gaseous_server.Controllers } [HttpGet] - [Route("{GameId}/artwork")] - [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] - public ActionResult GameArtwork(long GameId) - { - Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - - List artworks = new List(); - if (gameObject.Artworks != null) - { - foreach (long ArtworkId in gameObject.Artworks.Ids) - { - Artwork GameArtwork = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); - artworks.Add(GameArtwork); - } - } - - return Ok(artworks); - } - - [HttpGet] - [Route("{GameId}/artwork/{ArtworkId}")] - [ProducesResponseType(typeof(Artwork), StatusCodes.Status200OK)] + [Route("{GameId}/agerating")] + [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GameArtwork(long GameId, long ArtworkId) + public ActionResult GameAgeClassification(long GameId) { - IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - try { - IGDB.Models.Artwork artworkObject = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); - if (artworkObject != null) + Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); + + if (gameObject.AgeRatings != null) { - return Ok(artworkObject); + List ageRatings = new List(); + foreach (long ageRatingId in gameObject.AgeRatings.Ids) + { + ageRatings.Add(AgeRatings.GetConsolidatedAgeRating(ageRatingId)); + } + return Ok(ageRatings); } else { @@ -197,28 +185,50 @@ namespace gaseous_server.Controllers { return NotFound(); } - } [HttpGet] - [Route("{GameId}/artwork/{ArtworkId}/image")] - [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] + [Route("{GameId}/agerating/{RatingId}/image")] + [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GameCoverImage(long GameId, long ArtworkId) + public ActionResult GameAgeClassification(long GameId, long RatingId) { - IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - try { - 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"); - if (System.IO.File.Exists(coverFilePath)) + GameAgeRating gameAgeRating = GetConsolidatedAgeRating(RatingId); + + string fileExtension = ""; + string fileType = ""; + switch (gameAgeRating.RatingBoard) + { + case AgeRatingCategory.ESRB: + fileExtension = "svg"; + fileType = "image/svg+xml"; + break; + case AgeRatingCategory.PEGI: + fileExtension = "jpg"; + fileType = "image/jpg"; + break; + case AgeRatingCategory.ACB: + fileExtension = "png"; + fileType = "image/png"; + break; + } + + string resourceName = "gaseous_server.Assets.Ratings." + gameAgeRating.RatingBoard.ToString() + "." + gameAgeRating.RatingTitle.ToString() + "." + fileExtension; + + var assembly = Assembly.GetExecutingAssembly(); + string[] resources = assembly.GetManifestResourceNames(); + if (resources.Contains(resourceName)) + { + using (Stream stream = assembly.GetManifestResourceStream(resourceName)) + using (StreamReader reader = new StreamReader(stream)) { - string filename = artworkObject.ImageId + ".png"; - string filepath = coverFilePath; - byte[] filedata = System.IO.File.ReadAllBytes(filepath); - string contentType = "image/png"; + byte[] filedata = new byte[stream.Length]; + stream.Read(filedata, 0, filedata.Length); + + string filename = gameAgeRating.RatingBoard.ToString() + "-" + gameAgeRating.RatingTitle.ToString() + "." + fileExtension; + string contentType = fileType; var cd = new System.Net.Mime.ContentDisposition { @@ -230,12 +240,119 @@ namespace gaseous_server.Controllers return File(filedata, contentType); } + } + return NotFound(); + } + catch + { + return NotFound(); + } + } + + [HttpGet] + [Route("{GameId}/artwork")] + [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult GameArtwork(long GameId) + { + try + { + Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); + + List artworks = new List(); + if (gameObject.Artworks != null) + { + foreach (long ArtworkId in gameObject.Artworks.Ids) + { + Artwork GameArtwork = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); + artworks.Add(GameArtwork); + } + } + + return Ok(artworks); + } + catch + { + return NotFound(); + } + } + + [HttpGet] + [Route("{GameId}/artwork/{ArtworkId}")] + [ProducesResponseType(typeof(Artwork), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult GameArtwork(long GameId, long ArtworkId) + { + try + { + IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); + + try + { + IGDB.Models.Artwork artworkObject = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); + if (artworkObject != null) + { + return Ok(artworkObject); + } else { return NotFound(); } } - else + catch + { + return NotFound(); + } + } + catch + { + return NotFound(); + } + } + + [HttpGet] + [Route("{GameId}/artwork/{ArtworkId}/image")] + [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult GameCoverImage(long GameId, long ArtworkId) + { + try + { + IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); + + try + { + 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"); + if (System.IO.File.Exists(coverFilePath)) + { + string filename = artworkObject.ImageId + ".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()); + + return File(filedata, contentType); + } + else + { + return NotFound(); + } + } + else + { + return NotFound(); + } + } + catch { return NotFound(); } @@ -284,26 +401,33 @@ namespace gaseous_server.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GameCoverImage(long GameId) { - IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); + try + { + IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, 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"; + 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 + var cd = new System.Net.Mime.ContentDisposition + { + FileName = filename, + Inline = true, + }; + + Response.Headers.Add("Content-Disposition", cd.ToString()); + + return File(filedata, contentType); + } + else { - FileName = filename, - Inline = true, - }; - - Response.Headers.Add("Content-Disposition", cd.ToString()); - - return File(filedata, contentType); + return NotFound(); + } } - else + catch { return NotFound(); } @@ -312,21 +436,29 @@ namespace gaseous_server.Controllers [HttpGet] [Route("{GameId}/screenshots")] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GameScreenshot(long GameId) { - Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - - List screenshots = new List(); - if (gameObject.Screenshots != null) + try { - foreach (long ScreenshotId in gameObject.Screenshots.Ids) - { - Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); - screenshots.Add(GameScreenshot); - } - } + Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - return Ok(screenshots); + List screenshots = new List(); + if (gameObject.Screenshots != null) + { + foreach (long ScreenshotId in gameObject.Screenshots.Ids) + { + Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject)); + screenshots.Add(GameScreenshot); + } + } + + return Ok(screenshots); + } + catch + { + return NotFound(); + } } [HttpGet] @@ -366,29 +498,36 @@ namespace gaseous_server.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GameScreenshotImage(long GameId, long ScreenshotId) { - IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - - 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"); - if (System.IO.File.Exists(coverFilePath)) + try { - string filename = screenshotObject.ImageId + ".png"; - string filepath = coverFilePath; - byte[] filedata = System.IO.File.ReadAllBytes(filepath); - string contentType = "image/png"; + IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - var cd = new System.Net.Mime.ContentDisposition + 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"); + if (System.IO.File.Exists(coverFilePath)) { - FileName = filename, - Inline = true, - }; + string filename = screenshotObject.ImageId + ".png"; + string filepath = coverFilePath; + byte[] filedata = System.IO.File.ReadAllBytes(filepath); + string contentType = "image/png"; - Response.Headers.Add("Content-Disposition", cd.ToString()); + var cd = new System.Net.Mime.ContentDisposition + { + FileName = filename, + Inline = true, + }; - return File(filedata, contentType); + Response.Headers.Add("Content-Disposition", cd.ToString()); + + return File(filedata, contentType); + } + else + { + return NotFound(); + } } - else + catch { return NotFound(); } @@ -397,21 +536,29 @@ namespace gaseous_server.Controllers [HttpGet] [Route("{GameId}/videos")] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GameVideo(long GameId) { - Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - - List videos = new List(); - if (gameObject.Videos != null) + try { - foreach (long VideoId in gameObject.Videos.Ids) - { - GameVideo gameVideo = GamesVideos.GetGame_Videos(VideoId); - videos.Add(gameVideo); - } - } + Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false); - return Ok(videos); + List videos = new List(); + if (gameObject.Videos != null) + { + foreach (long VideoId in gameObject.Videos.Ids) + { + GameVideo gameVideo = GamesVideos.GetGame_Videos(VideoId); + videos.Add(gameVideo); + } + } + + return Ok(videos); + } + catch + { + return NotFound(); + } } } } diff --git a/gaseous-server/gaseous-server.csproj b/gaseous-server/gaseous-server.csproj index 69b1685..a90a5d0 100644 --- a/gaseous-server/gaseous-server.csproj +++ b/gaseous-server/gaseous-server.csproj @@ -24,6 +24,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -33,6 +57,11 @@ + + + + + @@ -55,6 +84,25 @@ true PreserveNewest + + + + + + + + + + + + + + + + + + +