ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/anope-protocol-module/hybrid.cpp
Revision: 1561
Committed: Sun Oct 14 11:47:23 2012 UTC (14 years ago) by michael
Content type: text/x-c++src
File size: 20273 byte(s)
Log Message:
- Will use tabs especially for Adam :P

File Contents

# User Rev Content
1 michael 1556 /* ircd-hybrid-8 protocol module
2     *
3     * (C) 2003-2012 Anope Team
4     * (C) 2012 by the Hybrid Development Team
5     *
6     * Please read COPYING and README for further details.
7     *
8     * Based on the original code of Epona by Lara.
9     * Based on the original code of Services by Andy Church.
10     *
11     */
12    
13     #include "module.h"
14    
15     static Anope::string UplinkSID;
16    
17     class HybridProto : public IRCDProto
18     {
19 michael 1561 public:
20     HybridProto() : IRCDProto("Hybrid 8.0.0")
21     {
22     DefaultPseudoclientModes = "+oi";
23     CanSNLine = true;
24     CanSQLine = true;
25     CanSZLine = true;
26     RequiresID = true;
27     MaxModes = 4;
28     }
29 michael 1556
30 michael 1561 void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
31     {
32     UplinkSocket::Message(bi) << "NOTICE $$" << dest->GetName() << " :" << msg;
33     }
34 michael 1556
35 michael 1561 void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
36     {
37     UplinkSocket::Message(bi) << "PRIVMSG $$" << dest->GetName() << " :" << msg;
38     }
39 michael 1556
40 michael 1561 void SendGlobopsInternal(const BotInfo *bi, const Anope::string &buf) anope_override
41     {
42     UplinkSocket::Message(bi) << "GLOBOPS :" << buf;
43     }
44 michael 1556
45 michael 1561 void SendSQLine(User *, const XLine *x) anope_override
46     {
47     const BotInfo *bi = findbot(Config->OperServ);
48 michael 1558
49 michael 1561 UplinkSocket::Message(bi) << "RESV * " << x->Mask << " :" << x->GetReason();
50     }
51 michael 1556
52 michael 1561 void SendSGLineDel(const XLine *x) anope_override
53     {
54     const BotInfo *bi = findbot(Config->OperServ);
55 michael 1556
56 michael 1561 UplinkSocket::Message(bi) << "UNXLINE * " << x->Mask;
57     }
58 michael 1556
59 michael 1561 void SendSGLine(User *, const XLine *x) anope_override
60     {
61     const BotInfo *bi = findbot(Config->OperServ);
62 michael 1556
63 michael 1561 UplinkSocket::Message(bi) << "XLINE * " << x->Mask << " 0 :" << x->GetReason();
64     }
65 michael 1556
66 michael 1561 void SendSZLineDel(const XLine *x) anope_override
67     {
68     const BotInfo *bi = findbot(Config->OperServ);
69 michael 1558
70 michael 1561 UplinkSocket::Message(bi) << "UNDLINE * " << x->GetHost();
71     }
72 michael 1558
73 michael 1561 void SendSZLine(User *, const XLine *x) anope_override
74     {
75     const BotInfo *bi = findbot(Config->OperServ);
76     /* Calculate the time left before this would expire, capping it at 2 days */
77     time_t timeleft = x->Expires - Anope::CurTime;
78 michael 1558
79 michael 1561 if (timeleft > 172800 || !x->Expires)
80     timeleft = 172800;
81 michael 1558
82 michael 1561 UplinkSocket::Message(bi) << "DLINE * " << timeleft << " " << x->GetHost() << " :" << x->GetReason();
83     }
84 michael 1558
85 michael 1561 void SendAkillDel(const XLine *x) anope_override
86     {
87     if (x->IsRegex() || x->HasNickOrReal())
88     return;
89 michael 1556
90 michael 1561 const BotInfo *bi = findbot(Config->OperServ);
91 michael 1556
92 michael 1561 UplinkSocket::Message(bi) << "UNKLINE * " << x->GetUser() << " " << x->GetHost();
93     }
94 michael 1556
95 michael 1561 void SendSQLineDel(const XLine *x) anope_override
96     {
97     const BotInfo *bi = findbot(Config->OperServ);
98 michael 1558
99 michael 1561 UplinkSocket::Message(bi) << "UNRESV * " << x->Mask;
100     }
101 michael 1556
102 michael 1561 void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
103     {
104     /*
105     * Note that we must send our modes with the SJOIN and
106     * can not add them to the mode stacker because ircd-hybrid
107     * does not allow *any* client to op itself
108     */
109     UplinkSocket::Message() << "SJOIN " << c->creation_time << " " << c->name << " +"
110     << c->GetModes(true, true) << " :"
111     << (status != NULL ? status->BuildModePrefixList() : "") << user->GetUID();
112 michael 1556
113 michael 1561 /* And update our internal status for this user since this is not going through our mode handling system */
114     if (status != NULL)
115     {
116     UserContainer *uc = c->FindUser(user);
117 michael 1556
118 michael 1561 if (uc != NULL)
119     *uc->Status = *status;
120     }
121     }
122 michael 1556
123 michael 1561 void SendAkill(User *u, XLine *x) anope_override
124     {
125     const BotInfo *bi = findbot(Config->OperServ);
126 michael 1556
127 michael 1561 if (x->IsRegex() || x->HasNickOrReal())
128     {
129     if (!u)
130     {
131     /*
132     * No user (this akill was just added), and contains nick and/or realname.
133     * Find users that match and ban them.
134     */
135     for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
136     if (x->manager->Check(it->second, x))
137     this->SendAkill(it->second, x);
138 michael 1556
139 michael 1561 return;
140     }
141 michael 1556
142 michael 1561 const XLine *old = x;
143 michael 1556
144 michael 1561 if (old->manager->HasEntry("*@" + u->host))
145     return;
146 michael 1556
147 michael 1561 /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
148     XLine *xline = new XLine("*@" + u->host, old->By, old->Expires, old->Reason, old->UID);
149 michael 1556
150 michael 1561 old->manager->AddXLine(xline);
151     x = xline;
152 michael 1556
153 michael 1561 Log(bi, "akill") << "AKILL: Added an akill for " << x->Mask << " because " << u->GetMask() << "#"
154     << u->realname << " matches " << old->Mask;
155     }
156 michael 1556
157 michael 1561 /* Calculate the time left before this would expire, capping it at 2 days */
158     time_t timeleft = x->Expires - Anope::CurTime;
159 michael 1556
160 michael 1561 if (timeleft > 172800 || !x->Expires)
161     timeleft = 172800;
162 michael 1556
163 michael 1561 UplinkSocket::Message(bi) << "KLINE * " << timeleft << " " << x->GetUser() << " " << x->GetHost() << " :" << x->GetReason();
164     }
165 michael 1556
166 michael 1561 void SendServer(const Server *server) anope_override
167     {
168     UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
169     }
170 michael 1556
171 michael 1561 void SendConnect() anope_override
172     {
173     UplinkSocket::Message() << "PASS " << Config->Uplinks[CurrentUplink]->password << " TS 6 :" << Me->GetSID();
174 michael 1556
175 michael 1561 /*
176     * As of October 13, 2012, ircd-hybrid-8 does support the following capabilities
177     * which are required to work with IRC-services:
178     *
179     * QS - Can handle quit storm removal
180     * EX - Can do channel +e exemptions
181     * CHW - Can do channel wall @#
182     * IE - Can do invite exceptions
183     * KNOCK - Supports KNOCK
184     * TBURST - Supports topic burst
185     * ENCAP - Supports ENCAP
186     * HOPS - Supports HalfOps
187     * SVS - Supports services
188     * EOB - Supports End Of Burst message
189     * TS6 - Capable of TS6 support
190     */
191     UplinkSocket::Message() << "CAPAB :QS EX CHW IE ENCAP TBURST SVS HOPS EOB TS6";
192 michael 1556
193 michael 1561 SendServer(Me);
194 michael 1556
195 michael 1561 UplinkSocket::Message() << "SVINFO 6 5 0 :" << Anope::CurTime;
196     }
197 michael 1556
198 michael 1561 void SendClientIntroduction(const User *u) anope_override
199     {
200     Anope::string modes = "+" + u->GetModes();
201 michael 1556
202 michael 1561 UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " "
203     << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " 0 :" << u->realname;
204     }
205 michael 1556
206 michael 1561 void SendEOB() anope_override
207     {
208     UplinkSocket::Message(Me) << "EOB";
209     }
210 michael 1556
211 michael 1561 void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override
212     {
213     if (bi)
214     UplinkSocket::Message(bi) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf;
215     else
216     UplinkSocket::Message(Me) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf;
217     }
218 michael 1556
219 michael 1561 void SendLogin(User *u) anope_override
220     {
221     const BotInfo *ns = findbot(Config->NickServ);
222 michael 1556
223 michael 1561 ircdproto->SendMode(ns, u, "+d %s", u->Account()->display.c_str());
224     }
225 michael 1556
226 michael 1561 void SendLogout(User *u) anope_override
227     {
228     const BotInfo *ns = findbot(Config->NickServ);
229 michael 1556
230 michael 1561 ircdproto->SendMode(ns, u, "+d 0");
231     }
232 michael 1556
233 michael 1561 void SendChannel(Channel *c) anope_override
234     {
235     Anope::string modes = c->GetModes(true, true);
236 michael 1556
237 michael 1561 if (modes.empty())
238     modes = "+";
239 michael 1556
240 michael 1561 UplinkSocket::Message() << "SJOIN " << c->creation_time << " " << c->name << " " << modes << " :";
241     }
242 michael 1556
243 michael 1561 void SendTopic(BotInfo *bi, Channel *c) anope_override
244     {
245     bool needjoin = c->FindUser(bi) == NULL;
246 michael 1556
247 michael 1561 if (needjoin)
248     {
249     ChannelStatus status;
250 michael 1556
251 michael 1561 status.SetFlag(CMODE_OP);
252     bi->Join(c, &status);
253     }
254 michael 1556
255 michael 1561 IRCDProto::SendTopic(bi, c);
256 michael 1556
257 michael 1561 if (needjoin)
258     bi->Part(c);
259     }
260 michael 1556 };
261    
262     struct IRCDMessageBMask : IRCDMessage
263     {
264 michael 1561 IRCDMessageBMask() : IRCDMessage("BMASK", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
265 michael 1556
266 michael 1561 /* 0 1 2 3 */
267     /* :0MC BMASK 1350157102 #channel b :*!*@*.test.com */
268     bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
269     {
270     Channel *c = findchan(params[1]);
271 michael 1556
272 michael 1561 if (c)
273     {
274     ChannelMode *ban = ModeManager::FindChannelModeByName(CMODE_BAN),
275     *except = ModeManager::FindChannelModeByName(CMODE_EXCEPT),
276     *invex = ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE);
277 michael 1556
278 michael 1561 Anope::string bans = params[3];
279 michael 1556
280 michael 1561 int count = myNumToken(bans, ' '), i;
281 michael 1556
282 michael 1561 for (i = 0; i < count; ++i)
283     {
284     Anope::string b = myStrGetToken(bans, ' ', i);
285 michael 1556
286 michael 1561 if (ban && params[2].equals_cs("b"))
287     c->SetModeInternal(source, ban, b);
288     else if (except && params[2].equals_cs("e"))
289     c->SetModeInternal(source, except, b);
290     else if (invex && params[2].equals_cs("I"))
291     c->SetModeInternal(source, invex, b);
292     }
293     }
294 michael 1556
295 michael 1561 return true;
296     }
297 michael 1556 };
298    
299     struct IRCDMessageJoin : CoreIRCDMessageJoin
300     {
301 michael 1561 IRCDMessageJoin() : CoreIRCDMessageJoin("JOIN") { }
302 michael 1556
303 michael 1561 bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
304     {
305     if (params.size() < 2)
306     return true;
307 michael 1556
308 michael 1561 std::vector<Anope::string> p = params;
309     p.erase(p.begin());
310 michael 1556
311 michael 1561 return CoreIRCDMessageJoin::Run(source, p);
312     }
313 michael 1556 };
314    
315     struct IRCDMessageMode : IRCDMessage
316     {
317 michael 1561 IRCDMessageMode(const Anope::string &n) : IRCDMessage(n, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
318 michael 1556
319 michael 1561 bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
320     {
321     if (params.size() > 2 && ircdproto->IsChannelValid(params[0]))
322     {
323     Channel *c = findchan(params[0]);
324     time_t ts = Anope::CurTime;
325 michael 1556
326 michael 1561 try
327     {
328     ts = convertTo<time_t>(params[1]);
329     }
330     catch (const ConvertException &) { }
331 michael 1556
332 michael 1561 if (c)
333     c->SetModesInternal(source, params[2], ts);
334     }
335     else
336     {
337     User *u = finduser(params[0]);
338 michael 1556
339 michael 1561 if (u)
340     u->SetModesInternal("%s", params[1].c_str());
341     }
342 michael 1556
343 michael 1561 return true;
344     }
345 michael 1556 };
346    
347     struct IRCDMessageNick : IRCDMessage
348     {
349 michael 1561 IRCDMessageNick() : IRCDMessage("NICK", 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
350 michael 1556
351 michael 1561 /* 0 1 */
352     /* :0MCAAAAAB NICK newnick 1350157102 */
353     bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
354     {
355     source.GetUser()->ChangeNick(params[0], convertTo<time_t>(params[1]));
356     return true;
357     }
358 michael 1556 };
359    
360     struct IRCDMessagePass : IRCDMessage
361     {
362 michael 1561 IRCDMessagePass() : IRCDMessage("PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
363 michael 1556
364 michael 1561 /* 0 1 2 3 */
365     /* PASS password TS 6 0MC */
366     bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
367     {
368     UplinkSID = params[3];
369     return true;
370     }
371 michael 1556 };
372    
373     struct IRCDMessagePong : IRCDMessage
374     {
375 michael 1561 IRCDMessagePong() : IRCDMessage("PONG", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
376 michael 1556
377 michael 1561 bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
378     {
379     source.GetServer()->Sync(false);
380     return true;
381     }
382 michael 1556 };
383    
384     struct IRCDMessageServer : IRCDMessage
385     {
386 michael 1561 IRCDMessageServer() : IRCDMessage("SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
387 michael 1556
388 michael 1561 /* 0 1 2 */
389     /* SERVER hades.arpa 1 :ircd-hybrid test server */
390     bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
391     {
392     /* Servers other than our immediate uplink are introduced via SID */
393     if (params[1] != "1")
394     return true;
395 michael 1556
396 michael 1561 new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
397 michael 1556
398 michael 1561 ircdproto->SendPing(Config->ServerName, params[0]);
399     return true;
400     }
401 michael 1556 };
402    
403     struct IRCDMessageSID : IRCDMessage
404     {
405 michael 1561 IRCDMessageSID() : IRCDMessage("SID", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
406 michael 1556
407 michael 1561 /* 0 1 2 3 */
408     /* :0MC SID hades.arpa 2 4XY :ircd-hybrid test server */
409     bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
410     {
411     unsigned int hops = params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
412     new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]);
413 michael 1556
414 michael 1561 ircdproto->SendPing(Config->ServerName, params[0]);
415     return true;
416     }
417 michael 1556 };
418    
419     struct IRCDMessageSjoin : IRCDMessage
420     {
421 michael 1561 IRCDMessageSjoin() : IRCDMessage("SJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
422 michael 1556
423 michael 1561 bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
424     {
425     Channel *c = findchan(params[1]);
426     time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : 0;
427     bool keep_their_modes = true;
428 michael 1556
429 michael 1561 if (!c)
430     {
431     c = new Channel(params[1], ts);
432     c->SetFlag(CH_SYNCING);
433     }
434     /* Our creation time is newer than what the server gave us */
435     else if (c->creation_time > ts)
436     {
437     c->creation_time = ts;
438     c->Reset();
439     }
440     /* Their TS is newer than ours, our modes > theirs, unset their modes if need be */
441     else if (ts > c->creation_time)
442     keep_their_modes = false;
443 michael 1556
444 michael 1561 /* If we need to keep their modes, and this SJOIN string contains modes */
445     if (keep_their_modes && params.size() >= 3)
446     {
447     Anope::string modes;
448 michael 1556
449 michael 1561 for (unsigned i = 2; i < params.size() - 1; ++i)
450     modes += " " + params[i];
451 michael 1556
452 michael 1561 if (!modes.empty())
453     modes.erase(modes.begin());
454 michael 1556
455 michael 1561 /* Set the modes internally */
456     c->SetModesInternal(source, modes);
457     }
458 michael 1556
459 michael 1561 spacesepstream sep(params[params.size() - 1]);
460     Anope::string buf;
461 michael 1556
462 michael 1561 while (sep.GetToken(buf))
463     {
464     std::list<ChannelMode *> Status;
465     char ch;
466 michael 1556
467 michael 1561 /* Get prefixes from the nick */
468     while ((ch = ModeManager::GetStatusChar(buf[0])))
469     {
470     buf.erase(buf.begin());
471 michael 1556
472 michael 1561 ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
473 michael 1556
474 michael 1561 if (!cm)
475     {
476     Log() << "Received unknown mode prefix " << ch << " in SJOIN string";
477     continue;
478     }
479 michael 1556
480 michael 1561 if (keep_their_modes)
481     Status.push_back(cm);
482     }
483 michael 1556
484 michael 1561 User *u = finduser(buf);
485 michael 1556
486 michael 1561 if (!u)
487     {
488     Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << c->name;
489     continue;
490     }
491 michael 1556
492 michael 1561 EventReturn MOD_RESULT;
493     FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
494 michael 1556
495 michael 1561 /* Add the user to the channel */
496     c->JoinUser(u);
497 michael 1556
498 michael 1561 /*
499     * Update their status internally on the channel
500     * This will enforce secureops etc on the user
501     */
502     for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it)
503     c->SetModeInternal(source, *it, buf);
504 michael 1556
505 michael 1561 /* Now set whatever modes this user is allowed to have on the channel */
506     chan_set_correct_modes(u, c, 1, true);
507 michael 1556
508 michael 1561 /*
509     * Check to see if modules want the user to join, if they do
510     * check to see if they are allowed to join (CheckKick will kick/ban them)
511     * Don't trigger OnJoinChannel event then as the user will be destroyed
512     */
513     if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
514     continue;
515 michael 1556
516 michael 1561 FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
517     }
518 michael 1556
519 michael 1561 /* Channel is done syncing */
520     if (c->HasFlag(CH_SYNCING))
521     {
522     /* Unset the syncing flag */
523     c->UnsetFlag(CH_SYNCING);
524     c->Sync();
525     }
526 michael 1556
527 michael 1561 return true;
528     }
529 michael 1556 };
530    
531     struct IRCDMessageTBurst : IRCDMessage
532     {
533 michael 1561 IRCDMessageTBurst() : IRCDMessage("TBURST", 5) { }
534 michael 1556
535 michael 1561 bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
536     {
537     Anope::string setter = myStrGetToken(params[3], '!', 0);
538     time_t topic_time = Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime;
539     Channel *c = findchan(params[1]);
540 michael 1556
541 michael 1561 if (c)
542     c->ChangeTopicInternal(setter, params[4], topic_time);
543 michael 1556
544 michael 1561 return true;
545     }
546 michael 1556 };
547    
548     struct IRCDMessageTMode : IRCDMessage
549     {
550 michael 1561 IRCDMessageTMode() : IRCDMessage("TMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
551 michael 1556
552 michael 1561 bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
553     {
554     time_t ts = Anope::CurTime;
555 michael 1556
556 michael 1561 try
557     {
558     ts = convertTo<time_t>(params[0]);
559     }
560     catch (const ConvertException &) { }
561 michael 1556
562 michael 1561 Channel *c = findchan(params[1]);
563     Anope::string modes = params[2];
564 michael 1556
565 michael 1561 for (unsigned i = 3; i < params.size(); ++i)
566     modes += " " + params[i];
567 michael 1556
568 michael 1561 if (c)
569     c->SetModesInternal(source, modes, ts);
570 michael 1556
571 michael 1561 return true;
572     }
573 michael 1556 };
574    
575     struct IRCDMessageUID : IRCDMessage
576     {
577 michael 1561 IRCDMessageUID() : IRCDMessage("UID", 10) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
578 michael 1556
579 michael 1561 /* 0 1 2 3 4 5 6 7 8 9 */
580     /* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB 1350157108 :Mining all the time */
581     bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
582     {
583     /* Source is always the server */
584     User *user = new User(params[0], params[4], params[5], "",
585     params[6], source.GetServer(),
586     params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0,
587     params[3], params[7]);
588 michael 1556
589 michael 1561 if (user && nickserv)
590     {
591     const NickAlias *na = NULL;
592 michael 1560
593 michael 1561 if (params[8] != "0")
594     na = findnick(params[8]);
595 michael 1556
596 michael 1561 if (na)
597     {
598     user->Login(na->nc);
599 michael 1560
600 michael 1561 if (!Config->NoNicknameOwnership && na->nc->HasFlag(NI_UNCONFIRMED) == false)
601     user->SetMode(findbot(Config->NickServ), UMODE_REGISTERED);
602     }
603     else
604     nickserv->Validate(user);
605     }
606 michael 1556
607 michael 1561 return true;
608     }
609 michael 1556 };
610    
611     class ProtoHybrid : public Module
612     {
613 michael 1561 HybridProto ircd_proto;
614 michael 1556
615 michael 1561 /* Core message handlers */
616     CoreIRCDMessageAway core_message_away;
617     CoreIRCDMessageCapab core_message_capab;
618     CoreIRCDMessageError core_message_error;
619     CoreIRCDMessageKick core_message_kick;
620     CoreIRCDMessageKill core_message_kill;
621     CoreIRCDMessageMOTD core_message_motd;
622     CoreIRCDMessagePart core_message_part;
623     CoreIRCDMessagePing core_message_ping;
624     CoreIRCDMessagePrivmsg core_message_privmsg;
625     CoreIRCDMessageQuit core_message_quit;
626     CoreIRCDMessageSQuit core_message_squit;
627     CoreIRCDMessageStats core_message_stats;
628     CoreIRCDMessageTime core_message_time;
629     CoreIRCDMessageTopic core_message_topic;
630     CoreIRCDMessageVersion core_message_version;
631     CoreIRCDMessageWhois core_message_whois;
632 michael 1556
633 michael 1561 /* Our message handlers */
634     IRCDMessageBMask message_bmask;
635     IRCDMessageJoin message_join;
636     IRCDMessageMode message_mode, message_svsmode;
637     IRCDMessageNick message_nick;
638     IRCDMessagePass message_pass;
639     IRCDMessagePong message_pong;
640     IRCDMessageServer message_server;
641     IRCDMessageSID message_sid;
642     IRCDMessageSjoin message_sjoin;
643     IRCDMessageTBurst message_tburst;
644     IRCDMessageTMode message_tmode;
645     IRCDMessageUID message_uid;
646 michael 1556
647 michael 1561 void AddModes()
648     {
649     /* Add user modes */
650     ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
651     ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
652     ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
653     ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r'));
654     ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
655     ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
656     ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H'));
657     ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R'));
658 michael 1556
659 michael 1561 /* b/e/I */
660     ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
661     ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e'));
662     ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
663 michael 1556
664 michael 1561 /* v/h/o/a/q */
665     ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0));
666     ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 1));
667 michael 1556
668 michael 1561 /* Add channel modes */
669     ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
670     ModeManager::AddChannelMode(new ChannelModeKey('k'));
671     ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
672     ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
673     ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
674     ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p'));
675     ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
676     ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
677     ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
678     ModeManager::AddChannelMode(new ChannelModeOper('O'));
679     ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
680     ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'S'));
681     }
682 michael 1556
683     public:
684 michael 1561 ProtoHybrid(const Anope::string &modname, const Anope::string &creator) :
685     Module(modname, creator, PROTOCOL), message_mode("MODE"), message_svsmode("SVSMODE")
686     {
687     this->SetAuthor("Anope");
688     this->AddModes();
689 michael 1556
690 michael 1561 ModuleManager::Attach(I_OnUserNickChange, this);
691 michael 1556
692 michael 1561 if (Config->Numeric.empty())
693     {
694     Anope::string numeric = ts6_sid_retrieve();
695     Me->SetSID(numeric);
696     Config->Numeric = numeric;
697     }
698 michael 1556
699 michael 1561 for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
700     it->second->GenerateUID();
701     }
702 michael 1556
703 michael 1561 void OnUserNickChange(User *u, const Anope::string &) anope_override
704     {
705     u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
706     ircdproto->SendLogout(u);
707     }
708 michael 1556 };
709    
710     MODULE_INIT(ProtoHybrid)

Properties

Name Value
svn:keywords Id