Версия для печати темы
MyDC.ru _ Помощь по скриптам для PtokaX _ Вопрос по скрипту регистрации
Автор: 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",
}
Так вроде
А дальше придется вот так:
Код
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
Цитата
А банить нехочу их,просто чтобы не могли общатса и скачивать
Что за изощренный садизм
Забанил бы, да и дело с концом, чтоб не мучались.
А по использованию метода "дисконнект" есть вот такое соображение. Не раз был свидетелем, как отключенный от хаба подлец на ГрейЛинке переподключается обратно в течение нескольких секунд, причем каждый раз с новым ником. По-моему стоит серьезно задуматься о применении дисконнекта, и нужна ли хабу эта бесконечная долбежка, особенно, если на хабе установлен скрипт, логирующий коннекты.
Цитата
а как можно сделать чтобы диапазон ip запретить?
Вопрос был задан не мне, ну да я думаю адресат не обидится )).
Чтобы запретить что-либо для какого-либо диапазона IP, нужно :
1. Преобразовать IP-адрес юзера в числовую форму.
2. Сравнить получившееся число с хранимыми где-нибудь в таблице значениями начала и конца диапазона (диапазонов). Если диапазонов несколько, нужно пробежать по всей таблице. И если будет найден такой диапазон, числовое выражение начала которого меньше или равно, а числовое выражение конца - больше или равно проверяемому значению (т.е. наш IP окажется "внутри" диапазона), то можно действовать. В общем все просто.
Автор: Артём 10.7.2009, 18:53
вы наверно не поняли мой первый вопрос.....я хотел что бы нерегистрировались юзеры ( не могли регистрироватся определённые ip или ник),а не дисконектило их.
Автор: 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
.... чесно не всё понял
Автор: fixx 11.7.2009, 0:30
Цитата(Артём @ 10.7.2009, 20:24)
.... чесно не всё понял
щас разрулим.
Ну, кто на нас с
district!!??!!??
Код
Правда в том коде fixx'a есть пара-тройка ошибок, но это не смертельно, их можно и нужно уметь вылавливать самостоятельно.
о_О там всего-то 6 строк, где можно ошибиться
Автор: district 11.7.2009, 2:14
Цитата
о_О там всего-то 6 строк, где можно ошибиться
Ну вот смотри
Код
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 в данном контексте не несет тайного, сакрального смысла
А для себя и других, чтобы не запутаться, можно обозвать ее например
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)
Автор: 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
Тестировать не на чем, тестируй сам, если что - стучи, поправим.
Автор: 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+)"
Так как нагромождение скобками ухудшает читабельность кода, и скобки увеличивают размер кода
Точно также скобки можно опускать, когда в этот самый единственный аргумент у функции записывается конструктор таблицы.
Приведу пару примеров функций без скобок:
Код
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
В данных конструкциях тем более скобки бесполезны, так как во всех языках программирования конъюнкция всегда выполняется перед дизъюнкцией. Это даже никогда не обсуждается.
Скобки нужны только тем, кто не имел дела с языками программирования, или не проходил дискретную математику
Автор: district 11.7.2009, 14:32
Первая формулировка была вернее :
Цитата
Скобки нужны только тем, кто не знает ни одного языка программирования, или не проходил высшую математику
Думаю, таких деятелей, как обозначено в формулировке, кроме меня, на форуме еще немало наберется ))))
Поясню для форумчан, которые в ужасе прячутся под стол при виде слов "коньюнкция, дизъюнкция" и прочих нецензурных выражений :
Цитата
конъюнкция всегда выполняется перед дизъюнкцией
Это означает, на народном языке, примерно следующее.
В операции присваивания вроде :
Код
local sVar3 = (bCondition1 and sVar2) or sVar1
приоритет будет за оператором
and , то есть, сначала будет проверено условие :
что есть такая переменная
bCondition1 и ее значение в текущий момент равно
true, и если это условие выполняется, то переменной
sVar3 будет присвоено значение
sVar2, а если условие не выполняется ( переменной
bCondition1 вообще не существует или она равна
false), то переменной
sVar3 будет присвоено значение переменной
sVar1Поэтому, написать можно без скобок :
Код
local sVar3 = bCondition1 and sVar2 or sVar1
В общем, "ужос"
Артём, смотрю, вообще куда-то скрылся, свой ботик не забирает )) Наверное тоже пришел в ужос ))
Автор: Setuper 11.7.2009, 15:31
Тоже не правильно истолковал. Для единичного случая конечно же верно, однако для общего случая всё сложнее
Пусть у нас есть некое общее выражение:
Код
local Var4 = Var1 and Var2 or Var3
В языке lua любое значение, кроме nil и false, равносильно булевому значению true.
Например, условие if true then равносильно условиям
- if 0 then
- if 1 then
- if 100 then
- if -5 then
- if "" then
- if "str" then
- if {} then
и тд.
Условие if false then равносильно только условию if nil then
Однако, вернёмся к нашему выражению:
Код
local Var4 = Var1 and Var2 or Var3
Для языка lua существуют правила:
- В результат конъюнкции, в случае истинности обеих операндов, возвращается второй, в случае ложности обоих - первый, в остальных случаях - ложный.
- В результат дизъюнкции возвращается тот операнд, который является истинным, если истинных операндов много или они вовсе отсутствуют, то возвращается первый.
Сначала будет проверяться конъюнкция: 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
Автор: district 11.7.2009, 16:24
Истинно так, буквально неделю как подглядел эту фишку и начал внедрять активно. Дас Бог вскорости смогу и от скобок отказаться. Очень нравится фишка, элегантно, понятно, без замкнутых условий и объявления переменной за пределами условия, а значит, без лишней писанины и путаницы.
Автор: Артём 11.7.2009, 17:05
2district Спасибо за помощь,но скрипт не делает то что хотелосьбы (((
Хоть и ник вписал хоть диапозон,всеравно не хочет отклонять в регистрации автоматически ( можно ещё к диапозону ip добавить просто ip,чтобы и диапозон был и просто одному ip'y)
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
Ага. Я немного неверно написал. Пардон. Действительно оба должны быть истинными при конъюнкции.
Да да, ты верно расписал правила двоичной логики
Автор: Артём 12.7.2009, 11:15
Большое Спасибо district,Работает,ошибок пока что нету,надеюсь и не будит
Автор: fixx 12.7.2009, 11:42
Вот спасибо district и Setuper, узнал много чего, о чем даж недогадывался.
А способ, где district продемонстрировал отказ от захвата - ваще фокус какой-то.
ЗЫ Тему в закладки
Автор: Артём 12.7.2009, 13:19
Хм....раньше без пароля не регистрировало,а щас регистрирует и скрипт сам пароль выдает ((((( (ошибок нету )
Автор: 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
это давно прописанно....и работало,но сейчас отказуется почемуто
Автор: Артём 13.7.2009, 2:48
Ну помогите плиз...что я только уже не пробовал,не хочет он работать ( тобишь проводить регистрацию по обяз. введ.паролю)
Автор: district 13.7.2009, 3:35
Значит, не было ничего "давно прописано". Как может не работать простейшее условие?
Советую еще арфографею и легсигу поправить в коде, специально трогать не стал.
Цитата
розсмотрят ваше заявление
и
Цитата
незная
, а также мелочь вроде отсутствия пробела после запятой и непонятно почему продолжение предложения с заглавной буквы, после запятой.