public async Task BuyItemCommand(string shopId, int itemId) { var context = Context; var server = context.server; var memory = server.GetMemory(); var cmdShopServerData = memory.GetData <CommandShopSystem, CommandShopServerData>(); var currencies = memory.GetData <CurrencySystem, CurrencyServerData>().Currencies; var shops = cmdShopServerData.Shops; if (!shops.TryGetValue(shopId, out Shop shop)) { throw new BotError($"No such shop: `{shopId}`."); } itemId--; if (shop.Items == null || itemId < 0 || itemId >= shop.Items.Length) { throw new BotError($"Invalid item id."); } var userId = context.socketServerUser.Id; string error = null; //Any exceptions inside this delegate will remove the item from the shop. await shop.SafeItemAction(itemId, async item => { if (item.prices.TryGetFirst(p => currencies[p.currency].GetAmount(userId) < p.amount, out var p)) { //error = $"Not enough {currencies[price.currency]}. You need **{price.amount}**, but you only have **{currencyServerUserData[price.currency]}**."; var currency = currencies[p.currency]; error = $"Not enough {currency}. You need **{p.amount}**, but you only have **{currency.GetAmount(userId)}**."; return; } await item.command.Execute(context, (sc, cmd) => cmd.Replace("{item}", item.name, sc)); //Take the moneys CurrencyAmount.TakeFromUser(item.prices, Context.socketServerUser); }); if (error != null) { throw new BotError(error); } }