IRC parsing, tokenization, and state handling in C#
at ircrobots 107 lines 4.4 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Globalization; 4using System.Linq; 5 6// ReSharper disable InconsistentNaming 7// ReSharper disable StringLiteralTypo 8 9namespace IRCStates 10{ 11 public class ISupport 12 { 13 public Dictionary<string, string> Raw { get; } = new Dictionary<string, string>(); 14 public string Network { get; private set; } 15 public ISupportChanModes ChanModes { get; private set; } = new ISupportChanModes("b,k,l,imnpst"); 16 public ISupportPrefix Prefix { get; private set; } = new ISupportPrefix("(ov)@+"); 17 public int? Modes { get; private set; } = 3; 18 public Casemap.CaseMapping CaseMapping { get; private set; } = Casemap.CaseMapping.Rfc1459; 19 public List<string> ChanTypes { get; private set; } = new List<string> { "#" }; 20 public List<string> StatusMsg { get; private set; } = new List<string>(); 21 public string CallerId { get; private set; } 22 public string Excepts { get; private set; } 23 public string Invex { get; private set; } 24 public int? Monitor { get; private set; } 25 public int? Watch { get; private set; } 26 public bool Whox { get; private set; } 27 28 /// <summary> 29 /// Parse the ISupport values from the line's parameters 30 /// </summary> 31 /// <param name="tokens"></param> 32 public void Parse(IEnumerable<string> tokens) 33 { 34 if (tokens == null) return; 35 36 // remove first and last 37 tokens = tokens.Skip(1).SkipLast(1); 38 39 foreach (var token in tokens) 40 { 41 var split = token.Split('=', 2); 42 var key = split[0]; 43 44 var value = string.Empty; 45 if (split.Length > 1) 46 { 47 value = split[1]; 48 Raw[key] = value; 49 } 50 51 switch (split[0]) 52 { 53 case "NETWORK": 54 Network = value; 55 break; 56 case "CHANMODES": 57 ChanModes = new ISupportChanModes(value); 58 break; 59 case "PREFIX": 60 Prefix = new ISupportPrefix(value); 61 break; 62 case "STATUSMSG": 63 StatusMsg = new List<string>(); 64 StatusMsg.AddRange(value.Select(c => c.ToString(CultureInfo.InvariantCulture))); 65 break; 66 case "MODES": 67 if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var modes)) 68 Modes = modes; 69 else 70 Modes = -1; 71 break; 72 case "MONITOR": 73 if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var monitor)) 74 Monitor = monitor; 75 else 76 Monitor = -1; 77 break; 78 case "WATCH": 79 if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var watch)) 80 Watch = watch; 81 else 82 Watch = -1; 83 break; 84 case "CASEMAPPING": 85 if (Enum.TryParse(value, true, out Casemap.CaseMapping caseMapping)) CaseMapping = caseMapping; 86 break; 87 case "CHANTYPES": 88 ChanTypes = new List<string>(); 89 ChanTypes.AddRange(value.Select(c => c.ToString(CultureInfo.InvariantCulture))); 90 break; 91 case "CALLERID": 92 CallerId = string.IsNullOrEmpty(value) ? "g" : value; 93 break; 94 case "EXCEPTS": 95 Excepts = string.IsNullOrEmpty(value) ? "e" : value; 96 break; 97 case "INVEX": 98 Invex = string.IsNullOrEmpty(value) ? "I" : value; 99 break; 100 case "WHOX": 101 Whox = true; 102 break; 103 } 104 } 105 } 106 } 107}