До сих пор эта функция оставалась тайной для многих скриптеров сампа, нигде и никто её не документировал. Что ж, пора пролить свет на эту тёмную сторону сампа.
Эта функция отправляет специальный запрос на клиент, затем клиент присылает свой ответ в колбэк OnClientCheckResponse. Задержка ответа зависит в основном от пинга игрока. Функция и паблик не объявлены в стандартных инклудах, так что их придётся объявить самостоятельно в начале скрипта (например, после подключения всех инклудов):
Разберем аргументы SendClientCheck:
playerid - кому мы отправим запрос
type - тип запроса
arg - специальный аргумент
offset - оффсет чтения памяти
size - размер для чтения (всегда должен быть равен или больше 2)
Разберём подробнее, что всё это значит, чуть позже.
Теперь OnClientCheckResponse:
playerid - от кого пришёл ответ
type - тип ответа
arg - специальный аргумент
response - ещё один аргумент (крутое описание, да?)
Теперь разберёмся, что всё это значит. Есть только 4 типа запросов, которые клиент обрабатывает (аргумент type). Это 0x2, 0x46, 0x47, 0x48.
Тип 0x48
Начнём с простого. Данный запрос не нуждается ни в каких дополнительных аргументах (arg, offset, size). Он возвращает количество секунд с момента запуска компьютера в arg. Пример:
При входе на сервер игроку напишет, сколько запущен его комп.
Тип 0x46
Этот тип читает данные структуры CBaseModelInfoSA указанной модели и возвращает однобайтовую чексумму. Можно указать, с какого оффсета начать чтение и сколько байт прочитать. Например, запрос SendClientCheck(playerid, 0x46, 1598, 0, 28) вернёт чексумму первых 28 байт структуры модели 1598. Более полный пример:
Тип 0x47
Этот тип уже читает данные структуры CColModelSA указанной модели (указатель на которую лежит по оффсету 20 в структуре CBaseModelInfoSA). Остальное всё аналогично предыдущему типу. Пример:
Тип 0x2
Вот мы и подобрались к самому интересному! Данный тип возвращает 32 (правда больше половины неизвестны/бесполезны) флага из структуры CPhysicalSA. Если игрок в транспорте, то возвращает информацию транспорта, а если пешком - то информацию о самом игроке. Это такие флаги как стоит ли игрок на земле, находится ли он в воде, касается ли воды, уязвим ли к различным типам урона (вот вам и античит на гм). Правда записывать данные мы не можем, только читать.
Пример использования будет ниже по ссылке.
Заключение
Вот, собственно, и всё, что из себя представляет эта секретная функция. К сожалению, сейчас она почти бесполезна. В 0.3x был ещё один тип - 0x5, он позволял читать указанный участок памяти сампа и тем самым проверять, установлены ли там патчи собейта и других читов, но его выпилили в 0.3z.
Полный скрипт-пример: http://pastebin.com/vndmMgFL
Автор урока: EvgeN 1137
Реверсинг: FYP, EvgeN 1137
Источник: http://lightcode.ru/showthread.php?t=112860
SendClientCheck
Эта функция отправляет специальный запрос на клиент, затем клиент присылает свой ответ в колбэк OnClientCheckResponse. Задержка ответа зависит в основном от пинга игрока. Функция и паблик не объявлены в стандартных инклудах, так что их придётся объявить самостоятельно в начале скрипта (например, после подключения всех инклудов):
Код:
native SendClientCheck(playerid, type, arg, offset, size);
forward OnClientCheckResponse(playerid, type, arg, response);
Разберем аргументы SendClientCheck:
playerid - кому мы отправим запрос
type - тип запроса
arg - специальный аргумент
offset - оффсет чтения памяти
size - размер для чтения (всегда должен быть равен или больше 2)
Разберём подробнее, что всё это значит, чуть позже.
Теперь OnClientCheckResponse:
playerid - от кого пришёл ответ
type - тип ответа
arg - специальный аргумент
response - ещё один аргумент (крутое описание, да?)
Теперь разберёмся, что всё это значит. Есть только 4 типа запросов, которые клиент обрабатывает (аргумент type). Это 0x2, 0x46, 0x47, 0x48.
Тип 0x48
Начнём с простого. Данный запрос не нуждается ни в каких дополнительных аргументах (arg, offset, size). Он возвращает количество секунд с момента запуска компьютера в arg. Пример:
C++:
#include <a_samp>
native SendClientCheck(playerid, type, arg, offset, size); forward OnClientCheckResponse(playerid, type, arg, response);
public OnPlayerConnect(playerid)
{
SendClientCheck(playerid, 0x48, 0, 0, 2);
return 1;
}
public OnClientCheckResponse(playerid, type, arg, response)
{
new str[128];
switch(type)
{
case 0x48:
{
format(str, sizeof(str), "Your computer has been running for %s!", Convert(arg / 1000));
SendClientMessage(playerid, -1, str);
}
}
return 1;
}
Convert(number)
{
new hours = 0, mins = 0, secs = 0, string[100]; hours = floatround(number / 3600);
mins = floatround((number / 60) - (hours * 60)); secs = floatround(number - ((hours * 3600) + (mins * 60)));
if(hours > 0)
{
format(string, 100, "%d:%02d:%02d", hours, mins, secs);
}
else
{
format(string, 100, "%d:%02d", mins, secs);
}
return string;
}
Тип 0x46
Этот тип читает данные структуры CBaseModelInfoSA указанной модели и возвращает однобайтовую чексумму. Можно указать, с какого оффсета начать чтение и сколько байт прочитать. Например, запрос SendClientCheck(playerid, 0x46, 1598, 0, 28) вернёт чексумму первых 28 байт структуры модели 1598. Более полный пример:
C++:
public OnPlayerConnect(playerid)
{
SendClientCheck(playerid, 0x46, 1598, 0, 28); // 1598 - beachball return 1;
}
public OnClientCheckResponse(playerid, type, arg, response)
{
new str[128];
switch(type)
{
case 0x46:
{
format(str, sizeof(str), "Model %d has checksum 0x%x", arg, response);
SendClientMessage(playerid, -1, str);
}
}
return 1;
}
Тип 0x47
Этот тип уже читает данные структуры CColModelSA указанной модели (указатель на которую лежит по оффсету 20 в структуре CBaseModelInfoSA). Остальное всё аналогично предыдущему типу. Пример:
C++:
public OnPlayerConnect(playerid)
{
SendClientCheck(playerid, 0x47, 1598, 0, 48); // 1598 - beachball return 1;
}
public OnClientCheckResponse(playerid, type, arg, response)
{
new str[128];
switch(type)
{
case 0x47:
{
format(str, sizeof(str), "Col model %d has checksum 0x%x", arg, response);
SendClientMessage(playerid, -1, str);
}
}
return 1;
}
Тип 0x2
Вот мы и подобрались к самому интересному! Данный тип возвращает 32 (правда больше половины неизвестны/бесполезны) флага из структуры CPhysicalSA. Если игрок в транспорте, то возвращает информацию транспорта, а если пешком - то информацию о самом игроке. Это такие флаги как стоит ли игрок на земле, находится ли он в воде, касается ли воды, уязвим ли к различным типам урона (вот вам и античит на гм). Правда записывать данные мы не можем, только читать.
Пример использования будет ниже по ссылке.
Заключение
Вот, собственно, и всё, что из себя представляет эта секретная функция. К сожалению, сейчас она почти бесполезна. В 0.3x был ещё один тип - 0x5, он позволял читать указанный участок памяти сампа и тем самым проверять, установлены ли там патчи собейта и других читов, но его выпилили в 0.3z.
Полный скрипт-пример: http://pastebin.com/vndmMgFL
Автор урока: EvgeN 1137
Реверсинг: FYP, EvgeN 1137
Источник: http://lightcode.ru/showthread.php?t=112860