234 lines
9.4 KiB
C#
234 lines
9.4 KiB
C#
using MarketPriceLookup.Helpers;
|
|
using Microsoft.VisualBasic.FileIO;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
|
|
namespace MarketPriceLookup.Common.Helpers
|
|
{
|
|
public static class MarketPricesHelper
|
|
{
|
|
private static readonly Dictionary<string, Prices> priceFile = new Dictionary<string, Prices>();
|
|
|
|
public static Dictionary<string, Prices> GetAllPrices()
|
|
{
|
|
if (priceFile.Count == 0)
|
|
{
|
|
//HydrateDictionaryCSV();
|
|
HydrateDictionaryTarkovDev();
|
|
}
|
|
|
|
return priceFile;
|
|
}
|
|
|
|
private static void HydrateDictionaryTarkovDev()
|
|
{
|
|
var request = new Dictionary<string, string>()
|
|
{
|
|
{"query", "{ items(lang: en) { name avg24hPrice changeLast48hPercent id historicalPrices{ price timestamp } }}"}
|
|
};
|
|
|
|
using (var httpClient = new HttpClient())
|
|
{
|
|
// call tarkov dev api
|
|
var httpResponse = httpClient.PostAsJsonAsync("https://api.tarkov.dev/graphql", request).GetAwaiter().GetResult();
|
|
var responseContent = httpResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
|
var parsedResponse = JsonSerializer.Deserialize<TarkovDevResponse>(responseContent, new JsonSerializerOptions());
|
|
|
|
// iterate over all items returned and filter out bad prices
|
|
foreach (var item in parsedResponse.data.items)
|
|
{
|
|
if (item.historicalPrices.Length == 0)
|
|
{
|
|
LoggingHelpers.LogError($"unable to add item {item.id} {item.name} with no historical prices, ignoring");
|
|
continue;
|
|
}
|
|
|
|
if (item.changeLast48hPercent > 100)
|
|
{
|
|
LoggingHelpers.LogWarning($"Item {item.id} {item.name} Has had recent {item.changeLast48hPercent}% increase in price. {item.historicalPrices.Length} price values");
|
|
}
|
|
|
|
var averagedItemPrice = GetAveragedPrice(item);
|
|
if (averagedItemPrice == 0)
|
|
{
|
|
LoggingHelpers.LogError($"unable to add item {item.id} {item.name} with average price of 0, ignoring");
|
|
continue;
|
|
}
|
|
|
|
if (item.name.Contains(" (0/"))
|
|
{
|
|
LoggingHelpers.LogWarning($"Skipping 0 durability item: {item.id} {item.name}");
|
|
continue;
|
|
}
|
|
|
|
if (priceFile.ContainsKey(item.id))
|
|
{
|
|
// Item already exists in the csv
|
|
var existingItem = priceFile[item.id];
|
|
LoggingHelpers.LogError($"Unable to add item: {item.id} {item.name} (price: {item.avg24hPrice}). existing item: {existingItem.TemplateId} {existingItem.Name} (price: {existingItem.Average24hPrice})");
|
|
if (existingItem.Average24hPrice < averagedItemPrice)
|
|
{
|
|
LoggingHelpers.LogError($"Price diff found: existing item price: {existingItem.Average7DaysPrice} new item price: {averagedItemPrice}, using larger price");
|
|
priceFile.Remove(item.id);
|
|
}
|
|
}
|
|
|
|
// Item not already in dictionary, add it
|
|
if (!priceFile.ContainsKey(item.id))
|
|
{
|
|
priceFile.Add(item.id, new Prices
|
|
{
|
|
Name = item.name,
|
|
//Price = price,
|
|
Average24hPrice = item.avg24hPrice,
|
|
Average7DaysPrice = averagedItemPrice,
|
|
//Trader = trader,
|
|
//BuyPackPrice = buyBackPrice,
|
|
//Currency = currency,
|
|
TemplateId = item.id,
|
|
//TraderPrice = traderPrice,
|
|
});
|
|
|
|
LoggingHelpers.LogSuccess($"Adding item: {item.id} {item.name}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get items average flea price from all readings taken over the past 7 days
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
private static int GetAveragedPrice(Item item)
|
|
{
|
|
var sevenDaysAgoTimestamp = DateTimeOffset.UtcNow.AddDays(-7).ToUnixTimeSeconds();
|
|
var pricesWithinLast7days = new List<int>();
|
|
foreach (var historicalPrice in item.historicalPrices)
|
|
{
|
|
if (long.Parse(historicalPrice.timestamp) > sevenDaysAgoTimestamp)
|
|
{
|
|
pricesWithinLast7days.Add(historicalPrice.price);
|
|
}
|
|
}
|
|
|
|
if (pricesWithinLast7days.Count == 0)
|
|
{
|
|
LoggingHelpers.LogError($"No prices found for item {item.name} in last 7 days, using any availible");
|
|
pricesWithinLast7days.AddRange(item.historicalPrices.Select(x => x.price));
|
|
}
|
|
|
|
return (int)Math.Round(pricesWithinLast7days.Average());
|
|
}
|
|
|
|
public static Prices GetItemPrice(string key)
|
|
{
|
|
// parse csv if dictionary is empty
|
|
if (priceFile.Count == 0)
|
|
{
|
|
//HydrateDictionaryCSV();
|
|
HydrateDictionaryTarkovDev();
|
|
}
|
|
|
|
if (!priceFile.ContainsKey(key))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return priceFile[key];
|
|
}
|
|
|
|
private static void HydrateDictionaryCSV()
|
|
{
|
|
var workingPath = Directory.GetCurrentDirectory();
|
|
var inputPath = $"{workingPath}//input";
|
|
var filePath = $"{inputPath}//marketPrices.csv";
|
|
DiskHelpers.CreateDirIfDoesntExist(inputPath);
|
|
|
|
using (TextFieldParser csvParser = new TextFieldParser(filePath))
|
|
{
|
|
csvParser.CommentTokens = new string[] { "#" };
|
|
csvParser.SetDelimiters(new string[] { "," });
|
|
csvParser.HasFieldsEnclosedInQuotes = true;
|
|
|
|
// Skip the row with the column names
|
|
csvParser.ReadLine();
|
|
csvParser.ReadLine();
|
|
|
|
while (!csvParser.EndOfData)
|
|
{
|
|
// Read current line fields, pointer moves to the next line.
|
|
string[] fields = csvParser.ReadFields();
|
|
//string uid = fields[0];
|
|
string name = fields[1];
|
|
int price = int.Parse(fields[2]);
|
|
int avg24hPrice = int.Parse(fields[3]);
|
|
int avg7daysPrice = int.Parse(fields[4]);
|
|
string trader = fields[5];
|
|
//int buyBackPrice = int.Parse(fields[6]);
|
|
string currency = GetCurrencyType(fields[7]);
|
|
string bsgId = fields[8];
|
|
int traderPrice = int.Parse(fields[9]);
|
|
|
|
if (avg7daysPrice == 0)
|
|
{
|
|
LoggingHelpers.LogError($"unable to add item {bsgId} {name} with average price of 0, ignoring");
|
|
continue;
|
|
}
|
|
|
|
if (name.Contains(" (0/"))
|
|
{
|
|
LoggingHelpers.LogWarning($"Skipping 0 durability item: {bsgId} {name}");
|
|
continue;
|
|
}
|
|
|
|
if (priceFile.ContainsKey(bsgId))
|
|
{
|
|
//oh no, item already exists in the csv
|
|
var existingItem = priceFile[bsgId];
|
|
LoggingHelpers.LogError($"Unable to add item: {bsgId} {name}. existing item: {existingItem.TemplateId} {existingItem.Name}");
|
|
if (existingItem.Average7DaysPrice < avg7daysPrice)
|
|
{
|
|
LoggingHelpers.LogError($"Price diff found: existing item price: {existingItem.Average7DaysPrice} new item price: {avg7daysPrice}, using larger price");
|
|
priceFile.Remove(bsgId);
|
|
}
|
|
}
|
|
if (!priceFile.ContainsKey(bsgId))
|
|
{
|
|
priceFile.Add(bsgId, new Prices
|
|
{
|
|
Name = name,
|
|
Price = price,
|
|
Average24hPrice = avg24hPrice,
|
|
Average7DaysPrice = avg7daysPrice,
|
|
Trader = trader,
|
|
//BuyPackPrice = buyBackPrice,
|
|
Currency = currency,
|
|
TemplateId = bsgId,
|
|
TraderPrice = traderPrice,
|
|
});
|
|
}
|
|
|
|
LoggingHelpers.LogSuccess($"Adding item: {bsgId} {name}");
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
private static string GetCurrencyType(string input)
|
|
{
|
|
return input switch
|
|
{
|
|
"₽" => "Rouble",
|
|
"$" => "Dollar",
|
|
"€" => "Euro",
|
|
_ => string.Empty,
|
|
};
|
|
}
|
|
}
|
|
}
|