PDA

Просмотр полной версии : [Урок] Защита от читерского ХП



wAx
12.02.2014, 14:51
В начале скажу: Данную тему я разместил именно в этом разделе, потому что, это урок. Да-да, самый настоящий урок...

И так, все мы когда-нибудь да и грешили, пользуясь собейтом на различных серверах SAMP'а. И наверное многие знакомы с так называемым "NOP SetPlayerHealth" в собейте (отключает изменение здоровья). Так вот, может и данную защиту уже придумали и давно и используют, моя задача донести до вас, как мы придумали и написали данную защиту. Приступим.

Для начала следует разобраться, как работает данный чит или по другому "НОП". Данный "НОП" запрещает серверу изменять здоровье игрока посредством функции SetPlayerHealth. Т.е при включенном "НОПе" мы не сможем ни отнять здоровье ни прибавить его. Все, разобрались!

Теперь переходим к этапу составления защиты. Давайте подумаем... В любых современных модах, здоровье игрока, так же лежит в переменной. Чит может блокировать функции, но до переменных ему не добраться: отсюда делаем вывод. В общем для защиты, нам нужно лишь над каждой функцией SetPlayerHealth устанавливать значение нашей переменной. Тоесть:


PlayerInfo[playerid][pHealth] += 0.5;
SetPlayerHealth(playerid, PlayerInfo[playerid][pHealth]);

И так, с тем, как спрятать данные от чита, разобрались. Теперь давайте подумаем как можно проверить соответствие данных.
Будем проверять в секундном таймере, к примеру:


new Float:hp;
GetPlayerHealth(playerid, hp);
if(hp - PlayerInfo[playerid][pHealth] > 0.5)
{
Kick(playerid);
return 1;
}
PlayerInfo[playerid][pHealth] = hp;

Вот и все! При условии что "видимое" хп игрока больше на 0,5 чем "невидимое" хп, игрока кикнет.
На этом все! Отзывы прошу в комментарии =)

Salvacore
12.02.2014, 18:07
Молодец...
Но
этот bbcode использовать лучше.

DeimoS
12.02.2014, 18:12
Странный НОП, если его можно обмануть подобным образом...
Логики в этом коде не вижу

new Float:hp;
GetPlayerHealth(playerid, hp);
if(hp - PlayerInfo[playerid][pHealth])//В чём заключается эта проверка? Тут ты отнимешь от значения, полученного в GetPlayerHealth, значение, хранящееся в pHealth. А условие для кика то где?
{
Kick(playerid);
return 1;
}
PlayerInfo[playerid][pHealth] = hp;//И зачем тогда этот код? Если значение не подходит, кикаем. А если подходит, зачем присваивать его повторно?

wAx
12.02.2014, 18:55
Странный НОП, если его можно обмануть подобным образом...
Логики в этом коде не вижу

new Float:hp;
GetPlayerHealth(playerid, hp);
if(hp - PlayerInfo[playerid][pHealth])//В чём заключается эта проверка? Тут ты отнимешь от значения, полученного в GetPlayerHealth, значение, хранящееся в pHealth. А условие для кика то где?
{
Kick(playerid);
return 1;
}
PlayerInfo[playerid][pHealth] = hp;//И зачем тогда этот код? Если значение не подходит, кикаем. А если подходит, зачем присваивать его повторно?

Дорогой друг! Объясняю на пальцах:

НОП используется для "обхода" системы сытости и прочих, которые отнимают у игрока ХП. НОП не дает серверу управлять здоровьем игрока с помощью SetPlayerHealth. Обмануть легко? Не вижу в этом ничего страшного...

Далее, с проверкой, в ней я действительно немного ошибся, исправил. При работе НОП'а, используя пример контроля ХП игрока в переменной, значение полученное через GetPlayerHealth, окажется больше чем значение в переменной, это и послужит причиной кика.

И последнее. Значение переменной может совпадать, но может быть и меньше (урон от гана, урон от падения). Конечно, можно модернизировать, добавить проверку:


if(hp < PlayerInfo[playerid][pHealth]) PlayerInfo[playerid][pHealth] = hp;

Но в любом случае смысл не изменяется. Надеюсь я ответил на все твои вопросы!

Спасибо за критику!

DeimoS
12.02.2014, 19:58
НОП используется для "обхода" системы сытости и прочих, которые отнимают у игрока ХП. НОП не дает серверу управлять здоровьем игрока с помощью SetPlayerHealth. Обмануть легко? Не вижу в этом ничего страшного...

НОП блокирует пакеты от сервера, которые несут в себе информацию о смене HP игроку через серверную функцию. (далее я расписал своё негодование по поводу твоих проверок, но...)
Кажется я понял то, какого результата ты пытаешься добиться. Раз игрок блокирует НОПом пакеты с SetPlayerHealth, значит здоровье его не меняется. Следовательно мы можем чуть увеличить значение, которое мы посылаем игроку, а после сделать проверку на то, изменилось ли у него здоровье или нет. Но я бы сделал так:


stock SetPlayerHealthEx(playerid, Float:Health)
{
new Float:OldHealth;
GetPlayerHealth(playerid, OldHealth);
SetPlayerHealth(playerid, Health);
if(Health != OldHealth) SetTimerEx("CheckNopHealth", 1000, 0, "iff", playerid, Health, OldHealth);
return 1;
}

forward CheckNopHealth(playerid, Float:Health, Float:OldHealth);
public CheckNopHealth(playerid, Float:Health, Float:OldHealth)
{
new Float:NewHealth;
GetPlayerHealth(playerid, NewHealth);
if(NewHealth != OldHealth) Kick(playerid);
return 1;
}
Правда не проверял на работоспособность. Но избавит от добавления кучи строк и избавит мод от вызова GetPlayerHealth для каждого игрока каждую секунду. Да и ложных срабатываний не должно быть.

UPD: Если присутствует в моде анти-гм, можно спокойно добавить в этот код нужные переменные, хранящие здоровье, и присвоить им новое значение здоровья

Salvacore
12.02.2014, 20:14
НОП блокирует пакеты от сервера, которые несут в себе информацию о смене HP игроку через серверную функцию. (далее я расписал своё негодование по поводу твоих проверок, но...)
Кажется я понял то, какого результата ты пытаешься добиться. Раз игрок блокирует НОПом пакеты с SetPlayerHealth, значит здоровье его не меняется. Следовательно мы можем чуть увеличить значение, которое мы посылаем игроку, а после сделать проверку на то, изменилось ли у него здоровье или нет. Но я бы сделал так:


stock SetPlayerHealthEx(playerid, Float:Health)
{
new Float:OldHealth;
GetPlayerHealth(playerid, OldHealth);
SetPlayerHealth(playerid, Health);
if(Health != OldHealth) SetTimerEx("CheckNopHealth", 1000, 0, "iff", playerid, Health, OldHealth);
return 1;
}

forward CheckNopHealth(playerid, Float:Health, Float:OldHealth);
public CheckNopHealth(playerid, Float:Health, Float:OldHealth)
{
new Float:NewHealth;
GetPlayerHealth(playerid, NewHealth);
if(NewHealth != NewHealth && NewHealth == OldHealth) Kick(playerid);
return 1;
}
Правда не проверял на работоспособность. Но избавит от добавления кучи строк и избавит мод от вызова GetPlayerHealth для каждого игрока каждую секунду. Да и ложных срабатываний не должно быть.

UPD: Если присутствует в моде анти-гм, можно спокойно добавить в этот код нужные переменные, хранящие здоровье, и присвоить им новое значение здоровья

Буду пользоваться.

Dima_Tushin
20.08.2014, 16:38
НОП блокирует пакеты от сервера, которые несут в себе информацию о смене HP игроку через серверную функцию. (далее я расписал своё негодование по поводу твоих проверок, но...)
Кажется я понял то, какого результата ты пытаешься добиться. Раз игрок блокирует НОПом пакеты с SetPlayerHealth, значит здоровье его не меняется. Следовательно мы можем чуть увеличить значение, которое мы посылаем игроку, а после сделать проверку на то, изменилось ли у него здоровье или нет. Но я бы сделал так:


stock SetPlayerHealthEx(playerid, Float:Health)
{
new Float:OldHealth;
GetPlayerHealth(playerid, OldHealth);
SetPlayerHealth(playerid, Health);
if(Health != OldHealth) SetTimerEx("CheckNopHealth", 1000, 0, "iff", playerid, Health, OldHealth);
return 1;
}

forward CheckNopHealth(playerid, Float:Health, Float:OldHealth);
public CheckNopHealth(playerid, Float:Health, Float:OldHealth)
{
new Float:NewHealth;
GetPlayerHealth(playerid, NewHealth);
if(NewHealth != OldHealth) Kick(playerid);
return 1;
}
Правда не проверял на работоспособность. Но избавит от добавления кучи строк и избавит мод от вызова GetPlayerHealth для каждого игрока каждую секунду. Да и ложных срабатываний не должно быть.

UPD: Если присутствует в моде анти-гм, можно спокойно добавить в этот код нужные переменные, хранящие здоровье, и присвоить им новое значение здоровья

как только SPAWN меня кикнуло!

underwoker
21.08.2014, 03:57
как только SPAWN меня кикнуло!
У тебя другая функция выдачи HP. Замени на эту.

iStrange
26.08.2014, 02:26
Довольно таки не плохо и познавательно. Благодарю.

VeRyNaYa
01.05.2015, 13:47
НОП блокирует пакеты от сервера, которые несут в себе информацию о смене HP игроку через серверную функцию. (далее я расписал своё негодование по поводу твоих проверок, но...)
Кажется я понял то, какого результата ты пытаешься добиться. Раз игрок блокирует НОПом пакеты с SetPlayerHealth, значит здоровье его не меняется. Следовательно мы можем чуть увеличить значение, которое мы посылаем игроку, а после сделать проверку на то, изменилось ли у него здоровье или нет. Но я бы сделал так:


stock SetPlayerHealthEx(playerid, Float:Health)
{
new Float:OldHealth;
GetPlayerHealth(playerid, OldHealth);
SetPlayerHealth(playerid, Health);
if(Health != OldHealth) SetTimerEx("CheckNopHealth", 1000, 0, "iff", playerid, Health, OldHealth);
return 1;
}

forward CheckNopHealth(playerid, Float:Health, Float:OldHealth);
public CheckNopHealth(playerid, Float:Health, Float:OldHealth)
{
new Float:NewHealth;
GetPlayerHealth(playerid, NewHealth);
if(NewHealth != OldHealth) Kick(playerid);
return 1;
}
Правда не проверял на работоспособность. Но избавит от добавления кучи строк и избавит мод от вызова GetPlayerHealth для каждого игрока каждую секунду. Да и ложных срабатываний не должно быть.

UPD: Если присутствует в моде анти-гм, можно спокойно добавить в этот код нужные переменные, хранящие здоровье, и присвоить им новое значение здоровья

Код гораздо удобнее предложенного в теме, спасибо, буду пользоваться.

Vlad_Ray
18.09.2015, 22:09
НОП блокирует пакеты от сервера, которые несут в себе информацию о смене HP игроку через серверную функцию. (далее я расписал своё негодование по поводу твоих проверок, но...)
Кажется я понял то, какого результата ты пытаешься добиться. Раз игрок блокирует НОПом пакеты с SetPlayerHealth, значит здоровье его не меняется. Следовательно мы можем чуть увеличить значение, которое мы посылаем игроку, а после сделать проверку на то, изменилось ли у него здоровье или нет. Но я бы сделал так:


stock SetPlayerHealthEx(playerid, Float:Health)
{
new Float:OldHealth;
GetPlayerHealth(playerid, OldHealth);
SetPlayerHealth(playerid, Health);
if(Health != OldHealth) SetTimerEx("CheckNopHealth", 1000, 0, "iff", playerid, Health, OldHealth);
return 1;
}

forward CheckNopHealth(playerid, Float:Health, Float:OldHealth);
public CheckNopHealth(playerid, Float:Health, Float:OldHealth)
{
new Float:NewHealth;
GetPlayerHealth(playerid, NewHealth);
if(NewHealth != OldHealth) Kick(playerid);
return 1;
}
Правда не проверял на работоспособность. Но избавит от добавления кучи строк и избавит мод от вызова GetPlayerHealth для каждого игрока каждую секунду. Да и ложных срабатываний не должно быть.

UPD: Если присутствует в моде анти-гм, можно спокойно добавить в этот код нужные переменные, хранящие здоровье, и присвоить им новое значение здоровья

Не работает :C
P.S. Знаю что старая темка :/

Daniel_Cortez
20.09.2015, 12:48
Не работает :C
P.S. Знаю что старая темка :/
Не люблю отвечать цитатами на цитаты, но всё же...

А у меня машина не едет. Помоги и я тебе помогу =\
Больше информации.

vovandolg
28.12.2015, 00:46
Код:


stock SetPlayerHealthEx(playerid, Float:Health)
{
new Float:OldHealth;
GetPlayerHealth(playerid, OldHealth);
SetPlayerHealth(playerid, Health);
if(Health != OldHealth) SetTimerEx("CheckNopHealth", 1000, 0, "iff", playerid, Health, OldHealth);
return 1;
}

forward CheckNopHealth(playerid, Float:Health, Float:OldHealth);
public CheckNopHealth(playerid, Float:Health, Float:OldHealth)
{
new Float:NewHealth;
GetPlayerHealth(playerid, NewHealth);
if(NewHealth != OldHealth) Kick(playerid);
return 1;
}
Опробовал этот код, вывод что кикает если юзать SetPlayerHealthEx
И не кикает если юзать SetPlayerHealth
:wacko: (по моему кто то написал код и не проверил его)

Desulaid
28.12.2015, 01:17
Я просто оставлю это здесь: http://pro-pawn.ru/showthread.php?10586-dc_anti_hp_hack