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

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

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

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

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

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

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

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


Теперь а начале процедуры, например после проверки наличия флагов на канале проверяем сколько времени прошло с предыдущего запуска, и если прошло меньше, чем $cmd(delay) то сообщаем юзеру сколько ему еще ждать:
TCL: [ Скачать ] [ Скрыть ]
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 0
}


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


А эта процедура вернет правильные окончания для слов в сообщении о невозможности выполнить скрипт.
TCL: [ Скачать ] [ Скрыть ]
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}
    }
}


Все очень несложно, достаточно внимательно смотреть в чужие скрипты.
Если у кого-то есть другая реализация идеи то не стесняйтесь и поделитесь.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

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

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

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

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

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


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


Теперь добавляем в скрипт 2 дополнительные процедуры
TCL: [ Скачать ] [ Скрыть ]
    # Процедура инициализации антифлуда.
    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 0
}


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

Все работает вполне корректно. Дальнейшая модификация приветствуется.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

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

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

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

Добавьте в скрипт процедуру:
TCL: [ Скачать ] [ Скрыть ]
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
   }
}


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


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

Пример использования:
TCL: [ Скачать ] [ Скрыть ]
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
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

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

Сообщение tvrsh » 20 июл 2011 20:35

Еще парочка интересных вариантов.

1. В этом примере, если команда использовалась раньше, чем через floodtime секунд, то сообщение отправляется нотисом нику, который вызвал команду. Если позже, чем через floodtime секунд, то обычным сообщением в канал.
TCL: [ Скачать ] [ Скрыть ]
bind pub - !example PROCNAME
proc PROCNAME {nick host hand chan text} {

    # Время перед повторным использованием команды.
    set floodtime 120

    # Создаем глобальную переменную с временем последнего использования команды.
    if ![info exist ::mylastPROCNAME] {
        set ::mylastPROCNAME [unixtime]
    }

    # Выбираем способ отправки. Нотисом нику если использовал команду менее чем через 120 секунд.
    if {[expr [unixtime] - $::mylastPROCNAME] > $floodtime} {
        set type PRIVMSG
        set dest $chan
    } else {
        set type NOTICE
        set dest $nick
    }

    # Сохраняем время последнего использования команды.
    set ::mylastPROCNAME [unixtime]

    # Отправляем сообщение.
    puthelp "$type $dest :$text"
}


2. Тут схема почти такая же. Но флуд определяется количеством команд в промежуток времени.
TCL: [ Скачать ] [ Скрыть ]
bind pub - !example PROCNAME
proc PROCNAME {nick host hand chan text} {

    # Указываем сколько команд в какой промежуток времени можно использовать.
    set flood 3:180

    # Создаем счетчик.
    if ![info exists ::mylastPROCNAME] {
        set ::mylastPROCNAME 0
    }

    # Обрабатываем настройку флуда.
    set max [lindex [split $flood ":"] 0]
    set time [lindex [split $flood ":"] 1]

    # Выбираем способ отправки.
    if {$::mylastPROCNAME >= $max} {
        set type NOTICE
        set dest $nick
    } else {
        set type PRIVMSG
        set dest $chan
    }

    # Увеличиваем счетчик и после окончания времени уменьшаем его.
    incr ::mylastPROCNAME
    utimer $time [list incr ::mylastPROCNAME -1]

    # Отправляем сообщение.
    puthelp "$type $dest :$text"
}


(с) http://tclhelp.net/unb/39,1#125
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi


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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9

cron