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

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

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

beat_brick.gif У меня нет слов.
Я все это и сам вижу из кода. Но заниматься реверс-инжинирингом и восстанавливать их содержимое у меня нет времени. Если тебе нужна помощь, потрудись предоставить ВСЮ необходимую информацию. В данном случае - содержимое этих файлов.

Автор: MaxFox 2.2.2012, 15:42

Цитата(Enyby @ 2.2.2012, 16:29) *
beat_brick.gif У меня нет слов.
Я все это и сам вижу из кода. Но заниматься реверс-инжинирингом и восстанавливать их содержимое у меня нет времени. Если тебе нужна помощь, потрудись предоставить ВСЮ необходимую информацию. В данном случае - содержимое этих файлов.

да не вопрос...

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 как вариант может имееть следующее содержание
Это ты называешь таблицей диапазонов, с которой будет работать скрипт? big_smile.gif
Это у тебя обычный текстовый файл, а не таблица.
Не, ну можно через это работать, только это будет называться лечить гланды с помощью проктолога..

Автор: MaxFox 2.2.2012, 16:46

Цитата(Ksan @ 2.2.2012, 17:40) *
Это ты называешь таблицей диапазонов, с которой будет работать скрипт? big_smile.gif
Это у тебя обычный текстовый файл, а не таблица.
Не, ну можно через это работать, только это будет называться лечить гланды с помощью проктолога..

ок, внимательно слушаю ваш вариант... я всего лишь подсмотрел вариант в другом скрипте...
и насчет текстового файла... это да... прямо открыл мне глаза, кэп =)

Автор: 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