Гайд Использование функции sscanf напрямую

Статус
В этой теме нельзя размещать новые ответы.
Итак. Опкод 0AD4 не может сканировать строки, если они больше 14-16 символов(используются строковые переменные(@v, @s)), это мы и решим.

GTA:SA загружает все стандартные библиотеки, в том числе и ту, которая содержит функцию sscanf.
Её адрес(в процессе игры) - 0x8220AD.
И судя по данной статейке(уроку): http://blasthack.net/threads/10/ можно сказать, что данная функция является __cdecl => все параметры передаются справа налево.

В итоге, для того, чтобы использовать функцию sscanf в CLEO можно использовать следующий алгоритм:
Пишем что-то типа в этом роде(для того, чтобы потом было легче записывать параметры в обратном порядке):
Общий вид функции(С++): int sscanf ( const char * s, const char * format, ...);
Переделываем под себя: sscanf(0@, "%s [%d]", 1@, 2@v) (легче будет определиться, как записывать)
Пишем в CLEO: 0AA5: call 0x8220AD num_params 4 pop 4 params 2@v 1@ "%s [%d]" 0@
(также можно использовать опкод 0AA7, чтобы узнать кол-во прочитанных параметров)
  • 0@ - строка, которая содержит, к примеру, следующее: Egor [512];
  • 1@ - указатель на выделенную память(0AC8);
  • 2@v - указатель на значение переменной 2@(логично же, да? :ok:).
    Также можно использовать альтернативу: 0AC7: 3@ = var 2@ offset и вместо 2@v пишем 3@
  • "%s [%d]" - формат строки(для чтения);
  • num_params 4 - кол-во передаваемых параметров(в нашем случае 4 - 0@, строка с модификаторами, 1@, 2@v);
  • pop указываем столько же, сколько и параметров(зависит от типа соглашения, в нашем случае - __cdecl).
Сам ид будет храниться уже в 2@, а не в 2@v.

Итак. Полный пример:
CLEO:
{$CLEO}

0001: wait 0 ms

while not SAMP.Available()
    wait 400
end

wait 2000

0AC8: 0@ = allocate_memory_size 256
0AD3: 0@ = format "Egor [512]"

0AC8: 1@ = allocate_memory_size 24 // Используется под хранения никнейма

0AA5: call 0x8220AD num_params 4 pop 4 params 2@v 1@ "%s [%d]" 0@ // sscanf(0@, "%s [%d]", 1@, 2@v)
// 2@ - id
// 1@ - nick
// 0@ - string
0AF8: samp add_message_to_chat "Привет, %s" color -1 1@
0AF9: samp say_msg "/hi %d" 2@

// Завершаем скрипт и очищаем ранее выделенную память
0AC9: free_allocated_memory 0@
0AC9: free_allocated_memory 1@

0A93: end_custom_thread

Вот такой легкий метод можно применить.
TY.
 
Последнее редактирование:

Logan4ik

Новичок
139
216
Если не пизжу, то можно завести переменную, которую в свою очередь добавляешь в условие.
Она проверяет кол-во успешно прочтенных переменных.
Типо так:
Код:
0AA5: call 0x8220AD num_params 5 pop 5 params 2@v 1@ "%s[%d]" 0@ 3@
if 3@ > 0
then
// asd
end
Ну а лучше всего сканить строки с РПС хука, как грят посаны, это намного быстрее.
Подгон от легенда - http://dumpz.org/1303571/
Если не пизжу, то можно завести переменную, которую в свою очередь добавляешь в условие.
Она проверяет кол-во успешно прочтенных переменных.
Типо так:
Код:
0AA5: call 0x8220AD num_params 5 pop 5 params 2@v 1@ "%s[%d]" 0@ 3@
if 3@ > 0
then
// asd
end
Ну а лучше всего сканить строки с РПС хука, как грят посаны, это намного быстрее.
Подгон от легенда - http://dumpz.org/1303571/
Будет время проверю
call function?
 

Perojek)0

Известный
205
3
Почему, если строку записать через форматирование, то сканирует правильно, а если её получить через хук, то у меня ничего не робит..
В чём может быть проблема?
 

itsLegend

Фонд борьбы за жуков 🐞
Автор темы
Администратор
2,695
1,448
Какой хук?
 

itsLegend

Фонд борьбы за жуков 🐞
Автор темы
Администратор
2,695
1,448
Ну там цвета ещё могут быть.
{FFFFFF} типа
 

itsLegend

Фонд борьбы за жуков 🐞
Автор темы
Администратор
2,695
1,448
Ну попробовать их тоже учитывать, либо удалять.
 

Perojek)0

Известный
205
3
Ну попробовать их тоже учитывать, либо удалять.
Хорошо, спасибо :)

CLEO:
{$CLEO}
{$INCLUDE SF}

0001: wait 0 ms

while not SAMP.Available()
    wait 12000
end

0BE3: raknet setup_incoming_rpc_hook @1

0BDE: pause_thread 0


:1
0BE5: raknet 0@ = get_hook_param PARAM_PACKETID
if
    0@ == RPC_SCRCLIENTMESSAGE
then
0BE5: raknet 1@ = get_hook_param PARAM_BITSTREAM 
0AC8: 4@ = allocate_memory_size 228
0BE7: raknet 2@ = bit_stream_read 1@ type BS_TYPE_INT
0BE7: raknet 3@ = bit_stream_read 1@ type BS_TYPE_INT
0BE8: raknet bit_stream 1@ read_array 4@ size 3@
0C1E: array 4@ element 3@ el_size 1 = 0
0AC8: 6@ = allocate_memory_size 512
if
0C25: strncmp string1 4@ string2 "{FF8C00}SMS:" size 12
then
0AA5: call 0x8220AD num_params 5 pop 5 params 5@v 6@ 7@ "{FF8C00}SMS: {FFFF00}%s {FF8C00}| {FFFF00}Отправитель: %s (тел. %d)" 4@ 
end
0AC9: free_allocated_memory 6@
end
0BE0: raknet hook_ret true
Когда мне пишут SMS, меня крашит.
В чём ошибка?
 
Последнее редактирование модератором:

Perojek)0

Известный
205
3
Такая проблема возникла, если у меня стоит %s, а там несколько слов, то в переменную сохраняет только первое, как это можно исправить?
 
Статус
В этой теме нельзя размещать новые ответы.