-- vim:ts=4:sw=4:noet -- PtokaX OpComExtra.lua 1.1 (Sedulus/20030314) tested on PtokaX 0.3.2.4 IceCube-III-fix3 -- based on OpComExtra.lua for DCH++ by Sedulus -- created for Cop][Killer of the [TropiCo.se] network -- no rights reserved (although it would be nice if you kept my name in here) -- -- changes 1.1: -- * return 1 on commands, so command is not shown in main chat -- * added a number to the file{} table, so you can choose if you want it in pm or mainchat -- (when called from mainchat, that is) -- bot_name = "-OpComExtra-" max_table_siz = 8 -- the maximum number of nick/times per IP and ip/times per nick stored max_history_siz = 100 -- the maximum number of last logins recorded file = { -- location of the text files (make sure they have a final CRLF) faq = {"scripts/faq.txt", 1}, -- {filename, 1=pm,0=mainchat} network = {"scripts/network.txt", 0}, -- {filename, 1=pm,0=mainchat} rules = {"scripts/rules.txt", 0}, -- {filename, 1=pm,0=mainchat} } -- -- start -- IPTable = {} -- store info about IP's here NickTable = {} -- store info about Nicks here HistoryTable = {} -- store last logins -- Gets called upon arrival of a chat or pm message function clientMessage( client, msg, loc ) if msg == "help" then local str = "\r\n".. "This hub uses Sedulus's PtokaX OpComExtra lua script. ".. "You can do the following by typing the command in the main chat or in a pm:\r\n".. "\r\n".. "!faq read the faq\r\n".. "!history [num] get last [num] logins (ops only)\r\n".. "!ipinfo get info on the ip (ops only)\r\n".. "!network read about our network\r\n".. "!rules read the rules\r\n".. "!userinfo get info on the user (ops only)\r\n".. "\r\n".. "It also supports the $UserIP [name] extension for retrieving ones own IP." messageClient( client, loc, bot_name, str ) return 0 -- 0, or PtokaX won't send you his !help elseif strsub( msg, 1, 7 ) == "ipinfo " then if client.bOperator then local ip = strsub( msg, 8 ) if IPTable[ ip ] then local str = "ipinfo on: "..ip.."\r\n" for key, elem in IPTable[ ip ] do if key ~= "n" then str = str..elem.."\r\n" end end messageClient( client, loc, bot_name, str ) else messageClient( client, loc, bot_name, "no ipinfo on: "..ip ) end end return 1 elseif strsub( msg, 1, 9 ) == "userinfo " then if client.bOperator then local nick = strsub( msg, 10 ) if NickTable[ nick ] then local str = "userinfo on: "..nick.."\r\n" for key, elem in NickTable[ nick ] do if key ~= "n" then str = str..elem.."\r\n" end end messageClient( client, loc, bot_name, str ) else messageClient( client, loc, bot_name, "no userinfo on: "..nick ) end end return 1 elseif msg == "history" or strsub( msg, 1, 8 ) == "history " then if client.bOperator then local num = tonumber( strsub( msg, 10 ) ) local start local last = getn( HistoryTable ) if not num or num <= 0 or num > last then start = 1 else start = last - num + 1 end local str = "last login history:\r\n" for i = start, last do str = str..i.."\t"..HistoryTable[ i ].."\r\n" end messageClient( client, loc, bot_name, str ) end return 1 elseif msg == "faq" or msg == "network" or msg == "rules" then if loc == 1 then -- when called from pm, put results in pm messageClient( client, 1, bot_name, readFile( file[msg][1] ) ) else -- when called from mainchat, let file[what?][2] decide where to put it messageClient( client, file[msg][2], bot_name, readFile( file[msg][1] ) ) end return 1 end end -- Gets called when a new user connects function userConnected( client ) local nick = client.sName local ip = client.sIP local level = client.bOperator if not level then level = 0 else level = 1 end -- create tables if not IPTable[ ip ] then IPTable[ ip ] = {} end if not NickTable[ nick ] then NickTable[ nick ] = {} end -- remove first so we scroll (max_table_siz/max_history_siz) if getn( IPTable[ ip ] ) == max_table_siz then tremove( IPTable[ ip ], 1 ) end if getn( NickTable[ nick ] ) == max_table_siz then tremove( NickTable[ nick ], 1 ) end if getn( HistoryTable ) == max_history_siz then tremove( HistoryTable, 1 ) end -- add newest entry tinsert( IPTable[ ip ], date()..": ["..level.."] "..nick ) tinsert( NickTable[ nick ], date()..": "..ip ) tinsert( HistoryTable, date()..": ["..level.."] "..nick.." ("..ip..")" ) end -- Checks if this is a message for us function isMessageForMe( data ) local ret,c,msg = strfind( data, "^%b<> !(.*)|$" ) if ret then return msg,0 elseif strsub( data, 1, 5 ) == "$To: " then local n,i,dst,src,chatname,msg n,i,dst,src,chatname,msg = strfind( data, "$To: ([^ ]+) From: ([^ ]+) $<([^ ]+)> !(.*)|$" ) if not n then return nil end if dst == bot_name then return msg,1 end end return nil end -- Send client a message function messageClient( client, where, from, msg ) if where == 0 then client:SendData( "<"..from.."> "..msg.."|" ) elseif where == 1 then client:SendPM( from, msg.."|" ) end end -- return file contents function readFile( filename ) local fd,err = readfrom( filename ) local str = "" if not fd then str = "read `"..filename.."': "..err else while 1 do local tmp = read( "*l" ) if tmp then str = str..tmp.."\r\n" else break end end readfrom() end str = strsub( str, 1, strlen( str ) - 1 ) -- remove the last LF return str end -- Event: script startup function Main() frmHub:RegBot( bot_name ) end -- Event: arrival of data function DataArrival( curUser, sData ) -- pm or chat to us? local msg,loc = isMessageForMe( sData ) if msg then return clientMessage( curUser, msg, loc ) end -- $UserIP extension if strsub( sData, 1, 8 ) == "$UserIP " then local ret,c,nick = strfind( sData, "^%$UserIP ([^ |]+)|$" ) if ret and nick == curUser.sName then curUser:SendData( "$UserIP "..nick.." "..curUser.sIP ) end end end -- Event: new user function NewUserConnected( curUser ) return userConnected( curUser ) end -- Event: new op function OpConnected( curUser ) return userConnected( curUser ) end