diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index 0d6288b5a3..2bb7de1cae 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs @@ -29,6 +29,7 @@ using System; using System.Xml; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; @@ -40,6 +41,8 @@ namespace OpenSim.Framework.Console { public class Commands : ICommands { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// /// Encapsulates a command that can be invoked from the console /// @@ -76,12 +79,19 @@ namespace OpenSim.Framework.Console public List fn; } + public const string GeneralHelpText = "For more information, type 'help ' where is one of the following categories:"; + /// /// Commands organized by keyword in a tree /// private Dictionary tree = new Dictionary(); + /// + /// Commands organized by module + /// + private Dictionary> m_modulesCommands = new Dictionary>(); + /// /// Get help for the given help string /// @@ -98,8 +108,8 @@ namespace OpenSim.Framework.Console // General help if (helpParts.Count == 0) { - help.AddRange(CollectHelp(tree)); - help.Sort(); + help.Add(GeneralHelpText); + help.AddRange(CollectModulesHelp(tree)); } else { @@ -118,6 +128,13 @@ namespace OpenSim.Framework.Console { string originalHelpRequest = string.Join(" ", helpParts.ToArray()); List help = new List(); + + // Check modules first to see if we just need to display a list of those commands + if (TryCollectModuleHelp(originalHelpRequest, help)) + { + help.Insert(0, GeneralHelpText); + return help; + } Dictionary dict = tree; while (helpParts.Count > 0) @@ -161,25 +178,61 @@ namespace OpenSim.Framework.Console return help; } - private List CollectHelp(Dictionary dict) + /// + /// Try to collect help for the given module if that module exists. + /// + /// + /// /param> + /// true if there was the module existed, false otherwise. + private bool TryCollectModuleHelp(string moduleName, List helpText) { - List result = new List(); - - foreach (KeyValuePair kvp in dict) + lock (m_modulesCommands) { - if (kvp.Value is Dictionary) + if (m_modulesCommands.ContainsKey(moduleName)) { - result.AddRange(CollectHelp((Dictionary)kvp.Value)); + List commands = m_modulesCommands[moduleName]; + var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help)); + ourHelpText.Sort(); + helpText.AddRange(ourHelpText); + + return true; } else { - if (((CommandInfo)kvp.Value).long_help != String.Empty) - result.Add(((CommandInfo)kvp.Value).help_text+" - "+ - ((CommandInfo)kvp.Value).long_help); + return false; } } - return result; } + + private List CollectModulesHelp(Dictionary dict) + { + lock (m_modulesCommands) + { + List helpText = new List(m_modulesCommands.Keys); + helpText.Sort(); + return helpText; + } + } + +// private List CollectHelp(Dictionary dict) +// { +// List result = new List(); +// +// foreach (KeyValuePair kvp in dict) +// { +// if (kvp.Value is Dictionary) +// { +// result.AddRange(CollectHelp((Dictionary)kvp.Value)); +// } +// else +// { +// if (((CommandInfo)kvp.Value).long_help != String.Empty) +// result.Add(((CommandInfo)kvp.Value).help_text+" - "+ +// ((CommandInfo)kvp.Value).long_help); +// } +// } +// return result; +// } /// /// Add a command to those which can be invoked from the console. @@ -212,21 +265,19 @@ namespace OpenSim.Framework.Console Dictionary current = tree; - foreach (string s in parts) + foreach (string part in parts) { - if (current.ContainsKey(s)) + if (current.ContainsKey(part)) { - if (current[s] is Dictionary) - { - current = (Dictionary)current[s]; - } + if (current[part] is Dictionary) + current = (Dictionary)current[part]; else return; } else { - current[s] = new Dictionary(); - current = (Dictionary)current[s]; + current[part] = new Dictionary(); + current = (Dictionary)current[part]; } } @@ -250,6 +301,24 @@ namespace OpenSim.Framework.Console info.fn = new List(); info.fn.Add(fn); current[String.Empty] = info; + + // Now add command to modules dictionary + lock (m_modulesCommands) + { + List commands; + if (m_modulesCommands.ContainsKey(module)) + { + commands = m_modulesCommands[module]; + } + else + { + commands = new List(); + m_modulesCommands[module] = commands; + } + +// m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command); + commands.Add(info); + } } public string[] FindNextOption(string[] cmd, bool term) @@ -607,8 +676,9 @@ namespace OpenSim.Framework.Console { Commands = new Commands(); - Commands.AddCommand("console", false, "help", "help []", - "Get general command list or more detailed help on a specific command", Help); + Commands.AddCommand( + "Help", false, "help", "help []", + "Display help on a particular command or on a list of commands in a category", Help); } private void Help(string module, string[] cmd) diff --git a/OpenSim/Framework/ICommandConsole.cs b/OpenSim/Framework/ICommandConsole.cs index d33b9b5772..ca0ff936ca 100644 --- a/OpenSim/Framework/ICommandConsole.cs +++ b/OpenSim/Framework/ICommandConsole.cs @@ -40,7 +40,7 @@ namespace OpenSim.Framework /// /// Get help for the given help string /// - /// Parsed parts of the help string. If empty then general help is returned. + /// Parsed parts of the help string. If empty then general help is returned. /// List GetHelp(string[] cmd); diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 5f5142b4c9..06a8021b5f 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); } - m_console.Commands.AddCommand("base", false, "quit", + m_console.Commands.AddCommand("General", false, "quit", "quit", "Quit the application", HandleQuit); - m_console.Commands.AddCommand("base", false, "shutdown", + m_console.Commands.AddCommand("General", false, "shutdown", "shutdown", "Quit the application", HandleQuit); - m_console.Commands.AddCommand("base", false, "set log level", + m_console.Commands.AddCommand("General", false, "set log level", "set log level ", "Set the console logging level", HandleLogLevel); - m_console.Commands.AddCommand("base", false, "show info", + m_console.Commands.AddCommand("General", false, "show info", "show info", "Show general information about the server", HandleShow); - m_console.Commands.AddCommand("base", false, "show stats", + m_console.Commands.AddCommand("General", false, "show stats", "show stats", "Show statistics", HandleShow); - m_console.Commands.AddCommand("base", false, "show threads", + m_console.Commands.AddCommand("General", false, "show threads", "show threads", "Show thread status", HandleShow); - m_console.Commands.AddCommand("base", false, "show uptime", + m_console.Commands.AddCommand("General", false, "show uptime", "show uptime", "Show server uptime", HandleShow); - m_console.Commands.AddCommand("base", false, "show version", + m_console.Commands.AddCommand("General", false, "show version", "show version", "Show server version", HandleShow); - m_console.Commands.AddCommand("base", false, "threads abort", + m_console.Commands.AddCommand("General", false, "threads abort", "threads abort ", "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); - m_console.Commands.AddCommand("base", false, "threads show", + m_console.Commands.AddCommand("General", false, "threads show", "threads show", "Show thread status. Synonym for \"show threads\"", (string module, string[] args) => Notice(GetThreadsReport())); diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 31f2ed4889..8567eb874b 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -225,12 +225,12 @@ namespace OpenSim /// private void RegisterConsoleCommands() { - m_console.Commands.AddCommand("region", false, "force update", + m_console.Commands.AddCommand("Regions", false, "force update", "force update", "Force the update of all objects on clients", HandleForceUpdate); - m_console.Commands.AddCommand("region", false, "debug packet", + m_console.Commands.AddCommand("Comms", false, "debug packet", "debug packet [ ]", "Turn on packet debugging", "If level > 255 then all incoming and outgoing packets are logged.\n" @@ -242,7 +242,7 @@ namespace OpenSim + "If an avatar name is given then only packets from that avatar are logged", Debug); - m_console.Commands.AddCommand("region", false, "debug http", + m_console.Commands.AddCommand("Comms", false, "debug http", "debug http ", "Turn on inbound http request debugging for everything except the event queue (see debug eq).", "If level >= 2 then the handler used to service the request is logged.\n" @@ -250,37 +250,37 @@ namespace OpenSim + "If level <= 0 then no extra http logging is done.\n", Debug); - m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); + m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); - m_console.Commands.AddCommand("region", false, "debug scene", + m_console.Commands.AddCommand("Regions", false, "debug scene", "debug scene ", "Turn on scene debugging", Debug); - m_console.Commands.AddCommand("region", false, "change region", + m_console.Commands.AddCommand("Regions", false, "change region", "change region ", "Change current console region", ChangeSelectedRegion); - m_console.Commands.AddCommand("region", false, "save xml", + m_console.Commands.AddCommand("Archiving", false, "save xml", "save xml", "Save a region's data in XML format", SaveXml); - m_console.Commands.AddCommand("region", false, "save xml2", + m_console.Commands.AddCommand("Archiving", false, "save xml2", "save xml2", "Save a region's data in XML2 format", SaveXml2); - m_console.Commands.AddCommand("region", false, "load xml", + m_console.Commands.AddCommand("Archiving", false, "load xml", "load xml [-newIDs [ ]]", "Load a region's data from XML format", LoadXml); - m_console.Commands.AddCommand("region", false, "load xml2", + m_console.Commands.AddCommand("Archiving", false, "load xml2", "load xml2", "Load a region's data from XML2 format", LoadXml2); - m_console.Commands.AddCommand("region", false, "save prims xml2", + m_console.Commands.AddCommand("Archiving", false, "save prims xml2", "save prims xml2 [ ]", "Save named prim to XML2", SavePrimsXml2); - m_console.Commands.AddCommand("region", false, "load oar", + m_console.Commands.AddCommand("Archiving", false, "load oar", "load oar [--merge] [--skip-assets] []", "Load a region's data from an OAR archive.", "--merge will merge the OAR with the existing scene." + Environment.NewLine @@ -289,7 +289,7 @@ namespace OpenSim + " If this is not given then the command looks for an OAR named region.oar in the current directory.", LoadOar); - m_console.Commands.AddCommand("region", false, "save oar", + m_console.Commands.AddCommand("Archiving", false, "save oar", //"save oar [-v|--version=] [-p|--profile=] []", "save oar [-h|--home=] [--noassets] [--publish] [--perm=] []", "Save a region's data to an OAR archive.", @@ -306,54 +306,54 @@ namespace OpenSim + " If this is not given then the oar is saved to region.oar in the current directory.", SaveOar); - m_console.Commands.AddCommand("region", false, "edit scale", + m_console.Commands.AddCommand("Regions", false, "edit scale", "edit scale ", "Change the scale of a named prim", HandleEditScale); - m_console.Commands.AddCommand("region", false, "kick user", + m_console.Commands.AddCommand("Users", false, "kick user", "kick user [message]", "Kick a user off the simulator", KickUserCommand); - m_console.Commands.AddCommand("region", false, "show users", + m_console.Commands.AddCommand("Users", false, "show users", "show users [full]", "Show user data for users currently on the region", "Without the 'full' option, only users actually on the region are shown." + " With the 'full' option child agents of users in neighbouring regions are also shown.", HandleShow); - m_console.Commands.AddCommand("region", false, "show connections", + m_console.Commands.AddCommand("Comms", false, "show connections", "show connections", "Show connection data", HandleShow); - m_console.Commands.AddCommand("region", false, "show circuits", + m_console.Commands.AddCommand("Comms", false, "show circuits", "show circuits", "Show agent circuit data", HandleShow); - m_console.Commands.AddCommand("region", false, "show http-handlers", + m_console.Commands.AddCommand("Comms", false, "show http-handlers", "show http-handlers", "Show all registered http handlers", HandleShow); - m_console.Commands.AddCommand("region", false, "show pending-objects", + m_console.Commands.AddCommand("Comms", false, "show pending-objects", "show pending-objects", "Show # of objects on the pending queues of all scene viewers", HandleShow); - m_console.Commands.AddCommand("region", false, "show modules", + m_console.Commands.AddCommand("General", false, "show modules", "show modules", "Show module data", HandleShow); - m_console.Commands.AddCommand("region", false, "show regions", + m_console.Commands.AddCommand("Regions", false, "show regions", "show regions", "Show region data", HandleShow); - m_console.Commands.AddCommand("region", false, "show ratings", + m_console.Commands.AddCommand("Regions", false, "show ratings", "show ratings", "Show rating data", HandleShow); - m_console.Commands.AddCommand("region", false, "backup", + m_console.Commands.AddCommand("Regions", false, "backup", "backup", "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand); - m_console.Commands.AddCommand("region", false, "create region", + m_console.Commands.AddCommand("Regions", false, "create region", "create region [\"region name\"] ", "Create a new region.", "The settings for \"region name\" are read from . Paths specified with are relative to your Regions directory, unless an absolute path is given." @@ -362,62 +362,57 @@ namespace OpenSim + "If does not exist, it will be created.", HandleCreateRegion); - m_console.Commands.AddCommand("region", false, "restart", + m_console.Commands.AddCommand("Regions", false, "restart", "restart", "Restart all sims in this instance", RunCommand); - m_console.Commands.AddCommand("region", false, "config set", + m_console.Commands.AddCommand("General", false, "config set", "config set
", "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig); - m_console.Commands.AddCommand("region", false, "config get", + m_console.Commands.AddCommand("General", false, "config get", "config get [
] []", "Synonym for config show", HandleConfig); - m_console.Commands.AddCommand("region", false, "config show", + m_console.Commands.AddCommand("General", false, "config show", "config show [
] []", "Show config information", "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine + "If a section is given but not a field, then all fields in that section are printed.", HandleConfig); - m_console.Commands.AddCommand("region", false, "config save", + m_console.Commands.AddCommand("General", false, "config save", "config save ", "Save current configuration to a file at the given path", HandleConfig); - m_console.Commands.AddCommand("region", false, "command-script", + m_console.Commands.AddCommand("General", false, "command-script", "command-script