Trunk_ServerProperties.patch

Patch made by Thomas Bruderer <[email protected]> - Mirco Bauer, 04/10/2009 01:47 PM

Download (29.8 KB)

 
IrcClient/IrcClient.cs (working copy)
7 7
 *
8 8
 * SmartIrc4net - the IRC library for .NET/C# <http://smartirc4net.sf.net>
9 9
 *
10
 * Copyright (c) 2003-2008 Mirco Bauer <[email protected]>
10
 * Copyright (c) 2003-2009 Mirco Bauer <[email protected]>
11
 * Copyright (c) 2008-2009 Thomas Bruderer <[email protected]>
11 12
 *
12 13
 * Full LGPL License: <http://www.gnu.org/licenses/lgpl.txt>
13 14
 *
......
137 138
        public event CtcpEventHandler           OnCtcpRequest;
138 139
        public event CtcpEventHandler           OnCtcpReply;
139 140

  
141
 		private ServerProperties _Properties = new ServerProperties();
142
		public ServerProperties Properties {
143
			get {
144
				return _Properties;
145
			}
146
		}
147
        
140 148
        /// <summary>
141 149
        /// Enables/disables the active channel sync feature.
142 150
        /// Default: false
......
876 884
                case ReplyCode.ErrorNoChannelModes:
877 885
                    channel = linear[3];
878 886
                    break;
887
 				case ReplyCode.Bounce:
888
					if(!line.StartsWith("Try server")) {
889
						// RPL_ISUPPORT (Very common enhancement)
890
						ParseServerProperties(line.Substring(0, colonpos-1));
891
					} else {
892
						// RPL_BOUNCE (Rfc 2812)
893
					}
894
					break;
879 895
            }
880 896

  
881 897
            if ((channel != null) &&
......
899 915
            return data;
900 916
        }
901 917
        
918
        private void ParseServerProperties(string line)
919
        {
920
            string[] parameters = line.Split(new char[] {' '});
921
            int i = 0;
922
            foreach(string s in parameters)
923
            {
924
                if(i<3) {
925
                    i++; continue;
926
                }
927
                
928
                string[] pv = s.Split(new char[] {'='});
929
                Properties._Raw.Add(pv[0],((pv.Length>1)?pv[1]:"TRUE"));
930

  
931
                // Boolean value;
932
                switch(pv[0]) {
933
                    case "EXCEPTS": Properties._BanException = true;
934
                        break;
935
                    case "INVEX": Properties._InviteExceptions = true;
936
                        break;
937
                    case "WALLCHOPS": Properties._WAllChannelOps = true;
938
                        break;
939
                    case "WALLVOICES": Properties._WAllVoices = true;
940
                        break;
941
                    case "RFC2812": Properties._Rfc2812 = true;
942
                        break;
943
                    case "PENALTY": Properties._Penalty = true;
944
                        break;
945
                    case "FNC": Properties._ForcedNickChange = true;
946
                        break;
947
                    case "SAFELIST": Properties._SafeList = true;
948
                        break;
949
                    case "NOQUIT": Properties._NoQuit = true;
950
                        break;
951
                    case "USERIP": Properties._UserIp = true;
952
                        break;
953
                    case "CPRIVMSG": Properties._CPrivateMessage = true;
954
                        break;
955
                    case "CNOTICE": Properties._CNotice = true;
956
                        break;
957
                    case "KNOCK": Properties._Knock = true;
958
                        break;
959
                    case "VCHANS": Properties._VirtualChannels = true;
960
                        break;
961
                    case "WHOX": Properties._WhoX = true;
962
                        break;
963
                    case "CALLERID": Properties._ModeG = true;
964
                        break;
965
                    case "IRCD": Properties._IrcDaemon = pv[1];
966
                        break;
967
                    case "PREFIX": Properties._NickPrefix = pv[1];
968
                        break;
969
                    case "CHANTYPES": Properties._ChannelTypes = pv[1];
970
                        break;
971
                    case "CHANMODES": Properties._ChannelModes = pv[1];
972
                        break;
973
                    case "MODES": Properties._MaxChannelModes = int.Parse(pv[1]);
974
                        break;
975
                    case "MAXCHANNELS": Properties._MaxChannels = int.Parse(pv[1]);
976
                        break;
977
                    case "CHANLIMIT": Properties._MaxChannelsByType = pv[1];
978
                        break;
979
                    case "NICKLEN": Properties._MaxNickLength = int.Parse(pv[1]);
980
                        break;
981
                    case "MAXBANS": Properties._MaxBans = int.Parse(pv[1]);
982
                        break;
983
                    case "MAXLIST": Properties._MaxList = pv[1];
984
                        break;
985
                    case "NETWORK": Properties._NetworkName = pv[1];
986
                        break;
987
                    case "STATUSMSG": Properties._StatusMessage = pv[1];
988
                        break;
989
                    case "CASEMAPPING":
990
                        if (pv[1]=="ascii") Properties._CaseMapping = CaseMappingType.Ascii;
991
                        if (pv[1]=="rfc1459") Properties._CaseMapping = CaseMappingType.Rfc1459;
992
                        if (pv[1]=="strict-rfc1459") Properties._CaseMapping = CaseMappingType.Rfc1459Strict;
993
                        break;
994
                    case "ELIST": Properties._ExtendedListCommand = pv[1];
995
                        break;
996
                    case "TOPICLEN": Properties._MaxTopicLength = int.Parse(pv[1]);
997
                        break;
998
                    case "KICKLEN": Properties._MaxKickLength = int.Parse(pv[1]);
999
                        break;
1000
                    case "CHANNELLEN": Properties._MaxChannelLength = int.Parse(pv[1]);
1001
                        break;
1002
                    case "CHIDLEN": Properties._ChannelIDLength = int.Parse(pv[1]);
1003
                        break;
1004
                    case "IDCHAN": Properties._ChannelIDLengthByType = pv[1];
1005
                        break;
1006
                    case "STD": Properties._IrcStandard = pv[1];
1007
                        break;
1008
                    case "SILENCE": Properties._MaxSilence = int.Parse(pv[1]);
1009
                        break;
1010
                    case "AWAYLEN": Properties._MaxAwayLength = int.Parse(pv[1]);
1011
                        break;
1012
                    case "MAXTARGETS": Properties._MaxTargets = int.Parse(pv[1]);
1013
                        break;
1014
                    case "WATCH": Properties._MaxWatch = int.Parse(pv[1]);
1015
                        break;
1016
                    case "LANGUAGE": Properties._Language = pv[1];
1017
                        break;
1018
                    case "KEYLEN": Properties._MaxKeyLength = int.Parse(pv[1]);
1019
                        break;
1020
                    case "USERLEN": Properties._MaxUserLength = int.Parse(pv[1]);
1021
                        break;
1022
                    case "HOSTLEN": Properties._MaxHostLength = int.Parse(pv[1]);
1023
                        break;
1024
                    case "CMDS": Properties.SetCommands(pv[1]);
1025
                        break;
1026
                    case "MAXNICKLEN": Properties._MaxNickLength = int.Parse(pv[1]);
1027
                        break;
1028
                    case "MAXCHANNELLEN": Properties._MaxChannelLength = int.Parse(pv[1]);
1029
                        break;
1030
                    case "MAP": Properties._Map = true;
1031
                        break;
1032
                    case "TARGMAX": Properties._MaxTargetsByCommand = pv[1];
1033
                        break;
1034
                    default:
1035
#if LOG4NET
1036
                        Logger.MessageParser.Warn(pv[0] + " is not parsed yet but has value: " + ((pv.Length>1)?pv[1]:"true"));
1037
#endif
1038
                    break;
1039
                }
1040
            }
1041
        }
1042
        
902 1043
        protected virtual IrcUser CreateIrcUser(string nickname)
903 1044
        {
904 1045
             return new IrcUser(nickname, this);
IrcClient/ServerProperties.cs (revision 0)
1
/*
2
 *
3
 * SmartIrc4net - the IRC library for .NET/C# <http://smartirc4net.sf.net>
4
 *
5
* Copyright (c) 2008-2009 Thomas Bruderer <[email protected]> <http://www.apophis.ch>
6
 * 
7
 * Full LGPL License: <http://www.gnu.org/licenses/lgpl.txt>
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library 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.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23

  
24
using System;
25
using System.Collections.Generic;
26
using System.Collections.Specialized;
27

  
28
namespace Meebey.SmartIrc4net
29
{
30
    /// <summary>
31
    /// Description of ServerProperties.
32
    /// </summary>
33
    public class ServerProperties
34
    {
35
        internal ServerProperties()
36
        {
37
        }
38
        
39
        internal void SetCommands(string commandList)
40
        {
41
            foreach(string command in commandList.Split(new char[] {','}))
42
            {
43
                switch(command) {
44
                        case "KNOCK" : _Knock = true;
45
                        break;
46
                        case "MAP" : _Map = true;
47
                        break;
48
                        case "DCCALLOW" : _DccAllow = true;
49
                        break;
50
                        case "USERIP" : _UserIp = true;
51
                        break;
52
                    default:
53
#if LOG4NET
54
                        Logger.MessageParser.Warn("Unknown Command: " + command);
55
#endif
56
                        break;
57
                }
58
            }
59
        }
60
        
61
        internal Dictionary<string, string> _Raw = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
62
        
63
        /// <summary>
64
        /// Safe Access to All Values Sent in RPL_ISUPPORT
65
        /// If a Value is not Set this will Return "FALSE" (this can also mean: we don't know)
66
        /// If a Value has no Parameter this will Return "TRUE"
67
        /// The Index should be the Identifier sent by the Server like "PREFIX" (not casesensitive)
68
        /// </summary>
69
        public string this[string s] {
70
            get {
71
                if(_Raw.ContainsKey(s)) {
72
                    return _Raw[s];
73
                } else {
74
                    return "FALSE";
75
                }
76
            }
77
        }
78
        
79
        public IEnumerable<string> KnownValues() {
80
            return _Raw.Keys;
81
        }
82
        
83

  
84
        internal string _IrcDaemon = "unknown";
85
        /// <summary>
86
        /// Returns the Name of the IrcDaemon
87
        /// </summary>
88
        public string IrcDaemon {
89
            get {
90
                return _IrcDaemon;
91
            }
92
        }
93
        
94
        internal string _ChannelTypes = "";
95
        
96
        public IEnumerable<char> ChannelTypes {
97
            get {
98
                return _ChannelTypes.ToCharArray();
99
            }
100
        }
101
        
102
        internal string _ChannelModes = "";
103
        
104
        public IEnumerable<char> ChannelModes
105
        {
106
            get {
107
                List<char> temp = new List<char>();
108
                foreach(char c in _ChannelModes) {
109
                    if (c!=',') {
110
                        temp.Add(c);
111
                    }
112
                }
113
                return temp;
114
            }
115
        }
116
        
117
        public IEnumerable<char> GetChannelModes(ChannelModeType channelModeType)
118
        {
119
            List<char> temp = new List<char>();
120
            string[] modes = _ChannelModes.Split(new char[]{','});
121
            if (modes.Length<4)
122
                return temp;
123
            if(channelModeType== ChannelModeType.WithUserhostParameter) {
124
                AddCharsToList(ref temp, ref modes[0]);
125
            }
126
            if(channelModeType== ChannelModeType.WithAlwaysParamter) {
127
                AddCharsToList(ref temp, ref modes[1]);
128
            }
129
            if(channelModeType== ChannelModeType.WithSetOnlyParameter) {
130
                AddCharsToList(ref temp, ref modes[2]);
131
            }
132
            if(channelModeType== ChannelModeType.WithoutParameter) {
133
                AddCharsToList(ref temp, ref modes[3]);
134
            }
135
            return temp;
136
        }
137

  
138
        void AddCharsToList(ref List<char> temp, ref string modes)
139
        {
140
            foreach (char c in modes) {
141
                if (c != ',') {
142
                    temp.Add(c);
143
                }
144
            }
145
        }
146
        
147
        internal int _MaxChannelModes = -1;
148
        
149
        /// <summary>
150
        /// Returns the maximum number of channel modes with parameter allowed per MODE command (-1 if unknown)
151
        /// </summary>
152
        public int MaxChannelModes {
153
            get {
154
                return _MaxChannelModes;
155
            }
156
        }
157
        
158
        internal int _MaxChannels = -1;
159
        internal string _MaxChannelsByType = "";
160
        
161
        
162
        /// <summary>
163
        /// Maximum number of channels allowed to join (# channels);
164
        /// </summary>
165
        public int MaxChannels {
166
            get {
167
                return GetMaxChannels('#');
168
            }
169
        }
170
        
171
        /// <summary>
172
        /// Maximum number of channels allowed to join per Channel Type;
173
        /// </summary>
174
        /// <param name="channelPrefix">On Which Type of channels (ex. '#')</param>
175
        /// <returns>Length of Channel ID</returns>
176
        public int GetMaxChannels(char channelPrefix)
177
        {
178
            Dictionary<char, int> pfn = ParsePfxNum(_MaxChannelsByType);
179
            if (pfn.ContainsKey(channelPrefix)) {
180
                return pfn[channelPrefix];
181
            } else {
182
                return _MaxChannels;
183
            }
184
        }
185
                
186
        internal int _MaxNickLength = 9;  // Rfc 2812
187
        
188
        /// <summary>
189
        /// Returns the the maximum allowed nickname length.
190
        /// </summary>
191
        public int MaxNickLength {
192
            get {
193
                return _MaxNickLength;
194
            }
195
        }   
196
        
197
        internal string _MaxList = "";
198
        
199
        /// <summary>
200
        ///  Returns the maximal number of List entries in a List.
201
        /// </summary>
202
        /// <param name="channelPrefix">On Which type of List (ex. Ban: 'b' )</param>
203
        /// <returns>Maximal Length of List (of type listType)</returns>        
204
        public int GetMaxList(char listType) {
205
            Dictionary<char, int> pfn = ParsePfxNum(_MaxList);
206
            if (pfn.ContainsKey(listType)) {
207
                return pfn[listType];
208
            } else {
209
                return -1;
210
            }        
211
        }
212
        
213
        internal int _MaxBans = -1;
214
        /// <summary>
215
        /// Maximum number of bans per channel.
216
        /// Note: This Value is either from the MAXBANS or the MAXLIST Value
217
        /// </summary>
218
        public int MaxBans {
219
            get {
220
                return Math.Max(_MaxBans, GetMaxList('b'));
221
            }
222
        }   
223
        
224
        internal string _NetworkName = "unknwon";
225
        
226
        /// <summary>
227
        /// Returns the Network Name if known
228
        /// </summary>
229
        public string NetworkName {
230
            get {
231
                return _NetworkName;
232
            }
233
        }
234
        
235
        internal bool _BanException = false;
236
        
237
        /// <summary>
238
        /// Returns true if the server support ban exceptions (e mode).
239
        /// </summary>
240
        public bool BanException {
241
            get {
242
                return _BanException;
243
            }
244
        }
245
        
246
        internal bool _InviteExceptions = false;
247
        
248
        /// <summary>
249
        /// Returns true if the server support invite exceptions (+I mode).
250
        /// </summary>
251
        public bool InviteExceptions {
252
            get {
253
                return _InviteExceptions;
254
            }
255
        }
256
        
257
        
258
        internal string _StatusMessage = "";
259
        
260
        /// <summary>
261
        /// Returns a list of Prefixes which can be used before a Channel name to message nicks who have a certain status or higher.
262
        /// </summary>
263
        public IEnumerable<char> StatusMessage {
264
            get {
265
                return _StatusMessage.ToCharArray();
266
            }
267
        }
268

  
269
        internal bool _WAllVoices = false;
270
        
271
        /// <summary>
272
        /// Returns true if the server supports messaging channel operators (NOTICE @#channel)
273
        /// Note: This uses either the WALLVOICES or STATUSMSG whichever was sent
274
        /// </summary>
275
        public bool WAllVoices {
276
            get {
277
                bool statusContainsVoice = false;
278
                foreach(char c in this.StatusMessage) {
279
                    if(c == '+') statusContainsVoice = true;
280
                }
281
                return (_WAllVoices || statusContainsVoice);
282
            }
283
        }
284
        
285
        internal bool _WAllChannelOps = false;
286
        
287
        /// <summary>
288
        /// Returns true if the server supports messaging channel operators (NOTICE @#channel)
289
        /// Note: This uses either the WALLCHANOPS or STATUSMSG whichever was sent
290
        /// </summary>
291
        public bool WAllChannelOps {
292
            get {
293
                bool statusContainsOp = false;
294
                foreach(char c in this.StatusMessage) {
295
                    if(c == '@') statusContainsOp = true;
296
                }
297
                return (_WAllChannelOps || statusContainsOp);
298
            }
299
        }
300
        
301
        internal CaseMappingType _CaseMapping = CaseMappingType.Unknown;
302
        
303
        /// <summary>
304
        /// Returns the used Case Mapping type ascii or rfc1459
305
        /// </summary>
306
        public CaseMappingType CaseMapping {
307
            get {
308
                return _CaseMapping;
309
            }
310
        }
311
        
312
        
313
        internal string _ExtendedListCommand = "";
314
        
315
        /// <summary>
316
        /// Returns an Enum with all List Extentions possible on the server
317
        /// </summary>
318
        public EListType ExtendedListCommand {
319
            get {
320
                EListType result = 0;
321
                foreach(char c in _ExtendedListCommand) {
322
                    result |= (EListType)Enum.Parse(typeof(EListType), c.ToString());
323
                }
324
                return result;
325
            }
326
        }
327
        
328
        internal int _MaxTopicLength = -1;
329
        
330
        /// <summary>
331
        /// Retruns the maximal allowed Length of a channel topic if known (-1 otherwise)
332
        /// </summary>
333
        public int MaxTopicLength {
334
            get {
335
                return _MaxTopicLength;
336
            }
337
        }
338
        
339
        internal int _MaxKickLength = -1;
340
        
341
        /// <summary>
342
        /// Retruns the maximal allowed Length of a kick message if known (-1 otherwise)
343
        /// </summary>
344
        public int MaxKickLength {
345
            get {
346
                return _MaxKickLength;
347
            }
348
        }
349
        
350
        internal int _MaxChannelLength = 50;  // Rfc 2812
351
        
352
        /// <summary>
353
        /// Retruns the maximal allowed Length of a channel name
354
        /// </summary>
355
        public int MaxChannelLength {
356
            get {
357
                return _MaxChannelLength;
358
            }
359
        }
360
        
361
        internal int _ChannelIDLength = 5; // Rfc 2811
362
        internal string _ChannelIDLengthByType = "";
363
        
364
        
365
        /// <summary>
366
        /// Returns the ID length for channels (! channels);
367
        /// </summary>
368
        public int ChannelIDLength {
369
            get {
370
                return GetChannelIDLength('!');
371
            }
372
        }
373
            
374
        
375
        /// <summary>
376
        ///  with an ID. The prefix says for which channel type it is.
377
        /// </summary>
378
        /// <param name="channelPrefix">On Which Type of channels (ex. '#')</param>
379
        /// <returns>Length of Channel ID</returns>
380
        public int GetChannelIDLength(char channelPrefix) {
381
            Dictionary<char, int> pfn = ParsePfxNum(_ChannelIDLengthByType);
382
            if (pfn.ContainsKey(channelPrefix)) {
383
                return pfn[channelPrefix];
384
            } else {
385
                return _ChannelIDLength;
386
            }
387
        }
388
        
389
        private Dictionary<char, int> ParsePfxNum(string toParse)
390
        {
391
            Dictionary<char, int> result = new Dictionary<char, int>();
392
            foreach(string sr in toParse.Split(new char[] {','}))
393
            {
394
                string[] ssr = sr.Split(new char[] {':'});  // ssr[0] list of chars, ssr[1] numeric value
395
                foreach(char c in ssr[0]) {
396
                    result.Add(c, int.Parse(ssr[1]));
397
                }
398
            }
399
            return result;
400
        }
401

  
402
        internal string _IrcStandard = "none";
403
        
404
        /// <summary>
405
        /// Returns the used Irc-Standard if known
406
        /// </summary>
407
        public string IrcStandard {
408
            get {
409
                return _IrcStandard;
410
            }
411
        }
412
        
413
        
414
        internal int _MaxSilence = 0;
415
        
416
        /// <summary>
417
        /// If the server supports the SILENCE command. The number is the maximum number of allowed entries in the list. (0 otherwise)
418
        /// </summary>
419
        public int MaxSilence {
420
            get {
421
                return _MaxSilence;
422
            }
423
        }
424
        
425
        internal bool _Rfc2812 = false;
426
        
427
        /// <summary>
428
        /// Server supports Rfc2812 Features beyond Rfc1459
429
        /// </summary>
430
        public bool RfC2812 {
431
            get {
432
                return _Rfc2812;
433
            }
434
        }
435
        
436
        internal bool _Penalty = false;
437
        
438
        /// <summary>
439
        /// Server gives extra penalty to some commands instead of the normal 2 seconds per message and 1 second for every 120 bytes in a message.
440
        /// </summary>
441
        public bool Penalty {
442
            get {
443
                return _Penalty;
444
            }
445
        }
446
        
447
        internal bool _ForcedNickChange = false;
448
        
449
        /// <summary>
450
        /// Forced nick changes: The server may change the nickname without the client sending a NICK message.
451
        /// </summary>
452
        public bool ForcedNickChange {
453
            get {
454
                return _ForcedNickChange;
455
            }
456
        }
457
        
458
        internal bool _SafeList = false;
459
        
460
        /// <summary>
461
        /// The LIST is sent in multiple iterations so send queue won't fill and kill the client connection.
462
        /// </summary>
463
        public bool SafeList {
464
            get {
465
                return _SafeList;
466
            }
467
        }
468
        
469
        internal int _MaxAwayLength = -1;
470
        
471
        /// <summary>
472
        /// The maximum length of an away message, returns -1 if not known
473
        /// </summary>
474
        public int MaxAwayLength {
475
            get {
476
                return _MaxAwayLength;
477
            }
478
        }
479
        
480
        internal bool _NoQuit = false;
481
        
482
        /// <summary>
483
        /// NOQUIT
484
        /// </summary>
485
        public bool NoQuit {
486
            get {
487
                return _NoQuit;
488
            }
489
        }
490
        
491
        internal bool _UserIp = false;
492
        
493
        /// <summary>
494
        /// Returns true if the Server supports the Userip Command
495
        /// </summary>
496
        public bool UserIp {
497
            get {
498
                return _UserIp;
499
            }
500
        }
501
        
502
        internal bool _CPrivateMessage = false;
503
        
504
        /// <summary>
505
        /// Returns true if the Server supports the CPrivMsg Command
506
        /// </summary>
507
        public bool CPrivateMessage {
508
            get {
509
                return _CPrivateMessage;
510
            }
511
        }
512

  
513
        internal bool _CNotice = false;
514
        
515
        /// <summary>
516
        /// Returns true if the Server supports the CNotice Command
517
        /// </summary>
518
        public bool CNotice {
519
            get {
520
                return _CNotice;
521
            }
522
        }
523
        
524
        internal int _MaxTargets = 1;
525
        internal string _MaxTargetsByCommand = "";
526
        
527
        /// <summary>
528
        /// Returns the maximum number of targets for PrivMsg and Notice
529
        /// </summary>        
530
        public int MaxTargets {
531
            get {
532
                return _MaxTargets;
533
            }
534
        }
535

  
536
        /// <summary>
537
        /// Returns the MAXTARGETS String (unparsed);
538
        /// </summary>
539
        public string MaxTargetsByCommand {
540
            get {
541
                return _MaxTargetsByCommand;
542
            }
543
        }
544
        
545
        internal bool _Knock = false;
546
        
547
        /// <summary>
548
        /// Returns true if the Server supports the Knock Command
549
        /// </summary>
550
        public bool Knock {
551
            get {
552
                return _Knock;
553
                
554
            }
555
        }
556
        
557
        internal bool _VirtualChannels = false;
558
        
559
        /// <summary>
560
        /// Returns true if the Server supports Virtual Channels
561
        /// </summary>
562
        public bool VirtualChannels {
563
            get {
564
                return _VirtualChannels;
565
            }
566
        }
567
        
568
        internal int _MaxWatch = 0;
569
        
570
        /// <summary>
571
        /// Returns how many Users can be on the watch list, returns 0 if the Watch command is not available.
572
        /// </summary>
573
        public int MaxWatch {
574
            get {
575
                return _MaxWatch;
576
            }
577
        }
578
        
579
        internal bool _WhoX = false;
580
        
581
        /// <summary>
582
        /// Returns true if the Server  uses WHOX protocol for the Who command.
583
        /// </summary>
584
        public bool WhoX {
585
            get {
586
                return _WhoX;
587
            }
588
        }
589
        
590
        internal bool _ModeG = false;
591
        
592
        /// <summary>
593
        /// Returns true if the server supports server side ignores via the +g user mode.
594
        /// </summary>
595
        public bool ModeG {
596
            get {
597
                return _ModeG;
598
            }
599
        }
600
        
601
        internal string _Language = "";
602
        
603
        /// <summary>
604
        /// Returns a list of Languages if the Server supports the Language command.
605
        /// </summary>
606
        public IEnumerable<string> Languages
607
        {
608
            get {
609
                return _Language.Split(new char[] {','});
610
            }
611
        }
612
        
613
        
614
        internal string _NickPrefix ="";
615
        
616
        /// <summary>
617
        /// Returns a Dictionary with Usermodes and Userprefixes for Channels.
618
        /// If we don't have values from the servers you can assume at least +ov / @+ are supported
619
        /// However the dictionary will be empty!
620
        /// Key = Mode, Value = Prefix, ex. NickPrefix['o'] = '@'
621
        /// Note: Some servers only show the most powerful, others may show all of them. 
622
        /// </summary>
623
        public  Dictionary<char, char> NickPrefix {
624
            get {
625
                string[] np =_NickPrefix.Split(new char[] {')'});
626
                Dictionary<char, char> temp = new Dictionary<char, char>();
627
                int i = 0;
628
                foreach(char c in np[1]) {
629
                    i++;    
630
                    temp.Add(np[0][i], c);
631
                }
632
                return temp;
633
            }
634
        }
635
        
636
        internal int _MaxKeyLength = -1;
637
        
638
        /// <summary>
639
        /// Returns the maximum allowed Key length on this server or -1 if unknown
640
        /// </summary>
641
        public int MaxKeyLength {
642
            get {
643
                return _MaxKeyLength;
644
            }
645
        }
646
        
647
        internal int _MaxUserLength = -1;
648
        
649
        /// <summary>
650
        ///  Returns the Maximum allowed User length on this server or -1 if unknwon
651
        /// </summary>
652
        public int MaxUserLength {
653
            get {
654
                return _MaxUserLength;
655
            }
656
        }
657
        
658
        internal int _MaxHostLength = -1;
659

  
660
        /// <summary>
661
        ///  Returns the Maximum allowed Host length on this server or -1 if unknwon
662
        /// </summary>
663
        public int MaxHostLength {
664
            get {
665
                return _MaxHostLength;
666
            }
667
        }
668

  
669
        internal bool _Map = false;
670
        
671
        /// <summary>
672
        /// Returns true if we know this server supports the Map Command
673
        /// </summary>
674
        public bool Map {
675
            get {
676
                return _Map;
677
            }
678
        }
679
        
680
        internal bool _DccAllow = false;
681
        
682
        /// <summary>
683
        /// Server Supports the DccAllow Command
684
        /// </summary>
685
        public bool DccAllow {
686
            get {
687
                return _DccAllow;
688
            }
689
        }
690
    }
691
    
692
    public enum CaseMappingType {
693
        Unknown,
694
        Rfc1459,
695
        Rfc1459Strict,
696
        Ascii
697
            
698
    }
699
    
700
    [Flags]
701
    public enum ChannelModeType {
702
        WithUserhostParameter,
703
        WithAlwaysParamter,
704
        WithSetOnlyParameter,
705
        WithoutParameter
706
    }
707

  
708
    /// <summary>
709
    /// M = mask search,
710
    /// N = !mask search
711
    /// U = usercount search (< >)
712
    /// C = creation time search (C< C>)
713
    /// T = topic search (T< T>) 
714
    /// </summary>
715
    [Flags]
716
    public enum EListType {
717
        
718
        M,
719
        N,
720
        U,
721
        C,
722
        T
723
    }
724
}