From 134f86e8d5c414409631b25b8c6f0ee45fbd8631 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Thu, 3 Nov 2016 21:44:39 +1000 Subject: Initial update to OpenSim 0.8.2.1 source code. --- OpenSim/Framework/Console/AssemblyInfo.cs | 2 +- OpenSim/Framework/Console/CommandConsole.cs | 46 +++++-- OpenSim/Framework/Console/ConsoleDisplayUtil.cs | 48 +++++++ OpenSim/Framework/Console/ConsoleUtil.cs | 175 +++++++++++++++++++++--- OpenSim/Framework/Console/LocalConsole.cs | 85 +++++++++++- OpenSim/Framework/Console/MockConsole.cs | 3 + OpenSim/Framework/Console/RemoteConsole.cs | 4 +- 7 files changed, 320 insertions(+), 43 deletions(-) create mode 100644 OpenSim/Framework/Console/ConsoleDisplayUtil.cs (limited to 'OpenSim/Framework/Console') diff --git a/OpenSim/Framework/Console/AssemblyInfo.cs b/OpenSim/Framework/Console/AssemblyInfo.cs index 37c7304..67af471 100644 --- a/OpenSim/Framework/Console/AssemblyInfo.cs +++ b/OpenSim/Framework/Console/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.8.2.*")] diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index b9f402a..0f68afe 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs @@ -424,9 +424,9 @@ namespace OpenSim.Framework.Console return new string[] { new List(current.Keys)[0] }; } - public string[] Resolve(string[] cmd) + private CommandInfo ResolveCommand(string[] cmd, out string[] result) { - string[] result = cmd; + result = cmd; int index = -1; Dictionary current = tree; @@ -458,7 +458,7 @@ namespace OpenSim.Framework.Console } else if (found.Count > 0) { - return new string[0]; + return null; } else { @@ -467,21 +467,37 @@ namespace OpenSim.Framework.Console } if (current.ContainsKey(String.Empty)) + return (CommandInfo)current[String.Empty]; + + return null; + } + + public bool HasCommand(string command) + { + string[] result; + return ResolveCommand(Parser.Parse(command), out result) != null; + } + + public string[] Resolve(string[] cmd) + { + string[] result; + CommandInfo ci = ResolveCommand(cmd, out result); + + if (ci == null) + return new string[0]; + + if (ci.fn.Count == 0) + return new string[0]; + + foreach (CommandDelegate fn in ci.fn) { - CommandInfo ci = (CommandInfo)current[String.Empty]; - if (ci.fn.Count == 0) + if (fn != null) + fn(ci.module, result); + else return new string[0]; - foreach (CommandDelegate fn in ci.fn) - { - if (fn != null) - fn(ci.module, result); - else - return new string[0]; - } - return result; } - - return new string[0]; + + return result; } public XmlElement GetXml(XmlDocument doc) diff --git a/OpenSim/Framework/Console/ConsoleDisplayUtil.cs b/OpenSim/Framework/Console/ConsoleDisplayUtil.cs new file mode 100644 index 0000000..6417663 --- /dev/null +++ b/OpenSim/Framework/Console/ConsoleDisplayUtil.cs @@ -0,0 +1,48 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; + +namespace OpenSim.Framework.Console +{ + /// + /// This will be a set of typical column sizes to allow greater consistency between console commands. + /// + public static class ConsoleDisplayUtil + { + public const int CoordTupleSize = 11; + public const int PortSize = 5; + + public const int EstateNameSize = 20; + public const int ParcelNameSize = 40; + public const int RegionNameSize = 20; + public const int UserNameSize = 35; + + public const int UuidSize = 36; + public const int VectorSize = 15; + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs index dff956a..44f6dc1 100644 --- a/OpenSim/Framework/Console/ConsoleUtil.cs +++ b/OpenSim/Framework/Console/ConsoleUtil.cs @@ -49,14 +49,14 @@ namespace OpenSim.Framework.Console = @"Each component of the coord is comma separated. There must be no spaces between the commas. If you don't care about the z component you can simply omit it. If you don't care about the x or y components then you can leave them blank (though a comma is still required) - If you want to specify the maxmimum value of a component then you can use ~ instead of a number + If you want to specify the maximum value of a component then you can use ~ instead of a number If you want to specify the minimum value of a component then you can use -~ instead of a number e.g. - delete object pos 20,20,20 to 40,40,40 + show object pos 20,20,20 to 40,40,40 delete object pos 20,20 to 40,40 - delete object pos ,20,20 to ,40,40 + show object pos ,20,20 to ,40,40 delete object pos ,,30 to ,,~ - delete object pos ,,-~ to ,,30"; + show object pos ,,-~ to ,,30"; public const string MinRawConsoleVectorValue = "-~"; public const string MaxRawConsoleVectorValue = "~"; @@ -156,12 +156,32 @@ namespace OpenSim.Framework.Console } /// - /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3 + /// Convert a console input to a bool, automatically complaining if a console is given. /// /// Can be null if no console is available. /// /param> /// /// + public static bool TryParseConsoleBool(ICommandConsole console, string rawConsoleString, out bool b) + { + if (!bool.TryParse(rawConsoleString, out b)) + { + if (console != null) + console.OutputFormat("ERROR: {0} is not a true or false value", rawConsoleString); + + return false; + } + + return true; + } + + /// + /// Convert a console input to an int, automatically complaining if a console is given. + /// + /// Can be null if no console is available. + /// /param> + /// + /// public static bool TryParseConsoleInt(ICommandConsole console, string rawConsoleInt, out int i) { if (!int.TryParse(rawConsoleInt, out i)) @@ -174,6 +194,71 @@ namespace OpenSim.Framework.Console return true; } + + /// + /// Convert a console input to a float, automatically complaining if a console is given. + /// + /// Can be null if no console is available. + /// /param> + /// + /// + public static bool TryParseConsoleFloat(ICommandConsole console, string rawConsoleInput, out float i) + { + if (!float.TryParse(rawConsoleInput, out i)) + { + if (console != null) + console.OutputFormat("ERROR: {0} is not a valid float", rawConsoleInput); + + return false; + } + + return true; + } + + /// + /// Convert a console input to a double, automatically complaining if a console is given. + /// + /// Can be null if no console is available. + /// /param> + /// + /// + public static bool TryParseConsoleDouble(ICommandConsole console, string rawConsoleInput, out double i) + { + if (!double.TryParse(rawConsoleInput, out i)) + { + if (console != null) + console.OutputFormat("ERROR: {0} is not a valid double", rawConsoleInput); + + return false; + } + + return true; + } + + /// + /// Convert a console integer to a natural int, automatically complaining if a console is given. + /// + /// Can be null if no console is available. + /// /param> + /// + /// + public static bool TryParseConsoleNaturalInt(ICommandConsole console, string rawConsoleInt, out int i) + { + if (TryParseConsoleInt(console, rawConsoleInt, out i)) + { + if (i < 0) + { + if (console != null) + console.OutputFormat("ERROR: {0} is not a positive integer", rawConsoleInt); + + return false; + } + + return true; + } + + return false; + } /// /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3 @@ -207,24 +292,82 @@ namespace OpenSim.Framework.Console /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue /// Other than that, component values must be numeric. /// - /// + /// + /// Behaviour if component is blank. If null then conversion fails on a blank component. + /// /// /// public static bool TryParseConsoleVector( string rawConsoleVector, Func blankComponentFunc, out Vector3 vector) { - List components = rawConsoleVector.Split(VectorSeparatorChars).ToList(); - - if (components.Count < 1 || components.Count > 3) + return Vector3.TryParse(CookVector(rawConsoleVector, 3, blankComponentFunc), out vector); + } + + /// + /// Convert a vector input from the console to an OpenMetaverse.Vector2 + /// + /// + /// A string in the form , where there is no space between values. + /// Any component can be missing (e.g. ,40). blankComponentFunc is invoked to replace the blank with a suitable value + /// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40) + /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue + /// Other than that, component values must be numeric. + /// + /// + /// Behaviour if component is blank. If null then conversion fails on a blank component. + /// + /// + /// + public static bool TryParseConsole2DVector( + string rawConsoleVector, Func blankComponentFunc, out Vector2 vector) + { + // We don't use Vector2.TryParse() for now because for some reason it expects an input with 3 components + // rather than 2. + string cookedVector = CookVector(rawConsoleVector, 2, blankComponentFunc); + + if (cookedVector == null) { - vector = Vector3.Zero; + vector = Vector2.Zero; + return false; } + else + { + string[] cookedComponents = cookedVector.Split(VectorSeparatorChars); + + vector = new Vector2(float.Parse(cookedComponents[0]), float.Parse(cookedComponents[1])); + + return true; + } + + //return Vector2.TryParse(CookVector(rawConsoleVector, 2, blankComponentFunc), out vector); + } + + /// + /// Convert a raw console vector into a vector that can be be parsed by the relevant OpenMetaverse.TryParse() + /// + /// + /// + /// + /// null if conversion was not possible + private static string CookVector( + string rawConsoleVector, int dimensions, Func blankComponentFunc) + { + List components = rawConsoleVector.Split(VectorSeparatorChars).ToList(); - for (int i = components.Count; i < 3; i++) - components.Add(""); + if (components.Count < 1 || components.Count > dimensions) + return null; - List semiDigestedComponents + if (components.Count < dimensions) + { + if (blankComponentFunc == null) + return null; + else + for (int i = components.Count; i < dimensions; i++) + components.Add(""); + } + + List cookedComponents = components.ConvertAll( c => { @@ -238,11 +381,7 @@ namespace OpenSim.Framework.Console return c; }); - string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray()); - - // m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector); - - return Vector3.TryParse(semiDigestedConsoleVector, out vector); + return string.Join(VectorSeparator, cookedComponents.ToArray()); } } } \ No newline at end of file diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index d41481f..28293c0 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -32,6 +32,8 @@ using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading; +using System.IO; +using Nini.Config; using log4net; namespace OpenSim.Framework.Console @@ -41,11 +43,18 @@ namespace OpenSim.Framework.Console /// public class LocalConsole : CommandConsole { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private string m_historyPath; + private bool m_historyEnable; // private readonly object m_syncRoot = new object(); private const string LOGLEVEL_NONE = "(none)"; + // Used to extract categories for colourization. + private Regex m_categoryRegex + = new Regex( + @"^(?.*?)\[(?[^\]]+)\]:?(?.*)", RegexOptions.Singleline | RegexOptions.Compiled); + private int m_cursorYPosition = -1; private int m_cursorXPosition = 0; private StringBuilder m_commandLine = new StringBuilder(); @@ -74,8 +83,54 @@ namespace OpenSim.Framework.Console return Colors[(Math.Abs(input.ToUpper().GetHashCode()) % Colors.Length)]; } - public LocalConsole(string defaultPrompt) : base(defaultPrompt) + public LocalConsole(string defaultPrompt, IConfig startupConfig = null) : base(defaultPrompt) { + + if (startupConfig == null) return; + + m_historyEnable = startupConfig.GetBoolean("ConsoleHistoryFileEnabled", false); + if (!m_historyEnable) + { + m_log.Info("[LOCAL CONSOLE]: Persistent command line history from file is Disabled"); + return; + } + + string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt"); + int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100); + m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile)); + m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath); + + if (File.Exists(m_historyPath)) + { + using (StreamReader history_file = new StreamReader(m_historyPath)) + { + string line; + while ((line = history_file.ReadLine()) != null) + { + m_history.Add(line); + } + } + + if (m_history.Count > m_historySize) + { + while (m_history.Count > m_historySize) + m_history.RemoveAt(0); + + using (StreamWriter history_file = new StreamWriter(m_historyPath)) + { + foreach (string line in m_history) + { + history_file.WriteLine(line); + } + } + } + m_log.InfoFormat("[LOCAL CONSOLE]: Read {0} lines of command line history from file {1}", m_history.Count, m_historyPath); + } + else + { + m_log.InfoFormat("[LOCAL CONSOLE]: Creating new empty command line history file {0}", m_historyPath); + File.Create(m_historyPath).Dispose(); + } } private void AddToHistory(string text) @@ -84,6 +139,10 @@ namespace OpenSim.Framework.Console m_history.RemoveAt(0); m_history.Add(text); + if (m_historyEnable) + { + File.AppendAllText(m_historyPath, text + Environment.NewLine); + } } /// @@ -280,11 +339,8 @@ namespace OpenSim.Framework.Console string outText = text; if (level != LOGLEVEL_NONE) - { - string regex = @"^(?.*?)\[(?[^\]]+)\]:?(?.*)"; - - Regex RE = new Regex(regex, RegexOptions.Multiline); - MatchCollection matches = RE.Matches(text); + { + MatchCollection matches = m_categoryRegex.Matches(text); if (matches.Count == 1) { @@ -426,6 +482,21 @@ namespace OpenSim.Framework.Console System.Console.Write("{0}", prompt); break; + case ConsoleKey.Delete: + if (m_cursorXPosition == m_commandLine.Length) + break; + + m_commandLine.Remove(m_cursorXPosition, 1); + + SetCursorLeft(0); + m_cursorYPosition = SetCursorTop(m_cursorYPosition); + + if (m_echo) + System.Console.Write("{0}{1} ", prompt, m_commandLine); + else + System.Console.Write("{0}", prompt); + + break; case ConsoleKey.End: m_cursorXPosition = m_commandLine.Length; break; diff --git a/OpenSim/Framework/Console/MockConsole.cs b/OpenSim/Framework/Console/MockConsole.cs index 8ba58e4..1a142df 100644 --- a/OpenSim/Framework/Console/MockConsole.cs +++ b/OpenSim/Framework/Console/MockConsole.cs @@ -40,7 +40,9 @@ namespace OpenSim.Framework.Console /// public class MockConsole : ICommandConsole { +#pragma warning disable 0067 public event OnOutputDelegate OnOutput; +#pragma warning restore 0067 private MockCommands m_commands = new MockCommands(); @@ -80,6 +82,7 @@ namespace OpenSim.Framework.Console public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {} public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {} public string[] FindNextOption(string[] cmd, bool term) { return null; } + public bool HasCommand(string cmd) { return false; } public string[] Resolve(string[] cmd) { return null; } public XmlElement GetXml(XmlDocument doc) { return null; } } diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index 27edd4b..8ad7b0d 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -234,7 +234,7 @@ namespace OpenSim.Framework.Console string uri = "/ReadResponses/" + sessionID.ToString() + "/"; m_Server.AddPollServiceHTTPHandler( - uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID)); + uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout XmlDocument xmldoc = new XmlDocument(); XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, @@ -425,7 +425,7 @@ namespace OpenSim.Framework.Console return false; } - private Hashtable GetEvents(UUID RequestID, UUID sessionID, string request) + private Hashtable GetEvents(UUID RequestID, UUID sessionID) { ConsoleConnection c = null; -- cgit v1.1