diff options
author | ubq323 <ubq323@ubq323.website> | 2024-09-03 12:52:17 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2024-09-03 12:52:17 +0100 |
commit | b3de433cfd4e39c8fe6d776e258db3b44a3ddd39 (patch) | |
tree | 1467b88252052836f6344793eee2fe51b7dc5947 /irc.lua | |
parent | 643e4202f4c5a5ee7a87779ffb69928e685db451 (diff) |
more thing
Diffstat (limited to 'irc.lua')
-rw-r--r-- | irc.lua | 129 |
1 files changed, 129 insertions, 0 deletions
@@ -0,0 +1,129 @@ +local cqueues = require'cqueues' +local socket = require'cqueues.socket' +local condition = require'cqueues.condition' +local pprint = require'pprint' +local rirc = require'rirc' + +local Irc = {} + +function Irc.makepylon(pylonname, conf) + local self = {pylonname=pylonname} + local function conf_var(name) + assert(conf[name] ~= nil, 'missing conf field '..name) + self[name] = conf[name] + end + conf_var 'host' + conf_var 'port' + conf_var 'password' + conf_var 'nodename' + + self.outqueue = {} + self.outcv = condition.new() + setmetatable(self, {__index=Irc}) + return self +end + +function Irc.send(self, args) + args.source = args.source or self.nodename + rirc.send(self.sock, args) +end + +function Irc.connect(self) + self.sock = assert(socket.connect(self.host, self.port)) + self:send{'PASS', self.password, '0210-IRC', 'wilson|'} + self:send{'SERVER', self.nodename, '1', 'i am wilson'} +end + +function Irc.recving(self) + for line in self.sock:lines "*l" do + print('<', line) + local msg = rirc.parse(line) + if msg.op == 'PING' then + self:send{'PONG', msg.args[1]} + elseif msg.op == 'PRIVMSG' then + local ch = msg.args[1] + local body = msg.args[2] + local source = msg.source + local neighbors = self.network:neighbors_of(self.pylonname, ch) + pprint('gt neighbors', neighbors) + for _,other in ipairs(neighbors) do + other.pylon:enqueue { + channel = other.channel, + body = body, + source = source..'[i]' + } + end + end + end +end + +function Irc.sending(self) + local nicks_channels = {} + local function ensure_joined(nick, channel) + if not nicks_channels[nick] then + self:send{'NICK', nick, 1, 'username', 'host', 1, '+', 'realname'} + nicks_channels[nick] = {} + end + if not nicks_channels[nick][channel] then + self:send{source=nick, 'JOIN', channel} + nicks_channels[nick][channel] = true + end + end + local function say(nick, channel, body) + ensure_joined(nick, channel) + self:send{source=nick, 'PRIVMSG', channel, body} + end + + say('WILSON', '#test', 'i am wilson') + + while true do + while #self.outqueue > 0 do + local queue = self.outqueue + self.outqueue = {} + for _, outmsg in pairs(queue) do + assert(say(outmsg.source, outmsg.channel, outmsg.body)) + end + end + self.outcv:wait() + end +end + +function Irc.enqueue(self, message) + table.insert(self.outqueue, message) + self.outcv:signal() +end + +function Irc.run(self, cq, network) + self.network = network + self:connect() + cq:wrap(self.recving, self) + cq:wrap(self.sending, self) +end + + +local cq = cqueues.new() +local conf = { + host = 'localhost', + port = '6667', + password = 'mypassword', + nodename = 'wilson.ubq323', +} + +local dummy_pylon = { + enqueue = function(self, msg) + print(string.format( + "%s <%s> | %s", + msg.channel, msg.source, msg.body)) + end +} + +local network = {neighbors_of = function(self, pylonname, channel) + print('looking for neighbors of '..pylonname..', '..channel) + return { + {pylon = dummy_pylon, channel='#bridge'} + } +end} + +local pylon = Irc.makepylon('test', conf) +pylon:run(cq, network) +pprint(cq:loop()) |