This commit is contained in:
glax 2025-05-25 18:37:27 +02:00
parent 90d7281050
commit 01310020ce
10 changed files with 337 additions and 0 deletions

41
API/Api.cs Normal file
View File

@ -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<Context>();
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);
}
}

View File

@ -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"
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

9
API/appsettings.json Normal file
View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

12
Run/Program.cs Normal file
View File

@ -0,0 +1,12 @@
using API;
namespace Run;
class Program
{
static void Main(string[] args)
{
Api a = new (args);
Tracker.Tracker t = new ();
}
}

16
Run/Run.csproj Normal file
View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\API\API.csproj" />
<ProjectReference Include="..\Tracker\Tracker.csproj" />
</ItemGroup>
</Project>

38
SQLiteEF/Player.cs Normal file
View File

@ -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<Game> Games { get; init; } = null!;
public ICollection<TrackedTime> 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 = [];
}
/// <summary>
/// EF CORE
/// </summary>
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;
}
}

14
SQLiteEF/SQLiteEF.csproj Normal file
View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.5" />
</ItemGroup>
</Project>

155
Tracker/Tracker.cs Normal file
View File

@ -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<ulong> 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<Player> 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<Player> 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();
}
}

21
Tracker/Tracker.csproj Normal file
View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SQLiteEF\SQLiteEF.csproj" />
<ProjectReference Include="..\SteamApiWrapper\SteamApiWrapper.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.5" />
</ItemGroup>
</Project>