예제 #1
0
        public void Serialize()
        {
            var jsonSerializerSettings = new JsonSerializerSettings
            {
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
                DateParseHandling = DateParseHandling.DateTime,
                DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
            };

            var part = new FilePart {Connected = true, Enabled = true, Guid = Guid.Empty};

            Assert.AreEqual(
                "{\"StartSize\":0,\"StopSize\":0,\"CurrentSize\":0,\"MissingSize\":0,\"TimeMissing\":0,\"Speed\":0,\"State\":0,\"Checked\":false,\"ParentGuid\":\"00000000-0000-0000-0000-000000000000\",\"Guid\":\"00000000-0000-0000-0000-000000000000\",\"Name\":\"\",\"Connected\":true,\"Enabled\":true}",
                JsonConvert.SerializeObject(part, jsonSerializerSettings)
            );

            var packet = new Packet
            {
                Name = "Test Packet",
                Connected = true,
                Enabled = true,
                Guid = Guid.Empty,
                LastMentioned = DateTime.Now,
                LastUpdated = DateTime.Now,
                Part = part
            };

            Assert.AreEqual(
                "{\"Part\":{\"StartSize\":0,\"StopSize\":0,\"CurrentSize\":0,\"MissingSize\":0,\"TimeMissing\":0,\"Speed\":0,\"State\":0,\"Checked\":false,\"ParentGuid\":\"00000000-0000-0000-0000-000000000000\",\"Guid\":\"00000000-0000-0000-0000-000000000000\",\"Name\":\"\",\"Connected\":true,\"Enabled\":true},\"Name\":\"Test Packet\",\"Id\":-1,\"Size\":0,\"RealSize\":0,\"RealName\":\"\",\"LastUpdated\":\"" + JsonDate(packet.LastUpdated) + "\",\"LastMentioned\":\"" + JsonDate(packet.LastMentioned) + "\",\"Next\":false,\"ParentGuid\":\"00000000-0000-0000-0000-000000000000\",\"Guid\":\"00000000-0000-0000-0000-000000000000\",\"Connected\":true,\"Enabled\":true}",
                JsonConvert.SerializeObject(packet, jsonSerializerSettings)
            );

            var bot = new Bot
            {
                Name = "Test Bot",
                Connected = true,
                Enabled = true,
                Guid = Guid.Empty,
                InfoQueueCurrent = 16,
                InfoQueueTotal = 16,
                InfoSlotCurrent = 16,
                InfoSlotTotal = 16,
                InfoSpeedCurrent = 16,
                InfoSpeedMax = 16,
                LastMessage = "Test Message",
                QueuePosition = 16,
                QueueTime = 16,
                State = Bot.States.Idle,
                LastContact = DateTime.Now
            };
            bot.AddPacket(packet);

            Assert.AreEqual(
                "{\"State\":0,\"LastMessage\":\"Test Message\",\"LastMessageTime\":\"" + JsonDate(bot.LastMessageTime) + "\",\"LastContact\":\"" + JsonDate(bot.LastContact) + "\",\"QueuePosition\":16,\"QueueTime\":16,\"InfoSpeedMax\":16,\"InfoSpeedCurrent\":16,\"InfoSlotTotal\":16,\"InfoSlotCurrent\":16,\"InfoQueueTotal\":16,\"InfoQueueCurrent\":16,\"Speed\":0,\"HasNetworkProblems\":false,\"ParentGuid\":\"00000000-0000-0000-0000-000000000000\",\"Guid\":\"00000000-0000-0000-0000-000000000000\",\"Name\":\"Test Bot\",\"Connected\":true,\"Enabled\":true}",
                JsonConvert.SerializeObject(bot, jsonSerializerSettings)
            );
        }
예제 #2
0
        public void RegisterParser(Server.Irc.AParser aParser)
        {
            IrcParser = aParser;

            IrcParser.ParsingError += delegate(string aData) { EventParsingError = aData; };

            IrcParser.AddDownload += delegate(Packet aPack, long aChunk, IPAddress aIp, int aPort)
            {
                EventPacket = aPack;
                EventChunk = aChunk;
                EventIp = aIp;
                EventPort = aPort;
            };
            IrcParser.RemoveDownload += delegate(Bot aBot) { EventBot = aBot; };

            IrcParser.SendData += delegate(Core.Server aServer, string aData)
            {
                Assert.AreEqual(Server, aServer);
                EventData = aData;
            };
            IrcParser.JoinChannel += delegate(Core.Server aServer, Channel aChannel)
            {
                Assert.AreEqual(Server, aServer);
                EventChannel = aChannel;
            };
            IrcParser.CreateTimer += delegate(Core.Server aServer, AObject aObject, int aTime, bool aOverride)
            {
                Assert.AreEqual(Server, aServer);
                EventObject = aObject;
                EventTime = aTime;
                EventOverride = aOverride;
            };

            IrcParser.RequestFromBot += delegate(Core.Server aServer, Bot aBot)
            {
                Assert.AreEqual(Server, aServer);
                EventBot = aBot;
            };
            IrcParser.UnRequestFromBot += delegate(Core.Server aServer, Bot aBot)
            {
                Assert.AreEqual(Server, aServer);
                EventBot = aBot;
            };
        }
예제 #3
0
        void OnMessage(IWebSocketConnection aContext, string aMessage)
        {
            Log.Info("OnMessage(" + aContext.ConnectionInfo.ClientIpAddress + ", " + aMessage + ")");

            var currentUser = (from user in _users where user.Connection == aContext select user).SingleOrDefault();
            var request = JsonConvert.DeserializeObject<Request>(aMessage);
            #if !UNSAFE
            try
            {
            #endif
                // no pass, no way
                if (request.Password != Password)
                {
                    Log.Error("OnMessage(" + aContext.ConnectionInfo.ClientIpAddress + ") bad password");
                    // exit
                    return;
                }

                switch (request.Type)
                {
                    case Request.Types.AddServer:
                        AddServer(request.Name);
                        break;

                    case Request.Types.RemoveServer:
                        RemoveServer(request.Guid);
                        break;

                    case Request.Types.AddChannel:
                        AddChannel(request.Guid, request.Name);
                        break;

                    case Request.Types.RemoveChannel:
                        RemoveChannel(request.Guid);
                        break;

                    case Request.Types.ActivateObject:
                        ActivateObject(request.Guid);
                        break;

                    case Request.Types.DeactivateObject:
                        DeactivateObject(request.Guid);
                        break;

                    case Request.Types.Search:
                        var packets = FilteredPackets(AllPackets(request.IgnoreOfflineBots), request.Guid);
                        UnicastBlock(currentUser, "Packet", packets);

                        var bots = DistinctBots(packets);
                        UnicastBlock(currentUser, "Bot", bots);

                        currentUser.IgnoreOfflineBots = request.IgnoreOfflineBots;
                        currentUser.LastSearch = request.Guid;
                        currentUser.LastLoadedBots = bots;
                        currentUser.LastViewedBot = Guid.Empty;
                        currentUser.LastLoadedPackets = packets;
                        break;

                    case Request.Types.SearchExternal:
                        var searchExternal = Searches.WithGuid(request.Guid);
                        if (searchExternal != null)
                        {
                            ExternalSearch[] results = new ExternalSearch[0];
                            try
                            {
                                var uri = new Uri("http://xg.bitpir.at/index.php?show=search&action=external&search=" + searchExternal.Name + "&xg=" + Settings.Instance.XgVersion);
                                var req = HttpWebRequest.Create(uri);

                                var response = req.GetResponse();
                                StreamReader sr = new StreamReader(response.GetResponseStream());
                                string text = sr.ReadToEnd();
                                response.Close();

                                results = JsonConvert.DeserializeObject<ExternalSearch[]>(text, JsonSerializerSettings);
                            }
                            catch (Exception ex)
                            {
                                Log.Fatal("OnMessage() cant load external search for " + searchExternal.Name, ex);
                            }

                            Unicast(currentUser, new Response
                            {
                                Type = Response.Types.SearchExternal,
                                Data = results
                            });
                        }
                        break;

                    case Request.Types.AddSearch:
                        string name = request.Name;
                        var obj = Searches.Named(name);
                        if (obj == null)
                        {
                            obj = new Core.Object {Name = name};
                            Searches.Add(obj);
                        }
                        break;

                    case Request.Types.RemoveSearch:
                        var search = Searches.WithGuid(request.Guid);
                        if (search != null)
                        {
                            foreach (var user in _users)
                            {
                                if (user.LastSearch == request.Guid)
                                {
                                    user.LastSearch = Guid.Empty;
                                }
                            }

                            Searches.Remove(search);
                        }
                        break;

                    case Request.Types.Searches:
                        var searches = new List<Core.Object>();
                        searches.Add(_search0Day);
                        searches.Add(_search0Week);
                        searches.Add(_searchDownloads);
                        searches.Add(_searchEnabled);
                        searches.AddRange(Searches.All);

                        Unicast(currentUser, new Response
                        {
                            Type = Response.Types.Searches,
                            Data = searches
                        });
                        break;

                    case Request.Types.Servers:
                        UnicastBlock(currentUser, "Server", Servers.All);
                        break;

                    case Request.Types.ChannelsFromServer:
                        var channels = (from server in Servers.All from channel in server.Channels where channel.ParentGuid == request.Guid select channel).ToList();
                        UnicastBlock(currentUser, "Channel", channels);

                        currentUser.LastViewedServer = request.Guid;
                        currentUser.LastLoadedChannels = channels;
                        break;

                    case Request.Types.PacketsFromBot:
                        var botPackets = (from server in Servers.All
                                        from channel in server.Channels
                                        from bot in channel.Bots
                                        from packet in bot.Packets
                                        where packet.ParentGuid == request.Guid
                                        select packet).ToList();
                        UnicastBlock(currentUser, "Packet", botPackets);

                        currentUser.LastViewedBot = request.Guid;
                        currentUser.LastLoadedPackets = botPackets;
                        break;

                    case Request.Types.Statistics:
                        //response = Statistic2Json();
                        break;

                    case Request.Types.Snapshots:
                        Unicast(currentUser, new Response
                        {
                            Type = Response.Types.Snapshots,
                            Data = Snapshots2Flot(Snapshots)
                        });
                        break;

                    case Request.Types.Files:
                        UnicastBlock(currentUser, "File", Files.All);
                        break;

                    case Request.Types.CloseServer:
                        break;

                    case Request.Types.ParseXdccLink:
                        string[] link = request.Name.Substring(7).Split('/');
                        string serverName = link[0];
                        string channelName = link[2];
                        string botName = link[3];
                        int packetId = int.Parse(link[4].Substring(1));

                        // checking server
                        Core.Server serv = Servers.Server(serverName);
                        if (serv == null)
                        {
                            Servers.Add(serverName);
                            serv = Servers.Server(serverName);
                        }
                        serv.Enabled = true;

                        // checking channel
                        Channel chan = serv.Channel(channelName);
                        if (chan == null)
                        {
                            serv.AddChannel(channelName);
                            chan = serv.Channel(channelName);
                        }
                        chan.Enabled = true;

                        // checking bot
                        Bot tBot = chan.Bot(botName);
                        if (tBot == null)
                        {
                            tBot = new Bot {Name = botName};
                            chan.AddBot(tBot);
                        }

                        // checking packet
                        Packet pack = tBot.Packet(packetId);
                        if (pack == null)
                        {
                            pack = new Packet {Id = packetId, Name = link[5]};
                            tBot.AddPacket(pack);
                        }
                        pack.Enabled = true;
                        break;
                }
            #if !UNSAFE
            }
            catch (Exception ex)
            {
                Log.Fatal("OnMessage(" + aContext.ConnectionInfo.ClientIpAddress + ", " + aMessage + ")", ex);
            }
            #endif
        }
예제 #4
0
        void BotDisconnected(Packet aPacket, BotConnection aCon)
        {
            aCon.Packet = null;
            aCon.Connection = null;

            if (_downloads.ContainsKey(aPacket))
            {
                aCon.Connected -= BotConnected;
                aCon.Disconnected -= BotDisconnected;
                _downloads.Remove(aPacket);

                try
                {
                    // if the connection never connected, there will be no part!
                    // and if we manually killed stopped the packet there will be no parent of the part
                    if (aCon.Part != null && aCon.Part.Parent != null)
                    {
                        // do this here because the bothandler sets the part state and after this we can check the file
                        FileActions.CheckFile(aCon.Part.Parent);
                    }
                }
                catch (Exception ex)
                {
                    Log.Fatal("bot_Disconnected()", ex);
                }

                try
                {
                    ServerConnection sc = _servers[aPacket.Parent.Parent.Parent];
                    sc.CreateTimer(aPacket.Parent, Settings.Instance.CommandWaitTime, false);
                }
                catch (Exception ex)
                {
                    Log.Fatal("bot_Disconnected() request", ex);
                }
            }
        }
예제 #5
0
 void BotConnected(Packet aPack, BotConnection aCon)
 {
 }
예제 #6
0
        /// <summary>
        /// </summary>
        /// <param name="aPack"> </param>
        /// <param name="aChunk"> </param>
        /// <param name="aIp"> </param>
        /// <param name="aPort"> </param>
        void BotConnect(Packet aPack, Int64 aChunk, IPAddress aIp, int aPort)
        {
            if (!_downloads.ContainsKey(aPack))
            {
                new Thread(() =>
                {
                    var con = new BotConnection
                    {
                        FileActions = FileActions,
                        Packet = aPack,
                        StartSize = aChunk,
                        Connection = new Connection.Connection {Hostname = aIp.ToString(), Port = aPort, MaxData = aPack.RealSize - aChunk}
                    };

                    con.Connected += BotConnected;
                    con.Disconnected += BotDisconnected;

                    _downloads.Add(aPack, con);
                    con.Connection.Connect();
                }).Start();
            }
            else
            {
                // uhh - that should not happen
                Log.Error("IrcParserAddDownload(" + aPack + ") is already downloading");
            }
        }
예제 #7
0
 public void RemovePacket(Packet aPacket)
 {
     Remove(aPacket);
 }
예제 #8
0
 public void AddPacket(Packet aPacket)
 {
     Add(aPacket);
 }
예제 #9
0
 protected void FireAddDownload(Packet aPack, Int64 aChunk, IPAddress aIp, int aPort)
 {
     if (AddDownload != null)
     {
         AddDownload(aPack, aChunk, aIp, aPort);
     }
 }
예제 #10
0
        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();
            }
        }