-- disconnect logger -- debug gives log from strange disconnects (dropped users) -- Change opchat name in name where u want to recieve the massage ------------------------------------------------------------------------------- --// CHILL CODE \u2122 //-- -- table.ordered( [comp] ) -- from http://lua-users.org/wiki/OrderedAssociativeTable -- -- Lua 5.x add-on for the table library. -- Table using sorted index. Uses binary table for fast Lookup. -- http://lua-users.org/wiki/OrderedTable by PhilippeFremy -- table.ordered( [comp] ) -- Returns an ordered table. Can only take strings as index. -- fcomp is a comparison function behaves behaves just like -- fcomp in table.sort( t [, fcomp] ). function table.ordered(fcomp) local newmetatable = {} -- sort func newmetatable.fcomp = fcomp -- sorted subtable newmetatable.sorted = {} -- behavior on new index function newmetatable.__newindex(t, key, value) if type(key) == "string" then local fcomp = getmetatable(t).fcomp local tsorted = getmetatable(t).sorted table.binsert(tsorted, key , fcomp) rawset(t, key, value) end end -- behaviour on indexing function newmetatable.__index(t, key) if key == "n" then return table.getn( getmetatable(t).sorted ) end local realkey = getmetatable(t).sorted[key] if realkey then return realkey, rawget(t, realkey) end end local newtable = {} -- set metatable return setmetatable(newtable, newmetatable) end --// table.binsert( table, value [, comp] ) -- -- LUA 5.x add-on for the table library. -- Does binary insertion of a given value into the table -- sorted by [,fcomp]. fcomp is a comparison function -- that behaves like fcomp in in table.sort(table [, fcomp]). -- This method is faster than doing a regular -- table.insert(table, value) followed by a table.sort(table [, comp]). function table.binsert(t, value, fcomp) -- Initialise Compare function local fcomp = fcomp or function( a, b ) return a < b end -- Initialise Numbers local iStart, iEnd, iMid, iState = 1, table.getn( t ), 1, 0 -- Get Insertposition while iStart <= iEnd do -- calculate middle iMid = math.floor( ( iStart + iEnd )/2 ) -- compare if fcomp( value , t[iMid] ) then iEnd = iMid - 1 iState = 0 else iStart = iMid + 1 iState = 1 end end local pos = iMid+iState table.insert( t, pos, value ) return pos end -- Iterate in ordered form -- returns 3 values i, index, value -- ( i = numerical index, index = tableindex, value = t[index] ) function orderedPairs(t) return orderedNext, t end function orderedNext(t, i) i = i or 0 i = i + 1 local index = getmetatable(t).sorted[i] if index then return i, index, t[index] end end ------------------------------------------------------------------------------- target="OpChat" who = {}; erroronread = 0; socketerror = 0; timeout = 0; tot = 0; function EventDisconnect(nick, data) if string.find(data, "redirected") then return end if string.find(data, "State ") then for i,j in string.gfind (data, "(%a+:?) (%a+),*") do -- PMToNick ("", target, "DEBUG: " .. i .. " " .. j .. " " .. data); if (i == "Nick") then nick = j; elseif (i == "Reason:") then s,e = string.find (data, "Reason:"); reason = string.sub (data, e+1, -2); end end data = reason; end if string.find(data, "Error on read") then erroronread = (erroronread or 0 ) + 1 tot = (tot or 0 ) + 1 who[nick] = (who[nick] or 0 ) + 1 PMToNick("", target, "User " .. nick .. " disconnected: total "..tot.." / "..erroronread.." " .. data.." "..nick.." is seen "..(who[nick] or 0 ).." times"); return end if string.find(data, "Socket error") then socketerror = (socketerror or 0 ) + 1 tot = (tot or 0 ) + 1 who[nick] = (who[nick] or 0 ) + 1 PMToNick("", target, "User " .. nick .. " disconnected: total "..tot.." / "..socketerror.." " .. data.." "..nick.." is seen "..(who[nick] or 0 ).." times"); return end if string.find(data, "Timeout") then timeout = (timeout or 0 ) + 1 tot = (tot or 0 ) + 1 who[nick] = (who[nick] or 0 ) + 1 PMToNick("", target, "User " .. nick .. " disconnected: total "..tot.." / "..timeout.." " .. data.." "..nick.." is seen "..(who[nick] or 0 ).." times"); return end tot = (tot or 0 ) + 1 who[nick] = (who[nick] or 0 ) + 1 PMToNick("", target, "User " .. nick .. " disconnected: total "..tot.." ".. data.." "..nick.." is seen "..(who[nick] or 0 ).." times"); end function disconreport(nick, data) count = 0; tmp = table.ordered(function (a, b) return a < b; end); for k,v in pairs (who) do tmp[k] = v; count = count + 1; end; output = "Disconnect Report\n\n"; if (tot == 0) then output = output .. "No disconnects."; return output; end; output = output .. " Total disconnects: " .. tot .. "\n"; output = output .. " Total users: " .. count .. "\n"; output = output .. " Disconnect reasons:\n" output = output .. " Error on read " .. erroronread .. " (" .. string.format ("%2.2f", 100*erroronread/tot) .. "%)\n"; output = output .. " Socket Error " .. socketerror .. " (" .. string.format ("%2.2f", 100*socketerror/tot) .. "%)\n"; output = output .. " Timeout " .. timeout .. " (" .. string.format ("%2.2f", 100*timeout/tot) .. "%)\n"; other = tot - erroronread - socketerror - timeout; output = output .. " Others " .. other .. " (" .. string.format ("%2.2f", 100*other/tot) .. "%)\n"; output = output .. "\nTop reconnecting users:\n"; count = 0; for i,k,v in orderedPairs(tmp) do output = output .. " " .. k .. " " .. v .. "\n"; count = count + 1; if (count > 10) then break; end; end; return output; end PMToNick("", target, "Script started."); RegCommand ("disconreport", "", "Generate a disconnect report");