2012-05-28 22:01:03 +00:00
|
|
|
|
#if WINDOWS
|
|
|
|
|
#region Using Statements
|
|
|
|
|
|
2012-05-26 23:26:46 +00:00
|
|
|
|
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;
|
2012-05-26 23:36:11 +00:00
|
|
|
|
using XNACC.BaseTypes;
|
2012-05-26 23:26:46 +00:00
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
#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?
|
2012-05-28 22:01:03 +00:00
|
|
|
|
|
2012-05-26 23:26:46 +00:00
|
|
|
|
/// <summary>Namespace that contains code related to the XNACC (CommandConsole) component</summary>
|
2012-05-26 23:36:11 +00:00
|
|
|
|
namespace XNACC.Console
|
2012-05-26 23:26:46 +00:00
|
|
|
|
{
|
|
|
|
|
/// <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>
|
2012-05-29 21:43:50 +00:00
|
|
|
|
protected SortedDictionary<string,CmdObject> ms_commands = new SortedDictionary<string, CmdObject>();
|
2012-05-26 23:26:46 +00:00
|
|
|
|
/// <summary>Collection Of function Objects.</summary>
|
2012-05-29 21:43:50 +00:00
|
|
|
|
protected SortedDictionary<string, FuncObject> ms_functions = new SortedDictionary<string, FuncObject>();
|
2012-05-26 23:26:46 +00:00
|
|
|
|
/// <summary>Collection Of External Functions.</summary>
|
2012-05-29 21:43:50 +00:00
|
|
|
|
protected SortedDictionary<string, ExternalFuncObject> ms_externalFunctions = new SortedDictionary<string, ExternalFuncObject>();
|
2012-05-26 23:26:46 +00:00
|
|
|
|
/// <summary>Collection Of Binding Objects.</summary>
|
2012-05-29 21:43:50 +00:00
|
|
|
|
protected List<BindingObject> ms_bindings = new List<BindingObject>( 8 );
|
2012-05-26 23:26:46 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>Colleciton Of Partial Command Matches</summary>
|
2012-05-29 21:43:50 +00:00
|
|
|
|
protected List<string> ms_partialCmdMatches = new List<string>( 8 );
|
2012-05-26 23:26:46 +00:00
|
|
|
|
/// <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>
|
2012-05-29 21:43:50 +00:00
|
|
|
|
protected static List<string> m_log = new List<string>( 256 );
|
2012-05-26 23:26:46 +00:00
|
|
|
|
#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>
|
2012-05-29 21:43:50 +00:00
|
|
|
|
protected static List<string> m_cmdHistory = new List<string>( 128 );
|
2012-05-26 23:26:46 +00:00
|
|
|
|
/// <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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-29 21:43:50 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>Indicates if the console is active or not</summary>
|
|
|
|
|
public static bool Active
|
2012-05-26 23:26:46 +00:00
|
|
|
|
{
|
|
|
|
|
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
|
2012-05-28 22:01:03 +00:00
|
|
|
|
/// <summary>Load content for this component</summary>
|
2012-05-26 23:26:46 +00:00
|
|
|
|
/// <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
|
2012-05-28 22:01:03 +00:00
|
|
|
|
|
2012-05-26 23:26:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|