Based on this documentary, but this time I will demonstrate how we can register/Hook multiple new CMD and recover the parameters you've inputted in chat without using SAMPFUNCS Opcodes.

PHP:
:registerClientCommand // 0AB1: @registerClientCommand 3 _CommandName 0@ _TogglingVar 1@ _ParamsPtrToVar 2@
{
    Credits:
        Parazitas - UGBASE
        kawa_operand - BlastHack
 
    Note:
        The Reference Pointers passed at _TogglingVar and _ParamPtrToVar are required to be treated as ReadOnly. Which means that the value of those two Reference Pointers should not be manually overwritten/changed.

    I am having a problem with opcode 0AB1, it permanently writes on the main thread's local variables. Maybe its because I directly writes on the passed variable's memory pointer. An example case:
        Passing _ParamPtrToVar = 31@ , _TogglingVar = 30@
            Opcode 0AB1 31@ == Main Thread's 31@
            Opcode 0AB1 30@ == Main Thread's 30@

    Thats why I decided to use global variables since they aren't that exposed on scripts.
}
const
    //    WARNING:
    //        Do not use Local Variables
    //        Do not recycle/use the three variables on any operation inside the script because these variables will always be used by this function and doesn't override outside the function. I promise you that even if you replace this with a local variable, It will cause overwriting mistakes that will mess the operation
    // You can Replace any of these variables into any UNIQUE GLOBAL VARIABLES
    VAR1 = $2AFD
    VAR2 = $2BEC
    VAR3 = $2CDE
    VAR4 = $2DCB
    VAR5 = $2EBF
    VAR6 = $2FAA
end
IF 0AA2: VAR4 = "samp.dll"
THEN
        // ~~~~~~~~~~~~~ Create a New Callback Structure
        {
            51                      // push     ecx
            56                      // push     esi
            8B 74 24 0C             // mov     esi, [esp+0Ch]
            89 34 25 11 11 11 11    // mov     [11111111], esi // later: [11111111] becomes 1@
            83 35 11 11 11 11 01    // xor     [11111111], 01 // later: [11111111] becomes 2@
            5E                      // pop     esi
            59                      // pop     ecx
            C3 // retn
        }
            // Avoid using local variables by saving the values inside a global variables
    008A: VAR1 = 0@
    008A: VAR2 = 2@
    008A: VAR3 = 1@
            //
    0AC8: VAR5 = allocate_memory_size 23 // undeleteable memory region
    0084: VAR6 = VAR5
    0A8C: write_memory VAR6 size 4 value 0x748B5651 virtual_protect 1
    VAR6 += 4
    0A8C: write_memory VAR6 size 4 value 0x34890C24 virtual_protect 1
    VAR6 += 4
    0A8C: write_memory VAR6 size 1 value 0x25 virtual_protect 1
    VAR6++
    // 0A8C: write_memory VAR2 size 4 value 0 virtual_protect 0 // null string // NOT WORKING due to this function's varibles overriding
    0A8C: write_memory VAR6 size 4 value VAR2 virtual_protect 1
    VAR6 += 4
    0A8C: write_memory VAR6 size 2 value 0x3583 virtual_protect 1
    VAR6 += 2
    // 0A8C: write_memory VAR3 size 4 value 0 virtual_protect 0 // Zeroing TogglingVar // NOT WORKING due to this function's varibles overriding
    0A8C: write_memory VAR6 size 4 value VAR3 virtual_protect 1
    VAR6 += 4
    0A8C: write_memory VAR6 size 4 value 0xC3595E01 virtual_protect 1
        // ~~~~~~~~~~~~~ now callback struct VAR5 is ready

    0A8E: VAR6 = VAR4 + 0x21A0E8 // SAMP_CHAT_INPUT_INFO_OFFSET
    0A8D: VAR6 = read_memory VAR6 size 4 virtual_protect 1
    VAR4 += 0x65AD0 // SAMP_REGISTER_CLIENT_CMD_OFFSET
    0AA6: call_method VAR4 struct VAR6 num_params 2 pop 0 VAR5 VAR1
END
0AB2: ret 0


PHP:
{
    Custom CMD Testing Template by AJOM
        Type any of these CMD:
            /TypeThis <with or without params>
            /anothercommand <with or without params>
            /trymetoo <with or without params>
        Note: Case INSENSITVE, you can use both uppercase and lowercase combination
}
{$CLEO}
0000:

wait 5000

0AC8: 0@ = allocate_memory_size 9 // undeleteable memory region containing the cmdname1
0AD3: 0@ = string_format "TypeThis"
0AC7: 31@ = var 31@ pointer
0AC7: 30@ = var 30@ pointer
0AB1: @registerClientCommand 3 _CommandName 0@ _TogglingVar 30@ _ParamsPtrToVar 31@
31@ = 0 // null ptr
30@ = 0 // default disabled
    // we will not free memory region 0@ // let it remain at the memory forever since we need it

0AC8: 0@ = allocate_memory_size 15 // undeleteable memory region containing the cmdname2
0AD3: 0@ = string_format "anothercommand"
0AC7: 29@ = var 29@ pointer
0AC7: 28@ = var 28@ pointer
0AB1: @registerClientCommand 3 _CommandName 0@ _TogglingVar 28@ _ParamsPtrToVar 29@
29@ = 0 // null ptr
28@ = 0 // default disabled
    // we will not free memory region 0@ // let it remain at the memory forever since we need it

0AC8: 0@ = allocate_memory_size 9 // undeleteable memory region containing the cmdname3
0AD3: 0@ = string_format "trymetoo"
0AC7: 27@ = var 27@ pointer
0AC7: 26@ = var 26@ pointer
0AB1: @registerClientCommand 3 _CommandName 0@ _TogglingVar 26@ _ParamsPtrToVar 27@
27@ = 0 // null ptr
26@ = 0 // default disabled
    // we will not free memory region 0@ // let it remain at the memory forever since we need it

while true
    wait 0
    if 30@ <> 0
    then
        30@ = 0 // disable indication of the cmd
        if 31@ <> 0 // not null ptr
        then 0AD1: show_formatted_text_highpriority "You typed 'TypeThis'~n~Params=%s" time 5000 31@
        else 0ACD: show_text_highpriority "You typed 'TypeThis'~n~No Params" time 5000 // This will not happen because there will always be a reference ptr. But just to be sure!
        end
        00A1: put_actor $PLAYER_ACTOR at 345.5621 306.2212 998.4484
    end

    if 28@ <> 0
    then
        28@ = 0 // disable indication of the cmd
        if 29@ <> 0 // not null ptr
        then 0AD1: show_formatted_text_highpriority "You typed 'anothercommand'~n~Params=%s" time 5000 29@
        else 0ACD: show_text_highpriority "You typed 'anothercommand'~n~No Params" time 5000 // This will not happen because there will always be a reference ptr. But just to be sure!
        end
        00A1: put_actor $PLAYER_ACTOR at 0 0 0
    end

    if 26@ <> 0
    then
        26@ = 0 // disable indication of the cmd
        if 27@ <> 0 // not null ptr
        then 0AD1: show_formatted_text_highpriority "You typed 'trymetoo'~n~Params=%s" time 5000 27@
        else 0ACD: show_text_highpriority "You typed 'trymetoo'~n~No Params" time 5000 // This will not happen because there will always be a reference ptr. But just to be sure!
        end
        00A1: put_actor $PLAYER_ACTOR at 817.0 2813.4 15.0
    end
end
 
Last edited:

dev.tntd2k2

Member
Joined
Oct 5, 2020
Messages
19
Reaction score
20
Location
Vietnam
0.3.7 R3
PHP:
SAMP_FUNC_ADDCLIENTCMD                                             0x69000
SAMP_CHAT_INPUT_INFO_OFFSET                                        0x26E8CC
0.3.DL
PHP:
SAMP_FUNC_ADDCLIENTCMD                                             0x691B0
SAMP_CHAT_INPUT_INFO_OFFSET                                        0x2ACA14
0.3.7 R4
PHP:
SAMP_FUNC_ADDCLIENTCMD                                             0x69730
SAMP_CHAT_INPUT_INFO_OFFSET                                        0x26E9FC
 

dev.tntd2k2

Member
Joined
Oct 5, 2020
Messages
19
Reaction score
20
Location
Vietnam
0.3.7 R2
PHP:
SAMP_FUNC_ADDCLIENTCMD                                             0x65BA0
SAMP_CHAT_INPUT_INFO_OFFSET                                        0x26E8CC
0.3.7 R4 - v2
PHP:
SAMP_FUNC_ADDCLIENTCMD                                             0x69770
SAMP_CHAT_INPUT_INFO_OFFSET                                        0x26E9FC
 
Top