From 01310020ce0937200a0ce422d4b849f3b2575e4d Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 25 May 2025 18:37:27 +0200 Subject: [PATCH] Rework --- API/Api.cs | 41 ++++++++ API/Properties/launchSettings.json | 23 +++++ API/appsettings.Development.json | 8 ++ API/appsettings.json | 9 ++ Run/Program.cs | 12 +++ Run/Run.csproj | 16 +++ SQLiteEF/Player.cs | 38 +++++++ SQLiteEF/SQLiteEF.csproj | 14 +++ Tracker/Tracker.cs | 155 +++++++++++++++++++++++++++++ Tracker/Tracker.csproj | 21 ++++ 10 files changed, 337 insertions(+) create mode 100644 API/Api.cs create mode 100644 API/Properties/launchSettings.json create mode 100644 API/appsettings.Development.json create mode 100644 API/appsettings.json create mode 100644 Run/Program.cs create mode 100644 Run/Run.csproj create mode 100644 SQLiteEF/Player.cs create mode 100644 SQLiteEF/SQLiteEF.csproj create mode 100644 Tracker/Tracker.cs create mode 100644 Tracker/Tracker.csproj diff --git a/API/Api.cs b/API/Api.cs new file mode 100644 index 0000000..809fc9e --- /dev/null +++ b/API/Api.cs @@ -0,0 +1,41 @@ +using SQLiteEF; + +namespace API; + +public class Api +{ + public Api(string[] args) + { + WebApplicationBuilder builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi + builder.Services.AddOpenApi(); + + builder.Services.AddDbContext(); + + WebApplication app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.MapOpenApi(); + } + + app.UseHttpsRedirection(); + + app.UseAuthorization(); + + + app.MapControllers(); + + app.Run(); + } + + public static void Main(string[] args) + { + Api _ = new (args); + } +} \ No newline at end of file diff --git a/API/Properties/launchSettings.json b/API/Properties/launchSettings.json new file mode 100644 index 0000000..e25a4ca --- /dev/null +++ b/API/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5239", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7103;http://localhost:5239", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/API/appsettings.Development.json b/API/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/API/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/API/appsettings.json b/API/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/API/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Run/Program.cs b/Run/Program.cs new file mode 100644 index 0000000..546589b --- /dev/null +++ b/Run/Program.cs @@ -0,0 +1,12 @@ +using API; + +namespace Run; + +class Program +{ + static void Main(string[] args) + { + Api a = new (args); + Tracker.Tracker t = new (); + } +} \ No newline at end of file diff --git a/Run/Run.csproj b/Run/Run.csproj new file mode 100644 index 0000000..1c8f52c --- /dev/null +++ b/Run/Run.csproj @@ -0,0 +1,16 @@ + + + + Exe + net9.0 + latest + enable + enable + + + + + + + + diff --git a/SQLiteEF/Player.cs b/SQLiteEF/Player.cs new file mode 100644 index 0000000..db048f3 --- /dev/null +++ b/SQLiteEF/Player.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; + +namespace SQLiteEF; + +[PrimaryKey("SteamId")] +public class Player : IUpdateable +{ + public ulong SteamId { get; init; } + public string Name { get; set; } + public string ProfileUrl { get; set; } + public string AvatarUrl { get; set; } + + public ICollection Games { get; init; } = null!; + public ICollection TrackedTimes { get; init; } = null!; + public DateTime UpdatedAt { get; set; } = DateTime.Now; + + public Player(ulong steamid, string name, string profileUrl, string avatarUrl) + { + this.SteamId = steamid; + this.Name = name; + this.ProfileUrl = profileUrl; + this.AvatarUrl = avatarUrl; + this.Games = []; + this.TrackedTimes = []; + } + + /// + /// EF CORE + /// + internal Player(ulong steamid, string name, string profileUrl, string avatarUrl, DateTime updatedAt) + { + this.SteamId = steamid; + this.Name = name; + this.ProfileUrl = profileUrl; + this.AvatarUrl = avatarUrl; + this.UpdatedAt = updatedAt; + } +} \ No newline at end of file diff --git a/SQLiteEF/SQLiteEF.csproj b/SQLiteEF/SQLiteEF.csproj new file mode 100644 index 0000000..1211f9b --- /dev/null +++ b/SQLiteEF/SQLiteEF.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + + + + + + + + diff --git a/Tracker/Tracker.cs b/Tracker/Tracker.cs new file mode 100644 index 0000000..b399ad3 --- /dev/null +++ b/Tracker/Tracker.cs @@ -0,0 +1,155 @@ +using Microsoft.Extensions.Configuration; +using SQLiteEF; +using SteamApiWrapper.ReturnTypes; +using SteamGame = SteamApiWrapper.ReturnTypes.Game; +using Player = SQLiteEF.Player; +using SteamPlayer = SteamApiWrapper.ReturnTypes.Player; +using Steam = SteamApiWrapper.SteamApiWrapper; + +namespace Tracker; + +public class Tracker : IDisposable +{ + private IConfiguration Configuration { get; init; } + private readonly Thread _trackerThread; + private bool _running = true; + + public Tracker() + { + Configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + _trackerThread = new (TrackerLoop); + _trackerThread.Start(); + } + + private void UpdatePlayers() + { + Context context = new (Configuration); + IQueryable players = context.Players.Select(p => p.SteamId); + GetPlayerSummaries summaries = Steam.GetPlayerSummaries(players.ToArray()); + foreach (SteamPlayer summariesPlayer in summaries.players) + { + if (context.Players.Find(summariesPlayer.steamid) is not { } player) + { + context.Players.Add(new (summariesPlayer.steamid, summariesPlayer.personaname, + summariesPlayer.profileurl, summariesPlayer.avatar)); + continue; + } + player.Name = summariesPlayer.personaname; + player.ProfileUrl = summariesPlayer.profileurl; + player.AvatarUrl = summariesPlayer.avatar; + try + { + context.SaveChanges(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } + + private void UpdateOwnedGames() + { + Context context = new (Configuration); + IQueryable players = context.Players; + foreach (Player player in players) + { + GetOwnedGames ownedGames = Steam.GetOwnedGames(player.SteamId); + foreach (SteamGame ownedGame in ownedGames.games) + { + if (context.Games.Find(ownedGame.appid) is not { } game) + { + game = new(ownedGame.appid, ownedGame.name); + } + + if (!player.Games.Contains(game)) + { + player.Games.Add(game); + game.PlayedBy.Add(player); + player.TrackedTimes.Add(new (game, player, ownedGame.playtime_forever)); + } + + try + { + context.SaveChanges(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } + } + + private void UpdateGametimes() + { + Context context = new (Configuration); + IQueryable players = context.Players; + foreach (Player player in players) + { + GetRecentlyPlayedGames recentlyPlayed = Steam.GetRecentlyPlayedGames(player.SteamId); + foreach (SteamGame recentlyPlayedGame in recentlyPlayed.games) + { + if (context.Games.Find(recentlyPlayedGame.appid) is not { } game) + { + game = new(recentlyPlayedGame.appid, recentlyPlayedGame.name); + } + + if (!player.Games.Contains(game)) + { + player.Games.Add(game); + game.PlayedBy.Add(player); + } + + player.TrackedTimes.Add(new (game, player, recentlyPlayedGame.playtime_forever)); + + try + { + context.SaveChanges(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } + } + + private void TrackerLoop() + { + while (_running) + { + try + { + Thread.Sleep(TimeSpan.FromHours(1)); + } + catch (ThreadInterruptedException) + { + Console.WriteLine("Thread interrupted"); + } + catch (ThreadAbortException) + { + _running = false; + } + } + Console.WriteLine("Thread exited"); + } + + public void ForceLoop() + { + _trackerThread.Interrupt(); + } + + static void Main(string[] args) + { + Tracker _ = new (); + } + + public void Dispose() + { + _running = false; + _trackerThread.Interrupt(); + } +} \ No newline at end of file diff --git a/Tracker/Tracker.csproj b/Tracker/Tracker.csproj new file mode 100644 index 0000000..c46201b --- /dev/null +++ b/Tracker/Tracker.csproj @@ -0,0 +1,21 @@ + + + + Exe + net9.0 + latest + enable + enable + + + + + + + + + + + + +