+ Reply to Thread
Results 1 to 10 of 10

  Click here to go to the first staff post in this thread.   Thread: Command Interpreter

Hybrid View

  1. #1
    Join Date
    Oct 2002
    Location
    Intangible Space
    Posts
    3,742
    Thanks
    12
    Thanked 41 Times in 14 Posts
    Blog Entries
    2
    Rep Power
    5

    Command Interpreter

    Since people have recently been releasing various tools/libraries to help with hack development. . . why not throw another interpreter in the mix. The most interesting thing of this is probably the regex - other than that, its not that different from what people have done before. . .

    Interpreter.cpp
    Code:
    /*
    Game-Deception Property License 1.0
    2005-2008 Game-Deception( www.gamedeception.net )
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
    PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR Copyright   HOLDERS BE LIABLE
    FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN REGARD TO THE SOFTWARE.
    
    Permission is hereby granted, free of charge, to any person obtaining a copy of this
    software and associated documentation files (the "Software"), to deal in the Software
    without restriction, including without limitation the rights to use, copy, modify,
    merge and publish copies of the Software, and to permit persons to whom the Software
    is furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all copies
    or substantial portions of the Software.
    
    The Software must be redistributed free of charge to third parties.
    */
    /***************************************\
    \			 HackTools Library			/
    /			 By Absolution				\
    \				Source					/
    /		    Version 1.0.0.171			\
    \										/
    /		© Absolution 2003	- 2010		\
    \	  http://www.game-deception.org		/
    /***************************************/
    
    #include "../Includes.h"
    
    //========================================================================================
    // Interpreter
    //----------------------------------------------------------------------------------------
    void aui::Interpreter::AddCommand( const std::string &commandName, const commandType_t command )
    {
    	commandList[ commandName ] = command;
    }
    
    //----------------------------------------------------------------------------------------
    bool aui::Interpreter::Execute( const std::string &rawCommand )
    {
    	argumentDeque.clear();
    
    	std::string::const_iterator cSartIter = rawCommand.begin();
    	std::string::const_iterator cEndIter = rawCommand.end();
    	std::tr1::regex pattern( "(\")(.+?)\\1|(\\S+)" );
    
    	std::tr1::smatch res;
    	while( regex_search( cSartIter, cEndIter, res, pattern ) )
    	{
    		if( res[2].matched )
    		{
    			argumentDeque.push_back( res[2].str() );
    			cSartIter = res[2].second;
    			++cSartIter;
    		}
    		else if( res[3].matched )
    		{
    			argumentDeque.push_back( res[3].str() );
    			cSartIter = res[3].second;
    		}
    		else
    			break;
    	}
    	if( !argumentDeque.empty() )
    	{
    		return ExecuteCommand();
    	}
    	return false;
    }
    
    //----------------------------------------------------------------------------------------
    bool aui::Interpreter::ExecuteCommand() const
    {
    	commandList_t::const_iterator cCommandIter = commandList.find( argumentDeque.at( COMMAND_POSITION ) );
    	if( cCommandIter != commandList.end() )
    	{
    		cCommandIter->second();
    		return true;
    	}
    	return false;
    }
    
    //----------------------------------------------------------------------------------------
    size_t aui::Interpreter::ArgumentSize() const
    {
    	return argumentDeque.size();
    }
    
    //----------------------------------------------------------------------------------------
    std::string aui::Interpreter::Argument( const std::size_t index ) const
    {
    	return argumentDeque.at( index );
    }
    Interpreter.h
    Code:
    namespace aui
    {
    	class Interpreter
    	{
    	public:
    		enum { COMMAND_POSITION = 0 };
    		typedef void ( *commandType_t )();
    		typedef std::map< std::string, commandType_t > commandList_t;
    		typedef std::deque< std::string > argumentDeque_t;
    
    		void AddCommand( const std::string &commandName, const commandType_t command );
    
    		bool Execute( const std::string &rawCommand );
    
    		std::size_t ArgumentSize() const;	// argument size
    
    		template< class T >
    		void Argument( const std::size_t index, T &value ) const
    		{
    			std::istringstream buf( argumentDeque.at( index ) );
    
    			buf >> value;
    
    			if( buf.fail() )
    			{
    
    			}
    		}
    
    		template< class T, class Default >
    		void ArgumentOrDefault( const std::size_t index, T &value, const Default &defaultValue ) const
    		{
    			try
    			{
    				std::istringstream buf( argumentDeque.at( index ) );
    
    				buf >> value;
    
    				if( buf.fail() )
    				{
    
    				}
    			}
    			catch ( std::out_of_range )
    			{
    				value = defaultValue;
    			}
    		}
    
    		std::string Argument( const std::size_t index ) const;
    
    	protected:
    		bool ExecuteCommand() const;
    
    		argumentDeque_t argumentDeque;
    		commandList_t commandList;
    	};
    }
    Functionality
    This will function just like typing commands into a linux shell/windows cmd prompt. Quotes will group spaced characters/words together.

    Example Program
    Code:
    Interpreter interpreter;
    
    void test()
    {
    	cout << "blah" << endl;
    	string test = interpreter.Argument( 1 );
    	int i = 0;
    	interpreter.Argument( 3, &i );
    	interpreter.ArgumentOrDefault( 99, &i, 300 );
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	interpreter.AddCommand( "test", &test );
    
    	string command = "test BALLS BALS2 3 4 5 LOLOL \"hey thar\"";
    	interpreter.Execute( command );
    
    	while( true )
    	{
    		string keyIn;
    		cin >> keyIn;
    		interpreter.Execute( keyIn );
    	}
    	return 0;
    }
    C# Version
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    
    namespace Lab_4
    {
        class Interpreter
        {
            // Interpreter - basically calls a function based on a string, arguments to the call are available to the function
            // via the instance of this class (argumentList)
            public const int COMMAND_POSITION = 0;
    
            public delegate void commandType_t();
            Dictionary<string, commandType_t> commandList = new Dictionary<string, commandType_t>();
            List<string> argumentList = new List<string>();
    
            public void AddCommand( string commandName, commandType_t command )
            {
    	        commandList[commandName] = command;
            }
    
            public bool Execute( string rawCommand )
            {
                argumentList.Clear();
    
                const int quotesGroup = 2, nonQuotesGroup = 3;
                Regex regex = new Regex( "\\s+(\")(.+?)\\1|(\\S+)" );
                MatchCollection matches = regex.Matches( rawCommand );
    
                for( int i = 0; i != matches.Count; ++i )
                {
                    Group QuotesGroup = matches[i].Groups[quotesGroup];
                    Group NonQuotesGroup = matches[i].Groups[nonQuotesGroup];
                    if( QuotesGroup.Success )
                        argumentList.Add( QuotesGroup.Value );
                    else if( NonQuotesGroup.Success )
                        argumentList.Add( NonQuotesGroup.Value );
                    else
                        break;
                }
    
                if( argumentList.Count != 0 )
    	        {
    		        return ExecuteCommand();
    	        }
    	        return false;
            }
    
            bool ExecuteCommand()
            {
    	        commandType_t command = null;
                if( commandList.TryGetValue( argumentList[COMMAND_POSITION], out command ) )
                {
                    command();
                    return true;
                }
    	        return false;
            }
    
            public int ArgumentSize()
            {
                return argumentList.Count;
            }
    
            public string Argument( int index )
            {
                return argumentList[index];
            }
        }
    }
    Last edited by Absolution; 04-27-2010 at 09:04 AM.

    People are like the stars, there are bright ones, and those that are dim.

    Blog of Random Stuff

  2. #2
    Join Date
    Jan 2008
    Location
    Kynox's sister's bedroom
    Posts
    811
    Thanks
    1
    Thanked 5 Times in 4 Posts
    Rep Power
    80

    Re: Command Interpreter

    You shouldn't define empty constructors/destructors/etc unless it's necessary. The compiler with generate one for you if you don't declare one so not only is it redundant it's confusing.

    Also, if you're working in C++ you should avoid C style strings if you can in favour of the C++ solution (std::string).

    I notice you use a string for execute but not addcommand. Oh btw, in your execute prototype:
    bool Execute( const std::string rawCommand ) const; <-- Bad
    bool Execute( const std::string& rawCommand ) const; <-- Good

    You're not modifying the string so you should pass by reference-to-const. Most compilers should optimize out the temporary regardless but still, it's good practice. And oh, because the former is pass by value the const is redundant and confusing. It's an implementation detail not an interface detail.

    Btw, what's with the lack of handling of the conversion failing in your Argument templates? Seems silly to have an empty block.

    I personally use Lua as my command interpreter but still, thanks for the share.

    P.S. You shouldn't declare global objects like that, it's not thread safe.

    EDIT:

    Just notice you're using "if (blah.size())". Just fyi "if (!blah.empty())" is potentially of higher performance and never of lower performance, so that's another one of those things you should just get into the habit of doing. Reason being is that for some containers it's difficult to know the size at any given time so it may need to be calculated every time the function is called. Not an issue in this particular case, but again, its a good habit to get into.

  3. #3
    Join Date
    Oct 2002
    Location
    Intangible Space
    Posts
    3,742
    Thanks
    12
    Thanked 41 Times in 14 Posts
    Blog Entries
    2
    Rep Power
    5

    Re: Command Interpreter

    Quote Originally Posted by Chazwazza View Post
    You shouldn't define empty constructors/destructors/etc unless it's necessary. The compiler with generate one for you if you don't declare one so not only is it redundant it's confusing.

    Also, if you're working in C++ you should avoid C style strings if you can in favour of the C++ solution (std::string).

    I notice you use a string for execute but not addcommand. Oh btw, in your execute prototype:
    bool Execute( const std::string rawCommand ) const; <-- Bad
    bool Execute( const std::string& rawCommand ) const; <-- Good

    You're not modifying the string so you should pass by reference-to-const. Most compilers should optimize out the temporary regardless but still, it's good practice. And oh, because the former is pass by value the const is redundant and confusing. It's an implementation detail not an interface detail.

    Btw, what's with the lack of handling of the conversion failing in your Argument templates? Seems silly to have an empty block.

    I personally use Lua as my command interpreter but still, thanks for the share.

    P.S. You shouldn't declare global objects like that, it's not thread safe.

    EDIT:

    Just notice you're using "if (blah.size())". Just fyi "if (!blah.empty())" is potentially of higher performance and never of lower performance, so that's another one of those things you should just get into the habit of doing. Reason being is that for some containers it's difficult to know the size at any given time so it may need to be calculated every time the function is called. Not an issue in this particular case, but again, its a good habit to get into.
    Thanks for the input. The constructors were in there and had a use at some point and I just never took them out - removed.

    As for the failure handling, I decided to leave that out on purpose because I figured everyone would want to handle it a bit differently. It is there for more of a placeholder.

    Yup, globals are bad news - I don't have them in my actual implementation :p.

    As for the c-style strings, I figured that no one would/should ever try to add some sort of command who's name is refferenced from any type of string object but would rather just be in quotes. I just assumed it'd be faster using c-style strings than creating an std::string object on the stack and passing it by refference. Is that not the case?

    Good call on the if( blah.size() ) and Interpreter::Execute( const std::string &rawCommand ) - changed.


    Thanks for the feedback.
    Last edited by Absolution; 10-01-2009 at 11:39 AM.

    People are like the stars, there are bright ones, and those that are dim.

    Blog of Random Stuff

  4. #4
    Join Date
    Sep 2008
    Location
    USA
    Posts
    573
    Thanks
    62
    Thanked 22 Times in 18 Posts
    Blog Entries
    1
    Rep Power
    45

    Re: Command Interpreter

    Quote Originally Posted by Absolution View Post
    I just assumed it'd be faster using c-style strings than creating an std::string object on the stack and passing it by reference.
    Passing a c-string by reference will be the fastest you can ever get.



    ...But in perspective, it won't matter.
    how can i use this code? Will I must compiling it?

  5. #5
    Join Date
    Jan 2008
    Location
    Kynox's sister's bedroom
    Posts
    811
    Thanks
    1
    Thanked 5 Times in 4 Posts
    Rep Power
    80

    Re: Command Interpreter

    Quote Originally Posted by Absolution View Post
    Thanks for the input. The constructors were in there and had a use at some point and I just never took them out - removed.

    As for the failure handling, I decided to leave that out on purpose because I figured everyone would want to handle it a bit differently. It is there for more of a placeholder.

    Yup, globals are bad news - I don't have them in my actual implementation :p.

    As for the c-style strings, I figured that no one would/should ever try to add some sort of command who's name is refferenced from any type of string object but would rather just be in quotes. I just assumed it'd be faster using c-style strings than creating an std::string object on the stack and passing it by refference. Is that not the case?

    Good call on the if( blah.size() ) and Interpreter::Execute( const std::string &rawCommand ) - changed.


    Thanks for the feedback.
    Your map uses a C++ string, you're taking a C style string in your function.

    What that means is that a new string needs to be constructed to fill the key in the map.

    If you were to have your function take an std::string as reference-to-const then the copy constructor would be called instead of the regular constructor. For certain implementations this can be a faster operation. Not to mention the fact that you're already dealing with STL strings so why force your users to do conversions unnecessarily.

    I know what you mean (i.e. use of a string literal), but in that particular case the overhead is null because a string object needs to be constructed for the map anyway. No unnecessary temporary is created due to the use of a reference, so I can't really see a downside to using an STL string in that functions parameters.



    EDIT:

    On the note of references, why are your templates taking the value to modify by pointer rather than reference? As I say below, there's no such thing as a null-reference, and that argument should never be null, so a reference makes more sense, and is also safer.

    Quote Originally Posted by syntroniks View Post
    Passing a c-string by reference will be the fastest you can ever get.



    ...But in perspective, it won't matter.
    References are not pointers, and pointers are not references.

    Just wanted to make that clear.

    How they are IMPLEMENTED is something entirely different, but as far as the language goes there is a distinct difference. A reference IS THE OBJECT. It's not a 'pointer' to it. Also, there is no such thing as a 'null-reference', so they are quite different.

  6. #6
    Join Date
    Oct 2002
    Location
    Intangible Space
    Posts
    3,742
    Thanks
    12
    Thanked 41 Times in 14 Posts
    Blog Entries
    2
    Rep Power
    5

    Re: Command Interpreter

    Quote Originally Posted by Chazwazza View Post
    Your map uses a C++ string, you're taking a C style string in your function.

    What that means is that a new string needs to be constructed to fill the key in the map.
    Ya, I actually just realized that before your post.


    And the pointers in the argument functions, ya - again, good suggestion. Reason they are pointers is because the code is a year old and at the time, I [poorly] just threw pointers at everything. Fixed.


    The main reason I actually posted it was to get some feedback, so thank you

    People are like the stars, there are bright ones, and those that are dim.

    Blog of Random Stuff

  7. #7
    Join Date
    Jul 2003
    Location
    Lincoln, UK
    Posts
    1,278
    Thanks
    0
    Thanked 1 Time in 1 Post
    Rep Power
    111

    Re: Command Interpreter

    Handy bit of code, useful for anything that needs a console interface. Script interpreters for the win though
    I have become comfortably numb.

  8. #8
    Join Date
    Sep 2008
    Location
    USA
    Posts
    573
    Thanks
    62
    Thanked 22 Times in 18 Posts
    Blog Entries
    1
    Rep Power
    45

    Re: Command Interpreter

    Quote Originally Posted by Chazwazza View Post
    References are not pointers, and pointers are not references.
    Gah, sorry for my terminology, I meant to say Functionforstring( &string );
    Passing the address of the index of the string. I'm just used to C
    how can i use this code? Will I must compiling it?

  9. #9
    Join Date
    Jun 2003
    Location
    das Land der kalten Herzen
    Posts
    2,764
    Thanks
    0
    Thanked 13 Times in 10 Posts
    Rep Power
    189

    Re: Command Interpreter

    nice work... as always
    www.project-reloaded.com
    -------------------------
    http://youtube.com/watch?v=3O-vM69M_bg
    ------------------------------------------
    loop: I'll change the locks on this bitch
    ------------------------------------------
    [23:53] [gØt]wäv?: i am good for you
    [23:53] [gØt]wäv?: and you know it
    ------------------------------------------
    Xero|Hawk: yo dawg we herd you like aimbots so we put an aimbot in yo aimbot so it can aim for you while it aims for you

  10. #10
    Join Date
    May 2009
    Posts
    445
    Thanks
    0
    Thanked 5 Times in 3 Posts
    Rep Power
    39

    Re: Command Interpreter

    Danke. I suck at regex, so this is nice.
    Quote Originally Posted by Zaltekk
    +zaltekk : omg abso i can get you a blowjob

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Similar Threads

  1. Simpler Command Interpreter
    By Xeno123 in forum Utility Classes and Libraries
    Replies: 8
    Last Post: 10-26-2009, 06:17 AM
  2. CS:S Interpreter
    By s1n1s73r in forum Public Releases
    Replies: 19
    Last Post: 02-14-2005, 12:23 PM
  3. Replies: 6
    Last Post: 10-03-2004, 04:10 PM
  4. Bad command character in client command
    By olsdirty in forum Other Anti-Cheats
    Replies: 2
    Last Post: 07-19-2004, 04:30 AM
  5. Replies: 1
    Last Post: 07-15-2004, 09:14 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts