PtokaX forum

Lua 5.3/5.2/5.1 Scripts (for PtokaX 0.4.0.0 and newer) => Finished Scripts => Topic started by: ATAG on 09 September, 2008, 21:11:57

Title: Connection Chcker Lua5.1 API2
Post by: ATAG on 09 September, 2008, 21:11:57
--[[
Connection Checker Lua 5.1 PtokaX API2
Version: 0.1-beta5
Author: ATAG
Release: 2008.09.09.

Require LuaSocket 2.0.2   

This script check the connection of active users.
It informs the users about the result. In case of bad settings
the searches and downloads are forwarded as passive one.

]]


--// Message to send if user's connection is bad
warnmsg = [[Your connection settings are WRONG, please correct it.

Check this link for help: http://www.dslreports.com/faq/6518

Your search and download will work as in passive mode.
]]

--// Message to send if user's connection is ok. Leave it empty ( "" ) to ignore this message.
okmsg = "Congratulation! Your connection settings are good :)"

--// Set it true if you want to correct search and download requests of bad active users.
--// Recommended to turn it off!!!
translate_to_passive = true -- true = enable | false = disable

--// timeout in seconds
connection_timeout = 90
--------------------------------------------------------------------------------------------------

socket = require("socket")

function OnStartup()
sBot =  SetMan.GetHubBot().sNick
tmr = TmrMan.AddTimer(1000)
for _,user in ipairs(Core.GetOnlineUsers()) do
if Core.GetUserValue(user,10) then
Core.SendToUser(user, "$RevConnectToMe "..sBot.." "..user.sNick.."|")
end
end
end

--------------------------------------------------------------------------------------------------

function UserConnected(tUser)
--// if user is in active mode, we send a RCTM command to get his port number
if Core.GetUserValue(tUser,10) then
if not tCheck[tUser.sNick] then
Core.SendToUser(tUser, "$RevConnectToMe "..sBot.." "..tUser.sNick.."|")
end
end
end
OpConnected = UserConnected
RegConnected = UserConnected

--------------------------------------------------------------------------------------------------

function UserDisconnected(tUser)
if tCheck[tUser.sNick] then
if tCheck[tUser.sNick] == 1 then
if translate_to_passive then
for i,v in ipairs(tSearch) do
if v[1] == tUser.sNick then
table.remove(tSearch,i)
break
end
end
end
elseif tCheck[tUser.sNick] == 0 then
for cli,v in pairs(tSock_Nick) do
if v[1] == tUser.sNick then
for i in ipairs(tSelect) do
if tSelect[i] == cli then
table.remove(tSelect,i)
break
end
end
tSock_Nick[cli] = nil
cli:shutdown()
cli:close()
break
end
end
end

tCheck[tUser.sNick] = nil
end
end
OpDisconnected = UserDisconnected
RegDisconnected = UserDisconnected

--------------------------------------------------------------------------------------------------

function ConnectToMeArrival(tUser, sData)
local _,_, remotenick, ip, port = sData:find("^%$ConnectToMe%s(%S+)%s([^:]+):(%d+)|$")

if not port then return false end

if not tCheck[tUser.sNick] then
tCheck[tUser.sNick] = {ip, port}
if remotenick == sBot then return true end
else
if translate_to_passive then
if tCheck[tUser.sNick] == 1 and (tCheck[remotenick] and tCheck[remotenick] == 2) then
Core.SendToNick(remotenick,"$RevConnectToMe "..tUser.sNick.." "..remotenick.."|")
return true
end
end
end
end

--------------------------------------------------------------------------------------------------

function RevConnectToMeArrival(tUser, sData)
local _,_, remotenick = sData:find("%s(%S+)|$")
if not remotenick then return true end
if translate_to_passive then
if tCheck[remotenick] and tCheck[remotenick] == 1 then
Core.SendToUser(tUser,"$RevConnectToMe "..remotenick.." "..tUser.sNick.."|")
return true
end
end
end

--------------------------------------------------------------------------------------------------

function MultiSearchArrival(tUser, sData)
if tCheck[tUser.sNick] and tCheck[tUser.sNick] ~= 2 then return true end
end

--------------------------------------------------------------------------------------------------

function MultiConnectToMeArrival(tUser, sData)
if tCheck[tUser.sNick] and tCheck[tUser.sNick] ~= 2 then return true end
end

--------------------------------------------------------------------------------------------------

function SearchArrival(tUser, sData)
if not translate_to_passive and tCheck[tUser.sNick] and tCheck[tUser.sNick] ~= 2 then return true end

local _,_,ip,port,srstring = sData:find("^%$Search%s([^:]+):(%d+)%s(.*)|$")

if not ip then return false end

-- active search

if not tCheck[tUser.sNick] then
tCheck[tUser.sNick] = {ip, port}
return false
end

if tCheck[tUser.sNick] == 1 then -- tested, wrong active mode user
--// cache it and send in next second with other search strings...
table.insert(tSearch, "$Search Hub:"..tUser.sNick.." "..srstring.."|")
return true
end
end

--------------------------------------------------------------------------------------------------

function OnTimer(tmr)
--// connect to clients
local cli,nick,ip,port,res,err
for nick in pairs(tCheck) do
if type(tCheck[nick]) == "table" then
cli = socket.tcp()
cli:settimeout(0) --// make it non-blocking

ip, port = unpack(tCheck[nick])
res, err = cli:connect(ip, port)
tSock_Nick[cli] = {nick,os.time()}
if res then --// connected
-- Debug(nick.." is OK")
CloseOk(cli, nick)
else
if err == "timeout" then --// timeouted
table.insert(tSelect,cli)
tCheck[nick] = 0

else --// unable to connect
AddBad(cli)
end
end
end
end

--// select previously "timeouted" sockets
local r,w,err = socket.select(tSelect,tSelect,0) --// 0 means non-blockig!

local now = os.time()
for i, cli in ipairs(tSelect) do
--// remove connected sockets
if r[cli] then

CheckConn(cli, i, cli:receive(1))

elseif w[cli] then

CheckConn(cli, i, cli:send("|"))

else
--// check timeout counter
if ( tSock_Nick[cli][2] + connection_timeout ) <= now then
AddBad(cli, i)
end
end
end

--// send queued search commands
if translate_to_passive and next(tSearch) then
-- wrap message
local wrap = {table.concat(tSearch)}
local len,n = #wrap[1],1
while len > 128000 do
local k = string.find(string.sub(wrap[n],1,128000),"|[^|]*$") --// search for last endpipe
if not k then k = 128000 end
wrap[n+1] = string.sub(wrap[n],k+1)
wrap[n] = string.sub(wrap[n],1,k)
len = #wrap[n+1]
n = n+1
end

if next(wrap) then
-- send message to active users
for nick, value in ipairs(tCheck) do
if value == 2 then
for _,msg in ipairs(wrap) do
Core.SendToNick(nick, msg)
end
end
end
end
tSearch = {}
end

collectgarbage("collect")
end

--------------------------------------------------------------------------------------------------

function CheckConn(cli, index, res, err)
if res then
CloseOk(cli, tSock_Nick[cli][1], index)
elseif err == "timeout" then
if tSock_Nick[cli][2] + 30 <= now then
AddBad(cli, index)
end
else
AddBad(cli, index)
end
end

--------------------------------------------------------------------------------------------------

senddebug = nil

function Debug(msg)
if senddebug then
UDPDbg.Send("[LUA] "..msg)
end
end

--------------------------------------------------------------------------------------------------

function AddBad(cli, index)
Core.SendToNick(tSock_Nick[cli][1], "<"..sBot.."> "..warnmsg.."|")
tCheck[tSock_Nick[cli][1]] = 1

if index then table.remove(tSelect,index) end
tSock_Nick[cli] = nil

cli:shutdown()
cli:close()
end

--------------------------------------------------------------------------------------------------

function CloseOk(cli, nick, index)
if okmsg ~= "" then
Core.SendToNick(nick, "<"..sBot.."> "..okmsg.."|")
end

if index then table.remove(tSelect,index) end
if tSock_Nick[cli] then tSock_Nick[cli] = nil end

cli:shutdown()
cli:close()

tCheck[nick] = 2
end

--------------------------------------------------------------------------------------------------

tCheck = {}
-- tCheck values:
-- 0 = not_checked
-- "table" = checking
-- 1 = wrong
-- 2 = good

tSearch = {} -- search queue
tSelect = {} -- test array
tSock_Nick = {} -- socket hash
Title: Re: Connection Chcker Lua5.1 API2
Post by: P_pan on 21 September, 2008, 16:47:08
nice job m8....

great addon... :)
Title: Re: Connection Chcker Lua5.1 API2
Post by: ?StIfFLEr?? on 25 September, 2008, 06:08:17
nice script
Title: Re: Connection Chcker Lua5.1 API2
Post by: 11hh on 26 September, 2008, 21:41:34
Very good this script, congratulate ! (http://www.hallmark.com/wcsstore/HallmarkStore/images/products/ecards/nfg2687.swf)