protected override void Parse(Core.Server aServer, string aRawData, string aMessage, string[] aCommands) { ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType + "(" + aServer.Name + ")"); string tUserName = aCommands[0].Split('!')[0]; Bot tBot = aServer.Bot(tUserName); if (tBot != null) { bool isParsed = false; Match tMatch; Match tMatch1; Match tMatch2 ; Match tMatch3; Match tMatch4; int valueInt; aMessage = RemoveSpecialIrcChars(aMessage); //double valueDouble; #region ALL SLOTS FULL / ADDING TO QUEUE if (true) { tMatch1 = Regex.Match(aMessage, "(" + Magicstring + " All Slots Full, |)Added you to the main queue (for pack ([0-9]+) \\(\".*\"\\) |).*in positi(o|0)n (?<queue_cur>[0-9]+)\\. To Remove you(r|)self at a later time .*", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, "Queueing you for pack [0-9]+ \\(.*\\) in slot (?<queue_cur>[0-9]+)/(?<queue_total>[0-9]+)\\. To remove you(r|)self from the queue, type: .*\\. To check your position in the queue, type: .*\\. Estimated time remaining in queue: (?<queue_d>[0-9]+) days, (?<queue_h>[0-9]+) hours, (?<queue_m>[0-9]+) minutes", RegexOptions.IgnoreCase); tMatch3 = Regex.Match(aMessage, "(" + Magicstring + " |)Es laufen bereits genug .bertragungen, Du bist jetzt in der Warteschlange f.r Datei [0-9]+ \\(.*\\) in Position (?<queue_cur>[0-9]+)\\. Wenn Du sp.ter Abbrechen willst schreibe .*", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success || tMatch3.Success) { tMatch = tMatch1.Success ? tMatch1 : tMatch2; tMatch = tMatch.Success ? tMatch : tMatch3; isParsed = true; if (tBot.State == Bot.States.Idle) { tBot.State = Bot.States.Waiting; } tBot.InfoSlotCurrent = 0; if (int.TryParse(tMatch.Groups["queue_cur"].ToString(), out valueInt)) { tBot.QueuePosition = valueInt; tBot.InfoQueueCurrent = tBot.QueuePosition; } if (int.TryParse(tMatch.Groups["queue_total"].ToString(), out valueInt)) { tBot.InfoQueueTotal = valueInt; } else if (tBot.InfoQueueTotal < tBot.InfoQueueCurrent) { tBot.InfoQueueTotal = tBot.InfoQueueCurrent; } int time = 0; if (int.TryParse(tMatch.Groups["queue_m"].ToString(), out valueInt)) { time += valueInt * 60; } if (int.TryParse(tMatch.Groups["queue_h"].ToString(), out valueInt)) { time += valueInt * 60 * 60; } if (int.TryParse(tMatch.Groups["queue_d"].ToString(), out valueInt)) { time += valueInt * 60 * 60 * 24; } tBot.QueueTime = time; } } #endregion #region REMOVE FROM QUEUE if (!isParsed) { tMatch = Regex.Match(aMessage, Magicstring + " Removed From Queue: .*", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } FireCreateTimer(aServer, tBot, Settings.Instance.CommandWaitTime, false); } } #endregion #region INVALID PACKET NUMBER if (!isParsed) { tMatch1 = Regex.Match(aMessage, Magicstring + " Die Nummer der Datei ist ung.ltig", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, Magicstring + " Invalid Pack Number, Try Again", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success) { isParsed = true; Packet tPack = tBot.OldestActivePacket(); if (tPack != null) { // remove all packets with ids beeing greater than the current one because they MUST be missing, too var tPackets = from packet in tBot.Packets where packet.Id >= tPack.Id select packet; foreach (Packet pack in tPackets) { pack.Enabled = false; pack.Commit(); tBot.RemovePacket(pack); } } log.Error("Parse() invalid packetnumber from " + tBot); } } #endregion #region PACK ALREADY REQUESTED if (!isParsed) { tMatch1 = Regex.Match(aMessage, Magicstring + " You already requested that pack(.*|)", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, Magicstring + " Du hast diese Datei bereits angefordert(.*|)", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success) { isParsed = true; if (tBot.State == Bot.States.Idle) { tBot.State = Bot.States.Waiting; } } } #endregion #region ALREADY QUEUED / RECEIVING if (!isParsed) { tMatch1 = Regex.Match(aMessage, "Denied, You already have ([0-9]+) item(s|) queued, Try Again Later", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, Magicstring + " All Slots Full, Denied, You already have that item queued\\.", RegexOptions.IgnoreCase); tMatch3 = Regex.Match(aMessage, "You are already receiving or are queued for the maximum number of packs .*", RegexOptions.IgnoreCase); tMatch4 = Regex.Match(aMessage, "Du hast max\\. ([0-9]+) transfer auf einmal, Du bist jetzt in der Warteschlange f.r Datei .*", RegexOptions.IgnoreCase); Match tMatch5 = Regex.Match(aMessage, "Es laufen bereits genug .bertragungen, abgewiesen, Du hast diese Datei bereits in der Warteschlange\\.", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success || tMatch3.Success || tMatch4.Success || tMatch5.Success) { isParsed = true; if (tBot.State == Bot.States.Idle) { tBot.State = Bot.States.Waiting; } else if (tBot.State == Bot.States.Waiting) { // if there is no active packets lets remove us from the queue if (tBot.OldestActivePacket() == null) { FireUnRequestFromBot(aServer, tBot); } } } } #endregion #region DCC PENDING if (!isParsed) { tMatch1 = Regex.Match(aMessage, Magicstring + " You have a DCC pending, Set your client to receive the transfer\\. ((Type .*|Send XDCC CANCEL) to abort the transfer\\. |)\\((?<time>[0-9]+) seconds remaining until timeout\\)", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, Magicstring + " Du hast eine .bertragung schwebend, Du mu.t den Download jetzt annehmen\\. ((Schreibe .*|Sende XDCC CANCEL) an den Bot um die .bertragung abzubrechen\\. |)\\((?<time>[0-9]+) Sekunden bis zum Abbruch\\)", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success) { tMatch = tMatch1.Success ? tMatch1 : tMatch2; isParsed = true; if (int.TryParse(tMatch.Groups["time"].ToString(), out valueInt)) { if (valueInt == 30 && tBot.State != Bot.States.Active) { tBot.State = Bot.States.Idle; } FireCreateTimer(aServer, tBot, (valueInt + 2) * 1000, false); } } } #endregion #region ALL SLOTS AND QUEUE FULL if (!isParsed) { tMatch1 = Regex.Match(aMessage, Magicstring + " All Slots Full, Main queue of size (?<queue_total>[0-9]+) is Full, Try Again Later", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, Magicstring + " Es laufen bereits genug .bertragungen, abgewiesen, die Warteschlange ist voll, max\\. (?<queue_total>[0-9]+) Dateien, Versuche es sp.ter nochmal", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success) { tMatch = tMatch1.Success ? tMatch1 : tMatch2; isParsed = true; if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } tBot.InfoSlotCurrent = 0; tBot.InfoQueueCurrent = 0; if (int.TryParse(tMatch.Groups["queue_total"].ToString(), out valueInt)) { tBot.InfoQueueTotal = valueInt; } FireCreateTimer(aServer, tBot, Settings.Instance.BotWaitTime, false); } } #endregion #region TRANSFER LIMIT if (!isParsed) { tMatch = Regex.Match(aMessage, Magicstring + " You can only have ([0-9]+) transfer(s|) at a time,.*", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; if (tBot.State == Bot.States.Idle) { tBot.State = Bot.States.Waiting; } } } #endregion #region OWNER REQUEST if (!isParsed) { tMatch = Regex.Match(aMessage, Magicstring + " The Owner Has Requested That No New Connections Are Made In The Next (?<time>[0-9]+) Minute(s|)", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } if (int.TryParse(tMatch.Groups["time"].ToString(), out valueInt)) { FireCreateTimer(aServer, tBot, (valueInt * 60 + 1) * 1000, false); } } } #endregion #region XDCC DOWN if (!isParsed) { tMatch = Regex.Match(aMessage, "The XDCC is down, try again later.*", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } FireCreateTimer(aServer, tBot, Settings.Instance.BotWaitTime, false); } } #endregion #region XDCC DENIED if (!isParsed) { tMatch = Regex.Match(aMessage, Magicstring + " XDCC SEND denied, (?<info>.*)", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; string info = tMatch.Groups["info"].ToString().ToLower(); if (info.StartsWith("you must be on a known channel to request a pack")) { FireSendData(aServer, "WHOIS " + tBot.Name); } else if (info.StartsWith("i don't send transfers to")) { foreach (Packet tPacket in tBot.Packets) { if (tPacket.Enabled) { tPacket.Enabled = false; tPacket.Commit(); } } } else { if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } FireCreateTimer(aServer, tBot, Settings.Instance.CommandWaitTime, false); log.Error("Parse() XDCC denied from " + tBot + ": " + info); } } } #endregion #region XDCC SENDING if (!isParsed) { tMatch1 = Regex.Match(aMessage, Magicstring + " Sending You (Your Queued |)Pack .*", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, Magicstring + " Sende dir jetzt die Datei .*", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success) { isParsed = true; if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } } } #endregion #region QUEUED if (!isParsed) { tMatch1 = Regex.Match(aMessage, "Queued ([0-9]+)h([0-9]+)m for .*, in position (?<queue_cur>[0-9]+) of (?<queue_total>[0-9]+). (?<queue_h>[0-9]+)h(?<queue_m>[0-9]+)m or .* remaining\\.", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, "In der Warteschlange seit ([0-9]+)h([0-9]+)m f.r .*, in Position (?<queue_cur>[0-9]+) von (?<queue_total>[0-9]+). Ungef.hr (?<queue_h>[0-9]+)h(?<queue_m>[0-9]+)m oder .*", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success) { tMatch = tMatch1.Success ? tMatch1 : tMatch2; isParsed = true; if (tBot.State == Bot.States.Idle) { tBot.State = Bot.States.Waiting; } tBot.InfoSlotCurrent = 0; if (int.TryParse(tMatch.Groups["queue_cur"].ToString(), out valueInt)) { tBot.QueuePosition = valueInt; } if (int.TryParse(tMatch.Groups["queue_total"].ToString(), out valueInt)) { tBot.InfoQueueTotal = valueInt; } else if (tBot.InfoQueueTotal < tBot.QueuePosition) { tBot.InfoQueueTotal = tBot.QueuePosition; } int time = 0; if (int.TryParse(tMatch.Groups["queue_m"].ToString(), out valueInt)) { time += valueInt * 60; } if (int.TryParse(tMatch.Groups["queue_h"].ToString(), out valueInt)) { time += valueInt * 60 * 60; } tBot.QueueTime = time; } } #endregion #region CLOSING CONNECTION if (!isParsed) { // Closing Connection You Must JOIN MG-CHAT As Well To Download - Your Download Will Be Canceled Now tMatch1 = Regex.Match(aMessage, Magicstring + " (Closing Connection|Transfer Completed)(?<reason>.*)", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, Magicstring + " (Schlie.e Verbindung)(?<reason>.*)", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success) { isParsed = true; if (tBot.State != Bot.States.Active) { tBot.State = Bot.States.Idle; } else { // kill that connection if the bot sends a close message , but our real bot // connection is still alive and hangs for some crapy reason - maybe because // some admins do some network fu to stop my downloads (happend to me) FireRemoveDownload(tBot); } FireCreateTimer(aServer, tBot, Settings.Instance.CommandWaitTime, false); tMatch3 = Regex.Match(aMessage, @".*\s+JOIN (?<channel>[^\s]+).*", RegexOptions.IgnoreCase); if (tMatch3.Success && Settings.Instance.AutoJoinOnInvite) { string channel = tMatch3.Groups["channel"].ToString(); if (!channel.StartsWith("#")) { channel = "#" + channel; } // ok, lets do a silent auto join log.Info("Parse() auto joining " + channel); FireSendData(aServer, "JOIN " + channel); } } } #endregion #region YOU ARE NOT IN QUEUE if (!isParsed) { tMatch = Regex.Match(aMessage, "(You Don't Appear To Be In A Queue|Removed you from the queue for.*)", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } tBot.QueuePosition = 0; FireCreateTimer(aServer, tBot, Settings.Instance.CommandWaitTime, false); } } #endregion #region PUNISH / AUTO IGNORE if (!isParsed) { tMatch1 = Regex.Match(aMessage, "Punish-ignore activated for .* \\(.*\\) (?<time_m>[0-9]*) minutes", RegexOptions.IgnoreCase); tMatch2 = Regex.Match(aMessage, "Auto-ignore activated for .* lasting (?<time_m>[0-9]*)m(?<time_s>[0-9]*)s\\. Further messages will increase duration\\.", RegexOptions.IgnoreCase); tMatch3 = Regex.Match(aMessage, "Zur Strafe wirst du .* \\(.*\\) f.r (?<time_m>[0-9]*) Minuten ignoriert(.|)", RegexOptions.IgnoreCase); tMatch4 = Regex.Match(aMessage, "Auto-ignore activated for .* \\(.*\\)", RegexOptions.IgnoreCase); if (tMatch1.Success || tMatch2.Success || tMatch3.Success || tMatch4.Success) { tMatch = tMatch1.Success ? tMatch1 : tMatch2.Success ? tMatch2 : tMatch3.Success ? tMatch3 : tMatch4; isParsed = true; if (tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; } if (int.TryParse(tMatch.Groups["time_m"].ToString(), out valueInt)) { int time = valueInt * 60 + 1; if (int.TryParse(tMatch.Groups["time_s"].ToString(), out valueInt)) { time += valueInt; } FireCreateTimer(aServer, tBot, time * 1000, true); } } } #endregion #region NOT NEEDED INFOS if (!isParsed) { tMatch = Regex.Match(aMessage, ".* bandwidth limit .*", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; } } #endregion if (!isParsed) { FireParsingError("[DCC Notice] " + tBot + " : " + aMessage); } else { tBot.LastMessage = aMessage; log.Info("Parse() message from " + tBot + ": " + aMessage); } tBot.Commit(); } }
protected override void Parse(Core.Server aServer, string aRawData, string aMessage, string[] aCommands) { ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType + "(" + aServer.Name + ")"); string tUserName = aCommands[0].Split('!')[0]; Channel tChan = aServer.Channel(aCommands[2]); Bot tBot = aServer.Bot(tUserName); #region VERSION if (aMessage == "VERSION") { log.Info("Parse() VERSION: " + Settings.Instance.IrcVersion); FireSendData(aServer, "NOTICE " + tUserName + " :\u0001VERSION " + Settings.Instance.IrcVersion + "\u0001"); return; } #endregion #region XGVERSION if (aMessage == "XGVERSION") { log.Info("Parse() XGVERSION: " + Settings.Instance.XgVersion); FireSendData(aServer, "NOTICE " + tUserName + " :\u0001XGVERSION " + Settings.Instance.XgVersion + "\u0001"); return; } #endregion #region DCC DOWNLOAD MESSAGE if (aMessage.StartsWith("DCC") && tBot != null) { Packet tPacket = tBot.OldestActivePacket(); if (tPacket != null) { if (tPacket.Connected) { log.Error("Parse() ignoring dcc from " + tBot + " because " + tPacket + " is already connected"); } else { bool isOk = false; int tPort = 0; Int64 tChunk = 0; string[] tDataList = aMessage.Split(' '); if (tDataList[1] == "SEND") { log.Info("Parse() DCC from " + tBot); // if the name of the file contains spaces, we have to replace em if (aMessage.StartsWith("DCC SEND \"")) { Match tMatch = Regex.Match(aMessage, "DCC SEND \"(?<packet_name>.+)\"(?<bot_data>[^\"]+)$"); if (tMatch.Success) { aMessage = "DCC SEND " + tMatch.Groups["packet_name"].ToString().Replace(" ", "_").Replace("'", "") + tMatch.Groups["bot_data"]; tDataList = aMessage.Split(' '); } } #region IP CALCULATING try { // this works not in mono?! tBot.Ip = IPAddress.Parse(tDataList[3]); } catch (FormatException) { #region WTF - FLIP THE IP BECAUSE ITS REVERSED?! string ip; try { ip = new IPAddress(long.Parse(tDataList[3])).ToString(); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse bot ip from string: " + aMessage, ex); return; } string realIp = ""; int pos = ip.LastIndexOf('.'); try { realIp += ip.Substring(pos + 1) + "."; ip = ip.Substring(0, pos); pos = ip.LastIndexOf('.'); realIp += ip.Substring(pos + 1) + "."; ip = ip.Substring(0, pos); pos = ip.LastIndexOf('.'); realIp += ip.Substring(pos + 1) + "."; ip = ip.Substring(0, pos); pos = ip.LastIndexOf('.'); realIp += ip.Substring(pos + 1); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse bot ip '" + ip + "' from string: " + aMessage, ex); return; } log.Info("Parse() IP parsing failed, using this: " + realIp); try { tBot.Ip = IPAddress.Parse(realIp); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse bot ip from string: " + aMessage, ex); return; } #endregion } #endregion try { tPort = int.Parse(tDataList[4]); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse bot port from string: " + aMessage, ex); return; } // we cant connect to port <= 0 if (tPort <= 0) { log.Error("Parse() " + tBot + " submitted wrong port: " + tPort + ", disabling packet"); tPacket.Enabled = false; // statistics Statistic.Instance.Increase(StatisticType.BotConnectsFailed); } else { tPacket.RealName = tDataList[2]; try { tPacket.RealSize = Int64.Parse(tDataList[5]); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse packet size from string: " + aMessage, ex); return; } tChunk = FileActions.NextAvailablePartSize(tPacket.RealName, tPacket.RealSize); if (tChunk < 0) { log.Error("Parse() file for " + tPacket + " from " + tBot + " already in use, disabling packet"); tPacket.Enabled = false; FireUnRequestFromBot(aServer, tBot); } else if (tChunk > 0) { log.Info("Parse() try resume from " + tBot + " for " + tPacket + " @ " + tChunk); FireSendData(aServer, "PRIVMSG " + tBot.Name + " :\u0001DCC RESUME " + tPacket.RealName + " " + tPort + " " + tChunk + "\u0001"); } else { isOk = true; } } } else if (tDataList[1] == "ACCEPT") { log.Info("Parse() DCC resume accepted from " + tBot); try { tPort = int.Parse(tDataList[3]); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse bot port from string: " + aMessage, ex); return; } try { tChunk = Int64.Parse(tDataList[4]); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse packet chunk from string: " + aMessage, ex); return; } isOk = true; } if (isOk) { log.Info("Parse() downloading from " + tBot + " - Starting: " + tChunk + " - Size: " + tPacket.RealSize); FireAddDownload(tPacket, tChunk, tBot.Ip, tPort); } tPacket.Commit(); } } else { log.Error("Parse() DCC not activated from " + tBot); } } #endregion #region DCC INFO MESSAGE else if (tChan != null) { bool insertBot = false; if (tBot == null) { insertBot = true; tBot = new Bot {Name = tUserName, Connected = true, LastMessage = "initial creation", LastContact = DateTime.Now}; } bool isParsed = false; Match tMatch; #region PACKET /SLOT / QUEUE INFO if (true) { tMatch = Regex.Match(aMessage, Magicstring + " ([0-9]*) (pack(s|)|Pa(c|)ket(e|)|Fil[e]+s) " + Magicstring + "\\s*(?<slot_cur>[0-9]*) (of|von) (?<slot_total>[0-9]*) (slot(s|)|Pl(a|�|.)tz(e|)) (open|opened|free|frei|in use|offen)(, ((Queue|Warteschlange): (?<queue_cur>[0-9]*)(\\/| of )(?<queue_total>[0-9]*),|).*(Record( [a-zA-Z]+|): (?<record>[0-9.]*)(K|)B\\/s|)|)", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; int valueInt; if (int.TryParse(tMatch.Groups["slot_cur"].ToString(), out valueInt)) { tBot.InfoSlotCurrent = valueInt; } if (int.TryParse(tMatch.Groups["slot_total"].ToString(), out valueInt)) { tBot.InfoSlotTotal = valueInt; } if (int.TryParse(tMatch.Groups["queue_cur"].ToString(), out valueInt)) { tBot.InfoQueueCurrent = valueInt; } if (int.TryParse(tMatch.Groups["queue_total"].ToString(), out valueInt)) { tBot.InfoQueueTotal = valueInt; } if (tBot.InfoSlotCurrent > tBot.InfoSlotTotal) { tBot.InfoSlotTotal = tBot.InfoSlotCurrent; } if (tBot.InfoQueueCurrent > tBot.InfoQueueTotal) { tBot.InfoQueueTotal = tBot.InfoQueueCurrent; } // uhm, there is a free slot and we are still waiting? if (tBot.InfoSlotCurrent > 0 && tBot.State == Bot.States.Waiting) { tBot.State = Bot.States.Idle; FireCreateTimer(aServer, tBot, 0, false); } } } #endregion #region BANDWIDTH if (!isParsed) { tMatch = Regex.Match(aMessage, Magicstring + " ((Bandwidth Usage|Bandbreite) " + Magicstring + "|)\\s*(Current|Derzeit): (?<speed_cur>[0-9.]*)(?<speed_cur_end>(K|)(i|)B)(\\/s|s)(,|)(.*Record: (?<speed_max>[0-9.]*)(?<speed_max_end>(K|)(i|))B(\\/s|s)|)", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; string speedCurEnd = tMatch.Groups["speed_cur_end"].ToString().ToLower(); string speedMaxEnd = tMatch.Groups["speed_max_end"].ToString().ToLower(); string speedCur = tMatch.Groups["speed_cur"].ToString(); string speedMax = tMatch.Groups["speed_max"].ToString(); if (Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator == ",") { speedCur = speedCur.Replace('.', ','); speedMax = speedMax.Replace('.', ','); } double valueDouble; if (double.TryParse(speedCur, out valueDouble)) { tBot.InfoSpeedCurrent = speedCurEnd.StartsWith("k") ? (Int64) (valueDouble * 1024) : (Int64) valueDouble; } if (double.TryParse(speedMax, out valueDouble)) { tBot.InfoSpeedMax = speedMaxEnd.StartsWith("k") ? (Int64) (valueDouble * 1024) : (Int64) valueDouble; } } } #endregion #region PACKET INFO Packet newPacket = null; if (!isParsed) { // what is this damn char \240 and how to rip it off ??? tMatch = Regex.Match(aMessage, "#(?<pack_id>\\d+)(\u0240|�|)\\s+(\\d*)x\\s+\\[\\s*(�|)\\s*(?<pack_size>[\\<\\>\\d.]+)(?<pack_add>[BbGgiKMs]+)\\]\\s+(?<pack_name>.*)", RegexOptions.IgnoreCase); if (tMatch.Success) { isParsed = true; try { int tPacketId; try { tPacketId = int.Parse(tMatch.Groups["pack_id"].ToString()); } catch (Exception ex) { log.Fatal("Parse() " + tBot + " - can not parse packet id from string: " + aMessage, ex); return; } Packet tPack = tBot.Packet(tPacketId); if (tPack == null) { tPack = new Packet(); newPacket = tPack; tPack.Id = tPacketId; tBot.AddPacket(tPack); } tPack.LastMentioned = DateTime.Now; string name = RemoveSpecialIrcCharsFromPacketName(tMatch.Groups["pack_name"].ToString()); if (tPack.Name != name && tPack.Name != "") { tPack.Enabled = false; if (!tPack.Connected) { tPack.RealName = ""; tPack.RealSize = 0; } } tPack.Name = name; double tPacketSizeFormated; string stringSize = tMatch.Groups["pack_size"].ToString().Replace("<", "").Replace(">", ""); if (Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator == ",") { stringSize = stringSize.Replace('.', ','); } double.TryParse(stringSize, out tPacketSizeFormated); string tPacketAdd = tMatch.Groups["pack_add"].ToString().ToLower(); if (tPacketAdd == "k" || tPacketAdd == "kb") { tPack.Size = (Int64) (tPacketSizeFormated * 1024); } else if (tPacketAdd == "m" || tPacketAdd == "mb") { tPack.Size = (Int64) (tPacketSizeFormated * 1024 * 1024); } else if (tPacketAdd == "g" || tPacketAdd == "gb") { tPack.Size = (Int64) (tPacketSizeFormated * 1024 * 1024 * 1024); } if (tPack.Commit()) { log.Info("Parse() updated " + tPack + " from " + tBot); } } catch (FormatException) {} } } #endregion // insert bot if ok if (insertBot) { if (isParsed) { tChan.AddBot(tBot); log.Info("Parse() inserted " + tBot); } } // and insert packet _AFTER_ this if (newPacket != null) { tBot.AddPacket(newPacket); log.Info("Parse() inserted " + newPacket + " into " + tBot); } #if DEBUG #region NOT NEEDED INFOS if (!isParsed) { tMatch = Regex.Match(aMessage, Magicstring + " To request .* type .*", RegexOptions.IgnoreCase); if (tMatch.Success) { return; } tMatch = Regex.Match(aMessage, ".*\\/(msg|ctcp) .* xdcc (info|send) .*", RegexOptions.IgnoreCase); if (tMatch.Success) { return; } tMatch = Regex.Match(aMessage, Magicstring + " To list a group, type .*", RegexOptions.IgnoreCase); if (tMatch.Success) { return; } tMatch = Regex.Match(aMessage, "Total offered(\\!|): (\\[|)[0-9.]*\\s*[BeGgiKMsTty]+(\\]|)\\s*Total transfer(r|)ed: (\\[|)[0-9.]*\\s*[BeGgiKMsTty]+(\\]|)", RegexOptions.IgnoreCase); if (tMatch.Success) { return; } tMatch = Regex.Match(aMessage, ".* (brought to you|powered|sp(o|0)ns(o|0)red) by .*", RegexOptions.IgnoreCase); if (tMatch.Success) { return; } tMatch = Regex.Match(aMessage, Magicstring + " .*" + tChan.Name + " " + Magicstring, RegexOptions.IgnoreCase); if (tMatch.Success) { return; } } #endregion #region COULD NOT PARSE if (!isParsed) // && tBot.Packets.Count() > 0) { FireParsingError("[DCC Info] " + tBot.Name + " : " + RemoveSpecialIrcChars(aMessage)); } #endregion #endif } #endregion if (tBot != null) { tBot.Commit(); } if (tChan != null) { tChan.Commit(); } }
protected override void Parse(Core.Server aServer, string aRawData, string aMessage, string[] aCommands) { ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType + "(" + aServer.Name + ")"); string tUserName = aCommands[0].Split('!')[0]; string tComCodeStr = aCommands[1]; string tChannelName = aCommands[2]; Channel tChan = aServer.Channel(tChannelName); Bot tBot = aServer.Bot(tUserName); if (tBot != null) { tBot.LastContact = DateTime.Now; } #region PRIVMSG if (tComCodeStr == "PRIVMSG") { _privateMessage.ParseData(aServer, aRawData); return; } #endregion #region NOTICE if (tComCodeStr == "NOTICE") { if (tUserName.ToLower() == "nickserv") { _nickserv.ParseData(aServer, aRawData); } else { _notice.ParseData(aServer, aRawData); } return; } #endregion #region NICK if (tComCodeStr == "NICK") { if (tBot != null) { tBot.Name = aMessage; log.Info("con_DataReceived() bot " + tUserName + " renamed to " + tBot); } else if (tUserName == Settings.Instance.IrcNick) { // what should i do now?! log.Error("con_DataReceived() wtf? i was renamed to " + aMessage); } } #endregion #region KICK else if (tComCodeStr == "KICK") { if (tChan != null) { tUserName = aCommands[3]; if (tUserName == Settings.Instance.IrcNick) { tChan.Connected = false; log.Warn("con_DataReceived() kicked from " + tChan + (aCommands.Length >= 5 ? " (" + aCommands[4] + ")" : "") + " - rejoining"); log.Warn("con_DataReceived() " + aRawData); FireJoinChannel(aServer, tChan); // statistics Statistic.Instance.Increase(StatisticType.ChannelsKicked); } else { tBot = aServer.Bot(tUserName); if (tBot != null) { tBot.Connected = false; tBot.LastMessage = "kicked from " + tChan; log.Info("con_DataReceived() " + tBot + " is offline"); } } } } #endregion #region KILL else if (tComCodeStr == "KILL") { tUserName = aCommands[2]; if (tUserName == Settings.Instance.IrcNick) { log.Warn("con_DataReceived() i was killed from server because of " + aMessage); } else { tBot = aServer.Bot(tUserName); if (tBot != null) { log.Warn("con_DataReceived() " + tBot + " was killed from server?"); } } } #endregion #region JOIN else if (tComCodeStr == "JOIN") { tChannelName = aMessage; tChan = aServer.Channel(tChannelName); if (tChan != null) { if (tBot != null) { tBot.Connected = true; tBot.LastMessage = "joined channel " + tChan.Name; if (tBot.State != Bot.States.Active) { tBot.State = Bot.States.Idle; } log.Info("con_DataReceived() " + tBot + " is online"); FireRequestFromBot(aServer, tBot); } } } #endregion #region PART else if (tComCodeStr == "PART") { if (tChan != null) { if (tBot != null) { tBot.Connected = true; tBot.LastMessage = "parted channel " + tChan.Name; log.Info("con_DataReceived() " + tBot + " parted from " + tChan); } } } #endregion #region QUIT else if (tComCodeStr == "QUIT") { if (tBot != null) { tBot.Connected = false; tBot.LastMessage = "quited"; log.Info("con_DataReceived() " + tBot + " quited"); } } #endregion #region MODE / TOPIC / WALLOP else if (tComCodeStr == "MODE" || tComCodeStr == "TOPIC" || tComCodeStr == "WALLOP") { // uhm, what to do now?! } #endregion #region INVITE else if (tComCodeStr == "INVITE") { log.Info("con_DataReceived() received an invite for channel " + aMessage); // ok, lets do a silent auto join if (Settings.Instance.AutoJoinOnInvite) { log.Info("con_DataReceived() auto joining " + aMessage); FireSendData(aServer, "JOIN " + aMessage); } } #endregion #region PONG else if (tComCodeStr == "PONG") { log.Info("con_DataReceived() PONG"); } #endregion #region INT VALUES else { _intValue.ParseData(aServer, aRawData); } #endregion if (tBot != null) { tBot.Commit(); } if (tChan != null) { tChan.Commit(); } }
protected override void Parse(Core.Server aServer, string aRawData, string aMessage, string[] aCommands) { ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType + "(" + aServer.Name + ")"); Bot tBot = aServer.Bot(aCommands[0].Split('!')[0]); Channel tChan = aServer.Channel(aCommands[2]); string tComCodeStr = aCommands[1]; int tComCode; if (int.TryParse(tComCodeStr, out tComCode)) { switch (tComCode) { #region 4 case 4: // aServer.Connected = true; aServer.Commit(); break; #endregion #region RPL_WHOISCHANNELS case 319: // RPL_WHOISCHANNELS tBot = aServer.Bot(aCommands[3]); if (tBot != null) { string chanName = ""; bool addChan = true; string[] tChannelList = aRawData.Split(':')[2].Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); foreach (string chan in tChannelList) { chanName = "#" + chan.Split('#')[1]; if (aServer.Channel(chanName) != null) { addChan = false; FireRequestFromBot(aServer, tBot); break; } } if (addChan) { log.Info("Parse() auto adding channel " + chanName); aServer.AddChannel(chanName); } } break; #endregion #region RPL_NAMREPLY case 353: // RPL_NAMREPLY tChan = aServer.Channel(aCommands[4]); if (tChan != null) { string[] tUsers = aMessage.Split(' '); foreach (string user in tUsers) { string tUser = Regex.Replace(user, "^(@|!|%|\\+){1}", ""); tBot = tChan.Bot(tUser); if (tBot != null) { tBot.Connected = true; tBot.LastMessage = "joined channel " + tChan.Name; if (tBot.State != Bot.States.Active) { tBot.State = Bot.States.Idle; } log.Info("Parse() " + tBot + " is online"); tBot.Commit(); FireRequestFromBot(aServer, tBot); } } } break; #endregion #region RPL_ENDOFNAMES case 366: // RPL_ENDOFNAMES tChan = aServer.Channel(aCommands[3]); if (tChan != null) { tChan.ErrorCode = 0; tChan.Connected = true; log.Info("Parse() joined " + tChan); } // statistics Statistic.Instance.Increase(StatisticType.ChannelConnectsOk); break; #endregion #region RPL_ENDOFMOTD | ERR_NOMOTD case 376: // RPL_ENDOFMOTD case 422: // ERR_NOMOTD log.Info("Parse() really connected"); aServer.Connected = true; aServer.Commit(); foreach (Channel chan in aServer.Channels) { if (chan.Enabled) { FireJoinChannel(aServer, chan); } } // statistics Statistic.Instance.Increase(StatisticType.ServerConnectsOk); break; #endregion #region ERR_NOCHANMODES case 477: // ERR_NOCHANMODES tChan = aServer.Channel(aCommands[3]); // TODO should we nickserv register here? /*if(Settings.Instance.AutoRegisterNickserv && Settings.Instance.IrcPasswort != "" && Settings.Instance.IrcRegisterEmail != "") { FireSendDataEvent(aServer, "nickserv register " + Settings.Instance.IrcPasswort + " " + Settings.Instance.IrcRegisterEmail); }*/ if (tChan != null) { tChan.ErrorCode = tComCode; //CreateTimerEvent(aServer, tChan, Settings.Instance.ChannelWaitTime); } else { //tBot = aServer.getBot(tCommandList[3]); //if(tBot != null) { CreateTimerEvent(aServer, tBot, Settings.Instance.BotWaitTime); } } break; #endregion #region ERR_TOOMANYCHANNELS case 405: tChan = aServer.Channel(aCommands[3]); if (tChan != null) { tChan.ErrorCode = tComCode; tChan.Connected = false; log.Warn("Parse() could not join " + tChan + ": " + tComCode); } // statistics Statistic.Instance.Increase(StatisticType.ChannelConnectsFailed); break; #endregion #region ERR_CHANNELISFULL | ERR_INVITEONLYCHAN | ERR_BANNEDFROMCHAN | ERR_BADCHANNELKEY | ERR_UNIQOPPRIVSNEEDED case 471: // ERR_CHANNELISFULL case 473: // ERR_INVITEONLYCHAN case 474: // ERR_BANNEDFROMCHAN case 475: // ERR_BADCHANNELKEY case 485: // ERR_UNIQOPPRIVSNEEDED tChan = aServer.Channel(aCommands[3]); if (tChan != null) { tChan.ErrorCode = tComCode; tChan.Connected = false; log.Warn("Parse() could not join " + tChan + ": " + tComCode); FireCreateTimer(aServer, tChan, tComCode == 471 || tComCode == 485 ? Settings.Instance.ChannelWaitTime : Settings.Instance.ChannelWaitTimeLong, false); } // statistics Statistic.Instance.Increase(StatisticType.ChannelConnectsFailed); break; #endregion } if (tBot != null) { tBot.Commit(); } if (tChan != null) { tChan.Commit(); } } else { log.Error("Parse() Irc code " + tComCodeStr + " could not be parsed. (" + aRawData + ")"); } }