Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

MyDC.ru _ Помощь по скриптам для PtokaX _ Вопрос по скрипту регистрации

Автор: Отшельник 11.6.2009, 12:52

big_smile.gif У меня вопрос,а можно сделать "чёрный список для IP и ник" в скрипте  Registration_1_.v2.0.lua ( 14.3 килобайт ) : 14

Просто есть отдельные "люди" которых не хотелосьбы регистрировать на хабе (чтобы небыло возможности им общатса и скачивать),а просто когда меня нет за компом операторы без меня могу зарегистрировать тех "людей" (А банить нехочу их,просто чтобы не могли общатса и скачивать)...... eyes_droped.gif надеюсь поймёте что хотел этим сказать.
Если можно подскажите или добавьте,Зарание Спасибо! still_dreaming.gif

Автор: Nickolya 11.6.2009, 13:29

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

Код
tNicks = {
    ["mymeganick1"] = true,
    ["somenick"] = true,
    ["elsenick"] = true,
}

tIps = {
    ["127.0.0.1"] = true,
    ["89.3.1.57"] = true,
}

function ChatArrival(tUser)
    if tNicks[tUser.sNick] or tIps[tUser.sIP] then
        Core.SendToUser(tUser, "*** Вам запрещен вход на хаб, пока!")
        Core.Disconnect(tUser)
    end
end

Автор: Артём 10.7.2009, 13:12

2Nickolya
а как можно сделать чтобы диапазон ip запретить?

Автор: fixx 10.7.2009, 14:34

Код
tIpRange = {
"10.0.0.0-10.255.255.255",
}

Так вроде big_smile.gif
А дальше придется вот так:
Код
function UserConnected(tUser,sData)
    for i,e in pairs(tIpRange) do
        local _,_,ip1,ip2 = e:find"(%d+%p%d+%p%d+%p%d+)-(%d+%p%d+%p%d+%p%d+)"
        startip = Ip2Num(ip1)
        endip = Ip2Num(ip2)
        userip = Ip2Num(tUser.sIP)
        if userip > startip and userip < endip then
            Core.SendToUser(tUser, "*** Вам запрещен вход на хаб, пока!")
            Core.Disconnect(tUser)
        end
    end
end

Неуверен, что правильно, так примерно (не бейте меня)

Автор: district 10.7.2009, 14:36

Цитата
А банить нехочу их,просто чтобы не могли общатса и скачивать

Что за изощренный садизм big_smile1.gif Забанил бы, да и дело с концом, чтоб не мучались.

А по использованию метода "дисконнект" есть вот такое соображение. Не раз был свидетелем, как отключенный от хаба подлец на ГрейЛинке переподключается обратно в течение нескольких секунд, причем каждый раз с новым ником. По-моему стоит серьезно задуматься о применении дисконнекта, и нужна ли хабу эта бесконечная долбежка, особенно, если на хабе установлен скрипт, логирующий коннекты.

Цитата
а как можно сделать чтобы диапазон ip запретить?

Вопрос был задан не мне, ну да я думаю адресат не обидится )).
Чтобы запретить что-либо для какого-либо диапазона IP, нужно :
1. Преобразовать IP-адрес юзера в числовую форму.
2. Сравнить получившееся число с хранимыми где-нибудь в таблице значениями начала и конца диапазона (диапазонов). Если диапазонов несколько, нужно пробежать по всей таблице. И если будет найден такой диапазон, числовое выражение начала которого меньше или равно, а числовое выражение конца - больше или равно проверяемому значению (т.е. наш IP окажется "внутри" диапазона), то можно действовать. В общем все просто.

Автор: Артём 10.7.2009, 18:53

вы наверно не поняли мой первый вопрос.....я хотел что бы нерегистрировались юзеры ( не могли регистрироватся определённые ip или ник),а не дисконектило их. still_dreaming.gif

Автор: district 10.7.2009, 19:21

Да это так, к слову, про дисконнект, раз уж он тут в коде появился.
По поводу запрета регистрации. Нужно в боте, который заведует регистрацией, ловить команду вроде !regme, или какая принята в боте, и связывать ее с ником и IP подавшего команду. Ловить соответственно в ChatArrival'e...

Код
if sCmd == "regme" then
     if tBadNicks[tUser.sNick] or tBadIPs[tUser.sIP] then
        return true -- регистрация отклонена
else
     ... дальше процедура регистрации, как и положено для порядочных юзеров.


что касается запрета на регистрацию по признаку соответствия IP юзера какому-либо IP диапазону.
Думаю, можно сделать булеву переменную-индикатор, например bCanReg = true в начале проверки, а вот тот цикл, который привел fixx в случае обнаружения соответствия IP запрещенному к регистрации диапазону должен сбрасывать переменную в false
тогда условие запрета регистрации будет выглядеть примерно так :
Код
if tBadNicks[tUser.sNick] or tBadIPs[tUser.sIP] or not bCanReg then ...

Правда в том коде fixx'a есть пара-тройка ошибок, но это не смертельно, их можно и нужно уметь вылавливать самостоятельно.

Автор: Артём 10.7.2009, 19:24

eyes_droped.gif .... чесно не всё понял

Автор: fixx 11.7.2009, 0:30

Цитата(Артём @ 10.7.2009, 20:24) *
eyes_droped.gif .... чесно не всё понял

щас разрулим.
Ну, кто на нас с district!!??!!?? big_smile.gif

Код
Правда в том коде fixx'a есть пара-тройка ошибок, но это не смертельно, их можно и нужно уметь вылавливать самостоятельно.

о_О там всего-то 6 строк, где можно ошибиться unhappy.gif

Автор: district 11.7.2009, 2:14

Цитата
о_О там всего-то 6 строк, где можно ошибиться unhappy.gif

Ну вот смотри
Код
local _,_,ip1,ip2 = e:find"(%d+%p%d+%p%d+%p%d+)-(%d+%p%d+%p%d+%p%d+)"

1.Между двумя захватываемыми переменными стоит "минус". Это т.н. "magic character" (магический символ), а все такие символы нуждаются в "экранировании", т.е перед ними должен стоять знак "%". Иначе метод find не увидит этого минуса, и все что должно быть захвачено после этого минуса, тоже не будет обнаружено.
2.Не хватает общих скобок для всего выражения
Это самое явное. Т.е. должно быть так:
Код
local _,_,ip1,ip2 = e:find("(%d+%p%d+%p%d+%p%d+)%-(%d+%p%d+%p%d+%p%d+)")

Далее позанимаемся буквоедством и придирками))
3.Выражение
Код
"%d+%p%d+%p%d+%p%d+"

в принципе годится для того формата записи элементов в таблице, который был использован, но, думается, лучше сразу себя приучать к такому вот виду захвата :
Код
"%d+%.%d+%.%d+%.%d+"

это универсальный захват для IP-адреса, а тот захват который есть в твоем коде, может захватить и посчитать IP-адресом например вот такую белиберду:
Код
"6,7!8;5"

т.к. выражение
Код
%p

означает захват любого знака пунктуации.
Хотя, если мы работаем не с переменными, а с константами (т.е.значениями, жестко прописанными в самом коде), и эти наши константы гарантированно соответствуют формату IP-адреса, то захват может быть гораздо проще :
Код
local _,_,ip1,ip2 = e:find("(%S+)%-(%S+)")

(кучка любых непробельных символов, разделяющий знак "минус", и еще одна кучка символов)
4.Для операций присваивания значений переменным лучше юзать метод :
Код
local ip1,ip2 = e:match("(%d+%p%d+%p%d+%p%d+)%-(%d+%p%d+%p%d+%p%d+)")

а метод
Код
s:find()

использовать, когда требуется подтвердить условие :
Код
if s:find(...) then ...

5.Переменная i нигде в цикле не используется, поэтому оператор for для нашего случая может выглядеть так :
Код
for _,e in pairs(tIpRange) do

6.Переменную правильнее было бы назвать s вместо e, т.к. это строка, если только буква e в данном контексте не несет тайного, сакрального смысла big_smile1.gif А для себя и других, чтобы не запутаться, можно обозвать ее например sRange - буква s тут будет означать тип переменной по венгерской нотации (строка), а слово Range - смысл этой переменной ( диапазон).
7.Ну и наконец, в твоем коде не хватает функции преобразования IP-адреса в число.
Код
Ip2Num(sIP)


Ну и совсем для полного счастья можно было бы изменить сам способ хранения диапазонов в таблице
Код
tIpRanges = {["10.0.0.0"] = "10.0.255.255", ..., ...}

В таком варианте хранения необходимость в захватах отпадает, а цикл имеет такой вид:
Код
for k,v in pairs(tIpRanges) do
     local iIp1,iIp2 = Ip2Num(k),Ip2Num(v)
     if iUserIP >= iIp1 and iUserIp <= iIp2 then ... end
end

Переменная iUserIP (IP юзера в числовом виде) должна быть объявлена локальной и присвоена за пределами цикла и обязательно ПЕРЕД ним ( ну это понятно).
Код
local iUserIP = Ip2Num(tUser.sIP)

Автор: Артём 11.7.2009, 5:33

eyes_droped.gif ...... beat_brick.gif ......парни...если вам не трудно не моглибы вы сделать из того скрипта который я в первом посте приложил сразу....тобишь готовым,а то я совсем нечего не могу понять...Буду благодарен!!! still_dreaming.gif

Автор: district 11.7.2009, 6:48

Бери, пробуй...
Что добавлено. Режим регистрации равный 0 теперь (регистрация с подтверждением) включает теперь и проверку на соотв. ника и IP юзера значениям таблиц tRefusedNicks и tRefusedRanges. В таблицу tRefusedRanges можно вписывать и единичные IP в таком виде :

Код
["10.0.0.0"] = "10.0.0.0",


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

Сама функция проверки атрибутов юзера :
Код
function Refused(tUser)
    if tRefusedNicks[tUser.sNick] then return true; end
    local iIP = IPtoDec(tUser.sIP)
    for st,en in pairs(tRefusedRanges) do
        local ist,ien = IPtoDec(st),IPtoDec(en)
        if iIP >= st and iIP <= en then return true; end
    end
    return false
end

Тестировать не на чем, тестируй сам, если что - стучи, поправим.

 Registration_1_.v2.0.lua ( 15.82 килобайт ) : 3
 

Автор: Setuper 11.7.2009, 12:48

2district: Всё очень хорошо изложил, но вот по пункту 2 как раз таки наоборот.

Цитата(district @ 11.7.2009, 3:14) *
2.Не хватает общих скобок для всего выражения
Это самое явное. Т.е. должно быть так:
Код
local _,_,ip1,ip2 = e:find("(%d+%p%d+%p%d+%p%d+)%-(%d+%p%d+%p%d+%p%d+)")


Если у функции (или метода) всего лишь один аргумент, и этот аргумент является строкой без конкатенаций, то скобки можно и даже нужно опускать:
Код
local _,_,ip1,ip2 = e:find"(%d+%p%d+%p%d+%p%d+)%-(%d+%p%d+%p%d+%p%d+)"


Так как нагромождение скобками ухудшает читабельность кода, и скобки увеличивают размер кода big_smile.gif

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

Приведу пару примеров функций без скобок:
Код
MyFunc1"Всем пивет"
MyFunc2{[1] = 1, [2] = 1}

Автор: district 11.7.2009, 13:16

Цитата
Если у функции (или метода) всего лишь один аргумент, и этот аргумент является строкой без конкатенаций, то скобки можно и даже нужно опускать:

Что ж, век живи, век учись )) Запомним. Хотя честно скажу, по мне так со скобками понятнее (читабельнее) - особенно в конструкциях вроде :

Код
local sVar3 = (bCondition1 and sVar2) or sVar1


и тем более если что-то вроде :

Код
local bVar3 = ((bCondition1 and bVar2) or (bCondition2 and bVar1)) or false

Автор: Setuper 11.7.2009, 13:31

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

Скобки нужны только тем, кто не имел дела с языками программирования, или не проходил дискретную математику big_smile.gif

Автор: district 11.7.2009, 14:32

Первая формулировка была вернее :

Цитата
Скобки нужны только тем, кто не знает ни одного языка программирования, или не проходил высшую математику big_smile.gif

Думаю, таких деятелей, как обозначено в формулировке, кроме меня, на форуме еще немало наберется ))))
Поясню для форумчан, которые в ужасе прячутся под стол при виде слов "коньюнкция, дизъюнкция" и прочих нецензурных выражений :
Цитата
конъюнкция всегда выполняется перед дизъюнкцией

Это означает, на народном языке, примерно следующее.
В операции присваивания вроде :
Код
local sVar3 = (bCondition1 and sVar2) or sVar1

приоритет будет за оператором and , то есть, сначала будет проверено условие :
что есть такая переменная bCondition1 и ее значение в текущий момент равно true, и если это условие выполняется, то переменной sVar3 будет присвоено значение sVar2, а если условие не выполняется ( переменной bCondition1 вообще не существует или она равна false), то переменной sVar3 будет присвоено значение переменной sVar1
Поэтому, написать можно без скобок :
Код
local sVar3 = bCondition1 and sVar2 or sVar1

В общем, "ужос" big_smile1.gif
Артём, смотрю, вообще куда-то скрылся, свой ботик не забирает )) Наверное тоже пришел в ужос ))

Автор: Setuper 11.7.2009, 15:31

Тоже не правильно истолковал. Для единичного случая конечно же верно, однако для общего случая всё сложнее big_smile.gif

Пусть у нас есть некое общее выражение:

Код
local Var4 = Var1 and Var2 or Var3


В языке lua любое значение, кроме nil и false, равносильно булевому значению true.
Например, условие if true then равносильно условиям


и тд.

Условие if false then равносильно только условию if nil then


Однако, вернёмся к нашему выражению:
Код
local Var4 = Var1 and Var2 or Var3


Для языка lua существуют правила:

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




Сначала будет проверяться конъюнкция: Var1 and Var2

1. Если Var1 не false и не nil, и Var2 не false и не nil, то по правилу оба операнда являются истинными, следовательно должен возвращаться последний, то есть Var2.

2. Если Var1 равен false или nil, а Var2 не false и не nil, то по правилу вернётся ложный операнд, то есть Var1.

3. Если Var1 не false и не nil, а Var2 равен false или nil, то по правилу вернётся ложный операнд, то есть Var2.

4. Если Var1 равен false или nil, и Var2 равен false или nil, то истинных операндов нет. В этом случае вернётся первый операнд, то есть Var1.

Результат конъюнкции - это также некоторая булева переменная.
После конъюнкции выполняется дизъюнкция: Var1_2 or Var3
где переменная Var1_2 - это результат предыдущего шага (конъюнкции).

В случае дизъюнкции тоже можно расписать всё по пунктам, как я это сделал для конъюнкции. Однако, я думаю итак всё понятно.
Главное знать 2 правила и умело пользоваться приоритетами операций.

На последок напишу приоритеты всех операщий. Самый высокий приоритет у операции возведения в степень (^), дальше по убыванию.

Код
1) ^
2) not   #     - (unary)
3) *     /     %
4) +     -
5) ..
6) <     >     <=    >=    ~=    ==
7) and
8) or


Пример:
Код
if -5^3 * 2 + 15 > 13 and not 6 or 10 then


Равносильно:
Код
if ((((((-(5^3)) * 2) + 15) > 13) and (not 6)) or 10) then

Автор: district 11.7.2009, 15:52

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

Автор: Setuper 11.7.2009, 16:07

Кстати, о смысле этой записи. Код:

Код
local sVar3 = bCondition1 and sVar2 or sVar1

является результатом оптимизации кода:
Код
local sVar3
if bCondition1 then
  sVar3 = sVar2
else
  sVar3 = sVar1
end


big_smile.gif

Автор: district 11.7.2009, 16:24

Истинно так, буквально неделю как подглядел эту фишку и начал внедрять активно. Дас Бог вскорости смогу и от скобок отказаться. Очень нравится фишка, элегантно, понятно, без замкнутых условий и объявления переменной за пределами условия, а значит, без лишней писанины и путаницы.

Автор: Артём 11.7.2009, 17:05

2district Спасибо за помощь,но скрипт не делает то что хотелосьбы (((
Хоть и ник вписал хоть диапозон,всеравно не хочет отклонять в регистрации автоматически ( можно ещё к диапозону ip добавить просто ip,чтобы и диапозон был и просто одному ip'y) big_smile.gif
P.Sух...извеняюсь нащёд единичного ip не заметил.....спасиб,но всеравно скрипт не хочет работать)
P.S По нику скрипт работает замечательно " *** Заявка на регистрацию пользователя с ником: <Артём> и IP-адресом: 10.хх.хх.хх была отклонена в автоматическом режиме.",жаль что по самому ипу неработает,выдаёт ошибку (Registration_1_.v2.1.lua:127: attempt to compare string with number( и пропускает команду в чат

Автор: district 11.7.2009, 21:59

Исправил, передобавил, этот и по ипу работает

Setuper
А в логических вентилях (в простейшей цифровой схемотехнике), которые я еще худо-бедно помню, и впрямь не так как описано

Цитата
local Var4 = Var1 and Var2 or Var3

3. Если Var1 не false и не nil, а Var2 равен false или nil, то по правилу вернётся ложный операнд, то есть Var2.


Там принято так :
Логическое И -
1,1 = 1
1,0 = 0
0,1 = 0
0,0 = 0

Логическое ИЛИ
1,1 = 1
1,0 = 1
0,1 = 1
0,0 = 0

Вот эту разницу в подходах и впрямь важно запомнить.

Автор: Setuper 11.7.2009, 22:54

Ага. Я немного неверно написал. Пардон. Действительно оба должны быть истинными при конъюнкции.

Да да, ты верно расписал правила двоичной логики big_smile.gif

Автор: Артём 12.7.2009, 11:15

Большое Спасибо district,Работает,ошибок пока что нету,надеюсь и не будит still_dreaming.gif

Автор: fixx 12.7.2009, 11:42

Вот спасибо district и Setuper, узнал много чего, о чем даж недогадывался.
А способ, где district продемонстрировал отказ от захвата - ваще фокус какой-то.
ЗЫ Тему в закладки big_smile.gif

Автор: Артём 12.7.2009, 13:19

Хм....раньше без пароля не регистрировало,а щас регистрирует и скрипт сам пароль выдает ((((( (ошибок нету beat_plaster.gif )

Автор: district 12.7.2009, 13:51

Это потому, что в скрипте изначально заложена разница - если режим саморегистрации, то без пароля не зарегистрируешься. А если режим регистрации с подтверждением, то в случае, когда пароль не введен, скрипт сам генерирует пароль.
Пресечь это дело несложно.
Сразу после

Код
local _,_,pass = string.find(sData, "%b<>%s+%S+%s+(%S+)")

(стр.173)
нужно приписать вот такое условие :
Код
if not pass then Core.SendToNick(tUser.sNick,"<"..sBot.."> Обязательно введите пароль для регистрации!")     return true; end

т.е. сделать так же, как и при саморегистрации.

А вот это условие :
Код
if pass == nil then    
pass = tostring(math.random(os.date("%H%M%S")))
end

можно закомментировать или вовсе удалить.

Автор: Артём 12.7.2009, 14:11

это давно прописанно....и работало,но сейчас отказуется почемуто eyes_droped.gif

Автор: Артём 13.7.2009, 2:48

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

Автор: district 13.7.2009, 3:35

Значит, не было ничего "давно прописано". Как может не работать простейшее условие?
Советую еще арфографею и легсигу поправить в коде, специально трогать не стал.

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

 Registration_1_.v2.0.lua ( 15.83 килобайт ) : 4
 

Автор: Артём 13.7.2009, 9:45

district
eyes_droped.gif ..... victory.gif работает... dribble.gif я тя люблю)))) БОЛЬШУЩЕЕ спасибо тебе за реализацию этого скрипта