Проблема с античитом (hp)
#1

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

PHP Code:
new Float:HP[PLAYERS]; // Глоб. переменная хранящая ХП игрока
stock SetHP(playerid,Float:h// Установка ХП
{
HP[playerid]=h;
SetPlayerHealth(playerid,h);
}
public 
Test() // Вызывается раз с секунду (античит)
{
new 
Float:h;
for(new 
i=GetMaxPlayers()-1;i!=-1;--i)
{
if(!
IsPlayerConnected(i))continue;
GetPlayerHealth(i,h);
if(
h>HP[i])
{
/*Action*/
}
}
return 
1;

!!!: (в public Test как вы видите нет остановки цикла если условие выполнится, то есть античит должен вызываться бесконечное кол-во раз, а он вызывается 1 раз, из этого следует, что потом все нормально).

При использовании следующего действия иногда срабатывает античит:

PHP Code:
new Float:h;GetPlayerHealth(playerid,h);
new 
Float:r=random(4)+1;
SetHP(playerid,floatsub(h,r)); 
Решил вывести значения:

PHP Code:
new Float:h;GetPlayerHealth(playerid,h);
new 
Float:r=random(4)+1;
SetHP(playerid,floatsub(h,r));
new 
Float:h2;GetPlayerHealth(playerid,h2);
format(STR,128,"GPH (DO): %.1f | R: %.1f | floatsub: %.1f | GPH(Posle): %.1f | HP[i]: %.1f",h,r,floatsub(h,r),h2,HP[playerid]);
SendClientMessage(playerid,white,STR); 
Получаю следующее:



То есть HP до действия и после одинаковое. Прошу знающих в этом деле людей помочь в решении данной проблемы, заранее благодарю за помощь.

p.s. Тролей прошу пройти мимо.
Reply
#2

Я вижу у вас тут переменная объявлена для PLAYERS, а в цикле GetMaxPlayers() да еще и с конца. Может это из-за того, что значение PLAYERS < GetMaxPlayers() и в цикле вы пытаетесь использовать несуществующую ячейку переменной?

P.S. На счет примера изменения хп, который вы сделали. А вы попробуйте изменить хп своей функцией, а потом хотя бы через секунду проверку сделать: значения не будут одинаковыми, поверьте

Также советую сделать вот так, будет быстрее:

pawn Code:
new Float:HP[PLAYERS];

stock _SetPlayerHealth(playerid, Float:amount)
{
    HP[playerid] = amount;
    return SetPlayerHealth(playerid, amount);
}
#define SetPlayerHealth _SetPlayerHealth
Reply
#3

Quote:

PLAYERS < GetMaxPlayers()

PLAYERS = 20. GetMaxPlayers так же (т.к. 20 слотов на сервере).

Quote:

А вы попробуйте изменить хп своей функцией

Вроде как так и делаю:

PHP Code:
new Float:h;GetPlayerHealth(playerid,h); 
new 
Float:r=random(4)+1
SetHP(playerid,floatsub(h,r)); // Установка хп моей функцией. 
Протестировал:

PHP Code:
new Float:HP[PLAYERS];
stock _SetPlayerHealth(playeridFloat:amount)
{
    
HP[playerid] = amount;
    return 
SetPlayerHealth(playeridamount);
}
#define SetPlayerHealth _SetPlayerHealth 
проехался 100.000 раз, ваш способ выдал (GetTickCount):
116
Мой:
153
1.000.000 раз:
Ваш: 1116
Мой: 1746
Действительно быстрее).
Reply
#4

Quote:
Originally Posted by Maikkk
View Post
PLAYERS = 20. GetMaxPlayers так же (т.к. 20 слотов на сервере).



Вроде как так и делаю:

PHP Code:
new Float:h;GetPlayerHealth(playerid,h); 
new 
Float:r=random(4)+1
SetHP(playerid,floatsub(h,r)); // Установка хп моей функцией. 
На момент проверки (в примере) хп еще не успело измениться. Ключевое словосочетание было "хотя бы через секунду проверку сделать".

Тогда попробуйте сделать цикл проще:

pawn Code:
new Float:h;
for(new i; i < PLAYERS; i++)
{
    if(!IsPlayerConnected(i)) continue;
    GetPlayerHealth(i, h);
    if(h > HP[i])
    {
        //бла-бла-бла
    }
}
Он, кстати, в вашем текущем цикле без проверки на то, подключен ли игрок, мог остановиться при получении хп несуществующего игрока. (Но я не уверен в этом)
Reply
#5

Quote:

Он, кстати, в вашем текущем цикле без проверки на то, подключен ли игрок, мог остановиться при получении хп несуществующего игрока. (Но я не уверен в этом)

Дико извиняюсь, поправил первый пост, в цикле у меня есть проверка. Наверное нужно хранить время последнего изменения хп +1 ? (gettime()+1) и потом проверять каждую секунду в цикле, если время соответствует времени на сервере --- сравниваем HP.
Reply
#6

Quote:
Originally Posted by Maikkk
View Post
Дико извиняюсь, поправил первый пост, в цикле у меня есть проверка. Наверное нужно хранить время последнего изменения хп +1 ? (gettime()+1) и потом проверять каждую секунду в цикле, если время соответствует времени на сервере --- сравниваем HP.
new Float:HP[PLAYERS], HPc[PLAYERS char];

pawn Code:
stock _SetPlayerHealth(playerid, Float:amount)
{
    HP[playerid] = amount, HPc{playerid} = 1;
    return SetPlayerHealth(playerid, amount);
}
#define SetPlayerHealth _SetPlayerHealth
В цикле делать дополнительную проверку, прежде чем что-то предпринимать против "читера":

pawn Code:
if(h > HP[i])
{
    if(HPc{i}) HPc{i} = 0;
    else
    {
        //карательные меры
    }
}
Как-то так...
Reply
#7

Хм... просто проверять выдавалось ли HP сервером или нет? (как бы доп. проверка)

p.s. И по поводу хранения времени, что думаете?
Reply
#8

Quote:
Originally Posted by Maikkk
View Post
Хм... просто проверять выдавалось ли HP сервером или нет? (как бы доп. проверка)

p.s. И по поводу хранения времени, что думаете?
Это почти тоже самое, что и хранить время, только быстрее и лучше.
Reply
#9

Quote:
Originally Posted by stabker
View Post
Это почти тоже самое, что и хранить время, только быстрее и лучше.
Хорошо, спасибо, опробую данный вариант завтра, и отпишусь здесь о результате. Задам вопрос не касающийся темы: в массиве такого вида new Test[PLAYERS char]; можно хранить числа только от 0 до 255 (выделяется всего 20 байтов? вместо 80)?
Reply
#10

Quote:
Originally Posted by Maikkk
View Post
Хорошо, спасибо, опробую данный вариант завтра, и отпишусь здесь о результате. Задам вопрос не касающийся темы: в массиве такого вида new Test[PLAYERS char]; можно хранить числа только от 0 до 255 (выделяется всего 20 байтов? вместо 80)?
Да. Для разных флагов, подсчетов крайне удобно и выгодно.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)