Skip to content

Instantly share code, notes, and snippets.

@boxmein
Last active December 13, 2015 18:18
Show Gist options
  • Save boxmein/4954288 to your computer and use it in GitHub Desktop.
Save boxmein/4954288 to your computer and use it in GitHub Desktop.
IRC bot in Lua using luasocket for http://tpt.io/@jenn4
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) -- :nickname!~realname@host.com
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