Версия для печати темы
MyDC.ru _ Помощь по скриптам для PtokaX _ Скрипт рассылки сообщений
Автор: MaxFox 26.1.2012, 10:31
Всем привет. Хочу иметь скрипт рассылающий сообщения юзерам 1 раз при конекте на хаб, но если только этот юзер принадлежит определенному диапазону IP адресов. ДИапазоны чтобы можно было удобно добавлять или изменять.
Посмотрел, что имеется по данным темам... частично подходит OneSend, частично SendToRanges
Поковырялся сам, вот что получилось... но не выходит пока каменный цветок, прошу помощи =)
Код
path = debug.getinfo(1).source:match("^@?(.+[/\\]).-$"):gsub("\\","/")
Ranges = path.."rassilka.txt"
sMsg = "Текст для юзеров"
hFileName = "rasslka.dbs"
function string.InRange(ip,rnum)
local iIP = ip:iptonumber()
for i,v in ipairs(tRanges[rnum]) do
if v[1] <= iIP and iIP <= v[2] then
return true
end
end
end
function string.iptonumber(ip)
local i1, i2, i3, i4 = ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
if i1 then
local r = i1*16777216+i2*65536+i3*256+i4
if r < 0 then error(ip) end
return r
end
end
function LoadRanges()
local f = io.open(Ranges,"r")
if f then
tRanges,tRangeNames = {},{}
local rnum = 0
for line in f:lines() do
local ip1,ip2 = line:match("^(%d+%.%d+%.%d+%.%d+)%-(%d+%.%d+%.%d+%.%d+)")
if ip1 and ip2 then
if rnum > 0 then
table.insert(tRanges[rnum],{ip1:iptonumber(),ip2:iptonumber()})
end
else
local rname = line:match("^%[(.+)%]")
if rname then
rnum = rnum+1
tRanges[rnum] = {}
tRangeNames[rnum] = rname
end
end
end
f:close()
end
end
function OnStartup()
hFileName = Core.GetPtokaXPath().."scripts/"..hFileName
bot = SetMan.GetString(21)
assert(LoadRanges(),"Не удалось загрузить список диапазонов")
if loadfile(hFileName) then
dofile(hFileName)
end
if not tIpBase then tIpBase = {} end
end
function UserConnected(tUser)
if tUser.sIP:InRange(rnum) then
if not tIpBase[tUser.sIP] then
Core.SendPmToUser(tUser, sBot, sMsg)
tIpBase[tUser.sIP] = 1
SaveToFile(tIpBase, "tIpBase", hFileName)
end
end
end
function SaveToFile(tTable, sTableName, sFile)
local f = io.open(sFile, "r+")
if f then
Serialize(tTable, sTableName, f)
f:flush()
f:close()
end
end
function Serialize(tTable, sTableName, hFile, sTab)
sTab=sTab or ""
hFile:write(sTab..sTableName.." = {\n")
for i,v in pairs(tTable) do
local sKey=(type(i)=="string") and string.format("[%q]",i) or string.format("[%d]",i)
if(type(v)=="table") then Serialize(v,sKey,hFile,sTab.."\t")
else
local sValue=(type(value)=="string") and string.format("%q",v) or tostring(v)
hFile:write(sTab.."\t"..sKey.." = "..sValue)
end
hFile:write(",\n")
end
hFile:write(sTab.."}")
end
RegConnected = UserConnected
вот такая ошибка вылезает:
Код
rassilka.lua:51: Не удалось загрузить список диапазонов
rassilka.lua:8: bad argument #1 to 'ipairs' (table expected, got nil)
Я так полагаю ,что вторая следует из первой...
Автор: Enyby 26.1.2012, 10:52
Замени:
Код
path = debug.getinfo(1).source:match("^@?(.+[/\\]).-$"):gsub("\\","/")
На:
Код
path = Core.GetPtokaXPath()
Автор: MaxFox 26.1.2012, 12:45
Цитата(Enyby @ 26.1.2012, 11:52)
Замени:
Код
path = debug.getinfo(1).source:match("^@?(.+[/\\]).-$"):gsub("\\","/")
На:
Код
path = Core.GetPtokaXPath()
не помогло...
Автор: Enyby 26.1.2012, 12:53
Мде.
Код
Ranges = path.."scripts/rassilka.txt"
Файл должен там быть, иначе будет ошибка.
И
Код
function LoadRanges()
local f = io.open(Ranges,"r")
if f then
tRanges,tRangeNames = {},{}
local rnum = 0
for line in f:lines() do
local ip1,ip2 = line:match("^(%d+%.%d+%.%d+%.%d+)%-(%d+%.%d+%.%d+%.%d+)")
if ip1 and ip2 then
if rnum > 0 then
table.insert(tRanges[rnum],{ip1:iptonumber(),ip2:iptonumber()})
end
else
local rname = line:match("^%[(.+)%]")
if rname then
rnum = rnum+1
tRanges[rnum] = {}
tRangeNames[rnum] = rname
end
end
end
f:close()
return true
end
return false
end
Автор: MaxFox 26.1.2012, 12:55
Цитата(Enyby @ 26.1.2012, 13:53)
Мде.
Код
Ranges = path.."scripts/rassilka.txt"
Файл должен там быть, иначе будет ошибка.
И
Код
function LoadRanges()
local f = io.open(Ranges,"r")
if f then
tRanges,tRangeNames = {},{}
local rnum = 0
for line in f:lines() do
local ip1,ip2 = line:match("^(%d+%.%d+%.%d+%.%d+)%-(%d+%.%d+%.%d+%.%d+)")
if ip1 and ip2 then
if rnum > 0 then
table.insert(tRanges[rnum],{ip1:iptonumber(),ip2:iptonumber()})
end
else
local rname = line:match("^%[(.+)%]")
if rname then
rnum = rnum+1
tRanges[rnum] = {}
tRangeNames[rnum] = rname
end
end
end
f:close()
return true
end
return false
end
он там есть.. я проверял есесьно =)
и да.. ошбика ушла, осталась
Код
8: bad argument #1 to 'ipairs' (table expected, got nil)
Автор: Enyby 26.1.2012, 12:57
А изменения вышеуказанные ты внес? У меня работает. По крайней мере старт работает. Все остальное не проверял.
Автор: MaxFox 26.1.2012, 13:15
Цитата(Enyby @ 26.1.2012, 13:57)
А изменения вышеуказанные ты внес? У меня работает. По крайней мере старт работает. Все остальное не проверял.
он там есть.. я проверял есесьно =)
и да.. ошбика ушла, осталась
Код
8: bad argument #1 to 'ipairs' (table expected, got nil)
Автор: MaxFox 30.1.2012, 9:37
Цитата(MaxFox @ 26.1.2012, 14:15)
он там есть.. я проверял есесьно =)
и да.. ошбика ушла, осталась
Код
8: bad argument #1 to 'ipairs' (table expected, got nil)
ну таг?
Автор: Enyby 30.1.2012, 10:22
Код
function UserConnected(tUser)
if tUser.sIP:InRange(rnum) then
rnum не инициализировано перед вызовом. И вообще не ясно зачем оно тут.
Автор: MaxFox 2.2.2012, 14:22
Цитата(Enyby @ 30.1.2012, 11:22)
Код
function UserConnected(tUser)
if tUser.sIP:InRange(rnum) then
rnum не инициализировано перед вызовом. И вообще не ясно зачем оно тут.
Уважаемый, если вас не затруднит, не могли бы вы помочь с данным скриптом в полной мере...
Автор: Enyby 2.2.2012, 14:28
Не мог бы. Мне много чего тут не ясно. Например содержимое двух таблиц, загружающихся из файла, который тут не приведен. Судя по всему rnum означает номер диапазона. Только это лишено смысла, поскольку проверять нужно все диапазоны. Поэтому тут:
Код
function string.InRange(ip,rnum)
local iIP = ip:iptonumber()
for i,v in ipairs(tRanges[rnum]) do
Надо вставить перебор всех возможных rnum.
Автор: MaxFox 2.2.2012, 15:22
Цитата(Enyby @ 2.2.2012, 15:28)
Не мог бы. Мне много чего тут не ясно. Например содержимое двух таблиц, загружающихся из файла, который тут не приведен. Судя по всему rnum означает номер диапазона. Только это лишено смысла, поскольку проверять нужно все диапазоны. Поэтому тут:
Код
function string.InRange(ip,rnum)
local iIP = ip:iptonumber()
for i,v in ipairs(tRanges[rnum]) do
Надо вставить перебор всех возможных rnum.
в одном файле находятся указанные диапазоны, во второй файл пишутся ip которым уже было отправлено сообщение, чтобы при последующем конекте с этого ip сообщение не отправлялось.
Автор: Enyby 2.2.2012, 15:29
У меня нет слов.
Я все это и сам вижу из кода. Но заниматься реверс-инжинирингом и восстанавливать их содержимое у меня нет времени. Если тебе нужна помощь, потрудись предоставить ВСЮ необходимую информацию. В данном случае - содержимое этих файлов.
Автор: MaxFox 2.2.2012, 15:42
Цитата(Enyby @ 2.2.2012, 16:29)
У меня нет слов.
Я все это и сам вижу из кода. Но заниматься реверс-инжинирингом и восстанавливать их содержимое у меня нет времени. Если тебе нужна помощь, потрудись предоставить ВСЮ необходимую информацию. В данном случае - содержимое этих файлов.
да не вопрос...
rassilka.txt как вариант может имееть следующее содержание
Код
[Подсеть 1]
10.0.0.0-10.255.255.255
[Подсеть 2]
192.168.0.0-192.168.255.255
[Подсеть 3]
11.0.0.0-171.15.255.255
[Подсеть 4]
192.169.0.0-255.255.255.255
rasslka.dbs - изначально пустой, в последсвии он наполняется IP, например выглядит так:
Код
tIpBase = {
["89.251.107.9"] = 1,
["2.95.137.83"] = 1,
["178.74.121.145"] = 1,
["92.126.86.184"] = 1,
["77.120.154.155"] = 1,
["78.40.81.15"] = 1,
["46.72.23.247"] = 1,
["188.26.247.204"] = 1,
["10.181.80.173"] = 1,
["178.162.66.227"] = 1,
["2.25.80.57"] = 1,
["10.196.96.145"] = 1,
["79.99.217.19"] = 1,
["109.195.190.222"] = 1,
["92.100.2.30"] = 1,
["46.72.28.239"] = 1,
["195.49.206.242"] = 1,
["10.188.248.185"] = 1,
["213.111.181.72"] = 1,
["178.210.57.175"] = 1,
["213.222.227.76"] = 1,
["46.159.86.47"] = 1,
}
Автор: Ksan 2.2.2012, 16:40
Цитата
rassilka.txt как вариант может имееть следующее содержание
Это ты называешь таблицей диапазонов, с которой будет работать скрипт?
Это у тебя обычный текстовый файл, а не таблица.
Не, ну можно через это работать, только это будет называться лечить гланды с помощью проктолога..
Автор: MaxFox 2.2.2012, 16:46
Цитата(Ksan @ 2.2.2012, 17:40)
Это ты называешь таблицей диапазонов, с которой будет работать скрипт?
Это у тебя обычный текстовый файл, а не таблица.
Не, ну можно через это работать, только это будет называться лечить гланды с помощью проктолога..
ок, внимательно слушаю ваш вариант... я всего лишь подсмотрел вариант в другом скрипте...
и насчет текстового файла... это да... прямо открыл мне глаза, кэп =)
Автор: Ksan 2.2.2012, 17:58
MaxFox, посмотри на свою вторую таблицу. И сделай аналогичную таблицу, только вместо единичек вставляй вторую часть диапазонов в кавычках.
Вроде этого:
Код
tDiap = {
["10.0.0.0"] = {"10.255.255.255"},
}
Автор: MaxFox 2.2.2012, 19:54
Цитата(Ksan @ 2.2.2012, 18:58)
MaxFox, посмотри на свою вторую таблицу. И сделай аналогичную таблицу, только вместо единичек вставляй вторую часть диапазонов в кавычках.
Вроде этого:
Код
tDiap = {
["10.0.0.0"] = {"10.255.255.255"},
}
иии? в чем разница? просто хотелось бы более детального объяснения...
Автор: MaxFox 4.2.2012, 12:03
Цитата(MaxFox @ 2.2.2012, 20:54)
иии? в чем разница? просто хотелось бы более детального объяснения...
короче ну вас... вместо того чтобы помочь, развели тут полемику...
В итоге сделал по другому.. убрал файл диапазонов, закинул все в скрипт... в итоге получил что хотел...
пример скрипта:
Код
local sMsg = "Рассылаемый текст"
local hFileName = "rassilka.dbs"
local tRanks = {
{"10.10.10.0","10.10.10.255"},
}
function iIp(sIP)
local a, b, c, d = sIP:match"^(%d+)%.(%d+)%.(%d+)%.(%d+)$"
return a * 16777216 + b * 65536 + c * 256 + d
end
function OnStartup()
for k, v in ipairs(tRanks) do
tRanks[k][1], tRanks[k][2] = iIp(v[1]), iIp(v[2])
end
sBot = SetMan.GetString(21)
hFileName = Core.GetPtokaXPath().."scripts/"..hFileName
if loadfile(hFileName) then
dofile(hFileName)
end
if not tIpBase then tIpBase = {} end
end
function UserConnected(tUser)
local iIP = iIp(tUser.sIP)
for _, v in ipairs(tRanks) do
if iIP > v[1] and iIP < v[2] then
if not tIpBase[tUser.sIP] then
Core.SendPmToUser(tUser, sBot, sMsg)
tIpBase[tUser.sIP] = 1
SaveToFile(tIpBase, "tIpBase", hFileName)
end
end
end
end
function SaveToFile(tTable, sTableName, sFile)
local f = io.open(sFile, "r+")
if f then
Serialize(tTable, sTableName, f)
f:flush()
f:close()
end
end
function Serialize(tTable, sTableName, hFile, sTab)
sTab=sTab or ""
hFile:write(sTab..sTableName.." = {\n")
for i,v in pairs(tTable) do
local sKey=(type(i)=="string") and string.format("[%q]",i) or string.format("[%d]",i)
if(type(v)=="table") then Serialize(v,sKey,hFile,sTab.."\t")
else
local sValue=(type(value)=="string") and string.format("%q",v) or tostring(v)
hFile:write(sTab.."\t"..sKey.." = "..sValue)
end
hFile:write(",\n")
end
hFile:write(sTab.."}")
end
RegConnected = UserConnected
VipConnected = UserConnected