1 //=============================================================================
2 //
3 //   File : KviIrcConnectionServerInfo.cpp
4 //   Creation date : Tue 22 Jun 2004 03:57:32 by Szymon Stefanek
5 //
6 //   This file is part of the KVIrc IRC client distribution
7 //   Copyright (C) 2004-2010 Szymon Stefanek <pragma at kvirc dot net>
8 //
9 //   This program is FREE software. You can redistribute it and/or
10 //   modify it under the terms of the GNU General Public License
11 //   as published by the Free Software Foundation; either version 2
12 //   of the License, or (at your option) any later version.
13 //
14 //   This program is distributed in the HOPE that it will be USEFUL,
15 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 //   See the GNU General Public License for more details.
18 //
19 //   You should have received a copy of the GNU General Public License
20 //   along with this program. If not, write to the Free Software Foundation,
21 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24 
25 #include "KviIrcConnectionServerInfo.h"
26 
27 #include <utility>
28 #include "KviLocale.h"
29 #include "KviMemory.h"
30 #include "KviIrcUserDataBase.h"
31 
KviIrcConnectionServerInfo()32 KviIrcConnectionServerInfo::KviIrcConnectionServerInfo()
33 {
34 	// default assumptions
35 	buildModePrefixTable();
36 	m_pServInfo = new KviBasicIrcServerInfo(this);
37 }
38 
~KviIrcConnectionServerInfo()39 KviIrcConnectionServerInfo::~KviIrcConnectionServerInfo()
40 {
41 	if(m_pServInfo)
42 		delete m_pServInfo;
43 	if(m_pModePrefixTable)
44 		KviMemory::free(m_pModePrefixTable);
45 }
46 
isSupportedChannelType(QChar c) const47 bool KviIrcConnectionServerInfo::isSupportedChannelType(QChar c) const
48 {
49 	return m_szSupportedChannelTypes.contains(c);
50 }
51 
addSupportedCaps(const QString & szCapList)52 void KviIrcConnectionServerInfo::addSupportedCaps(const QString & szCapList)
53 {
54 	m_bSupportsCap = true;
55 
56 	QStringList lTmp = szCapList.split(' ', QString::SkipEmptyParts);
57 	foreach(QString szCap, lTmp)
58 	{
59 		// cap modifiers are:
60 		//  '-' : disable a capability (should not be present in a LS message...)
61 		//  '=' : sticky (can't be disabled once enabled)
62 		//  '~' : needs ack for modification
63 
64 		if(szCap.length() < 1)
65 			continue; // shouldn't happen
66 
67 		switch(szCap[0].unicode())
68 		{
69 			case '-':
70 			case '~':
71 			case '=':
72 				szCap.remove(0, 1);
73 				break;
74 			default:
75 				// ok
76 				break;
77 		}
78 
79 		szCap = szCap.toLower();
80 
81 		if(!m_lSupportedCaps.contains(szCap))
82 			m_lSupportedCaps.append(szCap);
83 	}
84 }
85 
setSupportedChannelModes(const QString & szSupportedChannelModes)86 void KviIrcConnectionServerInfo::setSupportedChannelModes(const QString & szSupportedChannelModes)
87 {
88 	QStringList szAllModes = szSupportedChannelModes.split(',', QString::KeepEmptyParts);
89 
90 	if(szAllModes.count() != 4)
91 	{
92 		// in this situation, better not to make assumptions about which modes needs a parameter
93 		return;
94 	}
95 
96 	m_szListModes = szAllModes.at(0);
97 	m_szParameterModes = szAllModes.at(1);
98 	m_szParameterWhenSetModes = szAllModes.at(2);
99 	m_szPlainModes = szAllModes.at(3);
100 
101 	m_szSupportedChannelModes = szSupportedChannelModes;
102 }
103 
setSupportedModePrefixes(const QString & szSupportedModePrefixes,const QString & szSupportedModeFlags)104 void KviIrcConnectionServerInfo::setSupportedModePrefixes(const QString & szSupportedModePrefixes, const QString & szSupportedModeFlags)
105 {
106 	m_szSupportedModeFlags = szSupportedModeFlags;
107 	m_szSupportedModePrefixes = szSupportedModePrefixes;
108 	buildModePrefixTable();
109 }
110 
buildModePrefixTable()111 void KviIrcConnectionServerInfo::buildModePrefixTable()
112 {
113 	if(m_pModePrefixTable)
114 		KviMemory::free(m_pModePrefixTable);
115 	const QChar * cPrefix = m_szSupportedModePrefixes.constData();
116 	const QChar * cFlag = m_szSupportedModeFlags.constData();
117 	if(!cPrefix || !cFlag)
118 		return; // eh ?
119 
120 	m_uPrefixes = qMin(m_szSupportedModePrefixes.length(), m_szSupportedModePrefixes.length());
121 	m_pModePrefixTable = (kvi_u32_t *)KviMemory::allocate(sizeof(kvi_u32_t) * 3 * m_uPrefixes);
122 
123 	unsigned short uPrefix, uFlag;
124 
125 	// Pragma: FIXME: The whole mode handling needs rethinking!
126 	// Alexey: FIXED: rethinked:)
127 	// Pragma: LOL :DDDD
128 	unsigned int i = 0;
129 	while((uPrefix = cPrefix->unicode()) && (uFlag = cFlag->unicode()) && i < m_uPrefixes * 3)
130 	{
131 		m_pModePrefixTable[i] = uPrefix;
132 		m_pModePrefixTable[i + 1] = uFlag;
133 		switch(uFlag)
134 		{
135 			case 'o':
136 				m_pModePrefixTable[i + 2] = KviIrcUserEntry::Op;
137 				break;
138 			case 'v':
139 				m_pModePrefixTable[i + 2] = KviIrcUserEntry::Voice;
140 				break;
141 			case 'h':
142 				m_pModePrefixTable[i + 2] = KviIrcUserEntry::HalfOp;
143 				break;
144 			case 'a':
145 				m_pModePrefixTable[i + 2] = KviIrcUserEntry::ChanAdmin;
146 				break;
147 			case 'u':
148 				m_pModePrefixTable[i + 2] = KviIrcUserEntry::UserOp;
149 				break;
150 			case 'q':
151 				m_pModePrefixTable[i + 2] = KviIrcUserEntry::ChanOwner;
152 				break;
153 			default:
154 				m_pModePrefixTable[i + 2] = 0;
155 				break;
156 		}
157 		i += 3;
158 		cPrefix++;
159 		cFlag++;
160 	}
161 }
162 
isSupportedModePrefix(QChar c) const163 bool KviIrcConnectionServerInfo::isSupportedModePrefix(QChar c) const
164 {
165 	if(!m_pModePrefixTable)
166 		return false;
167 	for(unsigned int i = 0; i < m_uPrefixes; i++)
168 	{
169 		if(m_pModePrefixTable[i * 3] == c.unicode())
170 			return true;
171 	}
172 	return false;
173 }
174 
isSupportedModeFlag(QChar c) const175 bool KviIrcConnectionServerInfo::isSupportedModeFlag(QChar c) const
176 {
177 	if(!m_pModePrefixTable)
178 		return false;
179 	for(unsigned int i = 0; i < m_uPrefixes; i++)
180 	{
181 		if(m_pModePrefixTable[(i * 3) + 1] == c.unicode())
182 			return true;
183 	}
184 	return false;
185 }
186 
modePrefixChar(kvi_u32_t flag) const187 QChar KviIrcConnectionServerInfo::modePrefixChar(kvi_u32_t flag) const
188 {
189 	if(!m_pModePrefixTable)
190 		return { 0 };
191 	for(unsigned int i = 0; i < m_uPrefixes; i++)
192 	{
193 		if(m_pModePrefixTable[i * 3 + 2] & flag)
194 			return QChar(m_pModePrefixTable[i * 3]);
195 	}
196 	return QChar(0);
197 }
198 
modeFlagChar(kvi_u32_t flag) const199 QChar KviIrcConnectionServerInfo::modeFlagChar(kvi_u32_t flag) const
200 {
201 	if(!m_pModePrefixTable)
202 		return { 0 };
203 	for(unsigned int i = 0; i < m_uPrefixes; i++)
204 	{
205 		if(m_pModePrefixTable[i * 3 + 2] & flag)
206 			return QChar(m_pModePrefixTable[i * 3 + 1]);
207 	}
208 	return QChar(0);
209 }
210 
modeFlagFromPrefixChar(QChar c) const211 kvi_u32_t KviIrcConnectionServerInfo::modeFlagFromPrefixChar(QChar c) const
212 {
213 	if(!m_pModePrefixTable)
214 		return 0;
215 	for(unsigned int i = 0; i < m_uPrefixes; i++)
216 	{
217 		if(m_pModePrefixTable[i * 3] == c.unicode())
218 			return m_pModePrefixTable[i * 3 + 2];
219 	}
220 	return 0;
221 }
222 
modeFlagFromModeChar(QChar c) const223 kvi_u32_t KviIrcConnectionServerInfo::modeFlagFromModeChar(QChar c) const
224 {
225 	if(!m_pModePrefixTable)
226 		return 0;
227 	for(unsigned int i = 0; i < m_uPrefixes; i++)
228 	{
229 		if(m_pModePrefixTable[i * 3 + 1] == c.unicode())
230 			return m_pModePrefixTable[i * 3 + 2];
231 	}
232 	return 0;
233 }
234 
setServerVersion(const QString & version)235 void KviIrcConnectionServerInfo::setServerVersion(const QString & version)
236 {
237 	if(m_pServInfo)
238 		delete m_pServInfo;
239 	if(version.contains("unrealircd-4", Qt::CaseInsensitive))
240 		m_pServInfo = new KviUnreal40IrcServerInfo(this, version);
241 	else if(version.contains("unreal3.2", Qt::CaseInsensitive))
242 		m_pServInfo = new KviUnreal32IrcServerInfo(this, version);
243 	else if(version.contains("unreal", Qt::CaseInsensitive))
244 		m_pServInfo = new KviUnrealIrcServerInfo(this, version);
245 	else if(version.contains("charybdis", Qt::CaseInsensitive))
246 		m_pServInfo = new KviCharybdisServerInfo(this, version);
247 	else if(version.contains("bahamut", Qt::CaseInsensitive))
248 		m_pServInfo = new KviBahamutIrcServerInfo(this, version);
249 	else if(version.contains("hyperion", Qt::CaseInsensitive))
250 		m_pServInfo = new KviHyperionIrcServerInfo(this, version);
251 	else if(version.contains("ircd-seven", Qt::CaseInsensitive))
252 		m_pServInfo = new KviIrcdSevenIrcServerInfo(this, version);
253 	else if(version.contains("ratbox", Qt::CaseInsensitive))
254 		m_pServInfo = new KviIrcdRatboxIrcServerInfo(this, version);
255 	else if(version.contains("inspircd", Qt::CaseInsensitive))
256 		m_pServInfo = new KviInspIRCdIrcServerInfo(this, version);
257 	else if(version.contains("snircd", Qt::CaseInsensitive))
258 		m_pServInfo = new KviSnircdIrcServerInfo(this, version);
259 	else if(version.contains("ircd-darenet", Qt::CaseInsensitive))
260 		m_pServInfo = new KviDarenetIrcServerInfo(this, version);
261 	else if(version.contains("u2", Qt::CaseInsensitive))
262 		m_pServInfo = new KviIrcuIrcServerInfo(this, version);
263 	else if(version.contains("plexus", Qt::CaseInsensitive))
264 		m_pServInfo = new KviPlexusIrcServerInfo(this, version);
265 	else if(version.contains("criten", Qt::CaseInsensitive))
266 		m_pServInfo = new KviCritenIrcServerInfo(this, version);
267 	else if(version.contains("nemesis2.0", Qt::CaseInsensitive))
268 		m_pServInfo = new KviNemesis20IrcServerInfo(this, version);
269 	else if(version.contains("nemesis", Qt::CaseInsensitive))
270 		m_pServInfo = new KviNemesisIrcServerInfo(this, version);
271 	else if(version.contains("oftc", Qt::CaseInsensitive))
272 		m_pServInfo = new KviOftcIrcServerInfo(this, version);
273 	else if(version.contains("hybrid", Qt::CaseInsensitive))
274 		m_pServInfo = new KviHybridServerInfo(this, version);
275 	else
276 		m_pServInfo = new KviBasicIrcServerInfo(this, version);
277 }
278 
KviBasicIrcServerInfo(KviIrcConnectionServerInfo * pParent,QString version)279 KviBasicIrcServerInfo::KviBasicIrcServerInfo(KviIrcConnectionServerInfo * pParent, QString version)
280     : m_szServerVersion(std::move(version)), m_pParent(pParent)
281 {
282 }
283 
284 KviBasicIrcServerInfo::~KviBasicIrcServerInfo()
285     = default;
286 
287 //
288 // User modes
289 //
290 
getUserModeDescription(QChar mode) const291 const QString & KviBasicIrcServerInfo::getUserModeDescription(QChar mode) const
292 {
293 	switch(mode.unicode())
294 	{
295 		case 'O':
296 			return __tr2qs("O: Local IRC Operator (locop)");
297 			break;
298 		case 'a':
299 			return __tr2qs("a: Server administrator");
300 			break;
301 		case 'c':
302 			return __tr2qs("c: Recipient for cconn messages");
303 			break;
304 		case 'd':
305 			return __tr2qs("d: Recipient for server debug notices");
306 			break;
307 		case 'f':
308 			return __tr2qs("f: Recipient for full server notices");
309 			break;
310 		case 'i':
311 			return __tr2qs("i: Invisible");
312 			break;
313 		case 'k':
314 			return __tr2qs("k: Recipient for server KILL messages");
315 			break;
316 		case 'n':
317 			return __tr2qs("n: Recipient for nick changes");
318 			break;
319 		case 'o':
320 			return __tr2qs("o: IRC Operator (oper)");
321 			break;
322 		case 'r':
323 			return __tr2qs("r: User with restricted connection (or recipient for messages about rejected bots)");
324 			break;
325 		case 's':
326 			return __tr2qs("s: Recipient for server notices");
327 			break;
328 		case 'w':
329 			return __tr2qs("w: Recipient for WALLOPS messages");
330 			break;
331 		case 'y':
332 			return __tr2qs("y: Recipient for spy notices");
333 			break;
334 		case 'z':
335 			return __tr2qs("z: Recipient for oper WALLOP messages");
336 			break;
337 	}
338 	return KviQString::Empty;
339 }
340 
getUserModeDescription(QChar mode) const341 const QString & KviHybridServerInfo::getUserModeDescription(QChar mode) const
342 {
343 	switch(mode.unicode())
344 	{
345 		case 'D':
346 			return __tr2qs("D: Deaf");
347 			break;
348 		case 'F':
349 			return __tr2qs("F: Recipient for far connect/quit notices");
350 			break;
351 		case 'G':
352 			return __tr2qs("G: Only accept private messages from users in common channels");
353 			break;
354 		case 'H':
355 			return __tr2qs("H: Hide oper status");
356 			break;
357 		case 'R':
358 			return __tr2qs("R: Only receive private messages from registered nicks");
359 			break;
360 		case 'S':
361 			return __tr2qs("S: Connected over SSL");
362 			break;
363 		case 'W':
364 			return __tr2qs("W: Connected over WEBIRC");
365 			break;
366 		case 'a':
367 			return __tr2qs("a: Server administrator");
368 			break;
369 		case 'b':
370 			return __tr2qs("b: Recipient for bot/join flood warnings");
371 			break;
372 		case 'e':
373 			return __tr2qs("e: Recipient for server introduction and split notices");
374 			break;
375 		case 'f':
376 			return __tr2qs("f: Recipient for full I-Line notices");
377 			break;
378 		case 'g':
379 			return __tr2qs("g: Only allow accepted clients to message you");
380 			break;
381 		case 'j':
382 			return __tr2qs("j: Recipient for rejected client notices");
383 			break;
384 		case 'l':
385 			return __tr2qs("l: Recipient for LOCOPS");
386 			break;
387 		case 'p':
388 			return __tr2qs("p: Channels hidden from WHOIS");
389 			break;
390 		case 'q':
391 			return __tr2qs("q: Idle time hidden from WHOIS");
392 			break;
393 		case 'r':
394 			return __tr2qs("r: Registered");
395 			break;
396 		case 'u':
397 			return __tr2qs("u: Recipient for unauthorized client notices");
398 			break;
399 		case 'x':
400 			return __tr2qs("x: Host hidden");
401 			break;
402 		case 'y':
403 			return __tr2qs("y: Can see stats/links/admin requests");
404 			break;
405 	}
406 	return KviBasicIrcServerInfo::getUserModeDescription(mode);
407 }
408 
getUserModeDescription(QChar mode) const409 const QString & KviIrcdRatboxIrcServerInfo::getUserModeDescription(QChar mode) const
410 {
411 	switch(mode.unicode())
412 	{
413 		case 'C':
414 			return __tr2qs("C: Prevent CTCPs");
415 			break;
416 		case 'D':
417 			return __tr2qs("D: Deaf");
418 			break;
419 		case 'Z':
420 			return __tr2qs("Z: Recipient for oper spy notices");
421 			break;
422 		case 'a':
423 			return __tr2qs("a: Server administrator");
424 			break;
425 		case 'b':
426 			return __tr2qs("b: Recipient for bot/join flood warnings");
427 			break;
428 		case 'f':
429 			return __tr2qs("f: Recipient for full I-Line notices");
430 			break;
431 		case 'g':
432 			return __tr2qs("g: Only allow accepted clients to message you");
433 			break;
434 		case 'l':
435 			return __tr2qs("l: Recipient for LOCOPS");
436 			break;
437 		case 'r':
438 			return __tr2qs("r: Recipient for rejected client notices");
439 			break;
440 		case 'u':
441 			return __tr2qs("u: Recipient for unauthorised client notices");
442 			break;
443 		case 'x':
444 			return __tr2qs("x: Recipient for remote server connection and split notices");
445 			break;
446 		case 'z':
447 			return __tr2qs("z: Recipient for OPERWALL messages");
448 			break;
449 	}
450 	return KviHybridServerInfo::getUserModeDescription(mode);
451 }
452 
getUserModeDescription(QChar mode) const453 const QString & KviCharybdisServerInfo::getUserModeDescription(QChar mode) const
454 {
455 	switch(mode.unicode())
456 	{
457 		case 'Q':
458 			return __tr2qs("Q: Prevents you from being affected by channel forwarding");
459 			break;
460 		case 'R':
461 			return __tr2qs("R: Only receive private messages from registered nicks");
462 			break;
463 		case 'S':
464 			return __tr2qs("S: Network service");
465 			break;
466 		case 'Z':
467 			return __tr2qs("Z: Connected over SSL");
468 			break;
469 		case 'h':
470 			return __tr2qs("h: Host hidden");
471 			break;
472 		case 'p':
473 			return __tr2qs("p: Enable oper overrides");
474 			break;
475 		case 'x':
476 			return __tr2qs("x: Host hidden");
477 			break;
478 	}
479 	return KviIrcdRatboxIrcServerInfo::getUserModeDescription(mode);
480 }
481 
getUserModeDescription(QChar mode) const482 const QString & KviIrcdSevenIrcServerInfo::getUserModeDescription(QChar mode) const
483 {
484 	switch(mode.unicode())
485 	{
486 		case 'O':
487 			return __tr2qs("O: IRC Help Operator");
488 			break;
489 		case 'h':
490 			return __tr2qs("h: Marks you as a helper in /stats p");
491 			break;
492 	}
493 	return KviCharybdisServerInfo::getUserModeDescription(mode);
494 }
495 
getUserModeDescription(QChar mode) const496 const QString & KviPlexusIrcServerInfo::getUserModeDescription(QChar mode) const
497 {
498 	switch(mode.unicode())
499 	{
500 		case 'C':
501 			return __tr2qs("C: Prevent CTCPs");
502 			break;
503 		case 'N':
504 			return __tr2qs("N: Network administrator");
505 			break;
506 		case 'U':
507 			return __tr2qs("U: Network service");
508 			break;
509 		case 'X':
510 			return __tr2qs("X: Recipient for new server introduction and split messages");
511 			break;
512 		case 'w':
513 			return __tr2qs("w: Recipient for server WALLOPS");
514 			break;
515 		case 'z':
516 			return __tr2qs("z: Recipient for oper WALLOPS");
517 			break;
518 		case 'y':
519 			return __tr2qs("y: Recipient for notices on WHOIS");
520 			break;
521 		case 'a':
522 			return __tr2qs("a: Server administrator");
523 			break;
524 		case 'q':
525 			return __tr2qs("q: Services administrator, can use SQUIT");
526 			break;
527 	}
528 	return KviHybridServerInfo::getUserModeDescription(mode);
529 }
530 
getUserModeDescription(QChar mode) const531 const QString & KviOftcIrcServerInfo::getUserModeDescription(QChar mode) const
532 {
533 	switch(mode.unicode())
534 	{
535 		case 'C':
536 			return __tr2qs("C: Recipient for far connect/quit notices");
537 			break;
538 		case 'P':
539 			return __tr2qs("P: Network service");
540 			break;
541 		case 'w':
542 			return __tr2qs("w: Recipient for server WALLOPS");
543 			break;
544 		case 'z':
545 			return __tr2qs("z: Recipient for oper WALLOPS");
546 			break;
547 	}
548 	return KviHybridServerInfo::getUserModeDescription(mode);
549 }
550 
getUserModeDescription(QChar mode) const551 const QString & KviIrcuIrcServerInfo::getUserModeDescription(QChar mode) const
552 {
553 	switch(mode.unicode())
554 	{
555 		case 'I':
556 			return __tr2qs("I: Idle time hidden");
557 			break;
558 		case 'd':
559 			return __tr2qs("d: Deaf");
560 			break;
561 		case 'g':
562 			return __tr2qs("g: Recipient for server debug notices");
563 			break;
564 		case 'k':
565 			return __tr2qs("k: Network service");
566 			break;
567 		case 'n':
568 			return __tr2qs("n: Channels hidden from WHOIS");
569 			break;
570 		case 'r':
571 			return __tr2qs("r: Registered");
572 			break;
573 		case 'x':
574 			return __tr2qs("x: Host hidden");
575 			break;
576 	}
577 	return KviBasicIrcServerInfo::getUserModeDescription(mode);
578 }
579 
getUserModeDescription(QChar mode) const580 const QString & KviSnircdIrcServerInfo::getUserModeDescription(QChar mode) const
581 {
582 	switch(mode.unicode())
583 	{
584 		case 'P':
585 			return __tr2qs("P: Recipient for notices on WHOIS");
586 			break;
587 		case 'R':
588 			return __tr2qs("R: Only receive private messages from registered nicks");
589 			break;
590 		case 'X':
591 			return __tr2qs("X: Special powers");
592 			break;
593 		case 'h':
594 			return __tr2qs("h: Host changed");
595 			break;
596 	}
597 	return KviIrcuIrcServerInfo::getUserModeDescription(mode);
598 }
599 
getUserModeDescription(QChar mode) const600 const QString & KviDarenetIrcServerInfo::getUserModeDescription(QChar mode) const
601 {
602 	switch(mode.unicode())
603 	{
604 		case 'F':
605 			return __tr2qs("F: Disable fake lag");
606 			break;
607 		case 'H':
608 			return __tr2qs("H: Hide oper status");
609 			break;
610 		case 'N':
611 			return __tr2qs("N: Network administrator");
612 			break;
613 		case 'P':
614 			return __tr2qs("P: Recipient for notices on WHOIS");
615 			break;
616 		case 'R':
617 			return __tr2qs("R: Only receive private messages from registered nicks");
618 			break;
619 		case 'X':
620 			return __tr2qs("X: Special powers");
621 			break;
622 		case 'a':
623 			return __tr2qs("a: Server administrator");
624 			break;
625 	}
626 	return KviIrcuIrcServerInfo::getUserModeDescription(mode);
627 }
628 
getUserModeDescription(QChar mode) const629 const QString & KviUnreal32IrcServerInfo::getUserModeDescription(QChar mode) const
630 {
631 	switch(mode.unicode())
632 	{
633 		case 'A':
634 			return __tr2qs("A: Server administrator");
635 			break;
636 		case 'B':
637 			return __tr2qs("B: Marks as being a bot");
638 			break;
639 		case 'C':
640 			return __tr2qs("C: Co-Admin");
641 			break;
642 		case 'F':
643 			return __tr2qs("F: Override filter settings");
644 			break;
645 		case 'G':
646 			return __tr2qs("G: Filter out bad words");
647 			break;
648 		case 'H':
649 			return __tr2qs("H: Hide oper status");
650 			break;
651 		case 'I':
652 			return __tr2qs("I: Idle time hidden from WHOIS");
653 			break;
654 		case 'N':
655 			return __tr2qs("N: Network administrator");
656 			break;
657 		case 'R':
658 			return __tr2qs("R: Only receive private messages from registered nicks");
659 			break;
660 		case 'S':
661 			return __tr2qs("S: Network service");
662 			break;
663 		case 'T':
664 			return __tr2qs("T: Prevent CTCPs");
665 			break;
666 		case 'V':
667 			return __tr2qs("V: Connected over WebTV");
668 			break;
669 		case 'W':
670 			return __tr2qs("W: Recipient for notices on WHOIS");
671 			break;
672 		case 'a':
673 			return __tr2qs("a: Services administrator");
674 			break;
675 		case 'd':
676 			return __tr2qs("d: Deaf");
677 			break;
678 		case 'g':
679 			return __tr2qs("g: Can send & read LOCOPS and GLOBOPS");
680 			break;
681 		case 'h':
682 			return __tr2qs("h: Available for help (helpop)");
683 			break;
684 		case 'p':
685 			return __tr2qs("p: Channels hidden from WHOIS");
686 			break;
687 		case 'q':
688 			return __tr2qs("q: Immune to kicks (except U-Line)");
689 			break;
690 		case 'r':
691 			return __tr2qs("r: Registered");
692 			break;
693 		case 't':
694 			return __tr2qs("t: Using a vhost");
695 			break;
696 		case 'v':
697 			return __tr2qs("v: Recipient for infected DCC SEND rejection notices");
698 			break;
699 		case 'x':
700 			return __tr2qs("x: Host hidden");
701 			break;
702 		case 'z':
703 			return __tr2qs("z: Connected over SSL");
704 			break;
705 	}
706 	return KviBasicIrcServerInfo::getUserModeDescription(mode);
707 }
708 
getUserModeDescription(QChar mode) const709 const QString & KviUnreal40IrcServerInfo::getUserModeDescription(QChar mode) const
710 {
711 	switch(mode.unicode())
712 	{
713 		case 'D':
714 			return __tr2qs("D: Only receive private messages from opers, servers, or services");
715 			break;
716 		case 'Z':
717 			return __tr2qs("Z: Only receive private messages from users with SSL");
718 			break;
719 	}
720 	return KviUnreal32IrcServerInfo::getUserModeDescription(mode);
721 }
722 
getUserModeDescription(QChar mode) const723 const QString & KviCritenIrcServerInfo::getUserModeDescription(QChar mode) const
724 {
725 	switch(mode.unicode())
726 	{
727 		case 'C':
728 			return __tr2qs("C: Can see CHATOPS notices");
729 			break;
730 		case 'D':
731 			return __tr2qs("D: Has seen DCCALLOW warning message");
732 			break;
733 		case 'F':
734 			return __tr2qs("F: Recipient for far connect/quit notices");
735 			break;
736 		case 'P':
737 			return __tr2qs("P: Services administrator");
738 			break;
739 		case 'S':
740 			return __tr2qs("S: Network service");
741 			break;
742 		case 'W':
743 			return __tr2qs("W: Recipient for notices on WHOIS");
744 			break;
745 		case 'Z':
746 			return __tr2qs("Z: Services root administrator");
747 			break;
748 		case 'a':
749 			return __tr2qs("a: Services operator");
750 			break;
751 		case 'e':
752 			return __tr2qs("e: Recipient for blocked DCC notices");
753 			break;
754 		case 'f':
755 			return __tr2qs("f: Recipient for excess flood notices");
756 			break;
757 		case 'g':
758 			return __tr2qs("g: Recipient for GLOBOPS notices");
759 			break;
760 		case 'h':
761 			return __tr2qs("h: Available for help (helpop)");
762 			break;
763 		case 'm':
764 			return __tr2qs("m: Recipient for spam warning notices");
765 			break;
766 		case 'n':
767 			return __tr2qs("n: Recipient for NETINFO and routing notices");
768 			break;
769 		case 'p':
770 			return __tr2qs("p: Protected IRC operator");
771 			break;
772 		case 'r':
773 			return __tr2qs("r: Registered");
774 			break;
775 		case 'x':
776 			return __tr2qs("x: Host hidden");
777 			break;
778 	}
779 	return KviBasicIrcServerInfo::getUserModeDescription(mode);
780 }
781 
getUserModeDescription(QChar mode) const782 const QString & KviBahamutIrcServerInfo::getUserModeDescription(QChar mode) const
783 {
784 	switch(mode.unicode())
785 	{
786 		case 'A':
787 			return __tr2qs("A: Server administrator");
788 			break;
789 		case 'C':
790 			return __tr2qs("C: Only accept private messages from users in common channels");
791 			break;
792 		case 'F':
793 			return __tr2qs("F: Can bypass the IRCd's recvq throttling");
794 			break;
795 		case 'I':
796 			return __tr2qs("I: Hide oper status");
797 			break;
798 		case 'K':
799 			return __tr2qs("K: Can see U:lined kill messages");
800 			break;
801 		case 'R':
802 			return __tr2qs("R: Only receive private messages from registered nicks");
803 			break;
804 		case 'S':
805 			return __tr2qs("S: Connected over SSL");
806 			break;
807 		case 'X':
808 			return __tr2qs("X: Squelch without notice");
809 			break;
810 		case 'a':
811 			return __tr2qs("a: Services administrator");
812 			break;
813 		case 'b':
814 			return __tr2qs("b: Can see CHATOPS notices");
815 			break;
816 		case 'e':
817 			return __tr2qs("e: Recipient for blocked DCC notices");
818 			break;
819 		case 'f':
820 			return __tr2qs("f: Recipient for flood warnings");
821 			break;
822 		case 'g':
823 			return __tr2qs("g: Recipient for GLOBOPS notices");
824 			break;
825 		case 'h':
826 			return __tr2qs("h: Available for help (helpop)");
827 			break;
828 		case 'j':
829 			return __tr2qs("j: Recipient for rejected client notices");
830 			break;
831 		case 'm':
832 			return __tr2qs("m: Recipient for spambot notices");
833 			break;
834 		case 'n':
835 			return __tr2qs("n: Recipient for routing notices");
836 			break;
837 		case 'r':
838 			return __tr2qs("r: Registered");
839 			break;
840 		case 's':
841 			return __tr2qs("s: Recipient for server KILL messages");
842 			break;
843 		case 'x':
844 			return __tr2qs("x: Squelch with notice");
845 			break;
846 		case 'y':
847 			return __tr2qs("y: Can see certain information requests (e.g. /stats)");
848 			break;
849 	}
850 	return KviBasicIrcServerInfo::getUserModeDescription(mode);
851 }
852 
getUserModeDescription(QChar mode) const853 const QString & KviHyperionIrcServerInfo::getUserModeDescription(QChar mode) const
854 {
855 	switch(mode.unicode())
856 	{
857 		case 'A':
858 			return __tr2qs("A: Can see all servers and IP addresses");
859 			break;
860 		case 'B':
861 			return __tr2qs("B: Allows the use of SETHOST, SETNAME, and SETIDENT commands on other people");
862 			break;
863 		case 'C':
864 			return __tr2qs("C: Prevent CTCPs");
865 			break;
866 		case 'D':
867 			return __tr2qs("D: Allows the use of DIE and RESTART");
868 			break;
869 		case 'E':
870 			return __tr2qs("E: Only receive private messages from registered nicks");
871 			break;
872 		case 'F':
873 			return __tr2qs("F: Immune to flood protection");
874 			break;
875 		case 'G':
876 			return __tr2qs("G: Allows the use of KILL for users on remote servers");
877 			break;
878 		case 'H':
879 			return __tr2qs("H: Allows the use of REHASH");
880 			break;
881 		case 'I':
882 			return __tr2qs("I: Prevents you from receiving INVITEs");
883 			break;
884 		case 'K':
885 			return __tr2qs("K: Allows the use of KLINE");
886 			break;
887 		case 'L':
888 			return __tr2qs("L: Allows the use of 4-argument LUSERS to force a recount");
889 			break;
890 		case 'M':
891 			return __tr2qs("M: Allows the use of NOTICE based on mask");
892 			break;
893 		case 'N':
894 			return __tr2qs("N: Can override Q-Lines");
895 			break;
896 		case 'P':
897 			return __tr2qs("P: Allows the use of SETHOST, SETIDENT and SETNAME");
898 			break;
899 		case 'Q':
900 			return __tr2qs("Q: Prevents you from being affected by channel forwarding");
901 			break;
902 		case 'R':
903 			return __tr2qs("R: Allows the use of CONNECT, SQUIT, and HTM");
904 			break;
905 		case 'S':
906 			return __tr2qs("S: Allows the use of remotely running server commands");
907 			break;
908 		case 'T':
909 			return __tr2qs("T: Allows you to appear in /stats p");
910 			break;
911 		case 'U':
912 			return __tr2qs("U: Allows the use of UNKLINE");
913 			break;
914 		case 'V':
915 			return __tr2qs("V: Allows the use of MAP, LINKS, as well as receiving connection information");
916 		case 'W':
917 			return __tr2qs("W: Allows the ability to send WALLOPS");
918 			break;
919 		case 'X':
920 			return __tr2qs("X: Grants access to experimental features");
921 			break;
922 		case 'Y':
923 			return __tr2qs("Y: Displays extra information during netjoins");
924 			break;
925 		case 'Z':
926 			return __tr2qs("Z: Allows the ability to send OPERWALL messages");
927 			break;
928 		case 'a':
929 			return __tr2qs("a: Can see all users and channels");
930 			break;
931 		case 'b':
932 			return __tr2qs("b: Recipient for spam warning notices");
933 			break;
934 		case 'c':
935 			return __tr2qs("c: Recipient for connect and netjoin notices");
936 			break;
937 		case 'e':
938 			return __tr2qs("e: Registered");
939 			break;
940 		case 'f':
941 			return __tr2qs("f: Recipient for full I-Line notices");
942 			break;
943 		case 'h':
944 			return __tr2qs("h: Sets user in high priority mode");
945 			break;
946 		case 'j':
947 			return __tr2qs("j: Allows the use of auto D-Lines");
948 			break;
949 		case 'l':
950 			return __tr2qs("l: Recipient for new channel creation notices");
951 			break;
952 		case 'm':
953 			return __tr2qs("m: Can't be KICKed, DEOPed, or D-Lined");
954 			break;
955 		case 'p':
956 			return __tr2qs("p: Allows implicit access in all channels, regardless of status");
957 			break;
958 		case 'r':
959 			return __tr2qs("r: Recipient for notices on users attempting to use invalid nicks, Q-Lined or X-Lined nicks");
960 			break;
961 		case 't':
962 			return __tr2qs("t: Allows the use of channel logging");
963 			break;
964 		case 'u':
965 			return __tr2qs("u: Allows the ability to join more channels than the default IRCd limit");
966 			break;
967 		case 'v':
968 			return __tr2qs("v: Allows the ability to view oper privileges via WHOIS");
969 			break;
970 		case 'x':
971 			return __tr2qs("x: Allows the ability to see netjoins");
972 			break;
973 		case 'z':
974 			return __tr2qs("z: Recipient for OPERWALL messages");
975 			break;
976 		case '0':
977 			return __tr2qs("0: Allows the ability to view oper information");
978 			break;
979 		case '1':
980 			return __tr2qs("1: Allows the ability to view I-Lines and Y-Lines");
981 			break;
982 		case '2':
983 			return __tr2qs("2: Allows the ability to view D-Lines and K-Lines");
984 			break;
985 		case '3':
986 			return __tr2qs("3: Allows the ability to view Q-Lines and X-Lines");
987 			break;
988 		case '4':
989 			return __tr2qs("4: Allows the ability to use STATS T");
990 			break;
991 		case '5':
992 			return __tr2qs("5: Allows the ability to use STATS ?");
993 			break;
994 		case '9':
995 			return __tr2qs("9: Allows the use of TESTLINE");
996 			break;
997 		case '*':
998 			return __tr2qs("*: Allows the user to grant umodes they have access to to other people");
999 			break;
1000 		case '@':
1001 			return __tr2qs("@: allows the user to change their host to anything with the SETHOST command");
1002 			break;
1003 	}
1004 	return KviBasicIrcServerInfo::getUserModeDescription(mode);
1005 }
1006 
getUserModeDescription(QChar mode) const1007 const QString & KviInspIRCdIrcServerInfo::getUserModeDescription(QChar mode) const
1008 {
1009 	switch(mode.unicode())
1010 	{
1011 		case 'c':
1012 			return __tr2qs("c: Prevent CTCPs");
1013 			break;
1014 		case 'd':
1015 			return __tr2qs("d: Deaf");
1016 			break;
1017 		case 'g':
1018 			return __tr2qs("g: Server side ignore");
1019 			break;
1020 		case 'h':
1021 			return __tr2qs("h: Available for help (helpop)");
1022 			break;
1023 		case 'k':
1024 			return __tr2qs("k: Network service");
1025 			break;
1026 		case 'r':
1027 			return __tr2qs("r: Registered");
1028 			break;
1029 		case 'x':
1030 			return __tr2qs("x: Host hidden");
1031 			break;
1032 		case 'B':
1033 			return __tr2qs("B: Marks as being a bot");
1034 			break;
1035 		case 'G':
1036 			return __tr2qs("G: Censor bad words");
1037 			break;
1038 		case 'H':
1039 			return __tr2qs("H: Hide oper status");
1040 			break;
1041 		case 'I':
1042 			return __tr2qs("I: Channels hidden from WHOIS");
1043 			break;
1044 		case 'Q':
1045 			return __tr2qs("Q: Marks an IRC operator as invisible from user lists");
1046 			break;
1047 		case 'R':
1048 			return __tr2qs("R: Only receive private messages from registered nicks");
1049 			break;
1050 		case 'S':
1051 			return __tr2qs("S: Strip colors out of private messages");
1052 			break;
1053 		case 'W':
1054 			return __tr2qs("W: Recipient for notices on WHOIS");
1055 			break;
1056 	}
1057 	return KviBasicIrcServerInfo::getUserModeDescription(mode);
1058 }
1059 
1060 //
1061 // UMODE Requirements
1062 //
1063 
1064 // Cases returning themselves (case 'o': return 'o';) are modes
1065 // that can be obtained by IRCd commands (/OPER) yet can be removed
1066 // by the user. e.g. you can obtain usermode +o by running /OPER
1067 // yet can remove it (de-oper) if you have it.
1068 //
1069 // Cases returning a mode different from their case are modes that
1070 // are dependent on the modes being returned. For example, the function
1071 // receives 'y' which could be, for example, routing requests. We would
1072 // return 'o', as 'y' requires operator privileges and the operator mode
1073 // is 'o'. We are then basically saying that 'y' requires 'o', so return
1074 // 'o' for further parsing. If they do not, then we know they are not an
1075 // IRC Operator and are not allowed to set mode 'y'.
1076 //
1077 // Cases returning a ! mean that the mode cannot be set by the user in
1078 // any way, shape, or form. It is strictly IRCd set and can not be set
1079 // or unset by the user. An example of this is 'S' for 'Connected over
1080 // SSL'. This is determined at connection time and set by the IRCd if
1081 // you are using SSL. There is no way to magically switch to SSL after
1082 // you've made the connection. Thus, the mode can never be set or unset
1083 // by the user.
1084 //
1085 // Cases returning QChar::Null are free to set by the user without restrictions.
getUserModeRequirement(QChar mode) const1086 QChar KviBasicIrcServerInfo::getUserModeRequirement(QChar mode) const
1087 {
1088 	switch(mode.unicode())
1089 	{
1090 		// These cases are for modes that can be obtained by IRCd
1091 		// commands (/OPER) and in no other way. However, they can
1092 		// be unset if the user has these modes. (i.e. de-opering)
1093 		case 'O':
1094 			return 'O';
1095 		case 'a':
1096 			return 'a';
1097 
1098 		// These modes require operator privileges to set. We return
1099 		// 'o' to see if the user is an oper.
1100 		case 'c':
1101 		case 'd':
1102 		case 'f':
1103 		case 'k':
1104 		case 'n':
1105 		case 'o':
1106 		case 's':
1107 		case 'y':
1108 		case 'z':
1109 			return 'o';
1110 	}
1111 	// No restriction, mode is free to set.
1112 	return QChar::Null;
1113 }
1114 
getUserModeRequirement(QChar mode) const1115 QChar KviHybridServerInfo::getUserModeRequirement(QChar mode) const
1116 {
1117 	switch(mode.unicode())
1118 	{
1119 		case 'a':
1120 			return 'a';
1121 
1122 		case 'S':
1123 		case 'W':
1124 		case 'r':
1125 		case 'x':
1126 			return '!';
1127 
1128 		case 'F':
1129 		case 'H':
1130 		case 'c':
1131 		case 'd':
1132 		case 'e':
1133 		case 'f':
1134 		case 'j':
1135 		case 'k':
1136 		case 'l':
1137 		case 'n':
1138 		case 'o':
1139 		case 's':
1140 		case 'u':
1141 		case 'y':
1142 			return 'o';
1143 	}
1144 	return QChar::Null;
1145 }
1146 
getUserModeRequirement(QChar mode) const1147 QChar KviIrcdRatboxIrcServerInfo::getUserModeRequirement(QChar mode) const
1148 {
1149 	switch(mode.unicode())
1150 	{
1151 		case 'a':
1152 			return 'a';
1153 
1154 		case 'Z':
1155 		case 'b':
1156 		case 'c':
1157 		case 'd':
1158 		case 'f':
1159 		case 'k':
1160 		case 'l':
1161 		case 'n':
1162 		case 'o':
1163 		case 'r':
1164 		case 'u':
1165 		case 'x':
1166 		case 'y':
1167 		case 'z':
1168 			return 'o';
1169 	}
1170 	return QChar::Null;
1171 }
1172 
getUserModeRequirement(QChar mode) const1173 QChar KviCharybdisServerInfo::getUserModeRequirement(QChar mode) const
1174 {
1175 	switch(mode.unicode())
1176 	{
1177 		case 'a':
1178 			return 'a';
1179 
1180 		case 'S':
1181 		case 'Z':
1182 			return '!';
1183 
1184 		case 'l':
1185 		case 'o':
1186 		case 'p':
1187 		case 's':
1188 		case 'z':
1189 			return 'o';
1190 	}
1191 	return QChar::Null;
1192 }
1193 
getUserModeRequirement(QChar mode) const1194 QChar KviIrcdSevenIrcServerInfo::getUserModeRequirement(QChar mode) const
1195 {
1196 	switch(mode.unicode())
1197 	{
1198 		case 'O':
1199 			return 'O';
1200 		case 'a':
1201 			return 'a';
1202 
1203 		case 'S':
1204 		case 'Z':
1205 			return '!';
1206 
1207 		case 'h':
1208 		case 'l':
1209 		case 'o':
1210 		case 'p':
1211 		case 'z':
1212 			return 'o';
1213 	}
1214 	return QChar::Null;
1215 }
1216 
getUserModeRequirement(QChar mode) const1217 QChar KviPlexusIrcServerInfo::getUserModeRequirement(QChar mode) const
1218 {
1219 	switch(mode.unicode())
1220 	{
1221 		case 'N':
1222 			return 'N';
1223 		case 'a':
1224 			return 'a';
1225 		case 'q':
1226 			return 'q';
1227 
1228 		case 'S':
1229 		case 'U':
1230 		case 'W':
1231 		case 'r':
1232 			return '!';
1233 
1234 		case 'F':
1235 		case 'X':
1236 		case 'b':
1237 		case 'c':
1238 		case 'd':
1239 		case 'f':
1240 		case 'j':
1241 		case 'k':
1242 		case 'l':
1243 		case 'n':
1244 		case 'o':
1245 		case 'u':
1246 		case 'y':
1247 		case 'z':
1248 			return 'o';
1249 	}
1250 	return QChar::Null;
1251 }
1252 
getUserModeRequirement(QChar mode) const1253 QChar KviOftcIrcServerInfo::getUserModeRequirement(QChar mode) const
1254 {
1255 	switch(mode.unicode())
1256 	{
1257 		case 'a':
1258 			return 'a';
1259 
1260 		case 'P':
1261 		case 'S':
1262 			return '!';
1263 
1264 		case 'C':
1265 		case 'b':
1266 		case 'c':
1267 		case 'd':
1268 		case 'f':
1269 		case 'k':
1270 		case 'l':
1271 		case 'n':
1272 		case 'o':
1273 		case 'r':
1274 		case 'u':
1275 		case 'y':
1276 		case 'x':
1277 		case 'z':
1278 			return 'o';
1279 	}
1280 	return QChar::Null;
1281 }
1282 
getUserModeRequirement(QChar mode) const1283 QChar KviIrcuIrcServerInfo::getUserModeRequirement(QChar mode) const
1284 {
1285 	switch(mode.unicode())
1286 	{
1287 		case 'O':
1288 			return 'O';
1289 
1290 		case 'k':
1291 		case 'r':
1292 		case 'x':
1293 			return '!';
1294 
1295 		case 'I':
1296 		case 'g':
1297 		case 'n':
1298 		case 'o':
1299 			return 'o';
1300 	}
1301 	return QChar::Null;
1302 }
1303 
getUserModeRequirement(QChar mode) const1304 QChar KviSnircdIrcServerInfo::getUserModeRequirement(QChar mode) const
1305 {
1306 	switch(mode.unicode())
1307 	{
1308 		case 'O':
1309 			return 'O';
1310 
1311 		case 'k':
1312 		case 'r':
1313 		case 'x':
1314 			return '!';
1315 
1316 		case 'I':
1317 		case 'P':
1318 		case 'X':
1319 		case 'g':
1320 		case 'n':
1321 		case 'o':
1322 			return 'o';
1323 	}
1324 	return QChar::Null;
1325 }
1326 
getUserModeRequirement(QChar mode) const1327 QChar KviDarenetIrcServerInfo::getUserModeRequirement(QChar mode) const
1328 {
1329 	switch(mode.unicode())
1330 	{
1331 		case 'N':
1332 			return 'N';
1333 		case 'O':
1334 			return 'O';
1335 		case 'a':
1336 			return 'a';
1337 
1338 		case 'k':
1339 		case 'x':
1340 			return '!';
1341 
1342 		case 'F':
1343 		case 'H':
1344 		case 'I':
1345 		case 'P':
1346 		case 'X':
1347 		case 'g':
1348 		case 'n':
1349 		case 'o':
1350 		case 'z':
1351 			return 'o';
1352 	}
1353 	return QChar::Null;
1354 }
1355 
getUserModeRequirement(QChar mode) const1356 QChar KviUnreal32IrcServerInfo::getUserModeRequirement(QChar mode) const
1357 {
1358 	switch(mode.unicode())
1359 	{
1360 		case 'A':
1361 			return 'A';
1362 		case 'C':
1363 			return 'C';
1364 		case 'N':
1365 			return 'N';
1366 		case 'O':
1367 			return 'O';
1368 		case 'a':
1369 			return 'a';
1370 		case 'r':
1371 			return 'r';
1372 		case 't':
1373 			return 't';
1374 
1375 		// Modes that cannot be set by the user
1376 		case 'S':
1377 		case 'V':
1378 		case 'x':
1379 		case 'z':
1380 			return '!';
1381 
1382 		// Modes requiring oper (o)
1383 		case 'F':
1384 		case 'H':
1385 		case 'I':
1386 		case 'W':
1387 		case 'f':
1388 		case 'g':
1389 		case 'h':
1390 		case 'o':
1391 		case 's':
1392 		case 'v':
1393 		case 'w':
1394 			return 'o';
1395 
1396 		// 'q': Only U:Lines can kick you (Services Admins Only)
1397 		// Requires 'a': Services Admin
1398 		case 'q':
1399 			return 'a';
1400 	}
1401 	return QChar::Null;
1402 }
1403 
getUserModeRequirement(QChar mode) const1404 QChar KviCritenIrcServerInfo::getUserModeRequirement(QChar mode) const
1405 {
1406 	switch(mode.unicode())
1407 	{
1408 		case 'O':
1409 			return 'O';
1410 
1411 		case 'P':
1412 		case 'S':
1413 		case 'Z':
1414 		case 'a':
1415 		case 'r':
1416 		case 'x':
1417 			return '!';
1418 
1419 		case 'c':
1420 		case 'C':
1421 		case 'd':
1422 		case 'e':
1423 		case 'f':
1424 		case 'F':
1425 		case 'g':
1426 		case 'm':
1427 		case 'n':
1428 		case 'p':
1429 		case 'W':
1430 		case 'y':
1431 		case 'h':
1432 		case 'o':
1433 			return 'o';
1434 	}
1435 	return QChar::Null;
1436 }
1437 
getUserModeRequirement(QChar mode) const1438 QChar KviBahamutIrcServerInfo::getUserModeRequirement(QChar mode) const
1439 {
1440 	switch(mode.unicode())
1441 	{
1442 		case 'A':
1443 			return 'A';
1444 		case 'O':
1445 			return 'O';
1446 
1447 		case 'S':
1448 		case 'W':
1449 		case 'X':
1450 		case 'a':
1451 		case 'r':
1452 		case 'w':
1453 		case 'x':
1454 			return '!';
1455 
1456 		case 'F':
1457 		case 'I':
1458 		case 'K':
1459 		case 'b':
1460 		case 'c':
1461 		case 'd':
1462 		case 'e':
1463 		case 'f':
1464 		case 'g':
1465 		case 'h':
1466 		case 'j':
1467 		case 'k':
1468 		case 'm':
1469 		case 'n':
1470 		case 'o':
1471 		case 'y':
1472 			return 'o';
1473 	}
1474 	return QChar::Null;
1475 }
1476 
getUserModeRequirement(QChar mode) const1477 QChar KviHyperionIrcServerInfo::getUserModeRequirement(QChar mode) const
1478 {
1479 	switch(mode.unicode())
1480 	{
1481 		case 'e':
1482 			return '!';
1483 		case 'A':
1484 		case 'B':
1485 		case 'D':
1486 		case 'F':
1487 		case 'G':
1488 		case 'K':
1489 		case 'L':
1490 		case 'M':
1491 		case 'N':
1492 		case 'P':
1493 		case 'R':
1494 		case 'S':
1495 		case 'T':
1496 		case 'U':
1497 		case 'V':
1498 		case 'W':
1499 		case 'X':
1500 		case 'Y':
1501 		case 'Z':
1502 		case 'a':
1503 		case 'b':
1504 		case 'c':
1505 		case 'd':
1506 		case 'f':
1507 		case 'h':
1508 		case 'H':
1509 		case 'j':
1510 		case 'k':
1511 		case 'l':
1512 		case 'm':
1513 		case 'n':
1514 		case 'o':
1515 		case 'p':
1516 		case 'r':
1517 		case 'u':
1518 		case 'v':
1519 		case 'x':
1520 		case 'y':
1521 		case 'z':
1522 		case '0':
1523 		case '1':
1524 		case '2':
1525 		case '3':
1526 		case '4':
1527 		case '5':
1528 		case '9':
1529 		case '*':
1530 		case '@':
1531 			return 'o';
1532 	}
1533 	return QChar::Null;
1534 }
1535 
getUserModeRequirement(QChar mode) const1536 QChar KviInspIRCdIrcServerInfo::getUserModeRequirement(QChar mode) const
1537 {
1538 	switch(mode.unicode())
1539 	{
1540 		case 'k':
1541 		case 'r':
1542 		case 'x':
1543 			return '!';
1544 
1545 		case 'H':
1546 		case 'Q':
1547 		case 'W':
1548 		case 'h':
1549 		case 'o':
1550 			return 'o';
1551 	}
1552 	return QChar::Null;
1553 }
1554 
1555 //
1556 // Channel modes
1557 //
1558 
getChannelModeDescription(char mode) const1559 const QString & KviBasicIrcServerInfo::getChannelModeDescription(char mode) const
1560 {
1561 	switch(mode)
1562 	{
1563 		case 'I':
1564 			return __tr2qs("Invite exceptions");
1565 			break;
1566 		case 'b':
1567 			return __tr2qs("Ban masks");
1568 			break;
1569 		case 'e':
1570 			return __tr2qs("Ban exceptions");
1571 			break;
1572 		case 'i':
1573 			return __tr2qs("Invite only");
1574 			break;
1575 		case 'k':
1576 			return __tr2qs("Key");
1577 			break;
1578 		case 'l':
1579 			return __tr2qs("Limited number of users");
1580 			break;
1581 		case 'm':
1582 			return __tr2qs("Moderated");
1583 			break;
1584 		case 'n':
1585 			return __tr2qs("No external messages");
1586 			break;
1587 		case 'o':
1588 			return __tr2qs("Channel operators");
1589 			break;
1590 		case 'p':
1591 			return __tr2qs("Private");
1592 			break;
1593 		case 's':
1594 			return __tr2qs("Secret");
1595 			break;
1596 		case 't':
1597 			return __tr2qs("Topic change restricted");
1598 			break;
1599 		case 'v':
1600 			return __tr2qs("Voiced users");
1601 			break;
1602 	}
1603 	return KviQString::Empty;
1604 }
1605 
getChannelModeDescription(char mode) const1606 const QString & KviHybridServerInfo::getChannelModeDescription(char mode) const
1607 {
1608 	switch(mode)
1609 	{
1610 		case 'C':
1611 			return __tr2qs("Forbid channel CTCPs");
1612 			break;
1613 		case 'M':
1614 			return __tr2qs("Moderate non auth users");
1615 			break;
1616 		case 'O':
1617 			return __tr2qs("IRC-Op only channel");
1618 			break;
1619 		case 'R':
1620 			return __tr2qs("Only registered nicks can join");
1621 			break;
1622 		case 'S':
1623 			return __tr2qs("Need SSL connection to join");
1624 			break;
1625 		case 'T':
1626 			return __tr2qs("Forbid channel NOTICEs");
1627 			break;
1628 		case 'c':
1629 			return __tr2qs("No control codes (colors, bold, ..)");
1630 			break;
1631 		case 'h':
1632 			return __tr2qs("Half-operators");
1633 			break;
1634 		case 'r':
1635 			return __tr2qs("Registered");
1636 			break;
1637 	}
1638 	return KviBasicIrcServerInfo::getChannelModeDescription(mode);
1639 }
1640 
getChannelModeDescription(char mode) const1641 const QString & KviIrcdRatboxIrcServerInfo::getChannelModeDescription(char mode) const
1642 {
1643 	switch(mode)
1644 	{
1645 		// not present of efnet, but supported by ratbox
1646 		case 'r':
1647 			return __tr2qs("Only registered nicks can join");
1648 			break;
1649 	}
1650 	return KviHybridServerInfo::getChannelModeDescription(mode);
1651 }
1652 
getChannelModeDescription(char mode) const1653 const QString & KviCharybdisServerInfo::getChannelModeDescription(char mode) const
1654 {
1655 	switch(mode)
1656 	{
1657 		case 'A':
1658 			return __tr2qs("Server administrator only channel");
1659 			break;
1660 		case 'F':
1661 			return __tr2qs("Allow anyone to forward users to this channel");
1662 			break;
1663 		case 'L':
1664 			return __tr2qs("Large ban/exempt/invex lists (staff only)");
1665 			break;
1666 		case 'M':
1667 			return __tr2qs("Disallow kicking opers (staff only)");
1668 			break;
1669 		case 'P':
1670 			return __tr2qs("Persistent (staff only)");
1671 			break;
1672 		case 'Q':
1673 			return __tr2qs("Block forwarded users");
1674 			break;
1675 		case 'R':
1676 			return __tr2qs("Only registered nicks can join");
1677 			break;
1678 		case 'S':
1679 			return __tr2qs("SSL Only");
1680 			break;
1681 		case 'T':
1682 			return __tr2qs("Forbid channel NOTICEs");
1683 			break;
1684 		case 'c':
1685 			return __tr2qs("Strip color codes");
1686 			break;
1687 		case 'f':
1688 			return __tr2qs("Forward to another channel on uninvited");
1689 			break;
1690 		case 'g':
1691 			return __tr2qs("Allow anybody to invite");
1692 			break;
1693 		case 'j':
1694 			return __tr2qs("Join throttling (<num>:<secs>)");
1695 			break;
1696 		case 'p':
1697 			return __tr2qs("Paranoid (disable KNOCK)");
1698 			break;
1699 		case 'q':
1700 			return __tr2qs("Quiet");
1701 			break;
1702 		case 'r':
1703 			return __tr2qs("Need auth to join channel");
1704 			break;
1705 		case 'z':
1706 			return __tr2qs("Reduced moderation for ops");
1707 			break;
1708 	}
1709 	return KviIrcdRatboxIrcServerInfo::getChannelModeDescription(mode);
1710 }
1711 
getChannelModeDescription(char mode) const1712 const QString & KviPlexusIrcServerInfo::getChannelModeDescription(char mode) const
1713 {
1714 	switch(mode)
1715 	{
1716 		case 'B':
1717 			return __tr2qs("Bandwidth Saver");
1718 			break;
1719 		case 'N':
1720 			return __tr2qs("Forbid channel NOTICEs");
1721 			break;
1722 		case 'a':
1723 			return __tr2qs("Protected/administrator nicks");
1724 			break;
1725 		case 'p':
1726 			return __tr2qs("Paranoia");
1727 			break;
1728 		case 'q':
1729 			return __tr2qs("Channel owners");
1730 			break;
1731 		case 'z':
1732 			return __tr2qs("Persistent (staff only)");
1733 			break;
1734 	}
1735 	return KviHybridServerInfo::getChannelModeDescription(mode);
1736 }
1737 
getChannelModeDescription(char mode) const1738 const QString & KviOftcIrcServerInfo::getChannelModeDescription(char mode) const
1739 {
1740 	switch(mode)
1741 	{
1742 		case 'q':
1743 			return __tr2qs("Quiet");
1744 			break;
1745 		case 'z':
1746 			return __tr2qs("Reduced moderation for ops");
1747 			break;
1748 	}
1749 	return KviHybridServerInfo::getChannelModeDescription(mode);
1750 }
1751 
getChannelModeDescription(char mode) const1752 const QString & KviIrcuIrcServerInfo::getChannelModeDescription(char mode) const
1753 {
1754 	switch(mode)
1755 	{
1756 		case 'A':
1757 			return __tr2qs("Admin password");
1758 			break;
1759 		case 'C':
1760 			return __tr2qs("Forbid channel CTCPs");
1761 			break;
1762 		case 'D':
1763 			return __tr2qs("Delay users join to first message");
1764 			break;
1765 		case 'R':
1766 			return __tr2qs("Registered (staff only)");
1767 			break;
1768 		case 'U':
1769 			return __tr2qs("User password");
1770 			break;
1771 		case 'c':
1772 			return __tr2qs("No control codes (colors, bold, ..)");
1773 			break;
1774 		case 'd':
1775 			return __tr2qs("Contains hidden users (previously +D)");
1776 			break;
1777 		case 'r':
1778 			return __tr2qs("Only registered nicks can join");
1779 			break;
1780 		case 'z':
1781 			return __tr2qs("Persistent (staff only)");
1782 			break;
1783 	}
1784 	return KviBasicIrcServerInfo::getChannelModeDescription(mode);
1785 }
1786 
getChannelModeDescription(char mode) const1787 const QString & KviSnircdIrcServerInfo::getChannelModeDescription(char mode) const
1788 {
1789 	switch(mode)
1790 	{
1791 		case 'M':
1792 			return __tr2qs("Moderate non auth users");
1793 			break;
1794 		case 'N':
1795 			return __tr2qs("Forbid channel NOTICEs");
1796 			break;
1797 		case 'T':
1798 			return __tr2qs("No multi-target messages");
1799 			break;
1800 		case 'u':
1801 			return __tr2qs("Hide QUIT and PART messages");
1802 			break;
1803 	}
1804 	return KviIrcuIrcServerInfo::getChannelModeDescription(mode);
1805 }
1806 
getChannelModeDescription(char mode) const1807 const QString & KviDarenetIrcServerInfo::getChannelModeDescription(char mode) const
1808 {
1809 	switch(mode)
1810 	{
1811 		case 'M':
1812 			return __tr2qs("Moderate non auth users");
1813 			break;
1814 		case 'N':
1815 			return __tr2qs("Block channel notices");
1816 			break;
1817 		case 'S':
1818 			return __tr2qs("Strip color codes");
1819 			break;
1820 		case 'T':
1821 			return __tr2qs("No multi-targets");
1822 			break;
1823 		case 'Z':
1824 			return __tr2qs("Need SSL connection to join");
1825 			break;
1826 		case 'h':
1827 			return __tr2qs("Half-operators");
1828 			break;
1829 		case 'q':
1830 			return __tr2qs("Quiet");
1831 			break;
1832 		case 'u':
1833 			return __tr2qs("Squelch parts/quits");
1834 			break;
1835 	}
1836 	return KviIrcuIrcServerInfo::getChannelModeDescription(mode);
1837 }
1838 
getChannelModeDescription(char mode) const1839 const QString & KviUnrealIrcServerInfo::getChannelModeDescription(char mode) const
1840 {
1841 	switch(mode)
1842 	{
1843 		case 'A':
1844 			return __tr2qs("Server/Network/Tech admin only channel");
1845 			break;
1846 		case 'C':
1847 			return __tr2qs("Forbid channel CTCPs");
1848 			break;
1849 		case 'G':
1850 			return __tr2qs("Censor bad words");
1851 			break;
1852 		case 'K':
1853 			return __tr2qs("Forbid /KNOCK");
1854 			break;
1855 		case 'L':
1856 			return __tr2qs("Redirect on channel full (mode +l)");
1857 			break;
1858 		case 'M':
1859 			return __tr2qs("Need auth to speak and change nick");
1860 			break;
1861 		case 'N':
1862 			return __tr2qs("Forbid nick change");
1863 			break;
1864 		case 'O':
1865 			return __tr2qs("IRC-Op only channel");
1866 			break;
1867 		case 'Q':
1868 			return __tr2qs("Disallow KICK (unless U-Line)");
1869 			break;
1870 		case 'R':
1871 			return __tr2qs("Only registered nicks can join");
1872 			break;
1873 		case 'a':
1874 			return __tr2qs("Protected/administrator nicks");
1875 			break;
1876 		case 'c':
1877 			return __tr2qs("No control codes (colors, bold, ..)");
1878 			break;
1879 		case 'f':
1880 			return __tr2qs("Flood protection (<num><type>:<secs>)");
1881 			break;
1882 		case 'h':
1883 			return __tr2qs("Half-operators");
1884 			break;
1885 		case 'j':
1886 			return __tr2qs("Join throttling (<num>:<secs>)");
1887 			break;
1888 		case 'q':
1889 			return __tr2qs("Channel owners");
1890 			break;
1891 		case 'r':
1892 			return __tr2qs("Registered");
1893 			break;
1894 		case 'u':
1895 			return __tr2qs("Auditorium: /NAMES and /WHO show only ops");
1896 			break;
1897 		case 'z':
1898 			return __tr2qs("Need SSL connection to join");
1899 			break;
1900 	}
1901 	return KviBasicIrcServerInfo::getChannelModeDescription(mode);
1902 }
1903 
getChannelModeDescription(char mode) const1904 const QString & KviUnreal32IrcServerInfo::getChannelModeDescription(char mode) const
1905 {
1906 	switch(mode)
1907 	{
1908 		case 'B':
1909 			return __tr2qs("No multi-target messages");
1910 			break;
1911 		case 'E':
1912 			return __tr2qs("Forbid ACTIONs from non-ops");
1913 			break;
1914 		case 'F':
1915 			return __tr2qs("Trusted filter (staff only)");
1916 			break;
1917 		case 'H':
1918 			return __tr2qs("Help operator and above only channel (staff only)");
1919 			break;
1920 		case 'M':
1921 			return __tr2qs("Moderate non auth users");
1922 			break;
1923 		case 'S':
1924 			return __tr2qs("Strip colors");
1925 			break;
1926 		case 'T':
1927 			return __tr2qs("Forbid channel NOTICEs");
1928 			break;
1929 		case 'V':
1930 			return __tr2qs("No invites");
1931 			break;
1932 		case 'Z':
1933 			return __tr2qs("All clients are using SSL (server only)");
1934 			break;
1935 	}
1936 	return KviUnrealIrcServerInfo::getChannelModeDescription(mode);
1937 }
1938 
getChannelModeDescription(char mode) const1939 const QString & KviUnreal40IrcServerInfo::getChannelModeDescription(char mode) const
1940 {
1941 	switch(mode)
1942 	{
1943 		case 'D':
1944 			return __tr2qs("Delay users join to first message");
1945 			break;
1946 		case 'P':
1947 			return __tr2qs("Persistent (staff only)");
1948 			break;
1949 		case 'd':
1950 			return __tr2qs("Contains hidden users (previously +D)");
1951 			break;
1952 	}
1953 	return KviUnreal32IrcServerInfo::getChannelModeDescription(mode);
1954 }
1955 
getChannelModeDescription(char mode) const1956 const QString & KviCritenIrcServerInfo::getChannelModeDescription(char mode) const
1957 {
1958 	switch(mode)
1959 	{
1960 		case 'A':
1961 			return __tr2qs("Server/Network/Tech admin only channel");
1962 			break;
1963 		case 'K':
1964 			return __tr2qs("Forbid /KNOCK");
1965 			break;
1966 		case 'M':
1967 			return __tr2qs("Need auth to speak and change nick");
1968 			break;
1969 		case 'N':
1970 			return __tr2qs("No invites");
1971 			break;
1972 		case 'O':
1973 			return __tr2qs("IRC-Op only channel");
1974 			break;
1975 		case 'R':
1976 			return __tr2qs("Only registered nicks can join");
1977 			break;
1978 		case 'S':
1979 			return __tr2qs("Need SSL connection to join");
1980 			break;
1981 		case 'c':
1982 			return __tr2qs("No control codes (colors, bold, ..)");
1983 			break;
1984 		case 'f':
1985 			return __tr2qs("Flood limit");
1986 			break;
1987 		case 'r':
1988 			return __tr2qs("Registered channel");
1989 			break;
1990 	}
1991 	return KviBasicIrcServerInfo::getChannelModeDescription(mode);
1992 }
1993 
getChannelModeDescription(char mode) const1994 const QString & KviBahamutIrcServerInfo::getChannelModeDescription(char mode) const
1995 {
1996 	switch(mode)
1997 	{
1998 		case 'L':
1999 			return __tr2qs("Channel visible in LIST");
2000 			break;
2001 		case 'M':
2002 			return __tr2qs("Need auth to speak and change nick");
2003 			break;
2004 		case 'O':
2005 			return __tr2qs("IRC-Op only channel");
2006 			break;
2007 		case 'R':
2008 			return __tr2qs("Only registered nicks can join");
2009 			break;
2010 		case 'c':
2011 			return __tr2qs("No control codes (colors, bold, ..)");
2012 			break;
2013 		case 'j':
2014 			if(m_pParent)
2015 			{
2016 				if(m_pParent->supportedPlainModes().contains('j'))
2017 				{
2018 					// Azzurra (bahamut 1.4) similar to 'R'
2019 					return __tr2qs("Only registered nicks can join");
2020 				}
2021 			}
2022 
2023 			// Dalnet (bahamut 1.8)
2024 			return __tr2qs("Join throttling (<num>:<secs>)");
2025 			break;
2026 		// azzurra (bahamuth 1.4) specific addition:
2027 		case 'S':
2028 			return __tr2qs("Need SSL connection to join");
2029 			break;
2030 		case 'U':
2031 			return __tr2qs("Permit foreign users without auth to JOIN");
2032 			break;
2033 		case 'd':
2034 			return __tr2qs("Need op/voice to change nick");
2035 			break;
2036 		case 'h':
2037 			return __tr2qs("Half-operators");
2038 			break;
2039 		case 'r':
2040 			return __tr2qs("Registered");
2041 			break;
2042 		case 'u':
2043 			return __tr2qs("Hide QUIT and PART messages");
2044 			break;
2045 	}
2046 	return KviBasicIrcServerInfo::getChannelModeDescription(mode);
2047 }
2048 
getChannelModeDescription(char mode) const2049 const QString & KviInspIRCdIrcServerInfo::getChannelModeDescription(char mode) const
2050 {
2051 	switch(mode)
2052 	{
2053 		case 'A':
2054 			return __tr2qs("Allow anybody to invite");
2055 			break;
2056 		case 'B':
2057 			return __tr2qs("Block messages with too many CAPS");
2058 			break;
2059 		case 'C':
2060 			return __tr2qs("Forbid channel CTCPs");
2061 			break;
2062 		case 'D':
2063 			return __tr2qs("Delay users join to first message");
2064 			break;
2065 		case 'F':
2066 			return __tr2qs("Limit nick changes (<num>:<secs>)");
2067 			break;
2068 		case 'G':
2069 			return __tr2qs("Censor bad words");
2070 			break;
2071 		case 'J':
2072 			return __tr2qs("Disable join after kick (<secs>)");
2073 			break;
2074 		case 'K':
2075 			return __tr2qs("Forbid /KNOCK");
2076 			break;
2077 		case 'L':
2078 			return __tr2qs("Redirect on channel full (mode +l)");
2079 			break;
2080 		case 'M':
2081 			return __tr2qs("Need auth to speak and change nick");
2082 			break;
2083 		case 'N':
2084 			return __tr2qs("Need auth to change nick");
2085 			break;
2086 		case 'O':
2087 			return __tr2qs("IRC-Op only channel");
2088 			break;
2089 		case 'P':
2090 			return __tr2qs("Persistent (staff only)");
2091 			break;
2092 		case 'Q':
2093 			return __tr2qs("Disallow KICK (unless U-Line)");
2094 			break;
2095 		case 'R':
2096 			return __tr2qs("Only registered nicks can join");
2097 			break;
2098 		case 'S':
2099 			return __tr2qs("Strip colors");
2100 			break;
2101 		case 'T':
2102 			return __tr2qs("Forbid channel NOTICEs");
2103 			break;
2104 		case 'X':
2105 			return __tr2qs("Channel exemptions");
2106 			break;
2107 		case 'Y':
2108 			return __tr2qs("Channel IRC op");
2109 			break;
2110 		case 'a':
2111 			return __tr2qs("Protected/administrator nicks");
2112 			break;
2113 		case 'c':
2114 			return __tr2qs("No control codes (colors, bold, ..)");
2115 			break;
2116 		case 'd':
2117 			return __tr2qs("Delay first message after join by n seconds");
2118 			break;
2119 		case 'f':
2120 			return __tr2qs("Kick/[*]ban on message flood ([*]<num>:<secs>)");
2121 			break;
2122 		case 'g':
2123 			return __tr2qs("Spam filter");
2124 			break;
2125 		case 'h':
2126 			return __tr2qs("Half-operators");
2127 			break;
2128 		case 'j':
2129 			return __tr2qs("Join throttling (<num>:<secs>)");
2130 			break;
2131 		case 'q':
2132 			return __tr2qs("Channel owners");
2133 			break;
2134 		case 'r':
2135 			return __tr2qs("Registered");
2136 			break;
2137 		case 'u':
2138 			return __tr2qs("Auditorium: /NAMES and /WHO show only ops");
2139 			break;
2140 		case 'w':
2141 			return __tr2qs("Channel access");
2142 			break;
2143 		case 'y':
2144 			return __tr2qs("Channel IRC op");
2145 			break;
2146 		case 'z':
2147 			return __tr2qs("Need SSL connection to join");
2148 			break;
2149 	}
2150 	return KviBasicIrcServerInfo::getChannelModeDescription(mode);
2151 }
2152