Last active
January 15, 2018 16:29
-
-
Save raelik/0dd5856d74d1839aeaa8bdc7e0475ba7 to your computer and use it in GitHub Desktop.
IRC Bridge for Eluna
This file contains 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
package.path = package.path .. ';lua_lib/?.lua;lua_lib/?/init.lua' | |
local irc = require("irc") | |
local mirc_colors = { | |
'FFFFFF', -- White | |
'000000', -- Black | |
'00007F', -- Blue | |
'009300', -- Green | |
'FF0000', -- Light Red | |
'7F0000', -- Brown | |
'9C009C', -- Purple | |
'FC7F00', -- Orange | |
'FFFF00', -- Yellow | |
'00FC00', -- Light Green | |
'009393', -- Cyan | |
'00FFFF', -- Light Cyan | |
'0000FC', -- Light Blue | |
'FF00FF', -- Pink | |
'7F7F7F', -- Grey | |
'D2D2D2' -- Light Grey | |
} | |
local repl = { | |
["\15"]="|cFF40FB40", | |
["\2"]="", | |
["\7"]="", | |
["\22"]="", | |
["\31"]="" | |
} | |
local events = {} | |
local bot = nil | |
local reg = false | |
local guid = CreateUint64(nil) -- empty guid for GM message | |
local function configure() | |
local output = { prefixes={}, channels={}, guilds={}, default_prefix={ text="IRC", color=11 } } | |
local results = CharDBQuery("SELECT * FROM irc_config LIMIT 1") | |
if results then | |
local row = results:GetRow() | |
output.user = { nick=row.nick, username=row.username, realname=row.realname } | |
output.connect = { host=row.host, port=row.port } | |
if row.secure == 1 then output.connect.secure = true end | |
output.connect_modes = row.connect_modes | |
if row.password then output.connect.password = row.password end | |
if row.nickserv_password then | |
output.nickserv = { name=row.nickserv, password=row.nickserv_password } | |
end | |
if row.add_modes or row.rem_modes then | |
output.modes = {} | |
if row.add_modes then output.modes.add = row.add_modes end | |
if row.rem_modes then output.modes.rem = row.add_modes end | |
end | |
end | |
results = CharDBQuery("SELECT * FROM irc_prefixes ORDER BY nick ASC") | |
if results then | |
repeat | |
local row = results:GetRow() | |
if row.nick == '' then | |
output.default_prefix = { text=row.prefix, color=row.color } | |
else | |
output.prefixes[row.nick] = { text=row.prefix, color=row.color } | |
end | |
until not results:NextRow() | |
end | |
results = CharDBQuery("SELECT * FROM irc_channels ORDER BY guildid ASC") | |
if results then | |
repeat | |
local row = results:GetRow() | |
output.channels[row.guildid] = row.channel | |
output.guilds[row.channel] = row.guildid | |
until not results:NextRow() | |
end | |
return output | |
end | |
local config = configure() | |
local function colorize(str, color) | |
return ("|cff%s%s|cff40FB40"):format(mirc_colors[color+1], str) | |
end | |
local function default_prefix() | |
return colorize(config.default_prefix.text, config.default_prefix.color) | |
end | |
local function register_chat() | |
return RegisterPlayerEvent(21, function(event, player, msg, chat_type, lang, guild) | |
local channel = config.channels[guild:GetId()] | |
if chat_type == 4 and channel then | |
bot:sendChat(channel, ("[\0038%s\15]: %s"):format(player:GetName(), msg)) | |
end | |
end) | |
end | |
local function register_login() | |
return RegisterPlayerEvent(3, function(event, player) | |
local channel = config.channels[player:GetGuildId()] | |
if channel then bot:sendChat(channel, ("%s has logged in."):format(player:GetName())) end | |
end) | |
end | |
local function register_logout() | |
return RegisterPlayerEvent(4, function(event, player) | |
local channel = config.channels[player:GetGuildId()] | |
if channel then bot:sendChat(channel, ("%s has logged out."):format(player:GetName())) end | |
end) | |
end | |
local function convert_mirc(str) | |
return string.gsub( | |
string.gsub( | |
string.gsub(str, "[|\2\7\15\22\31]", repl), "(\3%d%d?),%d%d?", "%1"), | |
"\3(%d%d?)", function(code) | |
return "|cFF" .. mirc_colors[code+1] | |
end) | |
end | |
local function send_guild(guild, pre, message) | |
local msg = ("|cFF40FB40[Guild] [%s]: %s"):format(pre, message) | |
local presz = string.len(pre) + 1 | |
local msgsz = string.len(msg) + 1 | |
-- SMSG_MESSAGECHAT 0x96 = 150 | |
-- 30 bytes is the non-string data length. | |
local packet = CreatePacket(150, msgsz + 30) | |
packet:WriteUByte(0) -- chat type (CHAT_MSG_SYSTEM) | |
packet:WriteLong(0) -- lang (Universal) | |
packet:WriteGUID(guid) -- sender guid (nil) | |
packet:WriteULong(0) -- flags | |
packet:WriteGUID(guid) -- recv guid (nil) | |
packet:WriteULong(msgsz) -- message size + 1 | |
packet:WriteString(msg) -- message | |
packet:WriteUByte(0) -- chat tag | |
GetGuildById(guild):SendPacket(packet) | |
end | |
local function start() | |
bot = irc.new(config.user) | |
bot:hook("OnDisconnect", function(message, errorOccurred) | |
reg = false | |
for key, value in pairs(events) do | |
if type(value) == "function" then | |
value() | |
elseif value ~= nil then | |
RemoveEventById(value) | |
end | |
events[key] = nil | |
end | |
if errorOccurred then | |
CreateLuaEvent(start, 5000, 1) | |
end | |
end) | |
bot:hook("OnConnect", function() | |
if config.nickserv then bot:sendChat(config.nickserv.name, ("IDENTIFY %s"):format(config.nickserv.password)) end | |
events.main_loop = CreateLuaEvent(function(event, delay, repeats) | |
bot:think() | |
end, 500, 0) | |
events.keepalive = CreateLuaEvent(function(event, delay, repeats) | |
bot:send(("PING :%s"):format(config.user.nick)) | |
end, 30000, 0) | |
-- events.packet_cancel = register_packet() | |
events.chat_cancel = register_chat() | |
events.login_cancel = register_login() | |
events.logout_cancel = register_logout() | |
end) | |
bot:hook("OnModeChange", function(user, target, modes) | |
local check_modes = ("+%s"):format(config.nickserv.password and "r" or config.connect_modes) | |
if (not reg) and target == config.user.nick and modes == check_modes then | |
reg = true | |
if config.modes then bot:setMode(config.modes) end | |
for k, channel in pairs(config.channels) do bot:join(channel) end | |
end | |
end) | |
bot:hook("OnJoin", function(user, channel) | |
local guild = config.guilds[channel] | |
if user.nick ~= config.user.nick and guild then | |
send_guild(guild, default_prefix(), ("%s has joined %s."):format(user.nick, channel)) | |
end | |
end) | |
bot:hook("OnPart", function(user, channel) | |
local guild = config.guilds[channel] | |
if user.nick ~= config.user.nick and guild then | |
send_guild(guild, default_prefix(), ("%s has left %s."):format(user.nick, channel)) | |
end | |
end) | |
bot:hook("OnQuitChannel", function(user, channel, msg) | |
local guild = config.guilds[channel] | |
if user.nick ~= config.user.nick and guild then | |
send_guild(guild, default_prefix(), ("%s has left %s. (Reason: %s)"):format(user.nick, channel, convert_mirc(msg))) | |
end | |
end) | |
bot:hook("OnChat", function(user, channel, message) | |
local guild = config.guilds[channel] | |
if guild then | |
local msg = string.gsub(message, "|", "||") | |
local pre = config.prefixes[user.nick] | |
if pre == nil then | |
pre = default_prefix() | |
msg = ("<%s> %s"):format(colorize(user.nick, 7), msg) | |
else | |
pre = colorize(pre.text, pre.color) | |
end | |
-- Convert mIRC codes | |
send_guild(guild, pre, convert_mirc(msg)) | |
end | |
end) | |
bot:connect(config.connect) | |
end | |
RegisterServerEvent(11, function() | |
pcall(bot.disconnect) | |
end) | |
RegisterServerEvent(16, function() | |
pcall(bot.disconnect) | |
end) | |
CreateLuaEvent(start, 500, 1) |
This file contains 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
CREATE TABLE `irc_config` ( | |
`nick` varchar(30) NOT NULL, | |
`username` varchar(32) NOT NULL, | |
`realname` varchar(255) NOT NULL, | |
`host` varchar(255) NOT NULL, | |
`port` smallint unsigned NOT NULL, | |
`secure` boolean NOT NULL DEFAULT 0, | |
`password` varchar(255), | |
`connect_modes` varchar(32) NOT NULL, | |
`add_modes` varchar(32), | |
`rem_modes` varchar(32), | |
`nickserv` varchar(30) NOT NULL DEFAULT 'NickServ', | |
`nickserv_password` varchar(32) | |
); | |
CREATE TABLE `irc_prefixes` ( | |
`nick` varchar(30) NOT NULL DEFAULT '', | |
`prefix` varchar(32) NOT NULL, | |
`color` tinyint unsigned NOT NULL, | |
PRIMARY KEY (`nick`) | |
); | |
CREATE TABLE `irc_channels` ( | |
`guildid` int(10) unsigned NOT NULL, | |
`channel` varchar(32) NOT NULL, | |
PRIMARY KEY (`guildid`), | |
UNIQUE KEY `channel` (`channel`) | |
); |
This file contains 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
diff --git a/handlers.lua b/handlers.lua | |
index cbd1c9e..8600bc4 100644 | |
--- a/handlers.lua | |
+++ b/handlers.lua | |
@@ -54,6 +54,7 @@ handlers["QUIT"] = function(o, prefix, msg) | |
if o.track_users then | |
for channel, v in pairs(o.channels) do | |
v.users[user.nick] = nil | |
+ o:invoke("OnQuitChannel", channel, user, msg) | |
end | |
end | |
o:invoke("OnQuit", user, msg) | |
diff --git a/init.lua b/init.lua | |
index 99ae7f5..8c895d2 100644 | |
--- a/init.lua | |
+++ b/init.lua | |
@@ -139,6 +139,8 @@ function meta_preconnect:connect(_host, _port) | |
self:think() | |
socket.select(nil, nil, 0.1) -- Sleep so that we don't eat CPU | |
until self.authed | |
+ | |
+ self:invoke("OnConnect") | |
end | |
function meta:disconnect(message) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment