using System; using System.Collections.Generic; using System.Linq; using StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData; namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player { /// A command which list items available to spawn. internal class ListItemsCommand : TrainerCommand { /********* ** Fields *********/ /// Provides methods for searching and constructing items. private readonly ItemRepository Items = new ItemRepository(); /********* ** Public methods *********/ /// Construct an instance. public ListItemsCommand() : base("list_items", "Lists and searches items in the game data.\n\nUsage: list_items [search]\n- search (optional): an arbitrary search string to filter by.") { } /// Handle the command. /// Writes messages to the console and log file. /// The command name. /// The command arguments. public override void Handle(IMonitor monitor, string command, ArgumentParser args) { // validate if (!Context.IsWorldReady) { monitor.Log("You need to load a save to use this command.", LogLevel.Error); return; } // handle SearchableItem[] matches = ( from item in this.GetItems(args.ToArray()) orderby item.Type.ToString(), item.Name select item ) .ToArray(); string summary = "Searching...\n"; if (matches.Any()) monitor.Log(summary + this.GetTableString(matches, new[] { "type", "name", "id" }, val => new[] { val.Type.ToString(), val.Name, val.ID.ToString() }), LogLevel.Info); else monitor.Log(summary + "No items found", LogLevel.Info); } /********* ** Private methods *********/ /// Get all items which can be searched and added to the player's inventory through the console. /// The search string to find. private IEnumerable GetItems(string[] searchWords) { // normalize search term searchWords = searchWords?.Where(word => !string.IsNullOrWhiteSpace(word)).ToArray(); if (searchWords?.Any() == false) searchWords = null; // find matches return ( from item in this.Items.GetAll() let term = $"{item.ID}|{item.Type}|{item.Name}|{item.DisplayName}" where searchWords == null || searchWords.All(word => term.IndexOf(word, StringComparison.CurrentCultureIgnoreCase) != -1) select item ); } } }