[C++] Simple command system (0.3.7R1)

y0mike

Active member
Joined
May 10, 2014
Messages
97
Reaction score
41
Location
mizus girl's house
C++:
struct SCommandEntry
{
    SCommandEntry( const std::string& cmd, int nargs, const std::function< void( const std::vector< std::string >& ) > & cb ) :
        strCmd( cmd ), numArgs( nargs ), fnCallback( cb ) 
    {
    }

    std::string strCmd;
    int            numArgs;
    std::function< void( const std::vector< std::string >& ) > fnCallback;
};

static std::vector< SCommandEntry > s_cmdEntries;

void AddCommand( const char * szCmd, int numArgs, const std::function< void( const std::vector< std::string >& ) > &fnCallback )
{
    s_cmdEntries.emplace_back( szCmd, numArgs, fnCallback );
}

bool iequals( const std::string& a, const std::string& b )
{
    return std::equal( a.begin(), a.end(),
                       b.begin(), b.end(),
                       [ ]( char a, char b ) {
        return tolower( a ) == tolower( b );
    } );
}

bool __stdcall onCommandReceived( const char * strCommand )
{
//    g_pCons->Write( "Command: %s\n", strCommand );

    std::vector< std::string > vecArgs = SplitString( strCommand, " " );

    for ( const auto & entry : s_cmdEntries ) {     
        if ( !vecArgs.empty() && !entry.strCmd.empty() &&
             iequals( vecArgs[ 0 ].c_str(), entry.strCmd.c_str() ) )
        {
            // remove the first argument which is the command name (e.g /command)
            vecArgs.erase( vecArgs.begin() );

            // ensure that the num. of arguments matched the amount this command hsould have
            int numArgs = vecArgs.size();
            if ( entry.numArgs != numArgs )
                return false; // todo: print return message but im lazy

            // make sure the callback is valid
            if ( entry.fnCallback )
            {
                // call it
                entry.fnCallback( vecArgs );
                return true;
            }
        }
    }
    return false;
}

uintptr_t _onCommandReceived_jmpBack; 
uintptr_t _onCommandReceived_jmpRet;

__declspec( naked ) void __stdcall proxy_onCommandReceived() {
                       
    __asm
    {         
        push edi
        call onCommandReceived 
        cmp al, 1
        je NoSir

        mov eax, edi
        mov dword ptr [ esp + 0x128 ], 0

        jmp _onCommandReceived_jmpBack

    NoSir:  
        pop edi
        pop esi

        jmp _onCommandReceived_jmpRet
    }
}


void InitCmdCode()
{
    /*  
    .text:00065C9A 8B C7                                   mov     eax, edi
    .text:00065C9C C7 84 24 28 01 00 00 00+                mov     dword ptr [esp+128h], 0
    */                                                                                                       
    HookInstallJUMP( ( uintptr_t )GetModuleHandle( "samp.dll" ) + 0x65C9A, proxy_onCommandReceived, 11 );

    _onCommandReceived_jmpBack = ( uintptr_t )GetModuleHandle( "samp.dll" ) + 0x65CA7;
    _onCommandReceived_jmpRet  = ( uintptr_t )GetModuleHandle( "samp.dll" ) + 0x65D15;
}

Example usage
C++:
AddCommand( "/loadcfg", 1, [ ]( const std::vector< std::string >& strArgs )
{
    if ( !std::experimental::filesystem::exists( strArgs.front() ) )
        return;

    settings.load( strArgs.front() );
} );
 

Scraatch

Active member
Joined
Jan 14, 2017
Messages
76
Reaction score
2
Location
Germany
how can i include that in my code?

C++:
#include "main.h"

#define SAMP_DLL        "samp.dll"
#define SAMP_CMP        "F8036A004050518D4C24"

using namespace std;

int playergodmode = 0;
int unlimitammo = 0;
int vehiclegodmode = 0;
float Old_Player_Health = 100.0;
int difference = 0;

DWORD CPed = 0xB6F5F0;
DWORD ADDR_INFIRUN = 0xB7CEE4;
DWORD ADDR_ALLNITRO = 0x969165;
DWORD ADDR_INFIAMMO = 0x969178;
DWORD ADDR_CURRENT_WEAPON = 0xBAA410;
DWORD ADDR_VEHICLE_PTR = 0xBA18FC;

void Start(void)
{
    addConsoleMessage("Grand Theft Auto: San Andreas was stared");
    while (true)
    {
        if (GetAsyncKeyState(VK_NUMPAD1) & 0x8000)
        {
            showGameText("Test", 3000, 3);
        }
        /*
        if (GetAsyncKeyState(VK_NUMPAD1) & 0x8000)
        {
            Sleep(200);
            SetPlayerHealth(100);
            showGameText("Health restored", 1500, 3);
            addConsoleMessage("[FUNC] Health restored up to 100.0");
        }
        if (GetAsyncKeyState(VK_NUMPAD2) & 0x8000)
        {
            Sleep(200);
            SetPlayerArmor(100);
            showGameText("Armor restored", 1500, 3);
            addConsoleMessage("[FUNC] Armor restored up to 100.0");
        }
        if (GetAsyncKeyState(VK_NUMPAD3) & 0x8000)
        {
            Sleep(200);
            *(int*)(ADDR_ALLNITRO) = 1;
            showGameText("All Vehicles Nitro", 1500, 3);
            addConsoleMessage("[FUNC] Nitro for all vehicle activated");
        }
        if (GetAsyncKeyState(VK_NUMPAD7) & 0x8000)
        {
            Sleep(200);
            playergodmode = !playergodmode;
            char buf[256];
            sprintf_s(buf, "player godmode %s", playergodmode ? "activ" : "deactiv");
            showGameText((const char*)buf, 1500, 3);
            if (playergodmode) {
                addConsoleMessage("[FUNC] Player godmode activated");
            }
            else {
                addConsoleMessage("[FUNC] Player godmode deactivated");
            }
        }
        if (GetAsyncKeyState(VK_NUMPAD8) & 0x8000)
        {
            Sleep(200);
            unlimitammo = !unlimitammo;
            if (unlimitammo) {
                * (int*)(ADDR_INFIAMMO) = 1;
                addConsoleMessage("[FUNC] Infinity ammunation activated");
            }
            else {
                * (int*)(ADDR_INFIAMMO) = 0;
                addConsoleMessage("[FUNC] Infinity ammunation deactivated");
            }
            char buf[256];
            sprintf_s(buf, "unlimited ammo %s", unlimitammo ? "activ" : "deactiv");
            showGameText((const char*)buf, 1500, 3);
        }
        if (GetAsyncKeyState(VK_NUMPAD5) & 0x8000)
        {
            //Testen hier...
        }
        if (GetAsyncKeyState(VK_NUMPAD9) & 0x8000)
        {
            Sleep(200);
            vehiclegodmode = !vehiclegodmode;
            if (vehiclegodmode) {
                addConsoleMessage("[FUNC] Vehicle godmode activated");
            }
            else {
                addConsoleMessage("[FUNC] Vehicle godmode deactivated");
            }
            char buf[256];
            sprintf_s(buf, "vehicle godmode %s", vehiclegodmode ? "activ" : "deactiv");
            showGameText((const char*)buf, 1500, 3);
        }
        //Autofuncs
        if (playergodmode) {
            SetPlayerHealth(100);
        }
        if (vehiclegodmode) {
            SetVehicleHealth(1000);
        }
        */
        Sleep(10);
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Start, NULL, 0, 0);
        AllocConsole();
        FILE* fp;
        freopen_s(&fp, "CONOUT$", "w", stdout);
        addConsoleMessage("Grand Theft Auto: San Andreas getting started...");
        break;

    case DLL_PROCESS_DETACH:
        break;
    }
    return true;
}
 

y0mike

Active member
Joined
May 10, 2014
Messages
97
Reaction score
41
Location
mizus girl's house
Copy paste the code in the thread and refer to the example for usage.

You could do this, the result would a message printed to SA:MP's chat window (e.g /test hello -> prints "Argument (1): hello")
C++:
// "/test" = the command's name
// 1 = the number of arguments this cmd has
// lambda function is the callback called when this command is entered
AddCommand( "/test", 1, [ ]( const std::vector< std::string >& strArgs )
{
    if ( strArgs.front().empty() )
        return;

     samp->AddMessageToChat( 0xffffffff, "Argument (1): %s", strArgs.front().c_str() );
} );
 

Scraatch

Active member
Joined
Jan 14, 2017
Messages
76
Reaction score
2
Location
Germany
Copy paste the code in the thread and refer to the example for usage.

You could do this, the result would a message printed to SA:MP's chat window (e.g /test hello -> prints "Argument (1): hello")
C++:
// "/test" = the command's name
// 1 = the number of arguments this cmd has
// lambda function is the callback called when this command is entered
AddCommand( "/test", 1, [ ]( const std::vector< std::string >& strArgs )
{
    if ( strArgs.front().empty() )
        return;

     samp->AddMessageToChat( 0xffffffff, "Argument (1): %s", strArgs.front().c_str() );
} );
i have no idea how to include that, i tried to put the first block of code in my main.h file and this
C++:
AddCommand( "/test", 1, [ ]( const std::vector< std::string >& strArgs )
{
    if ( strArgs.front().empty() )
        return;

     samp->AddMessageToChat( 0xffffffff, "Argument (1): %s", strArgs.front().c_str() );
} );
in my main.cpp but there are errors
 

Safa

Well-known member
Joined
Feb 24, 2015
Messages
342
Reaction score
127
i have no idea how to include that, i tried to put the first block of code in my main.h file and this
C++:
AddCommand( "/test", 1, [ ]( const std::vector< std::string >& strArgs )
{
    if ( strArgs.front().empty() )
        return;

     samp->AddMessageToChat( 0xffffffff, "Argument (1): %s", strArgs.front().c_str() );
} );
in my main.cpp but there are errors

mate maybe you should stop trying to paste some code you dont even understand lol
 

Scraatch

Active member
Joined
Jan 14, 2017
Messages
76
Reaction score
2
Location
Germany
Some std funcs dont work, but i think its because i used a namespace for std but the other error i do not know how to fix pls help
 

Attachments

  • notworking.PNG
    notworking.PNG
    154.4 KB · Views: 20
  • evennotwork.PNG
    evennotwork.PNG
    149.6 KB · Views: 19
Top