Working
This commit is contained in:
202
API/Tracker.cs
Normal file
202
API/Tracker.cs
Normal file
@ -0,0 +1,202 @@
|
||||
using System.Globalization;
|
||||
using log4net;
|
||||
using SQLiteEF;
|
||||
using SteamApiWrapper.ReturnTypes;
|
||||
using SteamGame = SteamApiWrapper.ReturnTypes.Game;
|
||||
using Player = SQLiteEF.Player;
|
||||
using SteamPlayer = SteamApiWrapper.ReturnTypes.Player;
|
||||
using Steam = SteamApiWrapper.SteamApiWrapper;
|
||||
|
||||
namespace API;
|
||||
|
||||
public class Tracker : IDisposable
|
||||
{
|
||||
private readonly Thread _trackerThread;
|
||||
private bool _running = true;
|
||||
private ILog Log { get; } = LogManager.GetLogger(typeof(Tracker));
|
||||
private TimeSpan Interval { get; init; }
|
||||
|
||||
public Tracker(IServiceProvider serviceProvider, IConfiguration configuration)
|
||||
{
|
||||
Interval = TimeSpan.Parse(configuration.GetValue<string>("UpdateInterval")!, CultureInfo.InvariantCulture);
|
||||
_trackerThread = new (TrackerLoop);
|
||||
_trackerThread.Start(serviceProvider);
|
||||
}
|
||||
|
||||
internal void UpdatePlayers(Context context)
|
||||
{
|
||||
Log.Info("Updating Players");
|
||||
Player[] dbPlayers = context.Players.ToArray();
|
||||
SteamPlayer[] summaries = Steam.GetPlayerSummaries(dbPlayers.Select(p => p.SteamId).ToArray());
|
||||
foreach (Player dbPlayer in dbPlayers)
|
||||
{
|
||||
if(summaries.All(summaryPlayer => summaryPlayer.steamid != dbPlayer.SteamId))
|
||||
continue;
|
||||
SteamPlayer summaryPlayer = summaries.First(summaryPlayer => summaryPlayer.steamid == dbPlayer.SteamId);
|
||||
|
||||
try
|
||||
{
|
||||
dbPlayer.Name = summaryPlayer.personaname;
|
||||
dbPlayer.AvatarUrl = summaryPlayer.avatar;
|
||||
dbPlayer.ProfileUrl = summaryPlayer.profileurl;
|
||||
dbPlayer.UpdatedAt = DateTime.UtcNow;
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdatePlayer(Context context, Player player)
|
||||
{
|
||||
SteamPlayer[] summaries = Steam.GetPlayerSummaries([player.SteamId]);
|
||||
if(summaries.All(summaryPlayer => summaryPlayer.steamid != player.SteamId))
|
||||
return;
|
||||
SteamPlayer summaryPlayer = summaries.First(summaryPlayer => summaryPlayer.steamid == player.SteamId);
|
||||
|
||||
try
|
||||
{
|
||||
player.Name = summaryPlayer.personaname;
|
||||
player.AvatarUrl = summaryPlayer.avatar;
|
||||
player.ProfileUrl = summaryPlayer.profileurl;
|
||||
player.UpdatedAt = DateTime.UtcNow;
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateOwnedGames(Context context)
|
||||
{
|
||||
Log.Info("Updating Owned Games");
|
||||
Player[] players = context.Players.ToArray();
|
||||
foreach (Player player in players)
|
||||
{
|
||||
UpdateOwnedGamesPlayer(context, player);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateOwnedGamesPlayer(Context context, Player player)
|
||||
{
|
||||
Log.Debug($"Updating owned games for player {player}");
|
||||
SteamGame[] ownedGames = Steam.GetOwnedGames(player.SteamId);
|
||||
foreach (SteamGame ownedGame in ownedGames)
|
||||
{
|
||||
if (context.Games.Find(ownedGame.appid) is not { } game)
|
||||
{
|
||||
game = new(ownedGame.appid, ownedGame.name);
|
||||
context.Games.Add(game);
|
||||
}
|
||||
|
||||
if (!player.Games.Contains(game))
|
||||
{
|
||||
context.Entry(player).Collection(p => p.Games).Load();
|
||||
player.Games.Add(game);
|
||||
context.Entry(game).Collection(g => g.PlayedBy).Load();
|
||||
game.PlayedBy.Add(player);
|
||||
context.Entry(player).Collection(p => p.TrackedTimes).Load();
|
||||
player.TrackedTimes.Add(new (game, player, ownedGame.playtime_forever));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateGameTimes(Context context)
|
||||
{
|
||||
Log.Info("Updating Game Times");
|
||||
Player[] players = context.Players.ToArray();
|
||||
foreach (Player player in players)
|
||||
{
|
||||
UpdateGameTimesPlayer(context, player);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateGameTimesPlayer(Context context, Player player)
|
||||
{
|
||||
Log.Debug($"Updating game times for player {player}");
|
||||
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);
|
||||
context.Games.Add(game);
|
||||
}
|
||||
|
||||
if (!player.Games.Contains(game))
|
||||
{
|
||||
context.Entry(player).Collection(p => p.Games).Load();
|
||||
player.Games.Add(game);
|
||||
context.Entry(game).Collection(g => g.PlayedBy).Load();
|
||||
game.PlayedBy.Add(player);
|
||||
}
|
||||
|
||||
context.Entry(player).Collection(p => p.TrackedTimes).Load();
|
||||
player.TrackedTimes.Add(new (game, player, recentlyPlayedGame.playtime_forever));
|
||||
|
||||
try
|
||||
{
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TrackerLoop(object? obj)
|
||||
{
|
||||
if (obj is not IServiceProvider serviceProvider)
|
||||
{
|
||||
Log.Fatal("Tracker loop wasn't started.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (_running)
|
||||
{
|
||||
IServiceScope scope = serviceProvider.CreateScope();
|
||||
Context context = scope.ServiceProvider.GetRequiredService<Context>();
|
||||
UpdatePlayers(context);
|
||||
UpdateOwnedGames(context);
|
||||
UpdateGameTimes(context);
|
||||
scope.Dispose();
|
||||
try
|
||||
{
|
||||
Thread.Sleep(Interval);
|
||||
}
|
||||
catch (ThreadInterruptedException)
|
||||
{
|
||||
Log.Debug("Thread interrupted");
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
_running = false;
|
||||
}
|
||||
}
|
||||
Log.Info("Thread exited");
|
||||
}
|
||||
|
||||
public void ForceLoop()
|
||||
{
|
||||
_trackerThread.Interrupt();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_running = false;
|
||||
_trackerThread.Interrupt();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user