Mercurial > 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 |
| parents | febfb59502fc |
| children |
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) |
