Итак. Опкод 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, чтобы узнать кол-во прочитанных параметров)
Итак. Полный пример:
Вот такой легкий метод можно применить.
TY.
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).
Итак. Полный пример:
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.
Последнее редактирование: