1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
local cqueues = require'cqueues'
local socket = require'cqueues.socket'
local pprint = require'pprint'
local rirc = require'rirc'
local Queue = require'queue'
local Irc = {}
function Irc._send(self, args)
args.source = args.source or self.nodename
local sent = rirc.send(self.sock, args)
print('>', sent)
end
function Irc.makepylon(pylonname, conf, cq, network)
local self = {
pylonname=pylonname,
cq = cq,
network = network,
inbox = Queue.make(),
}
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'
setmetatable(self, {__index=Irc})
return self
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.run(self)
self:_connect()
self.cq:wrap(self.recving, self)
self.cq:wrap(self.sending, self)
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 channel = msg.args[1]
local body = msg.args[2]
local source = msg.source
self.network:post(self.pylonname, channel, {
body = body,
source = source..'[i]'
})
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')
for ch, msg in self.inbox:iter() do
say(msg.source, ch, msg.body)
end
end
return Irc
-- local cq = cqueues.new()
-- local conf = {
-- host = 'localhost',
-- port = '6667',
-- password = 'mypassword',
-- nodename = 'wilson.ubq323',
-- }
-- local dummy_network = {
-- post = function(self, pylonname, channel, message)
-- pprint(pylonname, channel, message)
-- end
-- }
-- local pylon = Irc.makepylon('test', conf, cq, dummy_network)
-- pylon:run()
-- cq:wrap(function()
-- local i = 0
-- while true do
-- cqueues.sleep(1)
-- pylon.inbox:enqueue{
-- source = 'helen',
-- channel = '#test',
-- body = 'i am helen '..i,
-- }
-- i = i + 1
-- end
-- end)
-- pprint('cheese', cq:loop())
|