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)