diff --git a/API/Migrations/20250526144942_Game-Logo-and-Icon.Designer.cs b/API/Migrations/20250526144942_Game-Logo-and-Icon.Designer.cs new file mode 100644 index 0000000..78fff42 --- /dev/null +++ b/API/Migrations/20250526144942_Game-Logo-and-Icon.Designer.cs @@ -0,0 +1,154 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using SQLiteEF; + +#nullable disable + +namespace API.Migrations +{ + [DbContext(typeof(Context))] + [Migration("20250526144942_Game-Logo-and-Icon")] + partial class GameLogoandIcon + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.5"); + + modelBuilder.Entity("GamePlayer", b => + { + b.Property("GamesAppId") + .HasColumnType("INTEGER"); + + b.Property("PlayedBySteamId") + .HasColumnType("INTEGER"); + + b.HasKey("GamesAppId", "PlayedBySteamId"); + + b.HasIndex("PlayedBySteamId"); + + b.ToTable("GamePlayer"); + }); + + modelBuilder.Entity("SQLiteEF.Game", b => + { + b.Property("AppId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IconUrl") + .HasColumnType("TEXT"); + + b.Property("LogoUrl") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("AppId"); + + b.ToTable("Games"); + }); + + modelBuilder.Entity("SQLiteEF.Player", b => + { + b.Property("SteamId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarUrl") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProfileUrl") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("SteamId"); + + b.ToTable("Players"); + }); + + modelBuilder.Entity("SQLiteEF.TrackedTime", b => + { + b.Property("TimeStamp") + .HasColumnType("TEXT"); + + b.Property("GameAppId") + .HasColumnType("INTEGER"); + + b.Property("PlayerSteamId") + .HasColumnType("INTEGER"); + + b.Property("TimePlayed") + .HasColumnType("INTEGER"); + + b.HasKey("TimeStamp"); + + b.HasIndex("GameAppId"); + + b.HasIndex("PlayerSteamId"); + + b.ToTable("TrackedTime"); + }); + + modelBuilder.Entity("GamePlayer", b => + { + b.HasOne("SQLiteEF.Game", null) + .WithMany() + .HasForeignKey("GamesAppId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SQLiteEF.Player", null) + .WithMany() + .HasForeignKey("PlayedBySteamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("SQLiteEF.TrackedTime", b => + { + b.HasOne("SQLiteEF.Game", "Game") + .WithMany("TrackedTimes") + .HasForeignKey("GameAppId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SQLiteEF.Player", "Player") + .WithMany("TrackedTimes") + .HasForeignKey("PlayerSteamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Game"); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("SQLiteEF.Game", b => + { + b.Navigation("TrackedTimes"); + }); + + modelBuilder.Entity("SQLiteEF.Player", b => + { + b.Navigation("TrackedTimes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/API/Migrations/20250526144942_Game-Logo-and-Icon.cs b/API/Migrations/20250526144942_Game-Logo-and-Icon.cs new file mode 100644 index 0000000..338835c --- /dev/null +++ b/API/Migrations/20250526144942_Game-Logo-and-Icon.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace API.Migrations +{ + /// + public partial class GameLogoandIcon : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IconUrl", + table: "Games", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "LogoUrl", + table: "Games", + type: "TEXT", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IconUrl", + table: "Games"); + + migrationBuilder.DropColumn( + name: "LogoUrl", + table: "Games"); + } + } +} diff --git a/API/Migrations/ContextModelSnapshot.cs b/API/Migrations/ContextModelSnapshot.cs index 5ef4289..a9f4e1c 100644 --- a/API/Migrations/ContextModelSnapshot.cs +++ b/API/Migrations/ContextModelSnapshot.cs @@ -38,6 +38,12 @@ namespace API.Migrations .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("IconUrl") + .HasColumnType("TEXT"); + + b.Property("LogoUrl") + .HasColumnType("TEXT"); + b.Property("Name") .IsRequired() .HasColumnType("TEXT"); diff --git a/API/Tracker.cs b/API/Tracker.cs index c62d022..d67dd15 100644 --- a/API/Tracker.cs +++ b/API/Tracker.cs @@ -86,11 +86,23 @@ public class Tracker : IDisposable SteamGame[] ownedGames = Steam.GetOwnedGames(player.SteamId); foreach (SteamGame ownedGame in ownedGames) { + string? iconUrlStr = ownedGame.img_icon_url is not null + ? $"http://media.steampowered.com/steamcommunity/public/images/apps/{ownedGame.appid}/{ownedGame.img_icon_url}.jpg" + : null; + string? logoUrlStr = ownedGame.img_logo_url is not null + ? $"http://media.steampowered.com/steamcommunity/public/images/apps/{ownedGame.appid}/{ownedGame.img_logo_url}.jpg" + : null; if (context.Games.Find(ownedGame.appid) is not { } game) { - game = new(ownedGame.appid, ownedGame.name); + game = new(ownedGame.appid, ownedGame.name, iconUrlStr, logoUrlStr); context.Games.Add(game); } + else + { + game.Name = ownedGame.name; + game.IconUrl = iconUrlStr; + game.LogoUrl = logoUrlStr; + } if (!player.Games.Contains(game)) { @@ -129,11 +141,23 @@ public class Tracker : IDisposable GetRecentlyPlayedGames recentlyPlayed = Steam.GetRecentlyPlayedGames(player.SteamId); foreach (SteamGame recentlyPlayedGame in recentlyPlayed.games) { + string? iconUrlStr = recentlyPlayedGame.img_icon_url is not null + ? $"http://media.steampowered.com/steamcommunity/public/images/apps/{recentlyPlayedGame.appid}/{recentlyPlayedGame.img_icon_url}.jpg" + : null; + string? logoUrlStr = recentlyPlayedGame.img_logo_url is not null + ? $"http://media.steampowered.com/steamcommunity/public/images/apps/{recentlyPlayedGame.appid}/{recentlyPlayedGame.img_logo_url}.jpg" + : null; if (context.Games.Find(recentlyPlayedGame.appid) is not { } game) { - game = new(recentlyPlayedGame.appid, recentlyPlayedGame.name); + game = new(recentlyPlayedGame.appid, recentlyPlayedGame.name, iconUrlStr, logoUrlStr); context.Games.Add(game); } + else + { + game.Name = recentlyPlayedGame.name; + game.IconUrl = iconUrlStr; + game.LogoUrl = logoUrlStr; + } if (!player.Games.Contains(game)) { diff --git a/SQLiteEF/Game.cs b/SQLiteEF/Game.cs index 7c96587..acbd1c8 100644 --- a/SQLiteEF/Game.cs +++ b/SQLiteEF/Game.cs @@ -4,10 +4,12 @@ using Newtonsoft.Json; namespace SQLiteEF; [PrimaryKey("AppId")] -public class Game(ulong appId, string name) +public class Game(ulong appId, string name, string? iconUrl, string? logoUrl) { public ulong AppId { get; init; } = appId; - public string Name { get; init; } = name; + public string Name { get; set; } = name; + public string? IconUrl { get; set; } = iconUrl; + public string? LogoUrl { get; set; } = logoUrl; [JsonIgnore] public ICollection PlayedBy { get; init; } = null!; [JsonIgnore] public ICollection TrackedTimes { get; init; } = null!; } \ No newline at end of file diff --git a/SteamApiWrapper/ReturnTypes/Game.cs b/SteamApiWrapper/ReturnTypes/Game.cs index df38135..1aedda8 100644 --- a/SteamApiWrapper/ReturnTypes/Game.cs +++ b/SteamApiWrapper/ReturnTypes/Game.cs @@ -1,3 +1,3 @@ namespace SteamApiWrapper.ReturnTypes; -public record Game(ulong appid, ulong playtime_forever, string name); \ No newline at end of file +public record Game(ulong appid, ulong playtime_forever, string name, string? img_icon_url, string? img_logo_url); \ No newline at end of file