Last active
December 13, 2015 18:18
-
-
Save boxmein/4954288 to your computer and use it in GitHub Desktop.
IRC bot in Lua using luasocket for http://tpt.io/@jenn4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "socket" | |
--[[ Configuration ]]-- | |
__DEBUG = true -- USE THIS! | |
serv = "chat.eu.freenode.net" | |
nick = "jenn4|luabot" | |
user = nick | |
mode = "0" | |
realname = "jenn4|luabot" | |
channels = "#jenn4,#powder-bots" -- You can stack channels like #ch1,#ch2 NO SPACES! | |
prefix = "!!" -- Careful to make sure both of those are replaced | |
--[[ /Configuration ]]-- | |
function sendInitialConfig() | |
print ("-- Sending configuration... --") | |
s:send("NICK " .. nick .. "\r\n") -- NICK jenn4|bot | |
s:send("USER " .. user .. " " .. mode .. " * " .. " :" .. "LuaBot" .. "\r\n") -- USER jenn4|bot 8 * :LuaBot | |
s:send("JOIN " .. channels .. "\r\n") | |
end | |
function init() | |
print ("-- jenn4's bot --") | |
print("-- Initializing... --") | |
s = socket.tcp() | |
s:connect(serv, 6667) | |
socket.sleep(7) -- Wait for a bit for it to get your commands | |
sendInitialConfig() | |
startListen() | |
end | |
function startListen() | |
while true do | |
local st, status, partial = s:receive("*l") | |
-- *l listens to lines and removes \n | |
if __DEBUG then print("st: " .. st .."; partial: ".. partial) end | |
if status == "closed" then | |
print ("!! Status is closed, I think we lost connection") | |
break | |
end | |
handleRawIRC(partial) | |
end | |
print ("!! Listening loop stopped") | |
os.exit(0) | |
end | |
function handleRawIRC(rawstring) | |
-- Rawstring = ":boxmein!~boxmein@unaffiliated/boxmein PRIVMSG #powder-bots :Just using this to get raw mes..." | |
local rawarr = explode(rawstring, " ") | |
local rawdata = {} | |
-- I'm pretty sure this block below will make your life much much easier. | |
rawdata.hostmask = table.remove(rawarr, 1) -- :[email protected] | |
rawdata.hostmask = string.sub(rawdata.hostmask, 2) -- Remove the : | |
rawdata.sender = rawdata.hostmask:match "^[^!]*" -- Extracts nickname from the hostmask above | |
rawdata.irccommand = table.remove(rawarr, 1) -- Shift the first element off, the IRC command "PRIVMSG", "JOIN" | |
rawdata.channel = table.remove(rawarr, 1) -- can be either #channel OR your nickname when private messaging! | |
rawdata.message = string.sub(implode(rawarr, " "), 2) -- Removes the : at the front | |
rawdata.args = explode(rawdata.message, " ") -- Contains each word separate, useful in IRC commands | |
if __DEBUG then | |
print ("<< " .. rawstring) | |
print (".hostmask = " .. rawdata.hostmask) | |
print (".irccommand = " .. rawdata.irccommand) | |
print (".sender = " .. rawdata.sender) | |
print (".message = " .. rawdata.message) | |
end | |
-- Some default IRC handlers | |
if rawdata.irccommand == "PING" then | |
sendRawIRC("PONG :"..rawstring:match"^PING :(.*)") | |
elseif rawdata.irccommand == "PRIVMSG" then | |
--TODO: It's a channel message! This means I can parse this! | |
end | |
end | |
-- [[ Utility functions go below ]] -- | |
function sendCTCP(channel, data) -- Sends a CTCP request to user or channel, saying data. | |
sendRawIRC("PRIVMSG " ..channel.." :\x01"..data.."\x01") | |
end | |
function joinChan(channel) -- Joins the specified channel | |
sendRawIRC("JOIN "..channel) | |
end | |
function respondTo(rawdata, message) | |
end | |
function sendRawIRC(data) -- The most important utility, IRC data! Also good to log in here | |
if __DEBUG then print (">> " .. data) end -- PUT THESE EVERYWHERE | |
s:send(data .. "\r\n") | |
end | |
-- [[ Functions that should not have to be implemented ]] -- | |
function implode(list, delimiter) -- = Array => String. | |
-- Delimiter appends the character to every element | |
local len = #list | |
if len == 0 then | |
return "" | |
end | |
local string = list[1] | |
for i = 2, len do | |
string = string .. delimiter .. list[i] | |
end | |
return string | |
end | |
function explode(text, delimiter) | |
local list = {}; local pos = 1 | |
if string.find("", delimiter, 1) then | |
-- We'll look at error handling later! | |
error("delimiter matches empty string!") | |
end | |
while 1 do | |
local first, last = string.find(text, delimiter, pos) | |
print (first, last) | |
if first then | |
table.insert(list, string.sub(text, pos, first-1)) | |
pos = last+1 | |
else | |
table.insert(list, string.sub(text, pos)) | |
break | |
end | |
end | |
return list | |
end | |
-- [[ Crude error handling off StackOverflow ]] -- | |
_HandlingError = 0 | |
function errors(errobj) | |
if( _HandlingError == 0 ) then | |
_HandlingError = 1 | |
local errStr = tostring(errobj) or "" | |
if( type(errobj)=='table' ) then | |
errStr = "Table: {" .. table.concat(errobj, ',') .. "}" | |
end | |
print("Error: \"" .. errStr .. "\"") | |
--for k,v in pairs(_G) do print("GLOBAL:" , k,v) end | |
if( type(errobj)=='thread' ) then | |
print(debug.traceback(errobj)) | |
else | |
print(debug.traceback('',2)) | |
end | |
_HandlingError = 0 | |
end | |
return false | |
end | |
xpcall(init(), errors) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment