-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4223143
commit df64614
Showing
9 changed files
with
205 additions
and
0 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
SCMM.Market.SnipeSkins.Client/SCMM.Market.SnipeSkins.Client.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>true</ImplicitUsings> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\SCMM.Shared.Web.Client\SCMM.Shared.Web.Client.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace SCMM.Market.SnipeSkins.Client | ||
{ | ||
public class SnipeSkinsPricesResponse : Dictionary<string, int> | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using Microsoft.Extensions.Logging; | ||
using System.Text.Json; | ||
|
||
namespace SCMM.Market.SnipeSkins.Client | ||
{ | ||
public class SnipeSkinsWebClient : Shared.Web.Client.WebClientBase | ||
{ | ||
private const string WebsiteBaseUri = "https://snipeskins.com"; | ||
|
||
public SnipeSkinsWebClient(ILogger<SnipeSkinsWebClient> logger) : base(logger) | ||
{ | ||
} | ||
|
||
public async Task<SnipeSkinsPricesResponse> GetPricesAsync(string appId) | ||
{ | ||
using (var client = BuildWebApiHttpClient(host: new Uri(WebsiteBaseUri))) | ||
{ | ||
var url = $"{WebsiteBaseUri}/api/market/{appId}/prices"; | ||
var response = await RetryPolicy.ExecuteAsync(() => client.GetAsync(url)); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
var textJson = await response.Content.ReadAsStringAsync(); | ||
if (string.IsNullOrEmpty(textJson)) | ||
{ | ||
return default; | ||
} | ||
|
||
return JsonSerializer.Deserialize<SnipeSkinsPricesResponse>(textJson); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
SCMM.Steam.Functions/Timer/UpdateMarketItemPricesFromSnipeSkins.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
using Microsoft.Azure.Functions.Worker; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.Extensions.Logging; | ||
using SCMM.Market.SnipeSkins.Client; | ||
using SCMM.Shared.Abstractions.Statistics; | ||
using SCMM.Shared.Data.Models.Extensions; | ||
using SCMM.Shared.Data.Models.Statistics; | ||
using SCMM.Steam.Data.Models; | ||
using SCMM.Steam.Data.Models.Enums; | ||
using SCMM.Steam.Data.Models.Extensions; | ||
using SCMM.Steam.Data.Store; | ||
using SCMM.Steam.Data.Store.Types; | ||
using System.Diagnostics; | ||
|
||
namespace SCMM.Steam.Functions.Timer; | ||
|
||
public class UpdateMarketItemPricesFromSnipeSkins | ||
{ | ||
private const MarketType SnipeSkins = MarketType.SnipeSkins; | ||
|
||
private readonly SteamDbContext _db; | ||
private readonly SnipeSkinsWebClient _snipeSkinsWebClient; | ||
private readonly IStatisticsService _statisticsService; | ||
|
||
public UpdateMarketItemPricesFromSnipeSkins(SteamDbContext db, SnipeSkinsWebClient snipeSkinsWebClient, IStatisticsService statisticsService) | ||
{ | ||
_db = db; | ||
_snipeSkinsWebClient = snipeSkinsWebClient; | ||
_statisticsService = statisticsService; | ||
} | ||
|
||
[Function("Update-Market-Item-Prices-From-SnipeSkins")] | ||
public async Task Run([TimerTrigger("0 24/30 * * * *")] /* every 30mins */ TimerInfo timerInfo, FunctionContext context) | ||
{ | ||
if (!SnipeSkins.IsEnabled()) | ||
{ | ||
return; | ||
} | ||
|
||
var logger = context.GetLogger("Update-Market-Item-Prices-From-SnipeSkins"); | ||
|
||
var appIds = SnipeSkins.GetSupportedAppIds().Select(x => x.ToString()).ToArray(); | ||
var supportedSteamApps = await _db.SteamApps | ||
.Where(x => appIds.Contains(x.SteamId)) | ||
.ToListAsync(); | ||
if (!supportedSteamApps.Any()) | ||
{ | ||
return; | ||
} | ||
|
||
// Prices are returned in USD by default | ||
var usdCurrency = _db.SteamCurrencies.FirstOrDefault(x => x.Name == Constants.SteamCurrencyUSD); | ||
if (usdCurrency == null) | ||
{ | ||
return; | ||
} | ||
|
||
foreach (var app in supportedSteamApps) | ||
{ | ||
logger.LogTrace($"Updating market item price information from SnipeSkins (appId: {app.SteamId})"); | ||
await UpdateSnipeSkinsMarketPricesForApp(logger, app, usdCurrency); | ||
} | ||
} | ||
|
||
private async Task UpdateSnipeSkinsMarketPricesForApp(ILogger logger, SteamApp app, SteamCurrency cnyCurrency) | ||
{ | ||
var statisticsKey = String.Format(StatisticKeys.MarketStatusByAppId, app.SteamId); | ||
var stopwatch = new Stopwatch(); | ||
try | ||
{ | ||
stopwatch.Start(); | ||
|
||
var snipeSkinsPrices = await _snipeSkinsWebClient.GetPricesAsync(app.SteamId); | ||
var dbItems = await _db.SteamMarketItems | ||
.Where(x => x.AppId == app.Id) | ||
.Select(x => new | ||
{ | ||
Name = x.Description.NameHash, | ||
Currency = x.Currency, | ||
Item = x, | ||
}) | ||
.ToListAsync(); | ||
|
||
foreach (var snipeSkinsPrice in snipeSkinsPrices) | ||
{ | ||
var item = dbItems.FirstOrDefault(x => x.Name == snipeSkinsPrice.Key)?.Item; | ||
if (item != null) | ||
{ | ||
item.UpdateBuyPrices(SnipeSkins, new PriceWithSupply | ||
{ | ||
Price = item.Currency.CalculateExchange(snipeSkinsPrice.Value, cnyCurrency), | ||
Supply = null | ||
}); | ||
} | ||
} | ||
|
||
var missingItems = dbItems.Where(x => !snipeSkinsPrices.Any(y => x.Name == y.Key) && x.Item.BuyPrices.ContainsKey(SnipeSkins)); | ||
foreach (var missingItem in missingItems) | ||
{ | ||
missingItem.Item.UpdateBuyPrices(SnipeSkins, null); | ||
} | ||
|
||
await _db.SaveChangesAsync(); | ||
|
||
await _statisticsService.PatchDictionaryValueAsync<MarketType, MarketStatusStatistic>(statisticsKey, SnipeSkins, x => | ||
{ | ||
x.TotalItems = snipeSkinsPrices.Count(); | ||
x.TotalListings = null; | ||
x.LastUpdatedItemsOn = DateTimeOffset.Now; | ||
x.LastUpdatedItemsDuration = stopwatch.Elapsed; | ||
x.LastUpdateErrorOn = null; | ||
x.LastUpdateError = null; | ||
}); | ||
} | ||
catch (Exception ex) | ||
{ | ||
try | ||
{ | ||
logger.LogError(ex, $"Failed to update market item price information from SnipeSkins (appId: {app.SteamId}). {ex.Message}"); | ||
await _statisticsService.PatchDictionaryValueAsync<MarketType, MarketStatusStatistic>(statisticsKey, SnipeSkins, x => | ||
{ | ||
x.LastUpdateErrorOn = DateTimeOffset.Now; | ||
x.LastUpdateError = ex.Message; | ||
}); | ||
} | ||
catch (Exception) | ||
{ | ||
logger.LogError(ex, $"Failed to update market item price statistics for SnipeSkins (appId: {app.SteamId}). {ex.Message}"); | ||
} | ||
} | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters