| #region Using Statements␍␊ |
| #if WINDOWS␍␊ |
| using System;␍␊ |
| using System.Collections.Generic;␍␊ |
| using Microsoft.Xna.Framework;␍␊ |
| using Microsoft.Xna.Framework.Content;␍␊ |
| using Microsoft.Xna.Framework.Graphics;␍␊ |
| using Microsoft.Xna.Framework.Input;␍␊ |
| using System.Text;␍␊ |
| using System.Threading;␍␊ |
| using System.IO;␍␊ |
| using System.ComponentModel;␍␊ |
| using System.Reflection;␍␊ |
| using JRTS.XNA.Console.BaseTypes;␍␊ |
| using System.Diagnostics;␍␊ |
| #endif␍␊ |
| #endregion␍␊ |
| ␍␊ |
| /*␍␊ |
| * CommandConsoleBase.cs␍␊ |
| * (C) 2009-2011, James R. Twine of JRTwine Software, LLC␍␊ |
| *␍␊ |
| * *************************************************************************␍␊ |
| * * THIS CODE IS PROVIDED WITH NO WARRANTY - YOU USE IT AT YOUR OWN RISK! *␍␊ |
| * *************************************************************************␍␊ |
| * ␍␊ |
| * This Code Originated With Code From the "XNA Console Component Sample" by Kevin Jurkowski.␍␊ |
| * At The Time Of This Writing, The Original Code Was Available ␍␊ |
| * From: http://www.ziggyware.com/readarticle.php?article_id=163␍␊ |
| * (But, Ziggyware Is No Longer There! :<)␍␊ |
| *␍␊ |
| * Changes, (C) 2009, James R. Twine of JRTwine Software, LLC␍␊ |
| *␉Changes:␍␊ |
| * Converted to XNA 3.0␍␊ |
| * More input keys supported (Symbols, digits, etc.)␍␊ |
| * Better(?) Way of extending supported commands and their handlers, parameters, help, etc.␍␊ |
| * Slight Q&D colorizing of output to differenate commands and output␍␊ |
| * Extracted keyboard-specific functionality into an iterface␍␊ |
| * Command history␍␊ |
| * Command completion␍␊ |
| * Scrollable log/output␍␊ |
| * Base class supports "standard" commands␍␊ |
| * Support for "hidden" commands␍␊ |
| * Customizable scalable drawing ␍␊ |
| * Custom functions (basically macros that support parameters)␍␊ |
| * Binding commands/functions to <ALT>-Key combinations (when the console is closed)␍␊ |
| * ␍␊ |
| * And possibly some other fun stuff...!␍␊ |
| *␍␊ |
| * More Changes, (C) 2010, James R. Twine of JRTwine Software, LLC␍␊ |
| *␉Changes:␍␊ |
| * Expanded key bindings to support <ALT/SHIFT/CTRL> modifiers␍␊ |
| *␉␉Converted to XNA 4.0␍␊ |
| * Graphics optimizations␍␊ |
| * ␍␊ |
| * Still MORE Changes, (C) 2011, James R. Twine of JRTwine Software, LLC␍␊ |
| *␉Changes:␍␊ |
| * Additional ways to hook into command execution/handling␍␊ |
| * Addition of dynamic Console Variables (cvars)␍␊ |
| *␉␉Support for external managed functions that can manipulate cvars and do... just about anything␍␊ |
| *␉␉Ability to lock-down functions, bindings and external functions (to prevent tampering with a released game)␍␊ |
| *␉␉TODO: Wanna wrap command handlers into an "ICCCommand" interface...␍␊ |
| * ␍␊ |
| * ␍␊ |
| * ␍␊ |
| * ␍␊ |
| * ␍␊ |
| */␍␊ |
| ␍␊ |
| //NA: XNACC currently is only supported on Windows due to the fact that SortedDictionary is not avaiable on WP7/Xbox 360␍␊ |
| //NA: Seriously Microsoft?␍␊ |
| #if WINDOWS␍␊ |
| /// <summary>Namespace that contains code related to the XNACC (CommandConsole) component</summary>␍␊ |
| namespace JRTS.XNA.Console␍␊ |
| {␍␊ |
| ␉/// <summary>Base functionality of the XNACC (CommandConsole) component</summary>␍␊ |
| ␉public class CommandConsoleBase : DrawableGameComponent␍␊ |
| {␍␊ |
| #region EventArgs Object␍␊ |
| /// <summary>EA object for the CVarModified event</summary>␍␊ |
| public class CVarModifiedEventArgs : EventArgs␍␊ |
| {␍␊ |
| /// <summary>The actual CVar for this event</summary>␍␊ |
| ␉␉␉public CVar Value␍␊ |
| {␍␊ |
| get;␍␊ |
| protected set;␍␊ |
| }␍␊ |
| /// <summary>Constructor for this object</summary>␍␊ |
| /// <param name="value">The cvar that has been modified</param>␍␊ |
| public CVarModifiedEventArgs(CVar value)␍␊ |
| {␍␊ |
| Value = value;␍␊ |
| return;␍␊ |
| }␍␊ |
| }␍␊ |
| /// <summary>EA object for handling console command execution</summary>␍␊ |
| public class CommandConsoleEventArgs : EventArgs␍␊ |
| ␉ {␍␊ |
| /// <summary>The actual command line being executed</summary>␍␊ |
| public string CmdLine␍␊ |
| {␍␊ |
| get;␍␊ |
| set;␍␊ |
| }␍␊ |
| /// <summary>Flag indicating if the command has been handled by an event handler; if true, no further processing is done on the command</summary>␍␊ |
| public bool Handled␍␊ |
| {␍␊ |
| get;␍␊ |
| set;␍␊ |
| }␍␊ |
| /// <summary>Constructor for this object</summary>␍␊ |
| /// <param name="cmdLine">The command line being processed</param>␍␊ |
| public CommandConsoleEventArgs( string cmdLine )␍␊ |
| {␍␊ |
| CmdLine = cmdLine;␍␊ |
| Handled = false;␍␊ |
| return;␍␊ |
| }␍␊ |
| ␉ }␍␊ |
| ␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Command Object␍␊ |
| /// <summary>This object contains information on a single Command that the console understands.</summary>␍␊ |
| ␉␉protected class CmdObject : IComparable< CmdObject >␍␊ |
| {␍␊ |
| ␉␉␉/// <summary>Default constructor for the Command Object</summary>␍␊ |
| ␉␉␉public CmdObject()␍␊ |
| ␉␉␉␉: this( String.Empty, String.Empty, null, false, String.Empty, 0, 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Constuct an instance of the Command Object</summary>␍␊ |
| ␉␉␉/// <param name="command">The command identifier (no whitespace, please)</param>␍␊ |
| ␉␉␉/// <param name="help">The (brief) help for this command</param>␍␊ |
| ␉␉␉/// <param name="cmdAction">The delegate method that fires when the command is encountered</param>␍␊ |
| ␉␉␉public CmdObject( string command, string help, Action<string []> cmdAction )␍␊ |
| ␉␉␉␉: this( command, help, cmdAction, false, String.Empty, 0, 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Constuct an instance of the Command Object</summary>␍␊ |
| ␉␉␉/// <param name="command">The command identifier (no whitespace, please)</param>␍␊ |
| ␉␉␉/// <param name="help">The (brief) help for this command</param>␍␊ |
| ␉␉␉/// <param name="cmdAction">The delegate method that fires when the command is encountered</param>␍␊ |
| ␉␉␉/// <param name="isSecret">Is this a secret command (not shown in the help information)</param>␍␊ |
| ␉␉␉public CmdObject( string command, string help, Action<string []> cmdAction, bool isSecret )␍␊ |
| ␉␉␉␉: this( command, help, cmdAction, isSecret, String.Empty, 0, 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Constuct an instance of the Command Object</summary>␍␊ |
| ␉␉␉/// <param name="command">The command identifier (no whitespace, please)</param>␍␊ |
| ␉␉␉/// <param name="help">The (brief) help for this command</param>␍␊ |
| ␉␉␉/// <param name="cmdAction">The delegate method that fires when the command is encountered</param>␍␊ |
| ␉␉␉/// <param name="isSecret">Is this a secret command (not shown in the help information)</param>␍␊ |
| ␉␉␉/// <param name="detailedHelp">The detailed help for this command</param>␍␊ |
| ␉␉␉public CmdObject( string command, string help, Action<string []> cmdAction, bool isSecret, string detailedHelp )␍␊ |
| ␉␉␉␉: this( command, help, cmdAction, isSecret, detailedHelp, 0, 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Constuct an instance of the Command Object</summary>␍␊ |
| ␉␉␉/// <param name="command">The command identifier (no whitespace, please)</param>␍␊ |
| ␉␉␉/// <param name="help">The (brief) help for this command</param>␍␊ |
| ␉␉␉/// <param name="cmdAction">The delegate method that fires when the command is encountered</param>␍␊ |
| ␉␉␉/// <param name="isSecret">Is this a secret command (not shown in the help information)</param>␍␊ |
| ␉␉␉/// <param name="detailedHelp">The detailed help for this command</param>␍␊ |
| ␉␉␉/// <param name="minParams">The minimum number of parameters for this command (0 == no minimum)</param>␍␊ |
| ␉␉␉/// <param name="maxParams">The maximum number of parameters for this command (0 == no maximum)</param>␍␊ |
| ␉␉␉public CmdObject( string command, string help, Action<string []> cmdAction, bool isSecret, string detailedHelp, int minParams, int maxParams )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉Command = command;␍␊ |
| ␉␉␉␉CommandHelp = help;␍␊ |
| ␉␉␉␉if( cmdAction != null )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉CmdEvent += cmdAction;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉IsSecret = isSecret;␍␊ |
| ␉␉␉␉CommandHelpDetailed = detailedHelp;␍␊ |
| ␉␉␉␉MinParameters = minParams;␍␊ |
| ␉␉␉␉MaxParameters = maxParams;␍␊ |
| ␍␊ |
| ␉␉␉␉return;␍␊ |
| ␍␊ |
| ␉␉␉}␍␊ |
| /// <summary>Required - The command (single word, no spaces, and all commands will be converted to lowercase)</summary>␍␊ |
| public String Command␉␉␉␉{ get; set; }␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>Optional - Summary help information that briefly describes the command</summary>␍␊ |
| public String CommandHelp␉␉␉{ get; set; }␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>Optional - Detailed help information that explains the command and its usage</summary>␍␊ |
| public String CommandHelpDetailed␉{ get; set; }␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>The minimum number of parameters the command expects (set to zero for no minimum)</summary>␍␊ |
| public int MinParameters␉␉␉{ get; set; }␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>The maximum number of parameters the command expects (set to zero for no maximum)</summary>␍␊ |
| ␉␉␉public int MaxParameters␉␉␉{ get; set; }␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>Indicates if this command is secret -- if so, it will not appear when the user types ␍␊ |
| ␉␉␉///␉"help" and will not participate in command completion</summary>␍␊ |
| public bool IsSecret␉␉␉␉{ get; set; }␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>The event fired when the associated command is received</summary>␍␊ |
| ␉␉␉public event Action<string[]> CmdEvent;␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>This method fires the associated Delegate</summary>␍␊ |
| /// <param name="cmdLine">The complete command line. Not just the command's parameters!</param>␍␊ |
| ␉␉␉/// <remarks>This method is public to allow for artificial triggering of commands.</remarks>␍␊ |
| public void TriggerEvent( String[] cmdLine )␍␊ |
| {␍␊ |
| if( CmdEvent != null )␍␊ |
| {␍␊ |
| CmdEvent.Invoke( cmdLine );␍␊ |
| }␍␊ |
| }␍␊ |
| ␉␉␉#region IComparable<CmdObject> Members␍␊ |
| ␉␉␉␍␊ |
| ␉␉␉/// <summary>Compare this object with another object instance</summary>␍␊ |
| ␉␉␉/// <param name="other">The object to compare to</param>␍␊ |
| ␉␉␉/// <returns>The result of comparing the object's Command strings</returns>␍␊ |
| ␉␉␉public int CompareTo( CmdObject other )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return( Command.CompareTo( other.Command ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉#endregion␍␊ |
| ␉␉}␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Function Object␍␊ |
| /// <summary>This object contains information on a custom function that the console understands.</summary>␍␊ |
| protected class FuncObject : IComparable< FuncObject >␍␊ |
| {␍␊ |
| /// <summary>The function name</summary>␍␊ |
| ␉␉␉public String Function␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉get;␍␊ |
| ␉␉␉␉protected set;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>The code to execute when the function executes</summary>␍␊ |
| public IList<String> FunctionImpl␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉get;␍␊ |
| ␉␉␉␉protected set;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Constructor for the Function Object</summary>␍␊ |
| ␉␉␉/// <param name="funcName">The name of the Function</param>␍␊ |
| ␉␉␉/// <param name="funcImpl">The implementation of the Function</param>␍␊ |
| ␉␉␉public FuncObject( string funcName, string[] funcImpl )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( String.IsNullOrWhiteSpace( funcName ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉throw new ArgumentException( "The function name must not be whitespace.", "funcName" );␉␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉Function = funcName.Trim().ToLowerInvariant();␍␊ |
| ␉␉␉␉FunctionImpl = new List<string>( funcImpl );␉␉␉␉␍␊ |
| ␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| /// <summary>Indicates if this function is secret -- it will not appear when the user types "help"</summary>␍␊ |
| ␉␉␉public bool IsSecret␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉get;␍␊ |
| ␉␉␉␉set;␍␊ |
| ␉␉␉}␍␊ |
| /// <summary>Provide a string representation of this object</summary>␍␊ |
| /// <returns>A string containing a representation of the object</returns>␍␊ |
| ␉␉␉public override string ToString()␍␊ |
| {␍␊ |
| StringBuilder␉sbCmdLine = new StringBuilder( FunctionImpl.Count * 32 );␍␊ |
| ␍␊ |
| foreach( string line in FunctionImpl )␍␊ |
| {␍␊ |
| ␉␉␉␉␉if( sbCmdLine.Length > 0 )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉sbCmdLine.Append( "; " );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉sbCmdLine.Append( line );␍␊ |
| }␍␊ |
| ␉␉␉␉return ( String.Format( "{0} -> {1}", Function, sbCmdLine.ToString() ) );␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉␉#region IComparable<FuncObject> Members␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>Compare this object with another object instance</summary>␍␊ |
| ␉␉␉/// <param name="other">The object to compare to</param>␍␊ |
| ␉␉␉/// <returns>The result of comparing the object's Function strings</returns>␍␊ |
| ␉␉␉public int CompareTo( FuncObject other )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return( Function.CompareTo( other.Function ) );␍␊ |
| ␉␉␉}␍␊ |
| ␍␊ |
| ␉␉␉#endregion␍␊ |
| ␉␉}␍␊ |
| #endregion␍␊ |
| ␍␊ |
| ␉␉#region External Function Object␍␊ |
| ␉␉/// <summary>This object contains information on an external function (implemented in a .NET assembly) that the console understands.</summary>␍␊ |
| ␉␉protected class ExternalFuncObject : IComparable<ExternalFuncObject>␍␊ |
| ␉␉{␍␊ |
| ␉␉␉/// <summary>Collection Of Known Class Instances</summary>␍␊ |
| ␉␉␉static protected Dictionary< string, object >␉ms_classInstances = new Dictionary<string,object>( 8 );␍␊ |
| ␉␉␉␍␊ |
| ␉␉␉/// <summary>The method name</summary>␍␊ |
| ␉␉␉public String␉␉MethodName␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉get;␍␊ |
| ␉␉␉␉set;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Is this external function secret?</summary>␍␊ |
| ␉␉␉public bool IsSecret␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉get;␍␊ |
| ␉␉␉␉protected set;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Command line used to create the function</summary>␍␊ |
| ␉␉␉public String CommandLine␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉get;␍␊ |
| ␉␉␉␉set;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>The actual method metadata</summary>␍␊ |
| ␉␉␉protected␉MethodInfo␉m_method;␍␊ |
| ␉␉␉/// <summary>The actual class instance</summary>␍␊ |
| ␉␉␉protected␉object␉␉m_classInstance;␍␊ |
| ␉␉␉/// <summary>Construct an instance of this object, storing information on the specified method</summary>␍␊ |
| ␉␉␉/// <param name="assembly">The name/path of the assembly/DLL to load from</param>␍␊ |
| ␉␉␉/// <param name="className">The fully qualified, case-sensitive class name</param>␍␊ |
| ␉␉␉/// <param name="methodName">The case-sensitive name of the method to get</param>␍␊ |
| ␉␉␉public ExternalFuncObject( string assembly, string className, string methodName )␍␊ |
| ␉␉␉␉: this( assembly, className, methodName, false )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Construct an instance of this object, storing information on the specified method</summary>␍␊ |
| ␉␉␉/// <param name="assembly">The name/path of the assembly/DLL to load from</param>␍␊ |
| ␉␉␉/// <param name="className">The fully qualified, case-sensitive class name</param>␍␊ |
| ␉␉␉/// <param name="methodName">The case-sensitive name of the method to get</param>␍␊ |
| ␉␉␉/// <param name="isSecret">Is this a secret/hidden ExFunc?</param>␍␊ |
| ␉␉␉public ExternalFuncObject( string assembly, string className, string methodName, bool isSecret )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉Type␉classType = null;␍␊ |
| ␉␉␉␉␉␍␊ |
| ␉␉␉␉// See If We Already Have An Instance Of This Class␍␊ |
| ␉␉␉␉if( ms_classInstances.TryGetValue( className, ␍␊ |
| ␉␉␉␉␉␉out m_classInstance ) == false )␍␊ |
| ␉␉␉␉{␉// We Do Not, So Create And Store One␍␊ |
| ␍␊ |
| ␉␉␉␉␉Assembly␉asm = null;␍␊ |
| ␍␊ |
| ␉␉␉␉␉try␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉asm = Assembly.LoadFrom( assembly );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉catch( FileNotFoundException )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉asm = Assembly.LoadFrom( assembly + ".dll" );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉classType = asm.GetType( className, false );␍␊ |
| ␉␉␉␉␉if( classType == null )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉classType = asm.GetType( assembly + "." + className, true );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉m_classInstance = Activator.CreateInstance( classType );␍␊ |
| ␉␉␉␉␉ms_classInstances[ methodName ] = m_classInstance;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉// Store Name Of Method And ␍␊ |
| ␉␉␉␉MethodName = methodName;␍␊ |
| ␉␉␉␉m_method = classType.GetMethod( methodName );␍␊ |
| ␉␉␉␉IsSecret = isSecret;␍␊ |
| ␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>Attempt to invoke the previously loaded method dynamically</summary>␍␊ |
| ␉␉␉/// <param name="parameters">Parameters that should be passed to the method, or null if none</param>␍␊ |
| ␉␉␉/// <returns>A string return value from the method, or String.Empty if a null is returned or if the method returns void</returns>␍␊ |
| ␉␉␉public string Invoke( params object[] parameters )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉string ret;␍␊ |
| ␉␉␉␉␍␊ |
| ␉␉␉␉try␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉object returnVal = m_method.Invoke( m_classInstance, parameters );␍␊ |
| ␉␉␉␉␉␍␊ |
| ␉␉␉␉␉ret = ( returnVal != null ) ? returnVal.ToString() : String.Empty;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉catch( Exception ex )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉ret = ex.Message;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉return( ret );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉/// <summary>Provide a string representation of this object</summary>␍␊ |
| ␉␉␉/// <returns>A string containing a representation of the object</returns>␍␊ |
| ␉␉␉public override string ToString()␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return ( String.Format( "{0}::{1}", m_classInstance, MethodName ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉#region IComparable<FuncObject> Members␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>Compare this object with another object instance</summary>␍␊ |
| ␉␉␉/// <param name="other">The object to compare to</param>␍␊ |
| ␉␉␉/// <returns>The result of comparing the object's MethodName strings</returns>␍␊ |
| ␉␉␉public int CompareTo( ExternalFuncObject other )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return ( MethodName.CompareTo( other.MethodName ) );␍␊ |
| ␉␉␉}␍␊ |
| ␍␊ |
| ␉␉␉#endregion␍␊ |
| ␉␉}␍␊ |
| ␉␉#endregion␍␊ |
| ␉␉␍␊ |
| ␉␉#region Binding Object␍␊ |
| /// <summary>This object stores information on a bound key</summary>␍␊ |
| protected class BindingObject : IComparable< BindingObject >␍␊ |
| {␍␊ |
| /// <summary>Modifier keys for this key-binding</summary>␍␊ |
| [Flags]␍␊ |
| public enum EModifier␍␊ |
| {␍␊ |
| /// <summary>No modifier keys associated with this Binding</summary>␍␊ |
| ␉␉␉␉None = 0,␍␊ |
| ␉␉␉␉/// <summary>CTRL modifier key is associated with this Binding</summary>␍␊ |
| ␉␉␉␉Ctrl = 1,␍␊ |
| ␉␉␉␉/// <summary>SHIFT modifier key is associated with this Binding</summary>␍␊ |
| ␉␉␉␉Shift = 2,␍␊ |
| ␉␉␉␉/// <summary>ALT modifier key is associated with this Binding</summary>␍␊ |
| ␉␉␉␉Alt = 4,␍␊ |
| }␍␊ |
| /// <summary>The command/function to execute when the bound key is hit</summary>␍␊ |
| public string _text;␍␊ |
| /// <summary>The key that the command/function is bound to</summary>␍␊ |
| public Keys _key;␍␊ |
| /// <summary>The modifier key for _key (Ctrl, Alt, Shift) - modifiers use the LEFT version of the key identifier</summary>␍␊ |
| public EModifier _modifierKeys;␍␊ |
| /// <summary>Gets the modifier key(s) in human readable form</summary>␍␊ |
| /// <returns>A string representing this binding's modifiers, or an empty string if none</returns>␍␊ |
| public string GetModifierString()␍␊ |
| {␍␊ |
| StringBuilder sb = new StringBuilder( 32 );␍␊ |
| bool usesCtrl = ( ( _modifierKeys & EModifier.Ctrl ) == EModifier.Ctrl );␍␊ |
| bool usesShift = ( ( _modifierKeys & EModifier.Shift ) == EModifier.Shift );␍␊ |
| bool usesAlt = ( ( _modifierKeys & EModifier.Alt ) == EModifier.Alt );␍␊ |
| bool first = false;␍␊ |
| ␍␊ |
| if( usesCtrl )␍␊ |
| {␍␊ |
| sb.Append( "CTRL" );␍␊ |
| first = false;␍␊ |
| }␍␊ |
| if( usesAlt )␍␊ |
| {␍␊ |
| if( !first )␍␊ |
| {␍␊ |
| sb.Append( '+' );␍␊ |
| }␍␊ |
| sb.Append( "ALT" );␍␊ |
| }␍␊ |
| if( usesShift )␍␊ |
| {␍␊ |
| if( !first )␍␊ |
| {␍␊ |
| sb.Append( '+' );␍␊ |
| }␍␊ |
| sb.Append( "SHIFT" );␍␊ |
| }␍␊ |
| if( sb.Length > 0 )␍␊ |
| {␍␊ |
| sb.Append( '+' );␍␊ |
| }␍␊ |
| return( sb.ToString() );␍␊ |
| }␍␊ |
| /// <summary>Convert this binding object into an informational string</summary>␍␊ |
| /// <returns>The informational string</returns>␍␊ |
| public override string ToString()␍␊ |
| {␍␊ |
| return ( String.Format( "<{0}{1}> -> {2}", GetModifierString(), _key, _text ) );␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉␉#region IComparable<BindingObject> Members␍␊ |
| ␍␊ |
| ␉␉␉/// <summary>Compare this object with another object instance</summary>␍␊ |
| ␉␉␉/// <param name="other">The object to compare to</param>␍␊ |
| ␉␉␉/// <returns>Nothing - Not Implemented Yet</returns>␍␊ |
| ␉␉␉public int CompareTo( BindingObject other )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉throw new NotImplementedException();␍␊ |
| ␉␉␉}␍␊ |
| ␍␊ |
| ␉␉␉#endregion␍␊ |
| ␉␉}␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Fields␍␊ |
| ␉␉␉#region Command Processing ␍␊ |
| ␉␉// -- Command Processing-Related Fields...␍␊ |
| ␉␉/// <summary>Collection Of Command Objects.</summary>␍␊ |
| ␉␉protected static SortedDictionary<string,CmdObject> ms_commands = new SortedDictionary<string, CmdObject>();␍␊ |
| /// <summary>Collection Of function Objects.</summary>␍␊ |
| ␉␉protected static SortedDictionary<string, FuncObject> ms_functions = new SortedDictionary<string, FuncObject>();␍␊ |
| ␉␉/// <summary>Collection Of External Functions.</summary>␍␊ |
| ␉␉protected static SortedDictionary<string, ExternalFuncObject> ms_externalFunctions = new SortedDictionary<string, ExternalFuncObject>();␍␊ |
| ␉␉/// <summary>Collection Of Binding Objects.</summary>␍␊ |
| ␉␉protected static List<BindingObject> ms_bindings = new List<BindingObject>( 8 );␍␊ |
| ␉␉␍␊ |
| ␉␉/// <summary>Colleciton Of Partial Command Matches</summary>␍␊ |
| ␉␉protected static List<string>␉␉ms_partialCmdMatches = new List<string>( 8 );␍␊ |
| ␉␉/// <summary>Symbol table for the console variables</summary>␍␊ |
| ␉␉protected Dictionary<string, CVar> m_cVars = new Dictionary<string, CVar>( 8 );␍␊ |
| ␉␉/// <summary>Match index for the last partial command</summary>␍␊ |
| ␉␉protected int m_cmdMatchIndex = 0;␍␊ |
| ␉␉/// <summary>The last command match found</summary>␍␊ |
| ␉␉protected string m_lastCmdMatch = String.Empty;␍␊ |
| ␉␉/// <summary>The command line itself</summary>␍␊ |
| ␉␉protected string m_commandLine = String.Empty;␍␊ |
| ␍␊ |
| ␉␉/// <summary>Function-related functions are locked out</summary>␍␊ |
| ␉␉protected bool␉m_functionsLocked = false;␍␊ |
| ␉␉/// <summary>Binding-related functions are locked out</summary>␍␊ |
| ␉␉protected bool␉m_bindingsLocked = false;␍␊ |
| ␉␉/// <summary>External-Function-related functions are locked out</summary>␍␊ |
| ␉␉protected bool␉m_exfunsLocked = false;␍␊ |
| ␉␉␉#endregion␍␊ |
| ␍␊ |
| ␉␉␉#region Drawing and Graphics␍␊ |
| ␉␉// -- Drawing/Graphics-Related Fields...␍␊ |
| ␉␉/// <summary>Drawing object</summary>␍␊ |
| ␉␉protected SpriteBatch m_spriteBatch;␍␊ |
| ␉␉/// <summary>Font used for drawing the console's text</summary>␍␊ |
| ␉␉protected SpriteFont m_consoleFont;␍␊ |
| ␉␉/// <summary>Rectangle for the console area</summary>␍␊ |
| ␉␉protected Rectangle m_consoleRect;␍␊ |
| ␉␉/// <summary>Location of the command line</summary>␍␊ |
| ␉␉protected Vector2 m_commandPos;␍␊ |
| ␉␉/// <summary>Hight for the current console font</summary>␍␊ |
| ␉␉protected Vector2 m_stringHeight;␍␊ |
| ␉␉/// <summary>Offset for the command line</summary>␍␊ |
| ␉␉protected float m_commandStringHeightOffset;␍␊ |
| ␉␉/// <summary>Number of characters that can fit in the console area's width</summary>␍␊ |
| ␉␉protected int m_screenCharWidth;␍␊ |
| ␉␉/// <summary>Width of the console area</summary>␍␊ |
| ␉␉protected int m_width;␍␊ |
| ␉␉/// <summary>Height of the console area</summary>␍␊ |
| ␉␉protected int m_height;␍␊ |
| ␉␉/// <summary>Scale for drawing the console</summary>␍␊ |
| ␉␉protected float m_scale = 1.0f;␍␊ |
| ␉␉#endregion ␍␊ |
| ␍␊ |
| ␉␉␉#region Scrolling and Logging␍␊ |
| ␉␉// -- Scrolling-Related Fields...␍␊ |
| ␉␉/// <summary>The number of lines that are visible in the console area</summary>␍␊ |
| ␉␉protected int m_linesVisibleOnScreen;␍␊ |
| ␉␉/// <summary>Used for drawing an indicator to show that lines are scrolled above</summary>␍␊ |
| ␉␉protected bool m_linesAbove;␍␊ |
| ␉␉/// <summary>Used for drawing an indicator to show that lines are scrolled below</summary>␍␊ |
| ␉␉protected bool m_linesBelow;␍␊ |
| ␉␉/// <summary>Where the log starts at (for scrolling)</summary>␍␊ |
| ␉␉protected int m_logStart = 0;␍␊ |
| ␉␉/// <summary>Specifies the limit of the log buffer</summary>␍␊ |
| ␉␉protected int m_logLimit = 512;␍␊ |
| ␍␊ |
| ␉␉// -- Logging-Related Fields...␍␊ |
| ␉␉/// <summary>The path to the log shadow (copy of all logged lines)</summary>␍␊ |
| protected string m_logShadowFilePath = String.Empty;␍␊ |
| /// <summary>Flag indicating that the log is being shadowed</summary>␍␊ |
| protected bool m_logShadowEnabled = false;␍␊ |
| /// <summary>The stream for shadowing the log to</summary>␍␊ |
| ␉␉protected StreamWriter m_logShadowFile = null;␍␊ |
| ␉␉/// <summary>Storage for the log</summary>␍␊ |
| ␉␉protected List<string> m_log = new List<string>( 256 );␍␊ |
| ␉␉#endregion␍␊ |
| ␍␊ |
| ␉␉␉#region Command History␍␊ |
| ␉␉// Command History-Related Fields␍␊ |
| /// <summary>Specifies the limit of the command history</summary>␍␊ |
| protected int m_cmdHistoryLimit = 512;␍␊ |
| ␉␉/// <summary>Collection of command history</summary>␍␊ |
| ␉␉protected List<string> m_cmdHistory = new List<string>( 128 );␍␊ |
| ␉␉/// <summary>Current index in the command history</summary>␍␊ |
| ␉␉protected int m_cmdHistoryIndex = 0;␍␊ |
| ␉␉/// <summary>Scanning (up/down) index in of the command history</summary>␍␊ |
| ␉␉protected int m_cmdHistoryScanIndex = 0;␍␊ |
| ␉␉#endregion ␍␊ |
| ␍␊ |
| ␉␉␉#region Input Processing␍␊ |
| ␉␉// Input related fields␍␊ |
| ␉␉/// <summary>Time for key repeat</summary>␍␊ |
| ␉␉protected DateTime␉␉m_keyRepeatTime = DateTime.MinValue;␍␊ |
| ␉␉/// <summary>Character translation for ALL keyboard keys - contains an element for all values in the Keys enumeration</summary>␍␊ |
| ␉␉protected List<String>␉m_xlateAllKeys;␍␊ |
| ␉␉/// <summary>Character translation for ALL keyboard keys, shifted - contains an element for all values in the Keys enumeration</summary>␍␊ |
| ␉␉protected List<String>␉m_xlateAllKeysShifted;␍␊ |
| ␉␉#endregion␍␊ |
| ␉␉#endregion␍␊ |
| ␍␊ |
| ␉␉#region Events␍␊ |
| ␉␉/// <summary>Event fired right before handling/execution of a command. Allows interception of normal command processing.</summary>␍␊ |
| ␉␉public event EventHandler<CommandConsoleEventArgs>␉PreCommandExecutedEvent;␍␊ |
| ␉␉/// <summary>Event fired when a console variable has been created/modified</summary>␍␊ |
| ␉␉public event EventHandler<CVarModifiedEventArgs>␉␉CVarModifiedEvent;␍␊ |
| ␉␉#endregion␍␊ |
| ␍␊ |
| #region Properties␍␊ |
| ␉␉/// <summary>Interface to the keyboard used for console input</summary>␍␊ |
| ␉␉public IConsoleKeyboard Keyboard␍␊ |
| ␉␉{␍␊ |
| ␉␉␉get;␍␊ |
| ␉␉␉protected set;␍␊ |
| ␉␉}␍␊ |
| ␉␉/// <summary>Image/Texture used to fade the text underneath the console's text area</summary>␍␊ |
| ␉␉public Texture2D FadeImage␍␊ |
| ␉␉{␍␊ |
| ␉␉␉get;␍␊ |
| ␉␉␉set;␍␊ |
| ␉␉}␍␊ |
| ␉␉/// <summary>The color used to produce the fade</summary>␍␊ |
| ␉␉public Color FadeColor␍␊ |
| ␉␉{␍␊ |
| ␉␉␉get;␍␊ |
| ␉␉␉set;␍␊ |
| ␉␉}␍␊ |
| ␉␉/// <summary>Drawing scale for the console</summary>␍␊ |
| ␉␉public float Scale␍␊ |
| ␉␉{␍␊ |
| ␉␉␉get␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return m_scale;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉set␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉m_scale = value;␍␊ |
| ␉␉␉␉m_stringHeight = Vector2.Zero;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉}␍␊ |
| ␉␉/// <summary>Indicates if the console is active or not</summary>␍␊ |
| public bool Active␍␊ |
| {␍␊ |
| get;␍␊ |
| ␉␉␉set;␍␊ |
| }␍␊ |
| ␉␉/// <summary>The prompt shown for the command line</summary>␍␊ |
| ␉␉public string Prompt␍␊ |
| ␉␉{␍␊ |
| ␉␉␉get;␍␊ |
| ␉␉␉set;␍␊ |
| ␉␉}␍␊ |
| ␉␉/// <summary>The color used to display entered commands</summary>␍␊ |
| ␉␉public Color CommandColor␍␊ |
| ␉␉{␍␊ |
| ␉␉␉get;␍␊ |
| ␉␉␉set;␍␊ |
| ␉␉}␍␊ |
| /// <summary>The color used to display error messages</summary>␍␊ |
| public Color ErrorColor␍␊ |
| {␍␊ |
| get;␍␊ |
| set;␍␊ |
| }␍␊ |
| /// <summary>The color used to display output from executed commands</summary>␍␊ |
| public Color OutputColor␍␊ |
| {␍␊ |
| get;␍␊ |
| set;␍␊ |
| }␍␊ |
| /// <summary>The color used to display "normal" output messages</summary>␍␊ |
| public Color NormalColor␍␊ |
| {␍␊ |
| get;␍␊ |
| set;␍␊ |
| }␍␊ |
| /// <summary>The font used for text display</summary>␍␊ |
| public SpriteFont Font␍␊ |
| {␍␊ |
| get { return( m_consoleFont ); }␍␊ |
| set ␍␊ |
| ␉␉␉{ ␍␊ |
| ␉␉␉␉m_consoleFont = value;␍␊ |
| m_stringHeight = Vector2.Zero;␍␊ |
| }␍␊ |
| }␍␊ |
| /// <summary>Sets/Gets the height of the console window</summary>␍␊ |
| public int Height␍␊ |
| {␍␊ |
| get␍␊ |
| {␍␊ |
| return( m_height );␍␊ |
| }␍␊ |
| set␍␊ |
| {␍␊ |
| m_height = value;␍␊ |
| m_stringHeight = Vector2.Zero;␍␊ |
| }␍␊ |
| }␍␊ |
| /// <summary>Sets/Gets the width of the console window</summary>␍␊ |
| public int Width␍␊ |
| {␍␊ |
| get␍␊ |
| {␍␊ |
| return( m_width );␍␊ |
| }␍␊ |
| set␍␊ |
| {␍␊ |
| m_width = value;␍␊ |
| m_stringHeight = Vector2.Zero;␍␊ |
| }␍␊ |
| }␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Initialization␍␊ |
| /// <summary>Constructor for this base class</summary>␍␊ |
| ␉␉/// <param name="game">The Game object for the owning/managing game</param>␍␊ |
| ␉␉public CommandConsoleBase( Game game )␍␊ |
| : this( game, null )␍␊ |
| {␍␊ |
| return;␍␊ |
| }␍␊ |
| ␉␉/// <summary>Constructor for this base class</summary>␍␊ |
| ␉␉/// <param name="game">The Game object for the owning/managing game</param>␍␊ |
| ␉␉/// <param name="fontToUse">The font that the console should use to draw its text</param>␍␊ |
| ␉␉public CommandConsoleBase( Game game, SpriteFont fontToUse )␍␊ |
| : base( game )␍␊ |
| {␍␊ |
| m_consoleFont = fontToUse;␍␊ |
| ␉␉␉Prompt = "_>";␍␊ |
| ␉␉␉CommandColor = Color.SteelBlue;␍␊ |
| ␉␉␉ErrorColor = Color.Firebrick;␍␊ |
| ␉␉␉OutputColor = Color.Yellow;␍␊ |
| ␉␉␉NormalColor = Color.Silver;␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␉␉/// <summary>Primary initialization function</summary>␍␊ |
| ␉␉public override void Initialize()␍␊ |
| {␍␊ |
| base.Initialize();␍␊ |
| ␉␉␉// OK - This Seems Very Heavyweight, And It Kinda Is. But It Allows For␍␊ |
| ␉␉␉// Easy Mapping Of A "Keys" Value To Any String, Which Makes It Possible␍␊ |
| ␉␉␉// To Create Single Key Macros, Like Binding On Steroids, And Also Makes␍␊ |
| ␉␉␉// It Easy To Handle Non-US Or Gaming Keyboards.␍␊ |
| ␉␉␉␍␊ |
| ␉␉␉// The Format Of The Lines Below Is A Comment Line That Identifies The Array␍␊ |
| ␉␉␉// Indices, Which Correspond To Values In The "Keys" Enumeration, And Then␍␊ |
| ␉␉␉// The Actual Values For Those Indices.␍␊ |
| ␉␉␉m_xlateAllKeys = new List<String>( new[] {␍␊ |
| ␉␉␉// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉// 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31␉␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉// 32 ␉ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47␍␊ |
| ␉␉␉␉" ", "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉48 49 50 51 52 53 54 55 56 57 58 59 60 61 63 63␍␊ |
| ␉␉␉␉"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉64␉ 65␉ 66 67 68␉ 69␉ 70 71␉72␉ 73␉ 74 75␉76␉ 77␉ 78 79␍␊ |
| ␉␉␉␉"" , "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",␍␊ |
| ␉␉␉//␉80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95␍␊ |
| ␉␉␉␉"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111␍␊ |
| ␉␉␉␉"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "+", ",", "-", ".", "/",␍␊ |
| ␉␉␉//␉112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉144 145 146 147 148 149 150 151 152 153 154 155 156 157 159 159␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , ";", "=", ",", "-", ".", "/",␍␊ |
| ␉␉␉//␉192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207␍␊ |
| ␉␉␉␉"", "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "[", "\\","]", "'", "8",␍␊ |
| ␉␉␉//␉224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239␍␊ |
| ␉␉␉␉"" , "" ,"|", "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉␉} );␍␊ |
| ␉␉␉␍␊ |
| ␉␉␉// Create Collection Of Characters (Strings) For All Possible SHIFTED Key Values...␍␊ |
| ␉␉␉m_xlateAllKeysShifted = new List<String>( new[] {␍␊ |
| ␉␉␉// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉// 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31␉␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉// 32 ␉ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47␍␊ |
| ␉␉␉␉" ", "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉48 49 50 51 52 53 54 55 56 57 58 59 60 61 63 63␍␊ |
| ␉␉␉␉")", "!", "@", "#", "$", "%", "^", "&", "*", "(", "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉64␉ 65␉ 66 67 68␉ 69␉ 70 71␉72␉ 73␉ 74 75␉76␉ 77␉ 78 79␍␊ |
| ␉␉␉␉"" , "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",␍␊ |
| ␉␉␉//␉80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95␍␊ |
| ␉␉␉␉"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111␍␊ |
| ␉␉␉␉"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "+", ",", "-", ".", "/",␍␊ |
| ␉␉␉//␉112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉144 145 146 147 148 149 150 151 152 153 154 155 156 157 159 159␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , ":", "+", "<", "_", ">", "?",␍␊ |
| ␉␉␉//␉192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207␍␊ |
| ␉␉␉␉"", "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "{", "|", "}","\"", "*",␍␊ |
| ␉␉␉//␉224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239␍␊ |
| ␉␉␉␉"" , "" ,"\\", "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉//␉240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255␍␊ |
| ␉␉␉␉"" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" ,␍␊ |
| ␉␉␉} );␍␊ |
| ␉␉␉return;␍␊ |
| }␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Graphics Content␍␊ |
| ␉␉/// <summary>Load content for this component</summary>␍␊ |
| ␉␉/// <param name="content">The ContentManager that should be used </param>␍␊ |
| ␉␉public virtual void LoadContent( ContentManager content )␍␊ |
| {␍␊ |
| ␉␉␉m_spriteBatch = new SpriteBatch( GraphicsDevice );␍␊ |
| ␍␊ |
| ␉␉␉m_width = GraphicsDevice.Viewport.Width;␍␊ |
| m_height = ( GraphicsDevice.Viewport.Height / 3 );␍␊ |
| ␍␊ |
| ␉␉␉InitializeCommands();␍␊ |
| base.LoadContent();␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Update and Draw␍␊ |
| /// <summary>␍␊ |
| /// Recalculates measurements required for text display and wrapping. Sets the m_consoleRect,␍␊ |
| /// m_commandPos and m_linesVisibleOnScreen fields.␍␊ |
| /// </summary>␍␊ |
| protected virtual void RecalculateHeightSettings()␍␊ |
| {␍␊ |
| m_consoleRect = new Rectangle( 0, 0, m_width, m_height );␍␊ |
| m_commandPos = new Vector2( 10.0f, m_height - m_commandStringHeightOffset );␍␊ |
| m_linesVisibleOnScreen = ( (int)( m_height / m_stringHeight.Y ) - 1 );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| /// <summary>Update this component</summary>␍␊ |
| /// <param name="gameTime">Game's time</param>␍␊ |
| ␉␉public override void Update( GameTime gameTime )␍␊ |
| {␍␊ |
| CheckInput();␍␊ |
| ␍␊ |
| base.Update( gameTime );␍␊ |
| }␍␊ |
| /// <summary>Draw the console</summary>␍␊ |
| /// <param name="gameTime">Game's time</param>␍␊ |
| ␉␉public override void Draw( GameTime gameTime )␍␊ |
| {␍␊ |
| m_linesAbove = m_linesBelow = false;␍␊ |
| ␍␊ |
| ␉␉␉if( Active == true )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉m_spriteBatch.Begin( SpriteSortMode.Deferred, BlendState.AlphaBlend );␍␊ |
| ␍␊ |
| ␉␉␉␉if( FadeImage != null )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉// Fade The Console Area With The Specified Texture/Image...␍␊ |
| ␉␉␉␉␉m_spriteBatch.Draw( FadeImage, m_consoleRect, FadeColor );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉//␍␊ |
| ␉␉␉␉// Cache Pre-Calculatable Values...␍␊ |
| ␉␉␉␉//␍␊ |
| ␉␉␉␉if( m_stringHeight == Vector2.Zero )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_stringHeight = Vector2.Multiply( m_consoleFont.MeasureString( Prompt ), Scale );␍␊ |
| ␉␉␉␉␉m_screenCharWidth = (int)( ( m_width / m_stringHeight.X ) * 2 );␍␊ |
| ␉␉␉␉␉m_commandStringHeightOffset = ( ( m_stringHeight.Y * 2.0f ) - 4.0f );␍␊ |
| ␉␉␉␉␉RecalculateHeightSettings();␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉// Draw command string␍␊ |
| ␉␉␉␉m_spriteBatch.DrawString( m_consoleFont, Prompt + m_commandLine,␍␊ |
| ␉␉␉␉␉␉m_commandPos, Color.Yellow, 0.0f, Vector2.Zero,␍␊ |
| ␉␉␉␉␉␉Scale, SpriteEffects.None, 0.0f );␍␊ |
| ␍␊ |
| ␉␉␉␉// Draw log␍␊ |
| ␉␉␉␉Vector2 linePos = new Vector2( m_consoleRect.Left + 10.0f, ( m_commandPos.Y - m_stringHeight.Y ) );␍␊ |
| ␍␊ |
| ␉␉␉␉int endLine = Math.Max( 0, ( ( m_log.Count - m_logStart ) - 1 ) );␍␊ |
| ␍␊ |
| ␉␉␉␉if( m_logStart != 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_linesBelow = true;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉for( int i = endLine; i > 0; i-- )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉if( linePos.Y <= m_consoleRect.Top )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉m_linesAbove = true;␍␊ |
| ␉␉␉␉␉␉break;␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉String line = m_log[ i ];␍␊ |
| ␍␊ |
| ␉␉␉␉␉if( line.Length == 0 )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉continue;␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉Char firstChar = line[ 0 ];␍␊ |
| ␍␊ |
| ␉␉␉␉␉if( firstChar <= '\x03' )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉Color outColor = OutputColor;␍␊ |
| ␍␊ |
| ␉␉␉␉␉␉if( firstChar == '\x01' )␍␊ |
| ␉␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉␉outColor = CommandColor;␍␊ |
| ␉␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉␉else if( firstChar == '\x02' )␍␊ |
| ␉␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉␉outColor = ErrorColor;␍␊ |
| ␉␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉␉else if( firstChar == '\x03' )␍␊ |
| ␉␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉␉outColor = OutputColor;␍␊ |
| ␉␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉␉m_spriteBatch.DrawString( m_consoleFont, line.Substring( 1 ),␍␊ |
| ␉␉␉␉␉␉␉␉linePos, outColor, 0.0f, Vector2.Zero, Scale,␍␊ |
| ␉␉␉␉␉␉␉␉SpriteEffects.None, 0.0f );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉else␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉m_spriteBatch.DrawString( m_consoleFont, line, linePos,␍␊ |
| ␉␉␉␉␉␉␉␉NormalColor, 0.0f, Vector2.Zero, Scale,␍␊ |
| ␉␉␉␉␉␉␉␉SpriteEffects.None, 0.0f );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉linePos.Y -= m_stringHeight.Y;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉if( m_linesAbove )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉Vector2 starPos = new Vector2( m_width - 10.0f, m_consoleRect.Top );␍␊ |
| ␍␊ |
| ␉␉␉␉␉m_spriteBatch.DrawString( m_consoleFont, "^", starPos,␍␊ |
| ␉␉␉␉␉␉␉ErrorColor, 0.0f, Vector2.Zero, Scale,␍␊ |
| ␉␉␉␉␉␉␉SpriteEffects.None, 0.0f );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉if( m_linesBelow )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉Vector2 starPos = new Vector2( m_width - 10.0f, ( m_commandPos.Y - m_stringHeight.Y ) );␍␊ |
| ␍␊ |
| ␉␉␉␉␉m_spriteBatch.DrawString( m_consoleFont, "V", starPos,␍␊ |
| ␉␉␉␉␉␉␉ErrorColor, 0.0f, Vector2.Zero, Scale,␍␊ |
| ␉␉␉␉␉␉␉SpriteEffects.None, 0.0f );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉m_spriteBatch.End();␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉base.Draw( gameTime );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Input Handling␍␊ |
| ␉␉/// <summary>Process a keyboard key. Assumes that the Keyboard property is not null!</summary>␍␊ |
| ␉␉/// <param name="key">The key to process</param>␍␊ |
| ␉␉protected virtual void ProcessKey( Keys key )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉// Space - Special Handling To Eliminate Leading Whitespace␍␊ |
| ␉␉␉if( ( key == Keys.Space ) && ( !String.IsNullOrWhiteSpace( m_commandLine ) ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉m_commandLine += " ";␍␊ |
| ␉␉␉␉ms_partialCmdMatches.Clear();␍␊ |
| ␉␉␉␉m_lastCmdMatch = String.Empty;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Command History...␍␊ |
| ␉␉␉else if( key == Keys.Up )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( m_cmdHistory.Count == 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉return;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉m_cmdHistoryScanIndex--;␍␊ |
| ␉␉␉␉if( m_cmdHistoryScanIndex < 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_cmdHistoryScanIndex = 0;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉m_commandLine = m_cmdHistory[ m_cmdHistoryScanIndex ];␍␊ |
| ␉␉␉␉ms_partialCmdMatches.Clear();␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉else if( key == Keys.Down ) ␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( m_cmdHistory.Count == 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉return;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉m_cmdHistoryScanIndex++;␍␊ |
| ␉␉␉␉if( m_cmdHistoryScanIndex >= m_cmdHistory.Count )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_cmdHistoryScanIndex = ( m_cmdHistory.Count - 1 );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉m_commandLine = m_cmdHistory[ m_cmdHistoryScanIndex ];␍␊ |
| ␉␉␉␉ms_partialCmdMatches.Clear();␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Log Scrolling...␍␊ |
| ␉␉␉else if( ( key == Keys.PageUp ) && ( m_linesVisibleOnScreen < m_log.Count ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉m_logStart += ( m_linesVisibleOnScreen - 1 );␍␊ |
| ␉␉␉␉if( m_logStart >= ( m_log.Count - m_linesVisibleOnScreen ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_logStart = ( m_log.Count - m_linesVisibleOnScreen + 1 );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉else if( ( key == Keys.PageDown ) && ( m_linesVisibleOnScreen < m_log.Count ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉m_logStart -= ( m_linesVisibleOnScreen - 1 );␍␊ |
| ␉␉␉␉if( m_logStart < 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_logStart = 0;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Check input for Escape␍␊ |
| ␉␉␉else if( key == Keys.Escape )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉m_commandLine = String.Empty;␍␊ |
| ␉␉␉␉ms_partialCmdMatches.Clear();␍␊ |
| ␉␉␉␉m_lastCmdMatch = String.Empty;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Check input for Backspace␍␊ |
| ␉␉␉else if( ( key == Keys.Back ) && ( !String.IsNullOrEmpty( m_commandLine ) ) && ␍␊ |
| ␉␉␉␉␉␉( m_commandLine != Prompt ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉m_commandLine = m_commandLine.Remove( m_commandLine.Length - 1, 1 );␍␊ |
| ␉␉␉␉ms_partialCmdMatches.Clear();␍␊ |
| ␉␉␉␉m_lastCmdMatch = String.Empty;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Check input for Tab␍␊ |
| ␉␉␉else if( ( key == Keys.Tab ) && ( !String.IsNullOrEmpty( m_commandLine ) ) && ␍␊ |
| ␉␉␉␉␉␉( m_commandLine != Prompt ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉// Rebuild Partial Command Matches If List Is Empty/Reset␍␊ |
| ␉␉␉␉if( ms_partialCmdMatches.Count == 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉BuildCommandMatches( m_commandLine );␍␊ |
| ␉␉␉␉␉m_cmdMatchIndex = 0;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉// If We Have Partial Matches, Circularly Iterate Over Them And Show Them␍␊ |
| ␉␉␉␉if( ms_partialCmdMatches.Count > 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉if( m_cmdMatchIndex >= ms_partialCmdMatches.Count )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉m_cmdMatchIndex = 0;␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉m_commandLine = ms_partialCmdMatches[ m_cmdMatchIndex++ ];␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Enter - Commit Command Line␍␊ |
| ␉␉␉else if( ( key == Keys.Enter ) && ( !String.IsNullOrWhiteSpace( m_commandLine ) ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddToLog( "\x01" + m_commandLine );␍␊ |
| ␉␉␉␉m_logStart = 0;␍␊ |
| ␉␉␉␉ExecuteCommandLine( true );␍␊ |
| ␉␉␉␉m_commandLine = String.Empty;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Any Other Key, Process As Character (Even If Not A Real Character Key)␍␊ |
| ␉␉␉else␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉// Handle Shifted Chars␍␊ |
| ␉␉␉␉if( ( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.LeftShift ) ) ||␍␊ |
| ␉␉␉␉␉␉( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.RightShift ) ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_commandLine += m_xlateAllKeysShifted[ (int)key ];␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉else␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉m_commandLine += m_xlateAllKeys[ (int)key ];␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉ms_partialCmdMatches.Clear();␍␊ |
| ␉␉␉␉m_lastCmdMatch = String.Empty;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␉␉␍␊ |
| ␉␉/// <summary>Check input from the provided keyboard interface</summary>␍␊ |
| ␉␉protected virtual void CheckInput()␍␊ |
| {␍␊ |
| ␉␉␉//InputManager␉im = InputManager.Instance;␍␊ |
| ␍␊ |
| ␉␉␉// If No Interface To The Keyboard, Stop Here␍␊ |
| ␉␉␉if( Keyboard == null )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Toggle the console menu on or off␍␊ |
| ␉␉␉if( Keyboard.NewlyPressedKeys.Contains( Keys.OemTilde ) )␍␊ |
| {␍␊ |
| Active = !Active;␍␊ |
| ␉␉␉␉return;␍␊ |
| }␍␊ |
| // Only Check Bindings If The Console Is Not Active␍␊ |
| ␉␉␉if( Active == false )␍␊ |
| {␍␊ |
| CheckBindings();␍␊ |
| return;␍␊ |
| }␍␊ |
| ␉␉␉if( Keyboard.HeldKeys.Count > 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( DateTime.Now > m_keyRepeatTime )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉ProcessKey( Keyboard.HeldKeys[ 0 ] );␍␊ |
| ␉␉␉␉␉m_keyRepeatTime = DateTime.Now.AddMilliseconds( 100 );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( Keyboard.NewlyPressedKeys.Count > 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉ProcessKey( Keyboard.NewlyPressedKeys[ 0 ] );␍␊ |
| ␉␉␉␉m_keyRepeatTime = DateTime.Now.AddMilliseconds( 250 );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>Get binding information from a "binding string" input by the user</summary>␍␊ |
| /// <param name="bindString">The binding string to parse</param>␍␊ |
| /// <param name="bindModifiers">ref - the modifier keys for the binding</param>␍␊ |
| /// <param name="bindKey">ref - the key for the binding</param>␍␊ |
| /// <returns>true if the binding string was understood, false if not</returns>␍␊ |
| bool GetKeyBindingInfo( string bindString, ref BindingObject.EModifier bindModifiers, ref Keys bindKey )␍␊ |
| {␍␊ |
| bindString = bindString.ToUpper();␍␊ |
| if( bindString.Length == 1 )␍␊ |
| {␍␊ |
| char keyChar = ( bindString.Trim().ToUpper()[ 0 ] );␍␊ |
| int keyOffset = keyChar - 'A';␍␊ |
| bindKey = ( Keys.A + keyOffset );␍␊ |
| // Default To ALT Binding...␍␊ |
| // bindModifiers = BindingObject.EModifier.Alt;␍␊ |
| ␍␊ |
| if( ( bindKey >= Keys.A ) && ( bindKey <= Keys.Z ) )␍␊ |
| {␍␊ |
| return( true );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| return( false );␍␊ |
| }␍␊ |
| }␍␊ |
| string[] keyTokens = bindString.Split( '+' );␍␊ |
| bool parsed = false;␍␊ |
| ␍␊ |
| foreach( string ktoken in keyTokens )␍␊ |
| {␍␊ |
| if( ktoken == "ALT" )␍␊ |
| {␍␊ |
| bindModifiers |= BindingObject.EModifier.Alt;␍␊ |
| continue;␍␊ |
| }␍␊ |
| if( ktoken == "CTRL" )␍␊ |
| {␍␊ |
| bindModifiers |= BindingObject.EModifier.Ctrl;␍␊ |
| continue;␍␊ |
| }␍␊ |
| if( ktoken == "SHIFT" )␍␊ |
| {␍␊ |
| bindModifiers |= BindingObject.EModifier.Shift;␍␊ |
| continue;␍␊ |
| }␍␊ |
| if( ktoken.Length == 1 )␍␊ |
| {␍␊ |
| int keyOffset = ktoken[ 0 ] - 'A';␍␊ |
| bindKey = ( Keys.A + keyOffset );␍␊ |
| if( ( bindKey >= Keys.A ) && ( bindKey <= Keys.B ) )␍␊ |
| {␍␊ |
| parsed = true;␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| parsed = false;␍␊ |
| }␍␊ |
| break;␍␊ |
| }␍␊ |
| else if( ( ( ktoken.Length == 2 ) || ( ktoken.Length == 3 ) ) && ( ktoken[ 0 ] == 'F' ) )␍␊ |
| {␍␊ |
| // F-Key Binding...␍␊ |
| int fNumber = int.Parse( ktoken.Substring( 1 ) );␍␊ |
| Keys fKey = ( Keys.Divide + fNumber );␍␊ |
| ␍␊ |
| if( ( fKey >= Keys.F1 ) && ( fKey <= Keys.F24 ) )␍␊ |
| {␍␊ |
| bindKey = fKey;␍␊ |
| parsed = true;␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| parsed = false;␍␊ |
| }␍␊ |
| break;␍␊ |
| }␍␊ |
| else ␍␊ |
| {␍␊ |
| break;␍␊ |
| }␍␊ |
| }␍␊ |
| return ( parsed );␍␊ |
| }␍␊ |
| /// <summary>Check for bound keys - bound keys use the <ALT> modifier</summary>␍␊ |
| protected virtual void CheckBindings()␍␊ |
| {␍␊ |
| // Stop Here If No Bindings Are Set, Or No Interface To The Keyboard␍␊ |
| ␉␉␉if( ( ms_bindings.Count == 0 ) || ( Keyboard == null ) )␍␊ |
| {␍␊ |
| return;␍␊ |
| }␍␊ |
| ␉␉␉//InputManager␉im = InputManager.Instance;␍␊ |
| ␍␊ |
| ␉␉␉BindingObject.EModifier modifierKeys = BindingObject.EModifier.None;␍␊ |
| ␉␉␉bool altDown = ( ( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.LeftAlt ) ) || ( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.RightAlt ) ) );␍␊ |
| ␉␉␉bool ctrlDown = ( ( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.LeftControl ) ) || ( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.RightControl ) ) );␍␊ |
| ␉␉␉bool shiftDown = ( ( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.LeftShift ) ) || ( Keyboard.CurrentKeyboardState.IsKeyDown( Keys.RightShift ) ) );␍␊ |
| ␍␊ |
| if( altDown ) modifierKeys |= BindingObject.EModifier.Alt;␍␊ |
| if( ctrlDown ) modifierKeys |= BindingObject.EModifier.Ctrl;␍␊ |
| if( shiftDown ) modifierKeys |= BindingObject.EModifier.Shift;␍␊ |
| ␍␊ |
| foreach( BindingObject bs in ms_bindings )␍␊ |
| {␍␊ |
| // See if the Binding's modifier keys are down, and its command key. If so, execute the command.␍␊ |
| if( ( ( bs._modifierKeys & modifierKeys ) == modifierKeys ) &&␍␊ |
| ␉␉␉␉␉␉( Keyboard.NewlyPressedKeys.Contains( bs._key ) ) )␍␊ |
| {␍␊ |
| m_commandLine = bs._text;␍␊ |
| ExecuteCommandLine( false );␍␊ |
| m_commandLine = String.Empty;␍␊ |
| }␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉/// <summary>Build command matches for the specified (sub)string.</summary>␍␊ |
| ␉␉/// <param name="cmdMatch">The partial command to try to match</param>␍␊ |
| ␉␉/// <returns>Nothing</returns>␍␊ |
| ␉␉/// <remarks>Resets the ms_partialCmdMatches collection</remarks>␍␊ |
| ␉␉protected virtual void BuildCommandMatches( string cmdMatch )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉ms_partialCmdMatches.Clear();␍␊ |
| ␍␊ |
| ␉␉␉// Iterate Over Commands And Store Non-Secret Commands That Match Substring␍␊ |
| ␉␉␉foreach( CmdObject cmd in ms_commands.Values )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( ( !cmd.IsSecret ) && ( cmd.Command.StartsWith( cmdMatch ) ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉ms_partialCmdMatches.Add( cmd.Command );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Iterate Over Funcitons And Store Non-Secret Functions That Match Substring␍␊ |
| ␉␉␉foreach( FuncObject func in ms_functions.Values )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( ( !func.IsSecret ) && ( func.Function.StartsWith( cmdMatch ) ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉ms_partialCmdMatches.Add( func.Function );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Iterate Over External Funcitons And Store Non-Secret Functions That Match Substring␍␊ |
| ␉␉␉foreach( ExternalFuncObject extFunc in ms_externalFunctions.Values )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( ( extFunc.IsSecret ) && ( extFunc.MethodName.StartsWith( cmdMatch ) ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉ms_partialCmdMatches.Add( extFunc.MethodName );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉#endregion␍␊ |
| ␍␊ |
| ␉␉#region Log Output␍␊ |
| ␉␉/// <summary>Add executed command output to the log.</summary>␍␊ |
| /// <param name="text">The output text to add</param>␍␊ |
| public void AddOutputToLog( string text )␍␊ |
| {␍␊ |
| if( String.IsNullOrEmpty( text ) )␍␊ |
| {␍␊ |
| return;␍␊ |
| }␍␊ |
| AddToLog( "\x03" + DateTime.Now.ToString( "hh:mm:ss.fff" ) + "-" + text );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>Add error output to the log.</summary>␍␊ |
| /// <param name="text">The error text to add</param>␍␊ |
| public void AddErrorToLog( string text )␍␊ |
| {␍␊ |
| if( String.IsNullOrEmpty( text ) )␍␊ |
| {␍␊ |
| return;␍␊ |
| }␍␊ |
| AddToLog( "\x02" + DateTime.Now.ToString( "hh:mm:ss.fff" ) + "-" + text );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>Add executed command to the log.</summary>␍␊ |
| /// <param name="text">The command text to add</param>␍␊ |
| public void AddCommandToLog( string text )␍␊ |
| {␍␊ |
| if( String.IsNullOrEmpty( text ) )␍␊ |
| {␍␊ |
| return;␍␊ |
| }␍␊ |
| AddToLog( "\x01" + DateTime.Now.ToString( "hh:mm:ss.fff" ) + "-" + text );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>Method to add generic output text to the log</summary>␍␊ |
| /// <param name="text">The text to add</param>␍␊ |
| public void AddToLog( string text )␍␊ |
| {␍␊ |
| if( String.IsNullOrEmpty( text ) )␍␊ |
| {␍␊ |
| return;␍␊ |
| }␍␊ |
| if( m_logShadowEnabled )␍␊ |
| {␍␊ |
| m_logShadowFile.WriteLine( text );␍␊ |
| }␍␊ |
| lock( m_log )␍␊ |
| {␍␊ |
| if( ( m_screenCharWidth == 0 ) || ( text.Length < m_screenCharWidth ) )␍␊ |
| {␍␊ |
| m_log.Add( text );␍␊ |
| return;␍␊ |
| }␍␊ |
| List<string> lines = BreakTextIntoList( text, m_consoleFont, ( m_consoleRect.Width - 10 ), Scale );␍␊ |
| ␍␊ |
| ␉␉␉␉foreach( String line in lines )␍␊ |
| {␍␊ |
| ␉␉␉␉␉m_log.Add( line );␍␊ |
| }␍␊ |
| if( m_log.Count > m_logLimit )␍␊ |
| {␍␊ |
| int remove = Math.Max( 32, ( m_log.Count - m_logLimit ) );␍␊ |
| ␍␊ |
| remove--;␍␊ |
| m_log.RemoveRange( 0, remove );␍␊ |
| }␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉// JRT␉Only Evaluate This Once...␍␊ |
| ␉␉private static readonly␉char[] DELIMITERS = " .:,/\\-+=_[]{}()?!><|".ToCharArray();␍␊ |
| ␍␊ |
| ␉␉/// <summary>␍␊ |
| /// Break text up into separate lines to make it fit.␍␊ |
| /// (Originally From MS Provided Code - RBG Starter Kit/Template - Text Helper Methods)␍␊ |
| /// </summary>␍␊ |
| /// <param name="text">The text to be broken up.</param>␍␊ |
| /// <param name="font">The font used to measure the width of the text.</param>␍␊ |
| /// <param name="rowWidth">The maximum width of each line, in pixels.</param>␍␊ |
| ␉␉/// <param name="scale">Scale that should be used for the lines.</param>␍␊ |
| ␉␉protected static List<string> BreakTextIntoList( string text, SpriteFont font,␍␊ |
| int rowWidth, float scale )␍␊ |
| {␍␊ |
| // check parameters␍␊ |
| ␉␉␉if( String.IsNullOrEmpty( text ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return( new List<string>( new[] { String.Empty } ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( font == null )␍␊ |
| {␍␊ |
| throw new ArgumentNullException( "font" );␍␊ |
| }␍␊ |
| if( rowWidth <= 0 )␍␊ |
| {␍␊ |
| throw new ArgumentOutOfRangeException( "rowWidth" );␍␊ |
| }␍␊ |
| // create the list␍␊ |
| List<string> lines = new List<string>( text.Length / rowWidth );␍␊ |
| ␍␊ |
| // check for trivial text␍␊ |
| if( String.IsNullOrEmpty( text ) )␍␊ |
| {␍␊ |
| lines.Add( String.Empty );␍␊ |
| return lines;␍␊ |
| }␍␊ |
| char cLead = text[ 0 ];␍␊ |
| ␍␊ |
| //␍␊ |
| ␉␉␉// JRT␉Q&D Way To Get Rid Of The Coloring Characters - They Are Not Written␍␊ |
| //␉␉Out To The Screen, Anyway...␍␊ |
| //␍␊ |
| if( ( cLead == '\x01' ) || ( cLead == '\x02' ) || ( cLead == '\x03' ) )␍␊ |
| {␍␊ |
| text = text.Substring( 1 );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| cLead = '\x00';␍␊ |
| }␍␊ |
| // check for text that fits on a single line␍␊ |
| if( ( font.MeasureString( text ).X * scale ) <= rowWidth )␍␊ |
| {␍␊ |
| if( cLead != '\x00' )␍␊ |
| {␍␊ |
| text = text.Insert( 0, cLead.ToString() );␍␊ |
| }␍␊ |
| return lines;␍␊ |
| }␍␊ |
| ␍␊ |
| StringBuilder sb = new StringBuilder( 256 );␍␊ |
| int textIndex = 0;␍␊ |
| int currentDelimiterIndex = 0;␍␊ |
| ␍␊ |
| // JRT␉This Loop Will Cause The Occasional Leading Delimiter Character If The␍␊ |
| ␉␉␉//␉␉Line Break Occurs At A Place Where To Delimiters Are Next To Each␍␊ |
| ␉␉␉//␉␉Other, But I Consider This An Acceptable Tradeoff.␍␊ |
| ␉␉␉//␍␊ |
| ␉␉␉//␉␉Lines That Cannot Be Broken-Up Will Wrap, But The Wrapping Will Not␍␊ |
| ␉␉␉//␉␉Be Optimal.␍␊ |
| ␉␉␉while( textIndex < text.Length )␍␊ |
| {␍␊ |
| String appendedString;␍␊ |
| int lastLen = textIndex;␍␊ |
| ␍␊ |
| currentDelimiterIndex = text.IndexOfAny( DELIMITERS, textIndex );␍␊ |
| if( currentDelimiterIndex == -1 )␍␊ |
| {␍␊ |
| ␉␉␉␉␉appendedString = text.Substring( textIndex );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| appendedString = text.Substring( textIndex, ( currentDelimiterIndex - textIndex + 1 ) );␍␊ |
| }␍␊ |
| sb.Append( appendedString );␍␊ |
| ␉␉␉␉if( ( font.MeasureString( sb.ToString() ).X * scale ) > rowWidth )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉sb.Remove( ( sb.Length - appendedString.Length ), appendedString.Length );␍␊ |
| ␉␉␉␉␉if( cLead != '\x00' )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉sb.Insert( 0, cLead );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉lines.Add( sb.ToString() );␍␊ |
| ␉␉␉␉␉sb.Length = 0;␍␊ |
| ␉␉␉␉␉text = text.Substring( textIndex );␍␊ |
| ␉␉␉␉␉textIndex = 0;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉else␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉textIndex += appendedString.Length;␍␊ |
| ␉␉␉␉}␍␊ |
| }␍␊ |
| if( sb.Length > 0 )␍␊ |
| {␍␊ |
| lines.Add( sb.ToString() );␍␊ |
| }␍␊ |
| return( lines );␍␊ |
| }␍␊ |
| #endregion ␍␊ |
| ␍␊ |
| #region Built-In Commands␍␊ |
| /// <summary>Sets up the standard/built-in commands.</summary>␍␊ |
| protected void InitializeStandardCommands()␍␊ |
| {␍␊ |
| CmdObject cmdStruct = new CmdObject();␍␊ |
| ␍␊ |
| cmdStruct.Command = "help";␍␊ |
| cmdStruct.CommandHelp = "show game console help, or help for a specific command";␍␊ |
| cmdStruct.CommandHelpDetailed = "help [command]";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Help );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "quit";␍␊ |
| cmdStruct.CommandHelp = "immediately quit the game";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Quit );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "close";␍␊ |
| cmdStruct.CommandHelp = "close the command console.";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Close );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "consoleheight";␍␊ |
| cmdStruct.MinParameters = 0;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "set the height of the console window in pixels";␍␊ |
| cmdStruct.CommandHelpDetailed = "consoleheight <heightvalue>";␍␊ |
| cmdStruct.CmdEvent +=new Action<string[]>(CommandConsoleBase_ConsoleHeight);␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "consolescale";␍␊ |
| cmdStruct.MinParameters = 0;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "set the scale of the console window (1.0=100%, 0.75=75%, 0.5=50%, etc.)";␍␊ |
| cmdStruct.CommandHelpDetailed = "consolescale<scale>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ConsoleScale );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "cvar";␍␊ |
| ␉␉␉cmdStruct.MinParameters = 1;␍␊ |
| ␉␉␉cmdStruct.MaxParameters = 3;␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "add a new console variable (cvar), or modify an existing one";␍␊ |
| ␉␉␉cmdStruct.CommandHelpDetailed = "cvar <name> [Type] <value> -- examples: cvar myVar MyValue, cvar myInt Int32 42";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_CVar );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "cvars";␍␊ |
| ␉␉␉cmdStruct.MinParameters = 0;␍␊ |
| ␉␉␉cmdStruct.MaxParameters = 0;␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "view the available console variables (cvars)";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_CVars );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "gc";␍␊ |
| cmdStruct.CommandHelp = "immediately perform full garbage collection";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_GC );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "shadowlog";␍␊ |
| cmdStruct.MinParameters = 0;␍␊ |
| cmdStruct.MaxParameters = 2;␍␊ |
| cmdStruct.CommandHelp = "shadows the log to an external file, optionally truncating the external file first";␍␊ |
| cmdStruct.CommandHelpDetailed = "shadowlog <filepath> <true/false>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ShadowLog );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "noshadowlog";␍␊ |
| cmdStruct.CommandHelp = "turns off shadowing of the log to an external file";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_NoShadowLog );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "clear";␍␊ |
| cmdStruct.CommandHelp = "clears the console log";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Clear );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "loglimit";␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "sets the console log (buffer) limit";␍␊ |
| cmdStruct.CommandHelpDetailed = "loglimit <numlines>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_LogLimit );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "memoryinfo";␍␊ |
| cmdStruct.CommandHelp = "display memory info";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_MemInfo );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "exfunc";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "load external function from an assembly";␍␊ |
| ␉␉␉cmdStruct.CommandHelpDetailed = "exfunc <assemblypath> <classname> <functionname>";␍␊ |
| ␉␉␉cmdStruct.MinParameters = 3;␍␊ |
| ␉␉␉cmdStruct.MaxParameters = 3;␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ExFunc );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "systeminfo";␍␊ |
| cmdStruct.CommandHelp = "display system info";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_SystemInfo );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "sleep";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "eause execution of the command console";␍␊ |
| cmdStruct.CommandHelpDetailed = "sleep <durationms>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Sleep );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "exec";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "execute contents of a file as commands in this console";␍␊ |
| cmdStruct.CommandHelpDetailed = "exec <filepath>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Exec );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "savelog";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "save the console log to a file";␍␊ |
| cmdStruct.CommandHelpDetailed = "savelog <filepath>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_SaveLog );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "functions";␍␊ |
| cmdStruct.CommandHelp = "display all current functions";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Functions );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "nofunctions";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "disable the ability to add/remove functions";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_NoFunctions );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "exfuncs";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "display all current external functions";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ExFuncs );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "noexfuncs";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "disable the ability to add/remove exfuncs";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_NoExFunctions );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "bindings";␍␊ |
| cmdStruct.CommandHelp = "display all current key bindings";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Bindings );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "nobindings";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "disable the ability to add/remove bindings";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_NoBindings );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "resetbindings";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "clear all key bindings";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ResetBindings );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "resetexfuncs";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "clear all external functions";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ResetExFuncs );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "resetfunctions";␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "clear all functions";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ResetFunctions);␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "bind";␍␊ |
| cmdStruct.MinParameters = 2;␍␊ |
| cmdStruct.MaxParameters = 0;␍␊ |
| cmdStruct.CommandHelp = "bind an key to a command or function";␍␊ |
| cmdStruct.CommandHelpDetailed = "bind <key> <commandtext/functionname> -- examples: 'bind ALT+G gc', 'bind CTRL+SHIFT+Q quit'";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Bind );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "unbind";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "remove a previous key binding";␍␊ |
| cmdStruct.CommandHelpDetailed = "unbind <key>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_UnBind );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "function";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 0;␍␊ |
| cmdStruct.CommandHelp = "create a new function";␍␊ |
| cmdStruct.CommandHelpDetailed = "function <functionname> <line>;<line>;<...>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_Function );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "exportfunctions";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| cmdStruct.CommandHelp = "export functions to a file that can be EXEC-ed";␍␊ |
| cmdStruct.CommandHelpDetailed = "exportfunctions <filepath>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ExportFunctions );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| ␉␉␉cmdStruct.Command = "exportexfuncs";␍␊ |
| ␉␉␉cmdStruct.MinParameters = 1;␍␊ |
| ␉␉␉cmdStruct.MaxParameters = 1;␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "export exfuncs to a file that can be EXEC-ed";␍␊ |
| ␉␉␉cmdStruct.CommandHelpDetailed = "exportexfuncs <filepath>";␍␊ |
| ␉␉␉cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ExportExFuncs );␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| ␉␉␉cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "exportbindings";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "export binding information to a file that can be EXEC-ed";␍␊ |
| cmdStruct.CommandHelpDetailed = "exportbindings <filepath>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ExportBindings );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| cmdStruct = new CmdObject();␍␊ |
| cmdStruct.Command = "exportstate";␍␊ |
| cmdStruct.MinParameters = 1;␍␊ |
| cmdStruct.MaxParameters = 1;␍␊ |
| ␉␉␉cmdStruct.CommandHelp = "export the console's complete state information to a file that can be EXEC-ed, so that the state can be restored later";␍␊ |
| cmdStruct.CommandHelpDetailed = "exportstate <filepath>";␍␊ |
| cmdStruct.CmdEvent += new Action<string[]>( CommandConsoleBase_ExportState );␍␊ |
| ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>␍␊ |
| /// Overridable method used to add custom commands to the console.␍␊ |
| /// </summary>␍␊ |
| public virtual void InitializeCustomCommands()␍␊ |
| {␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉/// <summary>Initialize the Console's Commands -- is normally called via <see cref="LoadContent"/></summary>␍␊ |
| ␉␉public void InitializeCommands()␍␊ |
| {␍␊ |
| InitializeStandardCommands();␍␊ |
| ␍␊ |
| InitializeCustomCommands();␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>␍␊ |
| /// Add a command to the internal collection of commands. Throws an exception if duplicate identifiers are detected.␍␊ |
| /// </summary>␍␊ |
| /// <param name="cmdStruct">Command object to add</param>␍␊ |
| protected void AddCommand( CmdObject cmdStruct )␍␊ |
| {␍␊ |
| cmdStruct.Command = cmdStruct.Command.Trim().ToLowerInvariant();␍␊ |
| ␍␊ |
| ␉␉␉if( ms_commands.ContainsKey( cmdStruct.Command ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉throw( new InvalidOperationException( String.Format( ␍␊ |
| ␉␉␉␉␉␉"Command {0} already exists in the command list.", ␍␊ |
| ␉␉␉␉␉␉cmdStruct.Command ) ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_functions.ContainsKey( cmdStruct.Command ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉throw ( new InvalidOperationException( String.Format(␍␊ |
| ␉␉␉␉␉␉"Command {0} already exists as a function.",␍␊ |
| ␉␉␉␉␉␉cmdStruct.Command ) ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉ms_commands[ cmdStruct.Command ] = cmdStruct;␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>␍␊ |
| /// Add a function to the internal collection of functions. Throws an exception if duplicate identifiers are detected.␍␊ |
| /// </summary>␍␊ |
| /// <param name="fnStruct">Function object to add</param>␍␊ |
| protected void AddFunction( FuncObject fnStruct )␍␊ |
| {␍␊ |
| ␉␉␉if( ms_commands.ContainsKey( fnStruct.Function ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉throw ( new InvalidOperationException( String.Format(␍␊ |
| ␉␉␉␉␉␉"Function {0} already exists as a command.",␍␊ |
| ␉␉␉␉␉␉fnStruct.Function ) ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_functions.ContainsKey( fnStruct.Function ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉throw ( new InvalidOperationException( String.Format(␍␊ |
| ␉␉␉␉␉␉"Function {0} already exists in the function list.",␍␊ |
| ␉␉␉␉␉␉fnStruct.Function ) ) );␍␊ |
| ␉␉␉}␍␊ |
| ms_functions[ fnStruct.Function ] = fnStruct;␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| #endregion␍␊ |
| ␍␊ |
| #region Command Processing␍␊ |
| /// <summary>Execute the specified Function</summary>␍␊ |
| ␉␉/// <param name="fnStruct">Function to execute</param>␍␊ |
| ␉␉/// <param name="parameters">Parameters for the function</param>␍␊ |
| protected void ExecuteFunction( FuncObject fnStruct, string[] parameters )␍␊ |
| {␍␊ |
| foreach( string line in fnStruct.FunctionImpl )␍␊ |
| {␍␊ |
| m_commandLine = line;␍␊ |
| // If Function Parameters Exist, And Function Takes Parameters␍␊ |
| if( ( parameters != null ) && ( m_commandLine.IndexOf( '%' ) != -1 ) )␍␊ |
| {␍␊ |
| int count = 0;␍␊ |
| ␍␊ |
| // Build The Resulting Command Line␍␊ |
| foreach( string param in parameters )␍␊ |
| {␍␊ |
| m_commandLine = m_commandLine.Replace( "%" + count, parameters[ count ] );␍␊ |
| count++;␍␊ |
| }␍␊ |
| }␍␊ |
| AddToLog( "\x01-> " + m_commandLine );␍␊ |
| ExecuteCommandLine( false );␍␊ |
| m_commandLine = String.Empty;␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| /// <summary>Evaluates and executes the command line stored in the "_command" field.</summary>␍␊ |
| public virtual void ExecuteCommandLine( bool addToHistory )␍␊ |
| {␍␊ |
| ␉␉␉string trimmedCmdLine = m_commandLine.Trim();␍␊ |
| ␍␊ |
| ␉␉␉// Ignore Empty And Whitespace Command Lines...␍␊ |
| ␉␉␉if( String.IsNullOrWhiteSpace( trimmedCmdLine ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Ignore Comments...␍␊ |
| ␉␉␉if( trimmedCmdLine[ 0 ] == '#' )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// Bang Indicates That This Line Should NOT Be Added To Command History␍␊ |
| ␉␉␉if (trimmedCmdLine[0] == '!')␍␊ |
| {␍␊ |
| addToHistory = false;␍␊ |
| trimmedCmdLine = trimmedCmdLine.Substring(1);␍␊ |
| }␍␊ |
| else if( addToHistory )␍␊ |
| {␍␊ |
| m_cmdHistory.Add(trimmedCmdLine);␍␊ |
| if( m_cmdHistory.Count > m_cmdHistoryLimit )␍␊ |
| {␍␊ |
| m_cmdHistory.RemoveAt(m_cmdHistoryLimit);␍␊ |
| }␍␊ |
| m_cmdHistoryIndex = m_cmdHistory.Count;␍␊ |
| // m_cmdHistoryIndex = ( m_cmdHistory.Count - 1 );␍␊ |
| m_cmdHistoryScanIndex = m_cmdHistoryIndex;␍␊ |
| }␍␊ |
| // If A PreCommand Execution Handling Delegate Has Been Set,␍␊ |
| ␉␉␉// Execute The Delegate And See If The Command Was Handled␍␊ |
| ␉␉␉// Externally.␍␊ |
| ␉␉␉if( PreCommandExecutedEvent != null )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉CommandConsoleEventArgs ea = new CommandConsoleEventArgs( trimmedCmdLine );␍␊ |
| ␍␊ |
| ␉␉␉␉try␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉PreCommandExecutedEvent( this, ea );␍␊ |
| ␉␉␉␉␉trimmedCmdLine = ea.CmdLine;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉catch( Exception ex )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉AddErrorToLog( "** PreCommandExecuted delegate(s) thrown an exception: " + ex.Message );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉if( ea.Handled )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉return;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉try␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉CmdObject␉cs;␍␊ |
| ␉␉␉␉String[]␉cmds = trimmedCmdLine.Split( ' ' );␍␊ |
| ␉␉␉␉String␉␉cmd = cmds[ 0 ].ToLowerInvariant();␍␊ |
| ␉␉␉␉bool␉␉found = false;␍␊ |
| ␍␊ |
| ␉␉␉␉// Commands Are more Common Then Functions, So Check them First.␍␊ |
| ␉␉␉␉if( ms_commands.TryGetValue( cmd, out cs ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉found = ExecuteCommand( cs, cmds, cmd );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉// Next, Try External Functions...␍␊ |
| ␉␉␉␉if( ( !found ) && ( ms_externalFunctions.Count > 0 ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉found = ExecuteExternalFunc( cmds, cmd );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉// Next, Try Internal Functions...␍␊ |
| ␉␉␉␉if( ( !found ) && ( ms_functions.Count > 0 ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉found = ExecuteInternalFunc( cmds, cmd );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉// Lastly, See If A Console Variable...␍␊ |
| ␉␉␉␉if( ( !found ) && ( m_cVars.Count > 0 ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉found = HandleCVar( cmds, cmd );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉// If STILL Not Found...␍␊ |
| ␉␉␉␉if( !found )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉AddErrorToLog( "** Unknown command: " + trimmedCmdLine );␍␊ |
| ␉␉␉␉␉AddErrorToLog( "** type help for commands and usage." );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉catch( Exception e )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( String.Format( "Exception while processing \"{0}\" : {1}", trimmedCmdLine, e.Message ) );␍␊ |
| ␉␉␉}␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉/// <summary>Handle set/get cvar</summary>␍␊ |
| ␉␉/// <param name="cmds">Command Line</param>␍␊ |
| ␉␉/// <param name="cmd">Pre-processed command</param>␍␊ |
| ␉␉/// <returns>true if command was handled by this function</returns>␍␊ |
| ␉␉private bool HandleCVar( String[] cmds, String cmd )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉CVar␉cvar;␍␊ |
| ␉␉␉bool␉found = false;␍␊ |
| ␍␊ |
| ␉␉␉lock( m_cVars )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( m_cVars.TryGetValue( cmd, out cvar ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉found = true;␍␊ |
| ␉␉␉␉␉if( cmds.Length == 1 )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉AddOutputToLog( String.Format( "{0} ({1}) = {2}",␍␊ |
| ␉␉␉␉␉␉␉␉cvar.Name, cvar.ValueType.ToString(), cvar.Value.ToString() ) );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉else␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉cvar.Value = GetObjFromString( cvar.ValueType, cmds[ 1 ] );␍␊ |
| ␉␉␉␉␉␉if( CVarModifiedEvent != null )␍␊ |
| ␉␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉␉CVarModifiedEvent.Invoke( this, new CVarModifiedEventArgs( cvar ) );␍␊ |
| ␉␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return( found );␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉/// <summary>Execute an internal function</summary>␍␊ |
| ␉␉/// <param name="cmds">Command Line</param>␍␊ |
| ␉␉/// <param name="cmd">Pre-processed command</param>␍␊ |
| ␉␉/// <returns>true if command was handled by this function</returns>␍␊ |
| ␉␉private bool ExecuteInternalFunc( String[] cmds, String cmd )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉FuncObject␉fs;␍␊ |
| ␉␉␉bool found = false;␍␊ |
| ␍␊ |
| ␉␉␉if( ms_functions.TryGetValue( cmd, out fs ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉string[] parameters = new string[ cmds.Length - 1 ];␍␊ |
| ␉␉␉␉for( int param = 1; param < cmds.Length; param++ )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉parameters[ param - 1 ] = cmds[ param ];␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉ExecuteFunction( fs, parameters );␍␊ |
| ␉␉␉␉found = true;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return( found );␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉/// <summary>Execute a previously loaded external function</summary>␍␊ |
| ␉␉/// <param name="cmds">Command Line</param>␍␊ |
| ␉␉/// <param name="cmd">Pre-processed command</param>␍␊ |
| ␉␉/// <returns>true if command was handled by this function</returns>␍␊ |
| ␉␉private bool ExecuteExternalFunc( String[] cmds, String cmd )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉ExternalFuncObject␉efs;␍␊ |
| ␉␉␉bool found = false;␍␊ |
| ␍␊ |
| ␉␉␉// If Not Found, Try To Match Against External Functions␍␊ |
| ␉␉␉if( ms_externalFunctions.TryGetValue( cmd, out efs ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉string[] parameters = new string[ cmds.Length - 1 ];␍␊ |
| ␉␉␉␉List<object>␉cVarParams = new List<object>( 2 );␍␊ |
| ␉␉␉␉bool␉␉␉doInvoke = true;␍␊ |
| ␍␊ |
| ␉␉␉␉for( int param = 1; param < cmds.Length; param++ )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉try␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉cVarParams.Add( m_cVars[ cmds[ param ].ToLowerInvariant() ] );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉catch( Exception ex )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉doInvoke = false;␍␊ |
| ␉␉␉␉␉␉AddErrorToLog( "Exception while building parameters for external function: " + ex.Message );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉if( doInvoke )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉string ret = efs.Invoke( cVarParams.ToArray() );␍␊ |
| ␍␊ |
| ␉␉␉␉␉if( CVarModifiedEvent != null )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉foreach( CVar invokedVar in cVarParams )␍␊ |
| ␉␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉␉CVarModifiedEvent.Invoke( this,␍␊ |
| ␉␉␉␉␉␉␉␉␉new CVarModifiedEventArgs( invokedVar ) );␍␊ |
| ␉␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉if( String.IsNullOrWhiteSpace( ret ) == false )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉AddOutputToLog( ret );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉found = true;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return found;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉/// <summary>Execute a normal command</summary>␍␊ |
| ␉␉/// <param name="cs">Command Object</param>␍␊ |
| ␉␉/// <param name="cmds">Command Line</param>␍␊ |
| ␉␉/// <param name="cmd">Pre-processed command</param>␍␊ |
| ␉␉/// <returns>true if command was handled by this function</returns>␍␊ |
| ␉␉private bool ExecuteCommand( CmdObject cs, String[] cmds, String cmd )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉int parameters = ( cmds.Length - 1 );␍␊ |
| ␍␊ |
| ␉␉␉// Validate the parameter counts␍␊ |
| ␉␉␉if( ( cs.MinParameters != 0 ) && ( parameters < cs.MinParameters ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Not enough parameters specified for the " + cmd + " command." );␍␊ |
| ␉␉␉␉if( !String.IsNullOrEmpty( cs.CommandHelpDetailed ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉AddToLog( cs.CommandHelpDetailed );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉else if( ( cs.MaxParameters != 0 ) && ( parameters > cs.MaxParameters ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Too many parameters specified for the " + cmd + " command." );␍␊ |
| ␉␉␉␉if( !String.IsNullOrEmpty( cs.CommandHelpDetailed ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉AddToLog( cs.CommandHelpDetailed );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉else␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉// Fire The Delegate!␍␊ |
| ␉␉␉␉cs.TriggerEvent( cmds );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return( true );␍␊ |
| ␉␉}␍␊ |
| #endregion␍␊ |
| ␍␊ |
| ␉␉#region Parsing Helpers␍␊ |
| ␉␉/// <summary>Try to extract a double/Double value from the string</summary>␍␊ |
| ␉␉/// <param name="value">Value to parse</param>␍␊ |
| ␉␉/// <param name="parsedValue">out - receives the value parsed from the string</param>␍␊ |
| ␉␉/// <param name="errorIfParsingFails">Error msg to log if parsing fails</param>␍␊ |
| ␉␉/// <returns>True if parsed successfully, false otherwise</returns>␍␊ |
| ␉␉protected bool TryParseDouble( string value, out double parsedValue, string errorIfParsingFails )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( !Double.TryParse( value, out parsedValue ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( errorIfParsingFails );␍␊ |
| ␉␉␉␉return ( false );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return ( true );␍␊ |
| ␉␉}␍␊ |
| ␉␉/// <summary>Try to extract a float/Single value from the string</summary>␍␊ |
| ␉␉/// <param name="value">Value to parse</param>␍␊ |
| ␉␉/// <param name="parsedValue">out - receives the value parsed from the string</param>␍␊ |
| ␉␉/// <param name="errorIfParsingFails">Error msg to log if parsing fails</param>␍␊ |
| ␉␉/// <returns>True if parsed successfully, false otherwise</returns>␍␊ |
| ␉␉protected bool TryParseFloat( string value, out float parsedValue, string errorIfParsingFails )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( !Single.TryParse( value, out parsedValue ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( errorIfParsingFails );␍␊ |
| ␉␉␉␉return ( false );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return ( true );␍␊ |
| ␉␉}␍␊ |
| ␉␉/// <summary>Try to extract an int/Int32 value from the string</summary>␍␊ |
| ␉␉/// <param name="value">Value to parse</param>␍␊ |
| ␉␉/// <param name="parsedValue">out - receives the value parsed from the string</param>␍␊ |
| ␉␉/// <param name="errorIfParsingFails">Error msg to log if parsing fails</param>␍␊ |
| ␉␉/// <returns>True if parsed successfully, false otherwise</returns>␍␊ |
| ␉␉protected bool TryParseInt( string value, out int parsedValue, string errorIfParsingFails )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( !Int32.TryParse( value, out parsedValue ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( errorIfParsingFails );␍␊ |
| ␉␉␉␉return ( false );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return ( true );␍␊ |
| ␉␉}␍␊ |
| ␉␉#endregion␍␊ |
| ␉␉#region Standard Command Handlers␍␊ |
| void CommandConsoleBase_Help( string[] cmdLine )␍␊ |
| {␍␊ |
| if( cmdLine.Length == 1 )␍␊ |
| {␍␊ |
| StringBuilder sb = new StringBuilder( 512 );␍␊ |
| bool first = true;␍␊ |
| ␍␊ |
| sb.Append( "Commands: " );␍␊ |
| foreach( CmdObject cs in ms_commands.Values )␍␊ |
| {␍␊ |
| if( ( String.IsNullOrEmpty( cs.Command ) ) ||␍␊ |
| ( cs.IsSecret ) )␍␊ |
| {␍␊ |
| continue;␍␊ |
| }␍␊ |
| if( !first )␍␊ |
| {␍␊ |
| sb.Append( ", " );␍␊ |
| }␍␊ |
| first = false;␍␊ |
| sb.Append( cs.Command );␍␊ |
| }␍␊ |
| AddToLog( sb.ToString() );␍␊ |
| }␍␊ |
| else if( cmdLine.Length == 2 )␍␊ |
| {␍␊ |
| CmdObject␉cs;␍␊ |
| ␉␉␉␉String␉␉helpCommand = cmdLine[ 1 ];␍␊ |
| bool␉␉found = false;␍␊ |
| ␍␊ |
| ␉␉␉␉if( ms_commands.TryGetValue( helpCommand, out cs ) )␍␊ |
| {␍␊ |
| AddToLog( cs.Command + " - " + cs.CommandHelp );␍␊ |
| if( !String.IsNullOrEmpty( cs.CommandHelpDetailed ) )␍␊ |
| {␍␊ |
| AddToLog( cs.CommandHelpDetailed );␍␊ |
| }␍␊ |
| found = true;␍␊ |
| }␍␊ |
| if( !found )␍␊ |
| {␍␊ |
| AddErrorToLog( "Unknown command: " + helpCommand );␍␊ |
| }␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| AddErrorToLog( "Too many parameters specified. Try help or help <command>." );␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_Quit( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉// Stop -- no questions asked!␍␊ |
| ␉␉␉Game.Exit();␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_Exec( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉string␉scriptFile = cmdLine[ 1 ];␍␊ |
| ␍␊ |
| ␉␉␉if( !File.Exists( scriptFile ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Unable to execute " + scriptFile + ", the file cannot be found." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉string[] commandLines = File.ReadAllLines( cmdLine[ 1 ] );␍␊ |
| ␍␊ |
| ␉␉␉if( commandLines.Length == 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "File: " + scriptFile + " contains no lines." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉AddOutputToLog( "<--- Starting execution of commands from: " + scriptFile + " at " + DateTime.Now.ToString( "hh:mm:ss.fff" ) );␍␊ |
| ␍␊ |
| ␉␉␉bool␉bAddToHistory = commandLines[ 0 ].StartsWith( "!!" );␍␊ |
| ␉␉␉␍␊ |
| ␉␉␉foreach( string cmd in commandLines )␍␊ |
| {␍␊ |
| string cmdFixed = cmd.Trim();␍␊ |
| ␍␊ |
| AddToLog( "\x01-> " + cmd );␍␊ |
| if( cmdFixed.Length == 0 )␍␊ |
| {␍␊ |
| continue;␍␊ |
| }␍␊ |
| m_logStart = 0;␍␊ |
| m_commandLine = cmdFixed;␍␊ |
| ␉␉␉␉ExecuteCommandLine( bAddToHistory );␍␊ |
| m_commandLine = String.Empty;␍␊ |
| }␍␊ |
| AddOutputToLog( "<--- Ended execution of commands from: " + scriptFile + " at " + DateTime.Now.ToString( "hh:mm:ss.fff" ) );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_SaveLog( string[] cmdLine )␍␊ |
| {␍␊ |
| string[] lines = new String[ m_log.Count ];␍␊ |
| ␍␊ |
| m_log.CopyTo( lines );␍␊ |
| File.WriteAllLines( cmdLine[ 1 ], lines ); ␍␊ |
| AddOutputToLog( "<--- Log has been written to: " + cmdLine[ 1 ] );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_GC( string[] cmdLine )␍␊ |
| {␍␊ |
| AddOutputToLog( "Forcing Garbage Collection..." );␍␊ |
| DateTime now = DateTime.Now;␍␊ |
| ␍␊ |
| GC.Collect( 3, GCCollectionMode.Forced );␍␊ |
| GC.Collect( 2, GCCollectionMode.Forced );␍␊ |
| GC.Collect( 1, GCCollectionMode.Forced );␍␊ |
| ␍␊ |
| TimeSpan delta = DateTime.Now.Subtract( now );␍␊ |
| AddOutputToLog( "Garbage Collection took ~" + delta.TotalMilliseconds + "ms" );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_MemInfo( string[] cmdLine )␍␊ |
| {␍␊ |
| AddOutputToLog( "WSMem: " + Environment.WorkingSet );␍␊ |
| AddOutputToLog( "GCC1 : " + GC.CollectionCount( 0 ) );␍␊ |
| AddOutputToLog( "GCC2 : " + GC.CollectionCount( 1 ) );␍␊ |
| AddOutputToLog( "GCC3 : " + GC.CollectionCount( 2 ) );␍␊ |
| AddOutputToLog( "Total: " + GC.GetTotalMemory( false ) );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_ExFunc( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉if( m_exfunsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "ExFunc-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉string␉assembly = cmdLine[ 1 ];␍␊ |
| ␉␉␉string␉className = cmdLine[ 2 ];␍␊ |
| ␉␉␉string␉funcName = cmdLine[ 3 ];␍␊ |
| ␉␉␉bool␉isSecret = false;␍␊ |
| ␍␊ |
| ␉␉␉isSecret = ( ( cmdLine.Length == 5 ) && ␍␊ |
| ␉␉␉␉␉( cmdLine[ 4 ].ToLowerInvariant() == "secret" ) );␍␊ |
| ␉␉␉try␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉ExternalFuncObject␉efo = new ExternalFuncObject( assembly, className, funcName );␍␊ |
| ␍␊ |
| ␉␉␉␉efo.CommandLine = String.Format(␍␊ |
| ␉␉␉␉␉␉"exfunc {0} {1} {2}{3}",␍␊ |
| ␉␉␉␉␉␉assembly, className, funcName,␍␊ |
| ␉␉␉␉␉␉isSecret ? "secret" : String.Empty );␍␊ |
| ␉␉␉␉ms_externalFunctions.Add( funcName.ToLowerInvariant(), efo );␍␊ |
| ␉␉␉␉AddOutputToLog( String.Format( ␍␊ |
| ␉␉␉␉␉␉"Added external function {0}::{1}::{2}", ␍␊ |
| ␉␉␉␉␉␉assembly, className, funcName ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉catch( Exception ex )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( String.Format( ␍␊ |
| ␉␉␉␉␉␉"Unable to load/add {0}::{1}::{2} = {3}", ␍␊ |
| ␉␉␉␉␉␉assembly, className, funcName, ex.Message ) );␍␊ |
| ␉␉␉}␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_SystemInfo( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉AddOutputToLog( "Name : " + Environment.MachineName );␍␊ |
| ␉␉␉AddOutputToLog( "OSVer : " + Environment.OSVersion );␍␊ |
| ␉␉␉AddOutputToLog( "64BitOS : " + Environment.Is64BitOperatingSystem );␍␊ |
| ␉␉␉AddOutputToLog( "64BitProcess : " + Environment.Is64BitProcess );␍␊ |
| ␉␉␉AddOutputToLog( "PageFile : " + Environment.SystemPageSize );␍␊ |
| AddOutputToLog( "CPUs : " + Environment.ProcessorCount );␍␊ |
| ␉␉␉AddOutputToLog( "CLRVer : " + Environment.Version );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉/// <summary>Type converter helper - tries to convert the specified string to the specified type</summary>␍␊ |
| ␉␉/// <param name="type">The target type to convert to</param>␍␊ |
| ␉␉/// <param name="mystring">The source string to try to convert</param>␍␊ |
| ␉␉/// <returns>A reference to the successfully converted object, or null if conversion failed</returns>␍␊ |
| ␉␉public static object GetObjFromString( Type type, string mystring )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉var foo = TypeDescriptor.GetConverter( type );␍␊ |
| ␉␉␉␍␊ |
| ␉␉␉// Try To Convert From String To The Target Type Using Both Culture-Sensitive␍␊ |
| ␉␉␉// And The Culture-Insensitive Conversion. If Both Fail, Default To String␍␊ |
| ␉␉␉// Type.␍␊ |
| ␉␉␉try␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return ( foo.ConvertFromString( mystring ) );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉catch( Exception )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉try␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉return ( foo.ConvertFromInvariantString( mystring ) );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉catch( Exception )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉// Just Eat This One␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉// If Conversion Fails, Fall Back To String Type␍␊ |
| ␉␉␉return ( mystring );␍␊ |
| ␉␉}␍␊ |
| ␉␉␍␊ |
| ␉␉void CommandConsoleBase_CVar( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉CVar␉cvar = null;␍␊ |
| ␍␊ |
| ␉␉␉lock( m_cVars )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉string␉cvarName = cmdLine[ 1 ].ToLowerInvariant();␍␊ |
| ␉␉␉␉␍␊ |
| ␉␉␉␉if( m_cVars.TryGetValue( cvarName, out cvar ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉AddErrorToLog( "CVar " + cmdLine[ 1 ] + ␍␊ |
| ␉␉␉␉␉␉␉" already exists with a value of: " + cvar.Value ?? "(null" );␍␊ |
| ␉␉␉␉␉return;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉if( cmdLine.Length == 4 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉string␉typeName = cmdLine[ 2 ];␍␊ |
| ␉␉␉␉␉Type␉cvarType = Type.GetType( typeName, false );␍␊ |
| ␍␊ |
| ␉␉␉␉␉if( cvarType == null )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉cvarType = Type.GetType( "System." + typeName, false );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉if( cvarType == null )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉AddErrorToLog( "Cannot resolve type " + typeName + ␍␊ |
| ␉␉␉␉␉␉␉␉" -- try a fully qualified type name" );␍␊ |
| ␉␉␉␉␉␉return;␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉object␉objValue = GetObjFromString( cvarType, cmdLine[ 3 ] );␍␊ |
| ␍␊ |
| ␉␉␉␉␉cvar = new CVar( cvarName, objValue );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉else if( cmdLine.Length == 3 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉cvar = new CVar( cvarName, cmdLine[ 2 ] );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉else␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉cvar = new CVar( cvarName );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉m_cVars[ cvarName ] = cvar;␍␊ |
| ␍␊ |
| ␉␉␉␉AddOutputToLog( "CVar " + cvarName + " has been added" );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ( cvar != null ) && ( CVarModifiedEvent != null ) )␍␊ |
| ␉␉␉{␍␊ |
| CVarModifiedEvent.Invoke(this, new CVarModifiedEventArgs(cvar));␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␉␉void CommandConsoleBase_CVars( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉AddOutputToLog( "cvars:" );␍␊ |
| ␉␉␉lock( m_cVars )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉foreach( CVar cvar in m_cVars.Values )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉if( cvar.Value != null )␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉AddOutputToLog( String.Format( "{0} ({1}) = {2}",␍␊ |
| ␉␉␉␉␉␉␉␉cvar.Name, cvar.ValueType.ToString(), cvar.Value.ToString() ) );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉␉else␍␊ |
| ␉␉␉␉␉{␍␊ |
| ␉␉␉␉␉␉AddOutputToLog( cvar.Name + " (null) = null" );␍␊ |
| ␉␉␉␉␉}␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉}␍␊ |
| return;␍␊ |
| }␍␊ |
| ␉␉void CommandConsoleBase_ConsoleScale( string[] cmdLine )␍␊ |
| {␍␊ |
| if( cmdLine.Length < 2 )␍␊ |
| {␍␊ |
| AddOutputToLog( "Current ConsoleScale is: " + Scale );␍␊ |
| return;␍␊ |
| }␍␊ |
| float newScale;␍␊ |
| ␍␊ |
| ␉␉␉if( !TryParseFloat( cmdLine[ 1 ], out newScale, ␍␊ |
| ␉␉␉␉␉"Invalid scale - the specified value cannot be parsed" ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| if( ( newScale < 0.10f ) || ( newScale > 4.0f ) )␍␊ |
| {␍␊ |
| AddErrorToLog( "Invalid scale - must be between 0.10 (10%) and 4.0 (400%)" );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| Scale = newScale;␍␊ |
| m_stringHeight = Vector2.Zero;␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| ␉␉void CommandConsoleBase_ConsoleHeight( string[] cmdLine )␍␊ |
| {␍␊ |
| if( cmdLine.Length < 2 )␍␊ |
| {␍␊ |
| AddOutputToLog( "Current ConsoleHeight value is: " + m_height );␍␊ |
| return;␍␊ |
| }␍␊ |
| int newHeight;␍␊ |
| ␍␊ |
| ␉␉␉if( !TryParseInt( cmdLine[ 1 ], out newHeight, ␍␊ |
| ␉␉␉␉␉"Invalid height - the specified value cannot be parsed" ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| if( ( newHeight < 100 ) || ( newHeight > ( GraphicsDevice.Viewport.Height - 100 ) ) )␍␊ |
| {␍␊ |
| AddErrorToLog( "Invalid height - must be between 100 and " + ( GraphicsDevice.Viewport.Height - 100 ) );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| m_height = newHeight;␍␊ |
| m_stringHeight = Vector2.Zero;␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_Sleep( string[] cmdLine )␍␊ |
| {␍␊ |
| int sleepms;␍␊ |
| ␉␉␉␍␊ |
| ␉␉␉if( !TryParseInt( cmdLine[ 1 ], out sleepms, ␍␊ |
| ␉␉␉␉␉"Invalid sleep duration - the specified value cannot be parsed" ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| Thread.Sleep( sleepms );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_LogLimit( string[] cmdLine )␍␊ |
| {␍␊ |
| if( cmdLine.Length < 2 )␍␊ |
| {␍␊ |
| AddOutputToLog( "Current LogLimit value is: " + m_logLimit );␍␊ |
| return;␍␊ |
| }␍␊ |
| int lines;␍␊ |
| ␍␊ |
| ␉␉␉if( !TryParseInt( cmdLine[ 1 ], out lines,␍␊ |
| ␉␉␉␉␉"Invalid line count - the specified value cannot be parsed" ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ( lines < 32 ) || ( lines > 10240 ) )␍␊ |
| {␍␊ |
| AddErrorToLog( "Invalid line count - must be between 32 and 10240" );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| m_logLimit = lines;␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_Close( string[] cmdLine )␍␊ |
| {␍␊ |
| Active = false;␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| void CommandConsoleBase_ShadowLog( string[] cmdLine )␍␊ |
| {␍␊ |
| if( cmdLine.Length == 1 )␍␊ |
| {␍␊ |
| if( m_logShadowEnabled )␍␊ |
| {␍␊ |
| AddOutputToLog( "Log shadowing is enabled, writing to: " + m_logShadowFilePath );␍␊ |
| m_logShadowFile.Flush();␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| AddOutputToLog( "Log shadowing is disabled." );␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| string filePath = cmdLine[ 1 ];␍␊ |
| bool truncate = false;␍␊ |
| ␍␊ |
| if( cmdLine.Length == 3 )␍␊ |
| {␍␊ |
| if( ( bool.TryParse( cmdLine[ 2 ], out truncate ) ) && ( truncate ) )␍␊ |
| {␍␊ |
| File.Delete( cmdLine[ 2 ] );␍␊ |
| }␍␊ |
| }␍␊ |
| m_logShadowFile = new StreamWriter( filePath, !truncate, Encoding.ASCII );␍␊ |
| m_logShadowFilePath = filePath;␍␊ |
| m_logShadowEnabled = true;␍␊ |
| ␍␊ |
| AddOutputToLog( "Log shadowing has been enabled." );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_NoShadowLog( string[] cmdLine )␍␊ |
| {␍␊ |
| if( m_logShadowEnabled )␍␊ |
| {␍␊ |
| m_logShadowFile.Close();␍␊ |
| m_logShadowFile = null;␍␊ |
| m_logShadowEnabled = false;␍␊ |
| AddOutputToLog( "Log shadowing has been disabled." );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| AddOutputToLog( "Log shadowing was not enabled." );␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| void CommandConsoleBase_Clear( string[] cmdLine )␍␊ |
| {␍␊ |
| m_log.Clear();␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_NoFunctions( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉m_functionsLocked = true;␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_NoBindings( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉m_bindingsLocked = true;␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_NoExFunctions( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉m_exfunsLocked = true;␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_Bindings( string[] cmdLine )␍␊ |
| {␍␊ |
| if( ms_bindings.Count == 0 )␍␊ |
| {␍␊ |
| AddOutputToLog( "No bindings have been set." );␍␊ |
| ␉␉␉␉return;␍␊ |
| }␍␊ |
| ␉␉␉StringBuilder sb = new StringBuilder( 255 );␍␊ |
| ␉␉␉bool first = true;␍␊ |
| ␍␊ |
| ␉␉␉sb.Append( "Bindings: " );␍␊ |
| ␉␉␉foreach( BindingObject bs in ms_bindings )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( !first )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉sb.Append( ", " );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉first = false;␍␊ |
| ␉␉␉␉sb.Append( bs.ToString() );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉AddToLog( sb.ToString() );␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_ResetBindings( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( m_bindingsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Binding-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_bindings.Count == 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddOutputToLog( "No bindings have been set." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉ms_bindings.Clear();␍␊ |
| ␍␊ |
| ␉␉␉AddOutputToLog( "All bindings have been cleared." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_ResetFunctions( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( m_functionsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Function-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_functions.Count == 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddOutputToLog( "No functions have been created." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉ms_functions.Clear();␍␊ |
| ␍␊ |
| ␉␉␉AddOutputToLog( "All functions have been cleared." );␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_ResetExFuncs( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( m_exfunsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "ExFunc-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_externalFunctions.Count == 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddOutputToLog( "No external functions have been added." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉ms_externalFunctions.Clear();␍␊ |
| ␍␊ |
| ␉␉␉AddOutputToLog( "All external functions have been cleared." );␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_ExFuncs( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( m_exfunsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "ExFunc-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_externalFunctions.Count == 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddOutputToLog( "No external functions have been added." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉StringBuilder sb = new StringBuilder( 255 );␍␊ |
| ␉␉␉bool first = true;␍␊ |
| ␍␊ |
| ␉␉␉sb.Append( "ExFuncs: " );␍␊ |
| ␉␉␉foreach( ExternalFuncObject ef in ms_externalFunctions.Values )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( !first )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉sb.Append( ", " );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉first = false;␍␊ |
| ␉␉␉␉sb.Append( ef.ToString() );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉AddToLog( sb.ToString() );␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_Functions( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉if( ms_functions.Count == 0 )␍␊ |
| {␍␊ |
| AddOutputToLog( "No functions have been created." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉StringBuilder sb = new StringBuilder( 255 );␍␊ |
| ␉␉␉bool first = true;␍␊ |
| ␍␊ |
| ␉␉␉sb.Append( "Functions: " );␍␊ |
| ␉␉␉foreach( FuncObject fs in ms_functions.Values )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( !first )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉sb.Append( ", " );␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉first = false;␍␊ |
| ␉␉␉␉sb.Append( fs.ToString() );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉AddToLog( sb.ToString() );␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉private List<string> GetAllExFuncs()␍␊ |
| ␉␉{␍␊ |
| ␉␉␉List<string> exFuncs = new List<string>( ms_externalFunctions.Count );␍␊ |
| ␍␊ |
| ␉␉␉foreach( ExternalFuncObject efo in ms_externalFunctions.Values )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉exFuncs.Add( efo.CommandLine );␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉return( exFuncs );␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉private List<string> GetAllFunctions()␍␊ |
| {␍␊ |
| List<string> functions = new List<string>( ms_functions.Count );␍␊ |
| ␍␊ |
| foreach( FuncObject fs in ms_functions.Values )␍␊ |
| {␍␊ |
| string fnText = "function " + ␍␊ |
| ␉␉␉␉␉␉␉fs.ToString().Replace( "-> ", String.Empty );␍␊ |
| ␍␊ |
| ␉␉␉␉//foreach( string fnline in fs.FunctionImpl )␍␊ |
| ␉␉␉␉//{␍␊ |
| ␉␉␉␉// fnText += fnline;␍␊ |
| ␉␉␉␉// fnText += ";";␍␊ |
| ␉␉␉␉//}␍␊ |
| ␉␉␉␉//functions.Add( "function " + fs.Function + " " + fnText );␍␊ |
| ␉␉␉␉functions.Add( fnText );␍␊ |
| }␍␊ |
| return( functions );␍␊ |
| }␍␊ |
| ␍␊ |
| private List< string > GetAllBindings()␍␊ |
| {␍␊ |
| List<string> bindings = new List<string>( ms_bindings.Count );␍␊ |
| ␍␊ |
| foreach( BindingObject bo in ms_bindings )␍␊ |
| {␍␊ |
| bindings.Add( "bind " + bo.GetModifierString() + bo._key + " " + bo._text );␍␊ |
| }␍␊ |
| return( bindings );␍␊ |
| }␍␊ |
| ␍␊ |
| void CommandConsoleBase_ExportBindings( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉if( m_bindingsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Binding-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_bindings.Count == 0 )␍␊ |
| {␍␊ |
| AddErrorToLog( "No bindings have been set." );␍␊ |
| return;␍␊ |
| }␍␊ |
| string filePath = cmdLine[ 1 ];␍␊ |
| ␍␊ |
| File.WriteAllLines( filePath, GetAllBindings().ToArray() );␍␊ |
| ␍␊ |
| AddOutputToLog( "Bindings have been saved to: " + filePath );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| void CommandConsoleBase_ExportFunctions( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉if( m_functionsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Function-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_functions.Count == 0 )␍␊ |
| {␍␊ |
| AddErrorToLog( "No functions have been set." );␍␊ |
| return;␍␊ |
| }␍␊ |
| string filePath = cmdLine[ 1 ];␍␊ |
| ␍␊ |
| File.WriteAllLines( filePath, GetAllFunctions().ToArray() );␍␊ |
| AddOutputToLog( "Functions have been saved to: " + filePath );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| ␉␉void CommandConsoleBase_ExportExFuncs( string[] cmdLine )␍␊ |
| ␉␉{␍␊ |
| ␉␉␉if( m_exfunsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "ExFunc-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉if( ms_externalFunctions.Count == 0 )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "No ExFuncs have been set." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉string filePath = cmdLine[ 1 ];␍␊ |
| ␍␊ |
| ␉␉␉File.WriteAllLines( filePath, GetAllExFuncs().ToArray() );␍␊ |
| ␉␉␉AddOutputToLog( "ExFunc defs have been saved to: " + filePath );␍␊ |
| ␍␊ |
| ␉␉␉return;␍␊ |
| ␉␉}␍␊ |
| ␍␊ |
| ␉␉/// <summary>Special command handler for ExportState command</summary>␍␊ |
| ␉␉/// <param name="cmdLine">The command line for the command</param>␍␊ |
| ␉␉/// <remarks>This one is protected virtual so additional state can be stored if necessary by derived classes</remarks>␍␊ |
| ␉␉protected virtual void CommandConsoleBase_ExportState( string[] cmdLine )␍␊ |
| {␍␊ |
| string filePath = cmdLine[ 1 ];␍␊ |
| StreamWriter outFile = new StreamWriter( filePath, false, Encoding.ASCII );␍␊ |
| ␍␊ |
| if( ms_bindings.Count > 0 )␍␊ |
| {␍␊ |
| lock( ms_bindings )␍␊ |
| {␍␊ |
| List<string> bindings = GetAllBindings();␍␊ |
| ␍␊ |
| foreach( string line in bindings )␍␊ |
| {␍␊ |
| outFile.WriteLine( line );␍␊ |
| }␍␊ |
| }␍␊ |
| }␍␊ |
| if( ms_functions.Count > 0 )␍␊ |
| {␍␊ |
| lock( ms_functions )␍␊ |
| {␍␊ |
| List<string> functions = GetAllFunctions();␍␊ |
| ␍␊ |
| foreach( string line in functions )␍␊ |
| {␍␊ |
| outFile.WriteLine( line );␍␊ |
| }␍␊ |
| }␍␊ |
| }␍␊ |
| outFile.Write( "consoleheight " + m_height );␍␊ |
| outFile.Write( "consolescale " + Scale );␍␊ |
| outFile.Write( "loglimit " + m_logLimit );␍␊ |
| outFile.Close();␍␊ |
| outFile.Dispose();␍␊ |
| ␍␊ |
| ␍␊ |
| AddOutputToLog( "State has been saved to: " + filePath );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| void CommandConsoleBase_UnBind( string[] cmdLine )␍␊ |
| {␍␊ |
| string bindString = cmdLine[ 1 ];␍␊ |
| Keys bindKey = Keys.None;␍␊ |
| BindingObject.EModifier bindKeyModifiers = BindingObject.EModifier.None;␍␊ |
| bool parsed = GetKeyBindingInfo( bindString, ref bindKeyModifiers, ref bindKey );␍␊ |
| ␍␊ |
| if( !parsed )␍␊ |
| {␍␊ |
| AddErrorToLog( String.Format( "\"{0}\" was not understood as a proper binding string.", bindString ) );␍␊ |
| return;␍␊ |
| }␍␊ |
| foreach( BindingObject bs in ms_bindings )␍␊ |
| {␍␊ |
| if( ( bindKey == bs._key ) && ( bindKeyModifiers == bs._modifierKeys ) )␍␊ |
| {␍␊ |
| ms_bindings.Remove( bs );␍␊ |
| AddOutputToLog( bs.GetModifierString() + " has been unbound." );␍␊ |
| return;␍␊ |
| }␍␊ |
| }␍␊ |
| AddErrorToLog( bindString + " is not bound." );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| void CommandConsoleBase_Bind( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉if( m_bindingsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Binding-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉string bindString = cmdLine[ 1 ];␍␊ |
| BindingObject.EModifier bindKeyModifiers = BindingObject.EModifier.None;␍␊ |
| Keys bindKey = Keys.None;␍␊ |
| bool parsed = GetKeyBindingInfo( bindString, ref bindKeyModifiers, ref bindKey );␍␊ |
| ␍␊ |
| if( !parsed )␍␊ |
| {␍␊ |
| AddErrorToLog( String.Format( "\"{0}\" was not understood as a proper binding string.", bindString ) );␍␊ |
| return;␍␊ |
| }␍␊ |
| foreach( BindingObject bs in ms_bindings )␍␊ |
| {␍␊ |
| if( ( bindKey == bs._key ) && ( bindKeyModifiers == bs._modifierKeys ) )␍␊ |
| {␍␊ |
| AddErrorToLog( String.Format( "{0} is already bound.", bindString ) );␍␊ |
| return;␍␊ |
| }␍␊ |
| }␍␊ |
| BindingObject newBS = new BindingObject();␍␊ |
| string cmds = String.Empty;␍␊ |
| ␍␊ |
| for( int cmd = 2; cmd < cmdLine.Length; cmd++ )␍␊ |
| {␍␊ |
| cmds += cmdLine[ cmd ];␍␊ |
| cmds += " ";␍␊ |
| }␍␊ |
| newBS._key = bindKey;␍␊ |
| newBS._modifierKeys = bindKeyModifiers;␍␊ |
| newBS._text = cmds;␍␊ |
| ␍␊ |
| ms_bindings.Add( newBS );␍␊ |
| ␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| void CommandConsoleBase_Function( string[] cmdLine )␍␊ |
| {␍␊ |
| ␉␉␉if( m_functionsLocked )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Function-related actions have been disabled." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉string cmds = String.Empty;␍␊ |
| ␉␉␉bool isSecret = false;␍␊ |
| ␍␊ |
| ␉␉␉// This Is A Bit Heavyweight, Building A command Line And Then␍␊ |
| ␉␉␉// Breaking It Apart Again, But It Seemed Easier And Less ␍␊ |
| ␉␉␉// Complicated Than Trying To Do It All In One Shot␍␊ |
| ␉␉␉//␍␊ |
| ␉␉␉// Build Command Line Minus Command And Secret Option␍␊ |
| ␉␉␉for( int cmd = 2; cmd < cmdLine.Length; cmd++ )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉if( ( cmd == 2 ) && ( cmdLine[ cmd ].ToLowerInvariant() == "secret" ) )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉isSecret = true;␍␊ |
| ␉␉␉␉␉continue;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉cmds += cmdLine[ cmd ];␍␊ |
| cmds += " ";␍␊ |
| }␍␊ |
| ␉␉␉if( String.IsNullOrWhiteSpace( cmds ) )␍␊ |
| ␉␉␉{␍␊ |
| ␉␉␉␉AddErrorToLog( "Function contains no code to execute." );␍␊ |
| ␉␉␉␉return;␍␊ |
| ␉␉␉}␍␊ |
| ␉␉␉string[] ft = cmds.Split( ';' );␍␊ |
| ␉␉␉bool␉hasCode = false;␍␊ |
| ␍␊ |
| ␉␉␉// Reassemble Command Lines From Tokens␍␊ |
| ␉␉␉for( int line = 0; line <ft.Length; line++ )␍␊ |
| {␍␊ |
| ␉␉␉␉ft[ line ] = ft[ line ].Trim().ToLowerInvariant();␍␊ |
| ␉␉␉␉if( ft[ line ].Length == 0 )␍␊ |
| ␉␉␉␉{␍␊ |
| ␉␉␉␉␉continue;␍␊ |
| ␉␉␉␉}␍␊ |
| ␉␉␉␉hasCode = true;␍␊ |
| }␍␊ |
| ␉␉␉if( !hasCode )␍␊ |
| {␍␊ |
| AddErrorToLog( "Function contains no code to execute." );␍␊ |
| }␍␊ |
| else␍␊ |
| {␍␊ |
| ␉␉␉␉FuncObject newFN = new FuncObject( cmdLine[ 1 ], ft );␍␊ |
| ␍␊ |
| ␉␉␉␉newFN.IsSecret = isSecret;␍␊ |
| ␉␉␉␉AddFunction( newFN );␍␊ |
| }␍␊ |
| return;␍␊ |
| }␍␊ |
| ␍␊ |
| #endregion␍␊ |
| }␍␊ |
| }␍␊ |
| #endif |