-
Notifications
You must be signed in to change notification settings - Fork 45
/
TitleUpdateInfoProvider.cs
78 lines (71 loc) · 3.37 KB
/
TitleUpdateInfoProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
using CompatBot.Utils;
using Microsoft.EntityFrameworkCore;
using PsnClient.POCOs;
namespace CompatBot.Database.Providers;
public static class TitleUpdateInfoProvider
{
private static readonly PsnClient.Client Client = new();
public static async Task<TitlePatch?> GetAsync(string? productId, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(productId))
return default;
productId = productId.ToUpper();
var (update, xml) = await Client.GetTitleUpdatesAsync(productId, cancellationToken).ConfigureAwait(false);
if (xml is {Length: > 10})
{
var xmlChecksum = xml.GetStableHash();
await using var db = new ThumbnailDb();
var updateInfo = db.GameUpdateInfo.FirstOrDefault(ui => ui.ProductCode == productId);
if (updateInfo is null)
db.GameUpdateInfo.Add(new() {ProductCode = productId, MetaHash = xmlChecksum, MetaXml = xml, Timestamp = DateTime.UtcNow.Ticks});
else if (updateInfo.MetaHash != xmlChecksum && update?.Tag?.Packages is {Length: >0})
{
updateInfo.MetaHash = xmlChecksum;
updateInfo.MetaXml = xml;
updateInfo.Timestamp = DateTime.UtcNow.Ticks;
}
else if (updateInfo.MetaHash == xmlChecksum)
updateInfo.Timestamp = DateTime.UtcNow.Ticks;
await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
if (update?.Tag?.Packages?.Length is null or 0)
{
await using var db = new ThumbnailDb();
var updateInfo = db.GameUpdateInfo.FirstOrDefault(ui => ui.ProductCode == productId);
if (updateInfo is null)
return update;
await using var memStream = Config.MemoryStreamManager.GetStream(Encoding.UTF8.GetBytes(updateInfo.MetaXml));
var xmlSerializer = new XmlSerializer(typeof(TitlePatch));
update = (TitlePatch?)xmlSerializer.Deserialize(memStream);
if (update is not null)
update.OfflineCacheTimestamp = updateInfo.Timestamp.AsUtc();
return update;
}
return update;
}
public static async Task RefreshGameUpdateInfoAsync(CancellationToken cancellationToken)
{
await using var db = new ThumbnailDb();
do
{
var productCodeList = await db.Thumbnail.AsNoTracking().Select(t => t.ProductCode).ToListAsync(cancellationToken).ConfigureAwait(false);
foreach (var titleId in productCodeList)
{
var updateInfo = db.GameUpdateInfo.AsNoTracking().FirstOrDefault(ui => ui.ProductCode == titleId);
if (!cancellationToken.IsCancellationRequested
&& (updateInfo?.Timestamp is null or 0L || updateInfo.Timestamp.AsUtc() < DateTime.UtcNow.AddMonths(-1)))
{
await GetAsync(titleId, cancellationToken).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
}
}
await Task.Delay(TimeSpan.FromDays(1), cancellationToken).ConfigureAwait(false);
} while (!cancellationToken.IsCancellationRequested);
}
}