Ограничение на запуск скрипта.

Решение вопросов при работе с TCL скриптами.

Модератор: Модераторы

Ограничение на запуск скрипта.

Сообщение tvrsh » 12 окт 2008 19:40

В данном примере я покажу как можно запретить выполнение скрипта более одного раза в n секунд.

В меню настроек скрипта добавляем
Код: Выделить всё
set cmd(delay) 15
в этой переменной время в секундах через, которое возможен повторный запуск.

Далее в начале процедуры создаем область переменных cmd
Код: Выделить всё
variable cmd


Теперь а начале процедуры, например после проверки наличия флагов на канале проверяем сколько времени прошло с предыдущего запуска, и если прошло меньше, чем $cmd(delay) то сообщаем юзеру сколько ему еще ждать:
Код: Выделить всё
if {[info exists cmd(lasttime,$chan)] && [expr $cmd(lasttime,$chan) + $cmd(delay)] > [clock seconds]} {
      putserv "NOTICE $nick :Запрос не чаще одного раза в $cmd(delay) [lindex {. секунду секунды секунд} [numgrp $cmd(delay)]]."
      putserv "NOTICE $nick :Подождите [expr $cmd(delay) - [expr [clock seconds] - $cmd(lasttime,$chan)]] [lindex {. секунду секунды секунд} [numgrp [expr $cmd(delay) - [expr [clock seconds] - $cmd(lasttime,$chan)]]]] до следующего запроса."
      return
}


Если все в порядке, и время предыдущего запуска было позже, чем $cmd(delay), то, после выполнения процедуры сохраняем время когда она выполнилась, чтобы проводить проверку при следующей команде:
Код: Выделить всё
set cmd(lasttime,$chan) [clock seconds]


А эта процедура вернет правильные окончания для слов в сообщении о невозможности выполнить скрипт.
Код: Выделить всё
proc numgrp {number} {
    switch -glob -- "$number" {
        *11 {return 3}
        *12 {return 3}
        *13 {return 3}
        *14 {return 3}
        *1 {return 1}
        *2 {return 2}
        *3 {return 2}
        *4 {return 2}
        default {return 3}
    }
}


Все очень несложно, достаточно внимательно смотреть в чужие скрипты.
Если у кого-то есть другая реализация идеи то не стесняйтесь и поделитесь.
Аватара пользователя
tvrsh
 
Сообщения: 355
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Версия бота: Eggdrop 1.6.20

Re: Ограничение на запуск скрипта.

Сообщение tvrsh » 12 окт 2008 19:55

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

В меню настроек добавляем:
Код: Выделить всё
# Сколько команд за сколько секунд считать флудом и начинать игнорить юзера.
set cmd(flood) 5:60

# Время(мин) игнора.
set cmd(ignore) 10


Далее в начале процедуры создаем область переменных cmd
Код: Выделить всё
variable cmd


Теперь добавляем в скрипт 2 дополнительные процедуры
Код: Выделить всё
# Процедура инициализации антифлуда.
    proc flood_init {} {
    variable flood_array
    global cmd
      if {$cmd(ignore) < 1} {
        return 0
      }
      if {![string match *:* $cmd(flood)]} {
        putlog "variable flood not set correctly."
        return 1
      }
      set cmd(flood_num) [lindex [split $cmd(flood) :] 0]
      set cmd(flood_time) [lindex [split $cmd(flood) :] 1]
      set i [expr $cmd(flood_num) - 1]
      while {$i >= 0} {
        set flood_array($i) 0
        incr i -1
      }
    }
    ; flood_init

    # Процедура обновляет и возвращает флудстатус юзеров.
    proc flood_cmd {nick uhost} {
    variable flood_array
    global cmd
     if {$cmd(ignore) < 1} {
        return 0
      }
      if {$cmd(flood_num) == 0} {
        return 0
      }
      set i [expr $cmd(flood_num) - 1]
      while {$i >= 1} {
        set flood_array($i) $flood_array([expr $i - 1])
        incr i -1
      }
      set flood_array(0) [unixtime]
      set aaa [expr $cmd(flood_num) - 1]
      set bbb [expr [unixtime] - $flood_array($aaa)]
      if {$bbb <= $cmd(flood_time) } {
        putlog "flood detected from ${nick}."
        newignore [join [maskhost *!*[string trimleft $uhost ~]]] flooding $cmd(ignore)
        catch {unset cmd($uhost)}
        return 1
      } else {
        return 0
      }
    }


В первой процедуре происходит обработка значений из настройки скрипта и проверка верности их ввода. Вторая процедура будет срабатывать при каждой команде и проверять не превышел ли лимит использования команд за указанное время. В случае превышения, юзер будет игнориться ботом в течении времени указанного в настройках.

И теперь самое главное, сразу в начале вашей процедуры срабатывающей от использования команды добавляем следующий код
Код: Выделить всё
# Проверка на флуд.
if {[flood_cmd $nick $uhost]} {
return
}


В этой проверке в процедуру flood_cmd отсылаются $nick и $uhost юзера использовавшего команду.

Все работает вполне корректно. Дальнейшая модификация приветствуется.
Аватара пользователя
tvrsh
 
Сообщения: 355
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Версия бота: Eggdrop 1.6.20

Re: Ограничение на запуск скрипта.

Сообщение tvrsh » 22 июл 2009 23:41

Следующий вариант позволяет ограничить использование команды для user@host на определенном канале один раз в N секунд.

Добавьте в скрипт процедуру:
Код: Выделить всё
proc throttled {id time} {
   global throttled
   if {[info exists throttled($id)]} {
      return 1
   } {
      set throttled($id) [clock sec]
      utimer $time [list unset throttled($id)]
      return 0
   }
}


Далее, в процедуру, срабатывающую от команды, добавьте проверку:
Код: Выделить всё
if {[throttled $uhost,$chan 30]} {
      puthelp "PRIVMSG $chan :$nick: использование команды запрещено. (подождите или используйте ее на другом канале)"
   } else {
      puthelp "PRIVMSG $chan :$nick: разрешено (повторное использование через 30 секунд)"
   }


Где 30 это интервал в секундах, в течение которого, повторное использование для команды для $uhost на канале $chan запрещено.
Вместо сообщений можно вписать те действия, которые будут происходить при заданных условиях.

Пример использования:
Код: Выделить всё
bind pub n !test pub:test
proc pub:test {nick uhost hand chan text} {
   if {[throttled $uhost,$chan 30]} {
      puthelp "PRIVMSG $chan :$nick: использование команды запрещено. (подождите или используйте ее на другом канале)"
   } else {
      puthelp "PRIVMSG $chan :$nick: разрешено (повторное использование через 30 секунд)"
   }
}


Перевод поста с egghelp.org
Аватара пользователя
tvrsh
 
Сообщения: 355
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Версия бота: Eggdrop 1.6.20


Вернуться в TCL скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 1

cron