Software /
code /
prosody-modules
Comparison
mod_ircd/mod_ircd.lua @ 335:8b81257c9dc5
mod_ircd: Don't allow any command until nick has been set. Split out NAMES into a command.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 06 Feb 2011 05:05:49 +0100 |
parent | 329:febfb59502fc |
comparison
equal
deleted
inserted
replaced
334:54d4445cc5c6 | 335:8b81257c9dc5 |
---|---|
58 end | 58 end |
59 local function muc2irc(room) | 59 local function muc2irc(room) |
60 local channel, _, nick = jid.split(room); | 60 local channel, _, nick = jid.split(room); |
61 return "#"..channel, nick; | 61 return "#"..channel, nick; |
62 end | 62 end |
63 local rolemap = { | |
64 moderator = "@", | |
65 participant = "+", | |
66 } | |
67 local modemap = { | |
68 moderator = "o", | |
69 participant = "v", | |
70 } | |
63 | 71 |
64 local irc_listener = { default_port = 6667, default_mode = "*l" }; | 72 local irc_listener = { default_port = 6667, default_mode = "*l" }; |
65 | 73 |
66 local sessions = {}; | 74 local sessions = {}; |
67 local jids = {}; | 75 local jids = {}; |
89 local command, args = data:match("^%s*([^ ]+) *(.*)%s*$"); | 97 local command, args = data:match("^%s*([^ ]+) *(.*)%s*$"); |
90 if not command then | 98 if not command then |
91 return; | 99 return; |
92 end | 100 end |
93 command = command:upper(); | 101 command = command:upper(); |
102 if not session.nick then | |
103 if not (command == "USER" or command == "NICK") then | |
104 session.send(":" .. session.host .. " 451 " .. command .. " :You have not registered") | |
105 end | |
106 end | |
94 if commands[command] then | 107 if commands[command] then |
95 local ret = commands[command](session, args); | 108 local ret = commands[command](session, args); |
96 if ret then | 109 if ret then |
97 session.send(ret.."\r\n"); | 110 session.send(ret.."\r\n"); |
98 end | 111 end |
99 else | 112 else |
113 session.send(":" .. session.host .. " 421 " .. session.nick .. " " .. command .. " :Unknown command") | |
100 module:log("debug", "Unknown command: %s", command); | 114 module:log("debug", "Unknown command: %s", command); |
101 end | 115 end |
102 end | 116 end |
103 function session.send(data) | 117 function session.send(data) |
104 return conn:write(data.."\r\n"); | 118 return conn:write(data.."\r\n"); |
112 function irc_listener.ondisconnect(conn, error) | 126 function irc_listener.ondisconnect(conn, error) |
113 local session = sessions[conn]; | 127 local session = sessions[conn]; |
114 for _, room in pairs(session.rooms) do | 128 for _, room in pairs(session.rooms) do |
115 room:leave("Disconnected"); | 129 room:leave("Disconnected"); |
116 end | 130 end |
131 jids[session.full_jid] = nil; | |
132 nicks[session.nick] = nil; | |
117 sessions[conn] = nil; | 133 sessions[conn] = nil; |
118 end | 134 end |
119 | 135 |
120 function commands.NICK(session, nick) | 136 function commands.NICK(session, nick) |
121 if session.nick then | 137 if session.nick then |
122 session.send(":"..session.host.." 484 * "..nick.." :I'm afraid I can't let you do that, "..nick); | 138 session.send(":"..session.host.." 484 * "..nick.." :I'm afraid I can't let you do that, "..nick); |
139 --TODO Loop throug all rooms and change nick, with help from Verse. | |
123 return; | 140 return; |
124 end | 141 end |
125 nick = nick:match("^[%w_]+"); | 142 nick = nick:match("^[%w_]+"); |
126 if nicks[nick] then | 143 if nicks[nick] then |
127 session.send(":"..session.host.." 433 * "..nick.." :The nickname "..nick.." is already in use"); | 144 session.send(":"..session.host.." 433 * "..nick.." :The nickname "..nick.." is already in use"); |
139 function commands.USER(session, params) | 156 function commands.USER(session, params) |
140 -- FIXME | 157 -- FIXME |
141 -- Empty command for now | 158 -- Empty command for now |
142 end | 159 end |
143 | 160 |
144 local joined_mucs = {}; | |
145 function commands.JOIN(session, channel) | 161 function commands.JOIN(session, channel) |
146 if not session.nick then | |
147 return ":"..session.host.." 451 :You have not registered"; | |
148 end | |
149 | |
150 if not joined_mucs[channel] then | |
151 joined_mucs[channel] = { occupants = {}, sessions = {} }; | |
152 end | |
153 joined_mucs[channel].sessions[session] = true; | |
154 local room_jid = irc2muc(channel); | 162 local room_jid = irc2muc(channel); |
155 print(session.full_jid); | 163 print(session.full_jid); |
156 local room, err = c:join_room(room_jid, session.nick, { source = session.full_jid } ); | 164 local room, err = c:join_room(room_jid, session.nick, { source = session.full_jid } ); |
157 if not room then | 165 if not room then |
158 return ":"..session.host.." ERR :Could not join room: "..err | 166 return ":"..session.host.." ERR :Could not join room: "..err |
175 end); | 183 end); |
176 end | 184 end |
177 | 185 |
178 c:hook("groupchat/joined", function(room) | 186 c:hook("groupchat/joined", function(room) |
179 local session = room.session or jids[room.opts.source]; | 187 local session = room.session or jids[room.opts.source]; |
180 local channel = muc2irc(room.jid); | 188 local channel = room.channel; |
181 local nicks = session.nick; | 189 session.send((":%s!%s JOIN %s :"):format(session.nick, session.nick, channel)); |
182 -- TODO Break this out into commands.NAMES | 190 if room.topic then |
183 for nick in pairs(room.occupants) do | 191 session.send((":%s 332 %s :%s"):format(session.host, channel, room.topic)); |
184 if nick ~= session.nick then | 192 end |
185 nicks = nicks.." "..nick; | 193 commands.NAMES(session, channel) |
186 end | 194 --FIXME Ones own mode get's lost |
187 end | 195 --session.send((":%s MODE %s +%s %s"):format(session.host, room.channel, modemap[nick.role], nick.nick)); |
188 session.send(":"..session.host.." 366 "..session.nick.." "..channel.." :End of /NAMES list."); | |
189 session.send(":"..session.host.." 353 "..session.nick.." = "..channel.." :"..nicks); | |
190 room:hook("occupant-joined", function(nick) | 196 room:hook("occupant-joined", function(nick) |
191 session.send(":"..nick.nick.."!"..nick.nick.." JOIN :"..room.channel); | 197 session.send((":%s!%s JOIN :%s"):format(nick.nick, nick.nick, channel)); |
198 if nick.role and modemap[nick.role] then | |
199 session.send((":%s MODE %s +%s %s"):format(session.host, room.channel, modemap[nick.role], nick.nick)); | |
200 end | |
192 end); | 201 end); |
193 room:hook("occupant-left", function(nick) | 202 room:hook("occupant-left", function(nick) |
194 session.send(":"..nick.nick.."!"..nick.nick.." PART "..room.channel.." :"); | 203 session.send((":%s!%s PART %s :"):format(nick.nick, nick.nick, channel)); |
195 end); | 204 end); |
196 end); | 205 end); |
206 | |
207 function commands.NAMES(session, channel) | |
208 local nicks = { }; | |
209 local room = session.rooms[channel]; | |
210 if not room then return end | |
211 -- TODO Break this out into commands.NAMES | |
212 for nick, n in pairs(room.occupants) do | |
213 if n.role and rolemap[n.role] then | |
214 nick = rolemap[n.role] .. nick; | |
215 end | |
216 table.insert(nicks, nick); | |
217 end | |
218 nicks = table.concat(nicks, " "); | |
219 --:molyb.irc.bnfh.org 353 derp = #grill-bit :derp hyamobi walt snuggles_ E-Rock kng grillbit gunnarbot Frink shedma zagabar zash Mrw00t Appiah J10 lectus peck EricJ soso mackt offer hyarion @pettter MMN-o | |
220 session.send((":%s 353 %s = %s :%s"):format(session.host, session.nick, channel, nicks)); | |
221 session.send((":%s 366 %s %s :End of /NAMES list."):format(session.host, session.nick, channel)); | |
222 session.send(":"..session.host.." 353 "..session.nick.." = "..channel.." :"..nicks); | |
223 end | |
197 | 224 |
198 function commands.PART(session, channel) | 225 function commands.PART(session, channel) |
199 local channel, part_message = channel:match("^([^:]+):?(.*)$"); | 226 local channel, part_message = channel:match("^([^:]+):?(.*)$"); |
200 channel = channel:match("^([%S]*)"); | 227 channel = channel:match("^([%S]*)"); |
201 session.rooms[channel]:leave(part_message); | 228 session.rooms[channel]:leave(part_message); |
235 function commands.QUIT(session, message) | 262 function commands.QUIT(session, message) |
236 session.send("ERROR :Closing Link: "..session.nick); | 263 session.send("ERROR :Closing Link: "..session.nick); |
237 for _, room in pairs(session.rooms) do | 264 for _, room in pairs(session.rooms) do |
238 room:leave(message); | 265 room:leave(message); |
239 end | 266 end |
267 jids[session.full_jid] = nil; | |
268 nicks[session.nick] = nil; | |
269 sessions[session.conn] = nil; | |
240 session:close(); | 270 session:close(); |
241 end | 271 end |
242 | 272 |
243 function commands.RAW(session, data) | 273 function commands.RAW(session, data) |
244 --c:send(data) | 274 --c:send(data) |