PDA

Просмотр полной версии : [Вопрос] Анти флуд SendClientMessage



Freaky
29.01.2017, 18:41
Возможно ли как то сделать так что бы SendClientMessage выводился 1 раз, а далее начинался КД допустим на 10 сек. Зачем это?

Допустим, для того что бы например когда у игрока нету ключей от машины и он пытается в нее сесть, он не смог бы флудить себе "У вас нет ключей от этого транспорта".

VVWVV
29.01.2017, 18:49
Лучшее, по моему, решение - сделать проверку на время последнего отправленного сообщения.

(Код не проверял)


stock PrintMessage(playerid, color, const message[])
{
const TIME_MSG_INTERVAL = 1000;

static
flood_ticks[MAX_PLAYERS],
tick;

tick = GetTickCount();

if(tick - flood_ticks[playerid] >= TIME_MSG_INTERVAL)
SendClientMessage(playerid, color, message);

flood_ticks[playerid] = tick;

return 1;
}

DeimoS
29.01.2017, 18:51
if(нет_ключей)
{
static
antiflood[MAX_PLAYERS],
timestamp;

timestamp = gettime();
if(antiflood[playerid] <= timestamp)
{
SendCLientMessage(playerid, -1, "У вас нет ключей от этого транспорта");
}
antiflood[playerid]+=timestamp+10;
return 1;
}

Seviel
29.01.2017, 19:02
Можно ещё так:


if(Условие что нет ключей && GetPVarInt(playerid, "AntiflodKey") <= gettime())
{
SendCLientMessage(playerid, -1, "У вас нет ключей от этого транспорта");
SetPVarInt(playerid, "AntiflodKey", gettime());
}

Freaky
29.01.2017, 19:03
Лучшее, по моему, решение - сделать проверку на время последнего отправленного сообщения.

(Код не проверял)


new gLastMessageTime[MAX_PLAYERS];

stock PrintMessage(playerid, color, const message[])
{
const MESSAGE_INTERVAL = 10;
new current_time = gettime();
if (gLastMessageTime[playerid] < current_time)
return 0;
SendClientMessage(playerid, color, message);
gLastMessageTime[playerid] = current_time + MESSAGE_INTERVAL;
return 1;
}


То что нужно, но не работает, вариант DeimoS не подходит, т.к. хотелось бы использовать эту функцию не только для ключей (много где).

vovandolg
29.01.2017, 22:46
хм)


new gLastMessageTime[MAX_PLAYERS];

stock PrintMessage(playerid, color, const message[])
{
const MESSAGE_INTERVAL = 10;
new current_time = gettime();
if (gLastMessageTime[playerid] > current_time)
return 0;
SendClientMessage(playerid, color, message);
gLastMessageTime[playerid] = current_time + MESSAGE_INTERVAL;
return 1;
}

Long-
29.01.2017, 23:31
delete, ниже

DeimoS
29.01.2017, 23:37
Универсальную функцию сделать сложно без дополнительной мороки, ибо нужно как-то определять, повторяется ли сообщение или это совсем другое сообщение из другой части кода.
Мой вариант подразумевал то, что ты вручную будешь к каждому нужному сообщению делать проверки, но можно и сделать более универсальный вариант, который так же потребует правки существующего кода.


enum e_SERVER_MESSAGE_ANTIFLOOD// Тут перечисляются "ID" сообщений
{
MESSAGE_NAME_1,
MESSAGE_NAME_2,
MESSAGE_NAME_3
};

new server_message_antiflood_time[MAX_PLAYERS][e_SERVER_MESSAGE_ANTIFLOOD];// Название очень уникальное и оригинальное, ога

stock SendServerMessage(playerid, color, const message[], message_id, message_interval = 10)
{
static
smaf_timestamp;

/*Если не уверен, что сможешь самостоятельно контролировать валидность ID которые будет указывать - раскомментируй эту проверку
if(!(0 <= message_id < sizeof(server_message_antiflood_time[])))
return 1;
*/

smaf_timestamp = gettime();

if(server_message_antiflood_time[playerid][e_SERVER_MESSAGE_ANTIFLOOD:message_id] > smaf_timestamp)
return 1;
server_message_antiflood_time[playerid][e_SERVER_MESSAGE_ANTIFLOOD:message_id] = smaf_timestamp+message_interval;
return SendClientMessage(playerid, color, message);
}

Пример использования:

CMD:message_one(playerid, params[])
{
SendServerMessage(playerid, -1, "Сообщение №1", MESSAGE_NAME_1);
return 1;
}

CMD:message_two(playerid, params[])
{
SendServerMessage(playerid, -1, "Сообщение №2", MESSAGE_NAME_2);
return 1;
}

CMD:message_three(playerid, params[])
{
SendServerMessage(playerid, -1, "Сообщение №3", MESSAGE_NAME_3);
return 1;
}

Можешь так же для каждого конкретного сообщения свой интервал указывать после ID сообщения