Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
leMicin committed Dec 31, 2024
2 parents eecfc9c + 7bac7eb commit 510ade8
Show file tree
Hide file tree
Showing 114 changed files with 1,280 additions and 1,219 deletions.
Binary file modified Game Localization.xlsm
Binary file not shown.
12 changes: 6 additions & 6 deletions src/Sidekick.Apis.Poe/Bulk/BulkTradeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@ public class BulkTradeService(

public bool SupportsBulkTrade(Item? item)
{
return item?.Metadata.Rarity == Rarity.Currency && itemStaticDataProvider.GetId(item.Metadata) != null;
return item?.Header.Rarity == Rarity.Currency && itemStaticDataProvider.GetId(item.Header) != null;
}

public async Task<BulkResponseModel> SearchBulk(Item item)
{
logger.LogInformation("[Trade API] Querying Exchange API.");

var leagueId = await settingsService.GetString(SettingKeys.LeagueId);
var uri = $"{await GetBaseApiUrl(item.Metadata.Game)}exchange/{leagueId.GetUrlSlugForLeague()}";
var uri = $"{await GetBaseApiUrl(item.Header.Game)}exchange/{leagueId.GetUrlSlugForLeague()}";

var itemId = itemStaticDataProvider.GetId(item.Metadata);
var itemId = itemStaticDataProvider.GetId(item.Header);
if (itemId == null)
{
throw new ApiErrorException { AdditionalInformation = ["Sidekick could not find a valid item."], };
}

var currency = item.Metadata.Game == GameType.PathOfExile ? await settingsService.GetString(SettingKeys.PriceCheckBulkCurrency) : await settingsService.GetString(SettingKeys.PriceCheckBulkCurrencyPoE2);
var currency = item.Header.Game == GameType.PathOfExile ? await settingsService.GetString(SettingKeys.PriceCheckBulkCurrency) : await settingsService.GetString(SettingKeys.PriceCheckBulkCurrencyPoE2);
currency = filterProvider.GetPriceOption(currency);
var minStock = await settingsService.GetInt(SettingKeys.PriceCheckBulkMinimumStock);

Expand All @@ -53,7 +53,7 @@ public async Task<BulkResponseModel> SearchBulk(Item item)

if (currency == null || currency == "chaos_divine")
{
if (item.Metadata.Game == GameType.PathOfExile)
if (item.Header.Game == GameType.PathOfExile)
{
model.Query.Have.Add(model.Query.Want.Any(x => x == "chaos") ? "divine" : "chaos");
}
Expand Down Expand Up @@ -95,7 +95,7 @@ public async Task<BulkResponseModel> SearchBulk(Item item)

public async Task<Uri> GetTradeUri(Item item, string queryId)
{
var baseUri = new Uri(await GetBaseUrl(item.Metadata.Game) + "exchange/");
var baseUri = new Uri(await GetBaseUrl(item.Header.Game) + "exchange/");
var leagueId = await settingsService.GetString(SettingKeys.LeagueId);
return new Uri(baseUri, $"{leagueId.GetUrlSlugForLeague()}/{queryId}");
}
Expand Down
2 changes: 1 addition & 1 deletion src/Sidekick.Apis.Poe/Filters/FilterProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Sidekick.Apis.Poe.Clients;
using Sidekick.Apis.Poe.Filters.Models;
using Sidekick.Apis.Poe.Metadata.Models;
using Sidekick.Apis.Poe.Items.Models;
using Sidekick.Common.Cache;
using Sidekick.Common.Enums;
using Sidekick.Common.Extensions;
Expand Down
1 change: 0 additions & 1 deletion src/Sidekick.Apis.Poe/Filters/IFilterProvider.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Sidekick.Apis.Poe.Filters.Models;
using Sidekick.Apis.Poe.Metadata.Models;
using Sidekick.Common.Initialization;

namespace Sidekick.Apis.Poe.Filters;
Expand Down
8 changes: 8 additions & 0 deletions src/Sidekick.Apis.Poe/Filters/Models/ApiFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Sidekick.Apis.Poe.Filters.Models;

public class ApiFilter
{
public string? Id { get; set; }
public string? Title { get; set; }
public List<ApiFilters> Filters { get; set; } = new();
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Sidekick.Apis.Poe.Filters.Models;
namespace Sidekick.Apis.Poe.Filters.Models;

namespace Sidekick.Apis.Poe.Metadata.Models;

public class ApiFilterFilters
public class ApiFilters
{
public string? Id { get; set; }
public string? Text { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion src/Sidekick.Apis.Poe/IItemStaticDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ public interface IItemStaticDataProvider : IInitializableService
{
string? GetImage(string id);

string? GetId(ItemMetadata metadata);
string? GetId(Header header);
}
}
86 changes: 86 additions & 0 deletions src/Sidekick.Apis.Poe/Items/ApiInvariantItemProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Microsoft.Extensions.Logging;
using Sidekick.Apis.Poe.Clients;
using Sidekick.Apis.Poe.Items.Models;
using Sidekick.Common.Cache;
using Sidekick.Common.Enums;
using Sidekick.Common.Extensions;
using Sidekick.Common.Game;
using Sidekick.Common.Game.Items;
using Sidekick.Common.Game.Languages;
using Sidekick.Common.Settings;

namespace Sidekick.Apis.Poe.Items
{
public class ApiInvariantItemProvider
(
ICacheProvider cacheProvider,
IPoeTradeClient poeTradeClient,
ILogger<ApiInvariantItemProvider> logger,
IGameLanguageProvider gameLanguageProvider,
ISettingsService settingsService
) : IApiInvariantItemProvider
{
public Dictionary<string, ApiItem> IdDictionary { get; } = new();

public List<string> UncutGemIds { get; } = [];

/// <inheritdoc/>
public int Priority => 100;

/// <inheritdoc/>
public async Task Initialize()
{
IdDictionary.Clear();

var leagueId = await settingsService.GetString(SettingKeys.LeagueId);
var game = leagueId.GetGameFromLeagueId();
var cacheKey = $"{game.GetValueAttribute()}_InvariantItems";

var result = await cacheProvider.GetOrSet(cacheKey, () => poeTradeClient.Fetch<ApiCategory>(game, gameLanguageProvider.InvariantLanguage, "data/items"), (cache) => cache.Result.Any());

var categories = game switch
{
GameType.PathOfExile2 => ApiItemConstants.Poe2Categories,
_ => ApiItemConstants.Poe1Categories,
};
foreach (var category in categories)
{
FillCategoryItems(game, result.Result, category.Key, category.Value.Category);
}

InitializeUncutGemIds();
}

private void FillCategoryItems(GameType game, List<ApiCategory> categories, string categoryId, Category category)
{
var categoryItems = categories.SingleOrDefault(x => x.Id == categoryId);
if (categoryItems == null)
{
logger.LogWarning($"[MetadataProvider] The category '{categoryId}' could not be found in the metadata from the API.");
return;
}

for (var i = 0; i < categoryItems.Entries.Count; i++)
{
var entry = categoryItems.Entries[i];
entry.Id = $"{categoryId}.{i}";
entry.Game = game;
entry.Category = category;
IdDictionary.Add(entry.Id, entry);
}
}

private void InitializeUncutGemIds()
{
UncutGemIds.Clear();

foreach (var item in IdDictionary)
{
if(item.Value.Type == "Uncut Skill Gem" || item.Value.Type == "Uncut Spirit Gem" || item.Value.Type == "Uncut Support Gem")
{
UncutGemIds.Add(item.Key);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Sidekick.Common.Game.Items;

namespace Sidekick.Apis.Poe.Metadata;
namespace Sidekick.Apis.Poe.Items;

public class MetadataConstants
public class ApiItemConstants
{
public static Dictionary<string, (Category Category, bool UseRegex)> Poe1Categories = new()
{
Expand Down
101 changes: 101 additions & 0 deletions src/Sidekick.Apis.Poe/Items/ApiItemProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using Sidekick.Apis.Poe.Clients;
using Sidekick.Apis.Poe.Items.Models;
using Sidekick.Common.Cache;
using Sidekick.Common.Enums;
using Sidekick.Common.Extensions;
using Sidekick.Common.Game;
using Sidekick.Common.Game.Items;
using Sidekick.Common.Game.Languages;
using Sidekick.Common.Settings;

namespace Sidekick.Apis.Poe.Items;

public class ApiItemProvider
(
ICacheProvider cacheProvider,
IPoeTradeClient poeTradeClient,
ILogger<ApiItemProvider> logger,
IGameLanguageProvider gameLanguageProvider,
ISettingsService settingsService
) : IApiItemProvider
{
public Dictionary<string, List<ApiItem>> NameAndTypeDictionary { get; } = new();

public List<(Regex Regex, ApiItem Item)> NameAndTypeRegex { get; } = new();

/// <inheritdoc/>
public int Priority => 100;

/// <inheritdoc/>
public async Task Initialize()
{
NameAndTypeDictionary.Clear();
NameAndTypeRegex.Clear();

var leagueId = await settingsService.GetString(SettingKeys.LeagueId);
var game = leagueId.GetGameFromLeagueId();
var cacheKey = $"{game.GetValueAttribute()}_Items";

var result = await cacheProvider.GetOrSet(cacheKey, () => poeTradeClient.Fetch<ApiCategory>(game, gameLanguageProvider.Language, "data/items"), (cache) => cache.Result.Any());

var categories = game switch
{
GameType.PathOfExile2 => ApiItemConstants.Poe2Categories,
_ => ApiItemConstants.Poe1Categories,
};

foreach (var category in categories)
{
FillCategoryItems(game, result.Result, category.Key, category.Value.Category, category.Value.UseRegex);
}
}

private void FillCategoryItems(GameType game, List<ApiCategory> categories, string categoryId, Category category, bool useRegex = false)
{
var categoryItems = categories.SingleOrDefault(x => x.Id == categoryId);
if (categoryItems == null)
{
logger.LogWarning($"[MetadataProvider] The category '{categoryId}' could not be found in the metadata from the API.");
return;
}

for (var i = 0; i < categoryItems.Entries.Count; i++)
{
var entry = categoryItems.Entries[i];
entry.Id = $"{categoryId}.{i}";
entry.Game = game;
entry.Category = category;

if (!string.IsNullOrEmpty(entry.Name))
{
FillDictionary(entry.Name, entry);
if (!entry.IsUnique && useRegex) NameAndTypeRegex.Add((new Regex(Regex.Escape(entry.Name)), entry));
}

if (!string.IsNullOrEmpty(entry.Type))
{
FillDictionary(entry.Type, entry);
if (!entry.IsUnique && useRegex) NameAndTypeRegex.Add((new Regex(Regex.Escape(entry.Type)), entry));
}

if (!string.IsNullOrEmpty(entry.Text))
{
FillDictionary(entry.Text, entry);
if (!entry.IsUnique && useRegex) NameAndTypeRegex.Add((new Regex(Regex.Escape(entry.Text)), entry));
}
}
}

private void FillDictionary(string key, ApiItem metadata)
{
if (!NameAndTypeDictionary.TryGetValue(key, out var dictionaryEntry))
{
dictionaryEntry = new List<ApiItem>();
NameAndTypeDictionary.Add(key, dictionaryEntry);
}

dictionaryEntry.Add(metadata);
}
}
11 changes: 11 additions & 0 deletions src/Sidekick.Apis.Poe/Items/IApiInvariantItemProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Sidekick.Apis.Poe.Items.Models;
using Sidekick.Common.Initialization;

namespace Sidekick.Apis.Poe.Items;

public interface IApiInvariantItemProvider : IInitializableService
{
Dictionary<string, ApiItem> IdDictionary { get; }

List<string> UncutGemIds { get; }
}
12 changes: 12 additions & 0 deletions src/Sidekick.Apis.Poe/Items/IApiItemProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.RegularExpressions;
using Sidekick.Apis.Poe.Items.Models;
using Sidekick.Common.Initialization;

namespace Sidekick.Apis.Poe.Items;

public interface IApiItemProvider : IInitializableService
{
Dictionary<string, List<ApiItem>> NameAndTypeDictionary { get; }

List<(Regex Regex, ApiItem Item)> NameAndTypeRegex { get; }
}
13 changes: 13 additions & 0 deletions src/Sidekick.Apis.Poe/Items/Models/ApiCategory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Sidekick.Apis.Poe.Items.Models;

/// <summary>
/// Items from /trade/data/items.
/// </summary>
public class ApiCategory
{
public string? Id { get; set; }
public string? Label { get; set; }
public List<ApiItem> Entries { get; set; } = new();

public override string ToString() => $"{Label} - {Entries.Count} entries";
}
56 changes: 56 additions & 0 deletions src/Sidekick.Apis.Poe/Items/Models/ApiItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Text.Json.Serialization;
using Sidekick.Common.Game;
using Sidekick.Common.Game.Items;

namespace Sidekick.Apis.Poe.Items.Models;

public class ApiItem
{
public string? Name { get; init; }

public string? Type { get; init; }

public string? Text { get; init; }

[JsonPropertyName("disc")]
public string? Discriminator { get; init; }

public ApiItemFlags? Flags { get; init; }

[JsonIgnore]
public string? Id { get; set; }

[JsonIgnore]
public GameType Game { get; set; }

[JsonIgnore]
public Category? Category { get; set; }

[JsonIgnore]
public bool IsUnique => Flags?.Unique ?? false;

public Header ToHeader()
{
var categoryRarity = Category switch
{
Common.Game.Items.Category.DivinationCard => Rarity.DivinationCard,
Common.Game.Items.Category.Gem => Rarity.Gem,
Common.Game.Items.Category.Currency => Rarity.Currency,
_ => Rarity.Unknown
};

return new Header()
{
Name = Name,
Type = Text ?? Type,
ApiItemId = Id ?? string.Empty,
ApiName = Name,
ApiType = Type,
ApiText = Text,
ApiDiscriminator = Discriminator,
Game = Game,
Category = Category ?? Common.Game.Items.Category.Unknown,
Rarity = IsUnique ? Rarity.Unique : categoryRarity,
};
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Sidekick.Apis.Poe.Metadata.Models
namespace Sidekick.Apis.Poe.Items.Models
{
public class ApiItemFlags
{
Expand Down
Loading

0 comments on commit 510ade8

Please sign in to comment.