public async Task GetCraftingCost(int amount, [Remainder] string item) { //Search for the item through personal sheets to find corresponding id var itemSearchApi = new ItemSearchApi(_ssService); var id = await itemSearchApi.GetItemId(item); if (id == 0) { await ReplyAsync($"Could not find item with search key '{item}'"); return; } //Use item id to retrieve item details (in particular, image for the item) var itemApi = new ItemApi(); var itemDetails = await itemApi.GetItemDetails(id); if (itemDetails == null) { await ReplyAsync($"Could not find item with search key '{item}'"); return; } //Use item id to retrieve current marketplace value of the item var crApi = new CraftingApi(); var craftRecipes = await crApi.GetCraftingCost(itemDetails.Name); var chosenRecipe = craftRecipes.Where(r => r.Quantity == amount).FirstOrDefault(); if (chosenRecipe == null) { if (craftRecipes.Length == 0) { await ReplyAsync($"No crafting recipes available for '{itemDetails.Name}'"); } else { var amountList = craftRecipes.Aggregate("", (accum, cur) => accum + cur.Quantity + ", ", accum => accum.TrimEnd(',', ' ')); await ReplyAsync($"Must choose one of the following craft amounts for '{itemDetails.Name}': {amountList}"); } return; } var altRecipes = craftRecipes.Where(r => r.Quantity != chosenRecipe.Quantity); var mpApi = new MarketplaceApi(); var tasks = new List <Task>(); var mainItemListing = await mpApi.GetMarketplaceListing(itemDetails.Id); if ((mainItemListing?.Listings.Length ?? 0) == 0) { await ReplyAsync($"No maketplace listings available for '{itemDetails.Name}'"); return; } var outputPrice = mainItemListing.Listings.First().PricePerItem *chosenRecipe.Quantity; if (chosenRecipe.Ingredients != null) { //Currently the drive only supports searching for items in a serial manner //Can avoid this slow linear search if/when the unofficial api returns ids along with item names for (int i = 0; i < chosenRecipe.Ingredients.Length; i++) { var idx = i; chosenRecipe.Ingredients[idx].Id = await itemSearchApi.GetItemId(chosenRecipe.Ingredients[idx].Name); tasks.Add(Task.Run(async() => { chosenRecipe.Ingredients[idx].Cost = new Gold(0); //Some items may not be sellable items, or may not be listed on the marketplace; we ignore these if (chosenRecipe.Ingredients[idx].Id != 0) { var listing = await mpApi.GetMarketplaceListing(chosenRecipe.Ingredients[idx].Id); if ((listing?.Listings.Length ?? 0) != 0) { chosenRecipe.Ingredients[idx].Cost = listing.Listings.First().PricePerItem *chosenRecipe.Ingredients[idx].Quantity; } } })); } } if (chosenRecipe.AttemptIngredients != null) { //Currently the drive only supports searching for items in a serial manner //Can avoid this slow linear search if/when the unofficial api returns ids along with item names for (int i = 0; i < chosenRecipe.AttemptIngredients.Length; i++) { var idx = i; chosenRecipe.AttemptIngredients[idx].Id = await itemSearchApi.GetItemId(chosenRecipe.AttemptIngredients[idx].Name); tasks.Add(Task.Run(async() => { chosenRecipe.AttemptIngredients[idx].Cost = new Gold(0); //Some items may not be sellable items, or may not be listed on the marketplace; we ignore these if (chosenRecipe.AttemptIngredients[idx].Id != 0) { var listing = await mpApi.GetMarketplaceListing(chosenRecipe.AttemptIngredients[idx].Id); if ((listing?.Listings.Length ?? 0) != 0) { chosenRecipe.AttemptIngredients[idx].Cost = listing.Listings.First().PricePerItem *chosenRecipe.AttemptIngredients[idx].Quantity; } } })); } } await Task.WhenAll(tasks); var craftCost = chosenRecipe.Cost; var individualCostStr = $"{chosenRecipe.Cost.GoldPart} {GoldIcon} {chosenRecipe.Cost.SilverPart} {SilverIcon} - Crafting Price\r\n"; if (chosenRecipe.Ingredients != null) { foreach (var ing in chosenRecipe.Ingredients) { craftCost += ing.Cost; if (ing.Cost == 0) { individualCostStr += $"No marketplace value available - {ing.Name} x {ing.Quantity}\r\n"; } else { individualCostStr += $"{ing.Cost.GoldPart} {GoldIcon} {ing.Cost.SilverPart} {SilverIcon} - {ing.Name} x {ing.Quantity}\r\n"; } } } if (chosenRecipe.AttemptIngredients != null) { foreach (var atmpt in chosenRecipe.AttemptIngredients) { craftCost += atmpt.Cost; if (atmpt.Cost == 0) { individualCostStr += $"No marketplace value available - {atmpt.Name} x {atmpt.Quantity}\r\n"; } else { individualCostStr += $"{atmpt.Cost.GoldPart} {GoldIcon} {atmpt.Cost.SilverPart} {SilverIcon} - {atmpt.Name} x {atmpt.Quantity}\r\n"; } } } var netCost = outputPrice - craftCost; var embed = new EmbedBuilder(); embed.ThumbnailUrl = itemDetails.ImgUrl; embed.Title = itemDetails.Name; if (chosenRecipe.SuccessRate > 0.0 && chosenRecipe.SuccessRate < 1.0) { embed.Title += " (chance to fail)"; } embed.Description = $"Net Earnings: {netCost.GoldPart} {GoldIcon} {netCost.SilverPart} {SilverIcon}"; var altCraftAmtStr = altRecipes.Aggregate("", (accum, cur) => accum + cur.Quantity + ", ", accum => accum.TrimEnd(',', ' ')); var craftSpecsStr = $"Source: {chosenRecipe.CraftingSource}"; craftSpecsStr += chosenRecipe.CraftDuration > 0 ? $"\r\nDuration: {chosenRecipe.CraftDuration} hrs" : ""; craftSpecsStr += string.IsNullOrEmpty(altCraftAmtStr) ? "" : $"\r\nAmount: {chosenRecipe.Quantity} (alternate craft amounts: {altCraftAmtStr})"; embed.AddField("Crafting Information", craftSpecsStr, false); embed.AddField("Market Price", $"{outputPrice.GoldPart} {GoldIcon} {outputPrice.SilverPart} {SilverIcon}", true); embed.AddField("Crafting Cost", $"{craftCost.GoldPart} {GoldIcon} {craftCost.SilverPart} {SilverIcon}", true); embed.AddField("Individual Item Costs", individualCostStr, false); embed.Footer = new EmbedFooterBuilder() { Text = "Data retrieved from the Unofficial BnS API. Documentation: https://slate.silveress.ie/docs_bns" }; await ReplyAsync("", embed : embed.Build()); }
public async Task GetMarketplaceValue([Remainder] string item) { //Search for the item through personal sheets to find corresponding id var itemSearchApi = new ItemSearchApi(_ssService); var id = await itemSearchApi.GetItemId(item); if (id == 0) { await ReplyAsync($"Could not find item with search key '{item}'"); return; } //Use item id to retrieve item details (in particular, image for the item) var itemApi = new ItemApi(); var itemDetails = await itemApi.GetItemDetails(id); if (itemDetails == null) { await ReplyAsync($"Could not find item with search key '{item}'"); return; } //Use item id to retrieve current marketplace value of the item var mpApi = new MarketplaceApi(); var listings = await mpApi.GetMarketplaceListing(id); var embed = new EmbedBuilder(); embed.ThumbnailUrl = itemDetails.ImgUrl; embed.Title = itemDetails.Name; var maxListing = Math.Min(10, listings?.Listings.Length ?? 0); var formattedListings = ""; for (int i = 0; i < maxListing; i++) { var listing = listings.Listings[i]; formattedListings += $"{listing.PricePerItem.GoldPart} {GoldIcon} {listing.PricePerItem.SilverPart} {SilverIcon} x {listing.Count}"; formattedListings += $" | {listing.Price.Total/10000.0} g Total\r\n"; } formattedListings = string.IsNullOrEmpty(formattedListings) ? "<No listings available>" : formattedListings; embed.AddField(new EmbedFieldBuilder() { Name = $"Lowest marketplace listings for {itemDetails.Name}.", Value = formattedListings }); embed.Footer = new EmbedFooterBuilder() { Text = "Data retrieved from the Unofficial BnS API. Documentation: https://slate.silveress.ie/docs_bns" }; if (listings != null) { embed.Timestamp = new DateTimeOffset(listings.DateRetrieved); } await ReplyAsync("", embed : embed.Build()); }