Skip to content

Commit 5e02e98

Browse files
author
Moons
committed
feat(vendors): all the weapon vendors :)
1 parent cd48760 commit 5e02e98

15 files changed

+669
-86
lines changed

API.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<PackageReference Include="DotNetBungieAPI" Version="2.12.2" />
2727
<PackageReference Include="DotNetBungieAPI.AspNet.Security.OAuth.Providers" Version="1.0.2" />
2828
<PackageReference Include="DotNetBungieAPI.DefinitionProvider.Sqlite" Version="1.5.3" />
29-
<PackageReference Include="DotNetBungieAPI.HashReferences" Version="1.21.1" />
29+
<PackageReference Include="DotNetBungieAPI.HashReferences" Version="1.22.0" />
3030
<PackageReference Include="DotNetBungieAPI.Models" Version="2.11.3" />
3131
<PackageReference Include="DotNetBungieAPI.Service.Abstractions" Version="2.11.1" />
3232
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.0" />
@@ -38,7 +38,7 @@
3838
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
3939
<PackageReference Include="Serilog" Version="3.1.1" />
4040
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
41-
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.0" />
41+
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
4242
</ItemGroup>
4343

4444
</Project>

Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public static void Main()
3737
.CreateLogger();
3838

3939
Variables.Environment = Debugger.IsAttached ? Environment.Development : Environment.Production;
40+
Variables.StartTime = DateTime.UtcNow;
4041

4142
try
4243
{
@@ -113,7 +114,11 @@ public static void Main()
113114
.AddHostedService<BungieClientService>()
114115
.AddHostedService<SchedulerService>()
115116
.AddHostedService<UserRefresh>()
116-
.AddHostedService<VendorsGunsmith>();
117+
.AddHostedService<VendorsAdepts>()
118+
.AddHostedService<VendorsGunsmith>()
119+
.AddHostedService<VendorsIronBanner>()
120+
.AddHostedService<VendorsTrials>()
121+
.AddHostedService<VendorsWarTable>();
117122

118123
builder.Services
119124
.AddAuthentication(options =>

Routes/StatusRoute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static void MapStatus(this RouteGroupBuilder group)
1717
var statusResponse = new Status
1818
{
1919
ErrorCode = ErrorCode.Success,
20-
ErrorStatus = "Success",
20+
ErrorStatus = $"Uptime: {DateTime.UtcNow - Variables.StartTime}",
2121
Message = "Felicity.Api.Status",
2222
Response =
2323
[

Routes/VendorRoute.cs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using API.Contexts;
33
using API.Contexts.Objects;
44
using API.Responses;
5+
using DotNetBungieAPI.HashReferences;
56

67
namespace API.Routes;
78

@@ -21,6 +22,47 @@ public static void MapVendors(this RouteGroupBuilder group)
2122

2223
return TypedResults.Json(response, Common.JsonSerializerOptions);
2324
});
25+
26+
group.MapGet("/getAvailableWeapons", (DbManager db) =>
27+
{
28+
var response = new ListResponse
29+
{
30+
ErrorStatus = "Success",
31+
ErrorCode = ErrorCode.Success,
32+
Message = "Felicity.Api.Vendor",
33+
Response = GetWeapons(db.WeaponSales.Where(x => x.IsAvailable).ToList())
34+
};
35+
36+
return TypedResults.Json(response, Common.JsonSerializerOptions);
37+
});
38+
39+
group.MapGet("/getNightfallWeapon", (DbManager db) =>
40+
{
41+
var response = new ListResponse
42+
{
43+
ErrorStatus = "Success",
44+
ErrorCode = ErrorCode.Success,
45+
Message = "Felicity.Api.Vendor",
46+
Response = GetWeapons(db.WeaponSales.Where(x =>
47+
x.VendorId == DefinitionHashes.Vendors.CommanderZavala_69482069 && x.ItemPerks == "[[0]]").ToList())
48+
};
49+
50+
return TypedResults.Json(response, Common.JsonSerializerOptions);
51+
});
52+
53+
group.MapGet("/getTrialsWeapon", (DbManager db) =>
54+
{
55+
var response = new ListResponse
56+
{
57+
ErrorStatus = "Success",
58+
ErrorCode = ErrorCode.Success,
59+
Message = "Felicity.Api.Vendor",
60+
Response = GetWeapons(db.WeaponSales.Where(x =>
61+
x.VendorId == DefinitionHashes.Vendors.Saint14 && x.ItemPerks == "[[0]]").ToList())
62+
};
63+
64+
return TypedResults.Json(response, Common.JsonSerializerOptions);
65+
});
2466
}
2567

2668
private static List<object> GetWeapons(IEnumerable<WeaponSale> dbWeaponSales)
@@ -29,7 +71,6 @@ private static List<object> GetWeapons(IEnumerable<WeaponSale> dbWeaponSales)
2971

3072
// ReSharper disable once LoopCanBeConvertedToQuery
3173
foreach (var weaponSale in dbWeaponSales.OrderByDescending(x => x.QueryTime))
32-
{
3374
weaponSales.Add(new WeaponSaleResponse
3475
{
3576
IsAvailable = weaponSale.IsAvailable,
@@ -40,9 +81,7 @@ private static List<object> GetWeapons(IEnumerable<WeaponSale> dbWeaponSales)
4081
RequiredResets = weaponSale.RequiredResets,
4182
VendorId = weaponSale.VendorId
4283
});
43-
}
4484

4585
return [weaponSales];
4686
}
4787
}
48-

Services/SchedulerService.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken)
1515
{
1616
TaskSchedulerService.Tasks.Add(new ScheduledTask
1717
{ Name = "UserRefresh", IsRunning = false, LastRun = null });
18+
TaskSchedulerService.Tasks.Add(new ScheduledTask
19+
{ Name = "VendorsAdepts", IsRunning = false, LastRun = null });
1820
TaskSchedulerService.Tasks.Add(new ScheduledTask
1921
{ Name = "VendorsGunsmith", IsRunning = false, LastRun = null });
2022
TaskSchedulerService.Tasks.Add(new ScheduledTask
21-
{ Name = "VendorsXur", IsRunning = false, LastRun = null });
23+
{ Name = "VendorsIronBanner", IsRunning = false, LastRun = null });
24+
TaskSchedulerService.Tasks.Add(new ScheduledTask
25+
{ Name = "VendorsTrials", IsRunning = false, LastRun = null });
26+
TaskSchedulerService.Tasks.Add(new ScheduledTask
27+
{ Name = "VendorsWarTable", IsRunning = false, LastRun = null });
2228
}
2329
catch (Exception e)
2430
{

Tasks/UserRefresh.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
3333
var users = await db.Users.Include(u => u.BungieProfiles).ToListAsync(stoppingToken);
3434
var bungieProfiles = users.SelectMany(u => u.BungieProfiles)
3535
// TODO: .Where(u => u.NeverExpire)
36-
.Where(u => u.NeedsRefresh());
36+
.Where(u => u.NeedsRefresh(bungieClient).Result);
3737

3838
foreach (var profile in bungieProfiles)
3939
{
@@ -48,7 +48,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
4848
foreach (var user in users)
4949
{
5050
var userProfile =
51-
user.BungieProfiles.FirstOrDefault(p => p.TokenExpires < DateTime.UtcNow);
51+
user.BungieProfiles.FirstOrDefault(p => p.TokenExpires > DateTime.UtcNow);
5252
if (userProfile == null)
5353
continue;
5454

@@ -87,6 +87,8 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
8787

8888
if (addBannerUser)
8989
await db.VendorUsers.AddAsync(bannerVendorUser, stoppingToken);
90+
else
91+
db.VendorUsers.Update(bannerVendorUser);
9092
}
9193

9294
// ReSharper disable once InvertIf
@@ -114,6 +116,8 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
114116

115117
if (addTrialsUser)
116118
await db.VendorUsers.AddAsync(trialsVendorUser, stoppingToken);
119+
else
120+
db.VendorUsers.Update(trialsVendorUser);
117121
}
118122
}
119123

Tasks/VendorsAdepts.cs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
using API.Contexts;
2+
using API.Contexts.Objects;
3+
using API.Services;
4+
using API.Util;
5+
using DotNetBungieAPI.Extensions;
6+
using DotNetBungieAPI.Models.Destiny;
7+
using DotNetBungieAPI.Service.Abstractions;
8+
using Microsoft.EntityFrameworkCore;
9+
using static DotNetBungieAPI.HashReferences.DefinitionHashes;
10+
11+
namespace API.Tasks;
12+
13+
public class VendorsAdepts(
14+
IServiceProvider services,
15+
ILogger<VendorsAdepts> logger,
16+
IBungieClient bungieClient)
17+
: BackgroundService
18+
{
19+
private const string ServiceName = "VendorsAdepts";
20+
21+
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
22+
{
23+
using var scope = services.CreateScope();
24+
var db =
25+
scope.ServiceProvider
26+
.GetRequiredService<DbManager>();
27+
28+
// TODO: raise this to 5/10 minutes
29+
await Task.Delay(DateTimeExtensions.GetRoundTimeSpan(2), stoppingToken);
30+
31+
while (!stoppingToken.IsCancellationRequested)
32+
{
33+
while (TaskSchedulerService.Tasks.First(t => t.Name == "UserRefresh").IsRunning)
34+
await Task.Delay(DateTimeExtensions.GetRoundTimeSpan(1), stoppingToken);
35+
36+
TaskSchedulerService.Tasks.First(t => t.Name == ServiceName).IsRunning = true;
37+
38+
try
39+
{
40+
var vendorUser = db.Users.Include(u => u.BungieProfiles)
41+
.FirstOrDefault(x => x.Id == UserExtensions.SignId(Variables.OwnerId));
42+
43+
if (vendorUser == null)
44+
{
45+
logger.LogError("Vendor user not found.");
46+
return;
47+
}
48+
49+
var vendorProfile = vendorUser.BungieProfiles.First();
50+
51+
if (await vendorProfile.NeedsRefresh(bungieClient))
52+
await vendorProfile.RefreshToken(bungieClient, DateTime.UtcNow);
53+
54+
await db.SaveChangesAsync(stoppingToken);
55+
56+
var charactersQuery = await bungieClient.ApiAccess.Destiny2.GetProfile(
57+
vendorProfile.DestinyMembershipType,
58+
vendorProfile.DestinyMembershipId, [DestinyComponentType.Characters],
59+
cancellationToken: stoppingToken);
60+
61+
if (charactersQuery.IsSuccessfulResponseCode)
62+
{
63+
var vendorList = new Dictionary<uint, uint>
64+
{
65+
{
66+
Vendors.FocusedDecoding_502095006,
67+
Vendors.Saint14
68+
},
69+
{
70+
Vendors.FocusedDecoding_2232145065,
71+
Vendors.CommanderZavala_69482069
72+
}
73+
};
74+
75+
foreach (var vendor in vendorList)
76+
{
77+
var vendorQuery = await bungieClient.ApiAccess.Destiny2.GetVendor(
78+
vendorProfile.DestinyMembershipType, vendorProfile.DestinyMembershipId,
79+
charactersQuery.Response.Characters.Data.First().Key, vendor.Key,
80+
[
81+
DestinyComponentType.VendorSales
82+
], vendorProfile.GetTokenData(), stoppingToken);
83+
84+
if (!vendorQuery.IsSuccessfulResponseCode)
85+
continue;
86+
87+
var adeptWeapon = vendorQuery.Response.Sales.Data
88+
.Where(destinyVendorSaleItemComponent =>
89+
destinyVendorSaleItemComponent.Value.Item.Select(x =>
90+
x.DisplayProperties.Name.EndsWith("(Adept)")))
91+
.Select(destinyVendorSaleItemComponent => destinyVendorSaleItemComponent.Value.Item)
92+
.FirstOrDefault();
93+
94+
if (!adeptWeapon.HasValidHash)
95+
continue;
96+
97+
var adeptWeaponId = adeptWeapon.Select(x => x.Hash);
98+
99+
if (adeptWeaponId != 0)
100+
{
101+
var vendorWeapon = WeaponTools.GetWeaponFromDummy(adeptWeapon.Hash ?? 0);
102+
103+
logger.LogDebug("Converting {dummyId} to {vendorId}", adeptWeaponId, vendorWeapon);
104+
105+
var existingItem = db.WeaponSales.FirstOrDefault(x =>
106+
x.VendorId == vendor.Value && x.ItemId == vendorWeapon);
107+
if (existingItem != null)
108+
db.WeaponSales.Remove(existingItem);
109+
110+
var vendorItem = new WeaponSale
111+
{
112+
IsAvailable = true,
113+
ItemId = vendorWeapon,
114+
ItemPerks = "[[0]]",
115+
QueryTime = DateTime.UtcNow,
116+
VendorId = vendor.Value
117+
};
118+
119+
logger.LogInformation("[{service}]: Found adept weapon ID: {weaponId}",
120+
"FetchWeaponVendors", vendorWeapon);
121+
122+
db.WeaponSales.Add(vendorItem);
123+
}
124+
else
125+
{
126+
var existingItem =
127+
db.WeaponSales.FirstOrDefault(x => x.VendorId == vendor.Value && x.ItemId == 0);
128+
if (existingItem != null)
129+
db.WeaponSales.Remove(existingItem);
130+
131+
var vendorItem = new WeaponSale
132+
{
133+
IsAvailable = true,
134+
ItemId = 0,
135+
ItemPerks = "[[0]]",
136+
QueryTime = DateTime.UtcNow,
137+
VendorId = vendor.Value
138+
};
139+
140+
logger.LogInformation("[{service}]: No adept weapon found.", "FetchWeaponVendors");
141+
142+
db.WeaponSales.Add(vendorItem);
143+
}
144+
}
145+
146+
await db.SaveChangesAsync(stoppingToken);
147+
}
148+
}
149+
catch (Exception e)
150+
{
151+
logger.LogError(e, "Exception in {service}", ServiceName);
152+
}
153+
154+
TaskSchedulerService.Tasks.First(t => t.Name == ServiceName).IsRunning = false;
155+
TaskSchedulerService.Tasks.First(t => t.Name == ServiceName).LastRun = DateTime.UtcNow;
156+
157+
await Task.Delay(DateTimeExtensions.GetRoundTimeSpan(60), stoppingToken);
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)