Example #1
0
 /// <summary>
 /// Add Transfer request
 /// This is used when other users want something from us.
 /// </summary>
 /// <param name="req">Transfer request to add</param>
 public void AddTransferReq(TransferRequest req)
 {
     lock (requests)
     {
         if (!requests.ContainsKey(req.Key))
             requests.Add(req.Key, req);
     }
     // TODO : Add req limiter.
 }
        public void ActOnInMessage(IConMessage conMsg)
        {
            StrMessage message = (StrMessage)conMsg;
            if (message is Lock)
            {
                Lock lk = (Lock)message;
                if (lk.Extended)
                    trans.Send(mySupport = new Supports(trans));

                GetSegment(true);

                Direction dir = new Direction(trans, this.download);
                this.downloadRandom = dir.Number;
                trans.Send(dir);

                trans.Send(new Key(lk.Key, trans));
            }
            else if (message is Key)
            {
                OnDownload();
            }
            else if (message is MyNick)
            {
                MyNick myNick = (MyNick)message;

                if (trans.Source != null && !string.IsNullOrEmpty(trans.Source.ConnectionId))
                {
                    string conId = trans.Source.ConnectionId;
                    string usrId = trans.Source.UserId;
                    if (string.IsNullOrEmpty(usrId))
                    {
                        // connection Id + User Id will give us the users StoredId
                        trans.Source = new Source(conId, conId + myNick.Info.ID);
                    }
                }
                else
                {
                    trans.Source = new Source(null, myNick.Info.ID);
                }

                trans.User = myNick.Info;
                TransferRequest req = new TransferRequest(trans.Source);

                FmdcEventArgs eArgs = new FmdcEventArgs(0, req);
                RequestTransfer(trans, eArgs);
                req = eArgs.Data as TransferRequest;
                if (!eArgs.Handled || req == null)
                {

                    if (trans.Me == null || trans.Share == null)
                    {
                        // Can't see user on my allow list
                        trans.Disconnect("No match for Request");
                        return;
                    }
                    else
                    {
                        // As developers already started to use this.
                        // We need to support the same behaivor as before (not doing anything when we are passive).
                    }
                }

                if (trans.Me == null || trans.Share == null)
                {
                    trans.Me = req.Me;
                    trans.User = req.User;
                    trans.Share = req.Share;
                    trans.Source = req.Source;
                    trans.Send(new Lock(trans));
                }
                else
                {
                    trans.User = myNick.Info;
                    //trans.Source.UserId = trans.Source.ConnectionId.Replace(":", string.Empty) + trans.User.StoreID;

                    // Do we want to specify a Share for this connection?
                    if (eArgs.Handled && req.Share != null)
                    {
                        trans.Share = req.Share;
                    }
                }
            }
            else if (message is Supports)
            {
                // Sets Supports for protocol.
                Supports sup = (Supports)message;
                userSupport = sup;
            }
            else if (message is Direction)
            {
                userDir = (Direction)message;
            }
            else if (message is Sending)
            {
                Sending sending = (Sending)message;
                if (trans.DownloadItem.ContentInfo.Size == -1)
                {
                    trans.DownloadItem.ContentInfo.Size = sending.Length;
                    trans.DownloadItem.SegmentSize = sending.Length;
                    EnsureCurrentSegmentCancelation();
                    GetSegment(false);
                }
                else if (trans.CurrentSegment != null && trans.CurrentSegment.Length != sending.Length)
                {
                    trans.Disconnect("Why would i want to get a diffrent length of bytes then i asked for?");
                    return;
                }
                this.rawData = true;
                trans.ShouldBlockOnSend = true;
            }
            else if (message is FileLength)
            {
                FileLength fileLength = (FileLength)message;
                if (trans.DownloadItem.ContentInfo.Size == -1)
                {
                    trans.DownloadItem.ContentInfo.Size = fileLength.Length;
                    trans.DownloadItem.SegmentSize = fileLength.Length;
                    EnsureCurrentSegmentCancelation();
                    GetSegment(false);
                }
                else if (trans.CurrentSegment != null && trans.CurrentSegment.Length != fileLength.Length)
                {
                    trans.Disconnect("Why would i want to get a diffrent length of bytes then i asked for?");
                    return;
                }
                this.rawData = true;
                trans.ShouldBlockOnSend = true;
            }
            else if (message is ADCSND)
            {
                ADCSND adcsnd = (ADCSND)message;
                if (!trans.Content.Get(ContentInfo.REQUEST).Equals(adcsnd.Content))
                {
                    trans.Disconnect("I want my bytes..");
                    return;
                }
                if (trans.DownloadItem.ContentInfo.Size == -1)
                {
                    trans.DownloadItem.ContentInfo.Size = adcsnd.Length;
                    trans.DownloadItem.SegmentSize = adcsnd.Length;
                    EnsureCurrentSegmentCancelation();
                    GetSegment(false);
                }
                else if (trans.CurrentSegment != null && trans.CurrentSegment.Length != adcsnd.Length)
                {
                    trans.Disconnect("Why would i want to get a diffrent length of bytes then i asked for?");
                    return;
                }
                this.rawData = true;
                trans.ShouldBlockOnSend = true;
            }
            else if (message is Send)
            {
                if (this.download || bytesToSend == null || trans.CurrentSegment == null)
                {
                    trans.Disconnect();
                    return;
                }
                trans.CurrentSegment.Position = bytesToSend.Length;
                long length = trans.Content.Size;
                do
                {
                    trans.Send(new BinaryMessage(trans, bytesToSend, bytesToSend.Length));
                    trans.CurrentSegment.Position += bytesToSend.Length;
                } while (connectionStatus != TcpConnection.Disconnected && (bytesToSend = this.GetContent(System.Text.Encoding.ASCII, trans.CurrentSegment.Position, trans.CurrentSegment.Length - trans.CurrentSegment.Position)) != null);
                trans.Content = null;
                trans.Disconnect();
            }
            else if (message is Get)
            {
                // If we are supposed to download and other client tries to download. Disconnect.
                if (this.download)
                {
                    trans.Disconnect();
                    return;
                }
                Get get = (Get)message;

                trans.Content = new ContentInfo(ContentInfo.REQUEST, get.File);
                trans.CurrentSegment = new SegmentInfo(-1, get.Start, -1);
                if (get.File.Equals("files.xml.bz2"))
                {
                    //trans.Content.VirtualName = System.Text.Encoding.ASCII.WebName + get.File;
                    //trans.Content.IdType = ContentIdTypes.Filelist;
                    trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XMLBZ);
                    trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.ASCII.WebName + get.File);
                }
                else
                {
                    //trans.Content.VirtualName = get.File;
                    trans.Content.Set(ContentInfo.VIRTUAL, get.File);
                }
                bytesToSend = this.GetContent(System.Text.Encoding.ASCII, trans.CurrentSegment.Start + trans.CurrentSegment.Position, trans.CurrentSegment.Length - trans.CurrentSegment.Position);

                // Do file exist?
                if (trans.Content.Size > -1)
                {
                    trans.Send(new FileLength(trans, trans.Content.Size));
                }
                else
                {
                    trans.Send(new Error("File Not Available", trans));
                }
            }
            else if (message is GetBlocks)
            {
                // If we are supposed to download and other client tries to download. Disconnect.
                if (this.download)
                {
                    trans.Disconnect();
                    return;
                }
                GetBlocks getblocks = (GetBlocks)message;
                trans.Content = new Containers.ContentInfo(ContentInfo.REQUEST, getblocks.FileName);
                if (getblocks.FileName.Equals("files.xml.bz2"))
                {
                    //trans.Content.VirtualName = System.Text.Encoding.UTF8.WebName + getblocks.FileName;
                    //trans.Content.IdType = ContentIdTypes.Filelist;
                    trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + getblocks.FileName);
                    trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XMLBZ);
                }
                else
                {
                    trans.Content.Set(ContentInfo.VIRTUAL, getblocks.FileName);
                }

                trans.CurrentSegment = new SegmentInfo(-1, getblocks.Start, getblocks.Length);
                bool firstTime = true;
                while (connectionStatus != TcpConnection.Disconnected && (bytesToSend = GetContent(System.Text.Encoding.UTF8, trans.CurrentSegment.Start + trans.CurrentSegment.Position, trans.CurrentSegment.Length - trans.CurrentSegment.Position)) != null)
                {
                    if (firstTime)
                    {
                        trans.Send(new Sending(trans));
                        firstTime = false;
                    }
                    trans.Send(new BinaryMessage(trans, bytesToSend, bytesToSend.Length));
                    trans.CurrentSegment.Position += bytesToSend.Length;
                }
                if (firstTime)
                    trans.Send(new Failed("File Not Available", trans));
                trans.CurrentSegment = new SegmentInfo(-1);
                trans.Content = null;
            }
            else if (message is ADCGET)
            {
                // If we are supposed to download and other client tries to download. Disconnect.
                if (this.download)
                {
                    trans.Disconnect();
                    return;
                }
                ADCGET adcget = (ADCGET)message;
                trans.Content = new ContentInfo(ContentInfo.REQUEST, adcget.Content);
                switch (adcget.Type.ToLower())
                {
                    case "file":
                        if (adcget.Content.StartsWith("TTH/"))
                        {
                            //trans.Content.Id = adcget.Content.Substring(4);
                            //trans.Content.IdType = ContentIdTypes.TTH | ContentIdTypes.Hash;
                            trans.Content.Set(ContentInfo.TTH, adcget.Content.Substring(4));
                        }
                        else
                        {
                            if (adcget.Content.Equals("files.xml.bz2"))
                            {
                                //trans.Content.VirtualName = System.Text.Encoding.UTF8.WebName + adcget.Content;
                                //trans.Content.IdType = ContentIdTypes.Filelist;
                                trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + adcget.Content);
                                trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XMLBZ);
                            }
                            else
                            {
                                trans.Content.Set(ContentInfo.VIRTUAL, adcget.Content);
                            }
                        }
                        break;
                    case "tthl":
                        // TTH/DQSGG2MYKKLXX4N2P7TBPKSC5HVBO3ISYZPLMWA
                        if (adcget.Content.StartsWith("TTH/"))
                        {
                            trans.Content.Set(ContentInfo.TTH, adcget.Content.Substring(4));

                            ContentInfo tmp = trans.Content;
                            if (trans.Share != null && trans.Share.ContainsContent(ref tmp) && tmp.ContainsKey(ContentInfo.TTHL))
                            {
                                byte[] bytes = Utils.Convert.Base32.Decode(tmp.Get(ContentInfo.TTHL));
            #if !COMPACT_FRAMEWORK
                                trans.CurrentSegment = new SegmentInfo(-1, 0, bytes.LongLength);
            #else
                                trans.CurrentSegment = new SegmentInfo(-1, 0, bytes.Length);
            #endif
                                ADCSND adcsend = new ADCSND(trans);
                                adcsend.Type = adcget.Type;
                                adcsend.Content = adcget.Content;
                                adcsend.Start = trans.CurrentSegment.Start;
                                adcsend.Length = trans.CurrentSegment.Length;
                                adcsend.ZL1 = adcget.ZL1;
                                trans.Send(adcsend);
                                // Send content to user
                                trans.Send(new BinaryMessage(trans, bytes, bytes.Length));
                                //System.Console.WriteLine("TTH Leaves:" + FlowLib.Utils.Convert.Base32.Encode(bytes));
                                trans.Content = null;
                                //trans.Disconnect();
                                return;
                            }
                        }
                        break;
                }
                trans.CurrentSegment = new SegmentInfo(-1, adcget.Start, adcget.Length);
                bool firstTime = true;
                try
                {
                    // TODO : ZLib compression here doesnt work as we want. It takes much memory and much cpu
                    //Util.Compression.ZLib zlib = null;
                    //if (adcget.ZL1)
                    //    zlib = new Fmdc.Util.Compression.ZLib();
                    while (connectionStatus != TcpConnection.Disconnected && (bytesToSend = GetContent(System.Text.Encoding.UTF8, trans.CurrentSegment.Start + trans.CurrentSegment.Position, trans.CurrentSegment.Length - trans.CurrentSegment.Position)) != null)
                    {
                        if (firstTime)
                        {
                            ADCSND adcsend = new ADCSND(trans);
                            adcsend.Type = adcget.Type;
                            adcsend.Content = adcget.Content;
                            adcsend.Start = adcget.Start;
                            adcsend.Length = trans.CurrentSegment.Length;
                            adcsend.ZL1 = adcget.ZL1;
                            trans.Send(adcsend);

                            firstTime = false;
                        }

                        trans.CurrentSegment.Position += bytesToSend.Length;
                        // We want to compress content with ZLib
                        //if (zlib != null)
                        //{
                        //    zlib.Compress2(bytesToSend);
                        //    bytesToSend = zlib.Read();
                        //}
                        trans.Send(new BinaryMessage(trans, bytesToSend, bytesToSend.Length));
                        bytesToSend = null;

                    }

                    // If we compressing data with zlib. We need to send ending bytes too.
                    //if (zlib != null && connectionStatus != Connection.Disconnected)
                    //    trans.Send(new ConMessage(trans, zlib.close()));
                }
                catch (System.Exception e) { System.Console.WriteLine("ERROR:" + e); }
                trans.CurrentSegment = new SegmentInfo(-1);
                trans.Content = null;
                if (firstTime)
                {
                    // We should not get here if file is in share.
                    trans.Send(new Error("File Not Available", trans));
                    trans.Disconnect();
                }
            }
            else if (message is MaxedOut)
            {
                FmdcEventArgs e = new FmdcEventArgs((int)TransferErrors.NO_FREE_SLOTS);
                Error(trans, e);
                if (!e.Handled)
                    trans.Disconnect();
            }
            else if (message is Error)
            {
                TransferNmdc.Error error = (TransferNmdc.Error)message;
                FmdcEventArgs e = null;
                // TODO : Add more error messages here.
                switch (error.Message)
                {
                    case "File Not Available":
                        e = new FmdcEventArgs((int)TransferErrors.FILE_NOT_AVAILABLE);
                        break;
                    default:
                        e = new FmdcEventArgs((int)TransferErrors.UNKNOWN, error.Message);
                        break;
                }
                Error(trans, e);
                if (!e.Handled)
                    trans.Disconnect();
            }
            else if (message is Failed)
            {
                Failed failed = (Failed)message;
                FmdcEventArgs e = null;
                // TODO : Add more error messages here.
                switch (failed.Message)
                {
                    case "File Not Available":
                        e = new FmdcEventArgs((int)TransferErrors.FILE_NOT_AVAILABLE);
                        break;
                    default:
                        e = new FmdcEventArgs((int)TransferErrors.UNKNOWN, failed.Message);
                        break;
                }
                Error(trans, e);
                if (!e.Handled)
                    trans.Disconnect();
            }
        }
Example #3
0
        public void ActOnInMessage(IConMessage conMsg)
        {
            StrMessage message = (StrMessage)conMsg;
            #region INF
            if (message is INF)
            {
                INF inf = (INF)message;
                if (hub != null && inf.Type.Equals("I"))
                {
                    if (hub.RegMode < 0)
                        hub.RegMode = 0;
                    UpdateInf();
                    Info = inf.UserInfo;
                    if (hub != null && Info.Description == null)
                        Update(con, new FmdcEventArgs(Actions.Name, new Containers.HubName(Info.DisplayName)));
                    else if (hub != null)
                        Update(con, new FmdcEventArgs(Actions.Name, new Containers.HubName(Info.DisplayName, Info.Description)));
                }
                else if (trans != null && inf.Type.Equals("C"))
                {
                    string token = null;
                    // CINF IDE3VACJVAXNOQLGRFQS7D5HYH4A6GLZDO3LJ33HQ TO2718662518
                    if (trans.Me != null && trans.Me.ContainsKey("TO"))
                        token = trans.Me.Get("TO");
                    else if (inf.UserInfo.ContainsKey("TO"))
                        token = inf.UserInfo.Get("TO");

                    TransferRequest req = new TransferRequest(token, null, inf.UserInfo);
                    FmdcEventArgs eArgs = new FmdcEventArgs(0, req);
                    RequestTransfer(trans, eArgs);
                    req = eArgs.Data as TransferRequest;
                    if (!eArgs.Handled || req == null)
                    {
                        // Can't see user/connection on my allow list
                        trans.Disconnect("No match for Request");
                        return;
                    }
                    if (!((req.User.ContainsKey(UserInfo.CID) && inf.UserInfo.ContainsKey(UserInfo.CID)) && req.User.Get(UserInfo.CID).Equals(inf.UserInfo.Get(UserInfo.CID))))
                    {
                        // For some reason user is trying to tell us it is a diffrent user. We dont like that.
                        FmdcEventArgs e = new FmdcEventArgs((int)TransferErrors.USERID_MISMATCH);
                        Error(trans, e);
                        if (!e.Handled)
                        {
                            trans.Disconnect("User Id Mismatch");
                            return;
                        }
                    }
                    if (trans.Me == null)
                        trans.Me = req.Me;
                    trans.User = req.User;
                    info = trans.User;
                    trans.Share = req.Share;
                    trans.Source = req.Source;
                    download = req.Download;

                    con.Send(new INF(con, trans.Me));
                    if (download)
                    {
                        EnsureCurrentSegmentCancelation();
                        // Request new segment from user. IF we have found one. ELSE disconnect.
                        if (GetSegment(true))
                        {
                            OnDownload();
                        }
                        else
                            trans.Disconnect("All content downloaded");
                    }
                }
                else if (hub != null)
                {
                    User usr = null;
                    if ((usr = hub.GetUserById(inf.Id)) == null)
                    {
                        if (inf.UserInfo.Mode == ConnectionTypes.Unknown)
                        {
                            inf.UserInfo.Mode = ConnectionTypes.Passive;
                        }
                        Update(con, new FmdcEventArgs(Actions.UserOnline, inf.UserInfo));
                    }
                    else
                    {
                        usr.UserInfo = inf.UserInfo;
                        Update(con, new FmdcEventArgs(Actions.UserInfoChange, usr.UserInfo));
                    }
                    // This is so we update our own reg/op hub count.
                    if (string.Equals(hub.Me.ID,inf.Id))
                    {
                        // Should we be marked with key?
                        bool regmodeChanged = false;
                        if (hub.RegMode < 2)
                        {
                            if (((UserInfo.ACCOUNT_FLAG_OPERATOR & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_OPERATOR))
                            {
                                hub.RegMode = 2;
                                regmodeChanged = true;
                            }
                            else if (((UserInfo.ACCOUNT_FLAG_SUPERUSER & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_SUPERUSER))
                            {
                                hub.RegMode = 2;
                                regmodeChanged = true;
                            }
                            else if (((UserInfo.ACCOUNT_FLAG_HUBOWNER & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_HUBOWNER))
                            {
                                hub.RegMode = 2;
                                regmodeChanged = true;
                            }
                        }
                        // Should we be marked as reg?
                        if (hub.RegMode < 1)
                        {
                            if (((UserInfo.ACCOUNT_FLAG_REGISTERED & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_REGISTERED))
                            {
                                hub.RegMode = 1;
                                regmodeChanged = true;
                            }

                        }
                        if (regmodeChanged)
                            UpdateInf();

                        IsReady = true;
                    }
                }
            }
            #endregion
            #region MSG
            else if (message is MSG && hub != null)
            {
                MSG msg = (MSG)message;
                if (msg.PmGroup == null)
                {
                    MainMessage main = new MainMessage(msg.From, msg.Content);
                    Update(con, new FmdcEventArgs(Actions.MainMessage, main));
                }
                else
                {
                    PrivateMessage pm = new PrivateMessage(msg.To, msg.From, msg.Content, msg.PmGroup);
                    Update(con, new FmdcEventArgs(Actions.PrivateMessage, pm));
                }
            }
            #endregion
            #region SID
            else if (message is SID && hub != null)
            {
                SID sid = (SID)message;
                hub.Me.Set(UserInfo.SID, sid.Id);
            }
            #endregion
            #region STA
            else if (message is STA)
            {
                STA sta = (STA)message;
                if (hub != null)
                {
                    MainMessage main = new MainMessage(info.ID, sta.Content);
                    Update(con, new FmdcEventArgs(Actions.MainMessage, main));
                }
            }
            #endregion
            #region GPA
            else if (message is GPA)
            {
                GPA gpa = (GPA)message;
                this.gpaString = gpa.RandomData;
                if (trans != null)
                {
                    Update(con, new FmdcEventArgs(Actions.Password, null));
                }
                if (hub != null && hub.HubSetting.Password.Length == 0)
                {
                    Update(con, new FmdcEventArgs(Actions.Password, null));
                }
                else
                    hub.Send(new PAS(hub, gpa.RandomData, hub.HubSetting.Password));
            }
            #endregion
            #region QUI
            else if (message is QUI && hub != null)
            {
                QUI qui = (QUI)message;
                User usr = null;
                if ((usr = hub.GetUserById(qui.Id)) != null)
                {
                    Update(con, new FmdcEventArgs(Actions.UserOffline, usr.UserInfo));
                    if (usr.ID == hub.Me.ID)
                    {
                        // TODO : Banning and redirect handling
                        hub.Disconnect();
                        // Redirect
                        if (!string.IsNullOrEmpty(qui.Address))
                            Update(con, new FmdcEventArgs(Actions.Redirect, new RedirectInfo(qui.Address, qui.Message, qui.DisconnectedBy)));
                        // Banned
                        else
                        {
                            if (qui.Time != -1)
                                // Sets reconnect attempt to infinite
                                hub.KeepAliveInterval = 0;
                            else
                                hub.KeepAliveInterval = qui.Time;
                            Update(con, new FmdcEventArgs(Actions.Banned, new BannedInfo(qui.Time, qui.Message, qui.DisconnectedBy)));
                        }
                    }
                }
            }
            #endregion
            #region SUP
            else if (message is SUP)
            {
                if (trans != null && !hasSentSUP)
                {
                    con.Send(new SUP(con));
                }
                supports = (SUP)message;
                // TODO : We should really care about what hub support.
                if (!supports.BASE && !supports.TIGR)
                {
                    // We will just simply disconnect if hub doesnt support this right now
                    con.Disconnect("Connection doesnt support BASE or BAS0");
                }
            #if !COMPACT_FRAMEWORK
                // Encrypted transfers
                if (supports.ADCS)
                {
                    if (
                        (hub != null && hub.Me.ContainsKey(UserInfo.SECURE)) ||
                        (trans != null && trans.Me.ContainsKey(UserInfo.SECURE))
                        )
                    {
                        con.SecureProtocol = SecureProtocols.TLS;
                    }
                }
            #endif
            }
            #endregion
            #region RES
            else if (message is RES)
            {
                RES res = (RES)message;
                SearchResultInfo srinfo = new SearchResultInfo(res.Info, res.Id, res.Token);
                if (hub != null)
                    Update(con, new FmdcEventArgs(Actions.SearchResult, srinfo));
            }
            #endregion
            #region SCH
            else if (message is SCH)
            {
                SCH sch = (SCH)message;
                UserInfo usr = null;
                if (hub != null)
                {
                    User u = hub.GetUserById(sch.Id);
                    if (u != null)
                        usr = u.UserInfo;
                }
                else if (trans != null)
                    usr = trans.User;

                SendRES(sch.Info, usr);
            }
            #endregion
            #region CTM
            else if (message is CTM && hub != null)
            {
                CTM ctm = (CTM)message;

                // We really hate buggy hubsofts. Only reason we will get this message is because hubsoft dont know diffrent between E and D messages.
                if (ctm.Id == hub.Me.ID)
                    return;

                User usr = null;
                string addr = null;

                // Do we support same protocol?
                double version = 0.0;
                if (ctm.Protocol != null && (ctm.Protocol.StartsWith("ADC/") || ctm.Protocol.StartsWith("ADCS/")))
                {
                    try
                    {
                        version = double.Parse(ctm.Protocol.Substring( ctm.Protocol.IndexOf("/") +1), CultureInfo.GetCultureInfo("en-GB").NumberFormat);
                    }
                    catch { }
                }
                if (version > 1.0)
                {
                    hub.Send(new STA(hub, ctm.Id, hub.Me.ID, "241", "Protocol is not supported. I only support ADC 1.0/ADCS 0.10 and prior", "TO" + ctm.Token + " PR" + ctm.Protocol));
                    return;
                }

                if ((usr = hub.GetUserById(ctm.Id)) != null && usr.UserInfo.ContainsKey(UserInfo.IP))
                {
                    addr = usr.UserInfo.Get(UserInfo.IP);
                    Transfer trans = new Transfer(addr, ctm.Port);
                    trans.Share = hub.Share;
                    // We are doing this because we want to filter out PID and so on.
                    User me = hub.GetUserById(hub.Me.ID);
                    trans.Me = new UserInfo(me.UserInfo);
                    trans.Protocol = new AdcProtocol(trans);
            #if !COMPACT_FRAMEWORK
                    if (ctm.Secure)
                        trans.SecureProtocol = SecureProtocols.TLS;
            #endif

                    // Support for prior versions of adc then 1.0
                    string token = ctm.Token;
                    if (version < 1.0 && ctm.Token.StartsWith("TO"))
                        token = ctm.Token.Substring(2);
                    trans.Me.Set("TO", token);

                    Update(con, new FmdcEventArgs(Actions.TransferRequest, new TransferRequest(token, hub, usr.UserInfo,false)));
                    Update(con, new FmdcEventArgs(Actions.TransferStarted, trans));
                }
            }
            #endregion
            #region RCM
            else if (message is RCM && hub != null)
            {
                RCM rcm = (RCM)message;

                // We really hate buggy hubsofts. Only reason we will get this message is because hubsoft dont know diffrent between E and D messages.
                if (rcm.Id == hub.Me.ID)
                    return;

               if (hub.Me.Mode != FlowLib.Enums.ConnectionTypes.Passive && hub.Share != null)
                {
                    User usr = null;
                    if ((usr = hub.GetUserById(rcm.Id)) != null)
                    {
                        // Do we support same protocol?
                        double version = 0.0;
                        if (rcm.Protocol != null && (rcm.Protocol.StartsWith("ADC/") || rcm.Protocol.StartsWith("ADCS/")))
                        {
                            try
                            {
                                version = double.Parse(rcm.Protocol.Substring(rcm.Protocol.IndexOf("/") + 1), CultureInfo.GetCultureInfo("en-GB").NumberFormat);
                            }
                            catch { }
                            if (version <= 1.0)
                            {
                                // Support for prior versions of adc then 1.0
                                string token = rcm.Token;
                                if (version < 1.0 && rcm.Token.StartsWith("TO"))
                                    token = rcm.Token.Substring(2);

                                Update(con, new FmdcEventArgs(Actions.TransferRequest, new TransferRequest(token, hub, usr.UserInfo, false)));

                                if (rcm.Secure && hub.Me.ContainsKey(UserInfo.SECURE))
                                    hub.Send(new CTM(hub, rcm.Id, rcm.IDTwo, rcm.Protocol, int.Parse(0 + hub.Me.Get(UserInfo.SECURE)), token));
                                else
                                    hub.Send(new CTM(hub, rcm.Id, rcm.IDTwo, rcm.Protocol, hub.Share.Port, token));
                            }
                            else
                            {
                                hub.Send(new STA(hub, rcm.Id, hub.Me.ID, "241", "Protocol is not supported. I only support ADC 1.0 and prior", "TO" + rcm.Token + " PR" + rcm.Protocol));
                                return;
                            }
                        }
                    }
                }
                else
                {
                    // TODO : we should probably return a STA message.
                }
            }
            #endregion
            #region GFI
            else if (message is GFI && this.trans != null)
            {
                GFI gfi = (GFI)message;
                if (gfi.Identifier != null)
                {
                    trans.Content = new ContentInfo();
                    switch (gfi.ContentType)
                    {
                        case "file":        // Requesting file
                            // This is because we have support for old DC++ client and mods like (DCDM who has ASCII encoding)
                            if (gfi.Identifier.Equals("files.xml.bz2"))
                            {
                                trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XMLBZ);
                                trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + gfi.Identifier);
                            }
                            else if (gfi.Identifier.StartsWith("TTH/"))
                            {
                                trans.Content.Set(ContentInfo.TTH, gfi.Identifier.Substring(4));
                            }
                            else
                            {
                                trans.Content.Set(ContentInfo.VIRTUAL, gfi.Identifier);
                            }
                            break;
                        case "list":        // TODO : We dont care about what subdirectoy user whats list for
                            trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XML);
                            trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + "files.xml");
                            break;
                        default:            // We are not supporting type. Disconnect
                            con.Send(new STA(con, "251", "Type not known:" + gfi.ContentType, null));
                            con.Disconnect();
                            return;
                    }
                    SearchInfo si = new SearchInfo();
                    if (trans.Content.ContainsKey(ContentInfo.TTH))
                        si.Set(SearchInfo.TYPE, trans.Content.Get(ContentInfo.TTH));
                    si.Set(SearchInfo.SEARCH, trans.Content.Get(ContentInfo.VIRTUAL));
                    SendRES(si, trans.User);
                }
            }
            #endregion
            #region GET
            else if (message is GET && this.trans != null)
            {
                GET get = (GET)message;
                // If we are supposed to download and other client tries to download. Disconnect.
                if (trans != null && this.download)
                {
                    trans.Disconnect();
                    return;
                }
                bool firstTime = true;

                if (get.Identifier != null)
                {
                    trans.Content = new ContentInfo();
                    switch (get.ContentType)
                    {
                        case "file":        // Requesting file
                            // This is because we have support for old DC++ client and mods like (DCDM who has ASCII encoding)
                            if (get.Identifier.Equals("files.xml.bz2"))
                            {
                                trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XMLBZ);
                                trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + get.Identifier);
                            }
                            else if (get.Identifier.StartsWith("TTH/"))
                            {
                                trans.Content.Set(ContentInfo.TTH, get.Identifier.Substring(4));
                            }
                            else
                            {
                                trans.Content.Set(ContentInfo.VIRTUAL, get.Identifier);
                            }
                            break;
                        case "list":        // TODO : We dont care about what subdirectoy user whats list for
                            trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XML);
                            trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + "files.xml");
                            break;
                        case "tthl":
                            // TTH/DQSGG2MYKKLXX4N2P7TBPKSC5HVBO3ISYZPLMWA
                            if (get.Identifier.StartsWith("TTH/"))
                            {
                                trans.Content.Set(ContentInfo.TTH, get.Identifier.Substring(4));

                                ContentInfo tmp = trans.Content;
                                if (con.Share != null && con.Share.ContainsContent(ref tmp) && tmp.ContainsKey(ContentInfo.TTHL))
                                {
                                    byte[] bytes = Utils.Convert.Base32.Decode(tmp.Get(ContentInfo.TTHL));
            #if !COMPACT_FRAMEWORK
                                    trans.CurrentSegment = new SegmentInfo(-1, 0, bytes.LongLength);
            #else
                                    trans.CurrentSegment = new SegmentInfo(-1, 0, bytes.Length);
            #endif

                                    con.Send(new SND(trans, get.ContentType, get.Identifier, new SegmentInfo(-1, trans.CurrentSegment.Start, trans.CurrentSegment.Length)));
                                    // Send content to user
                                    System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
                                    ms.Flush();
                                    bytes = ms.ToArray();
                                    con.Send(new BinaryMessage(con, bytes, bytes.Length));
                                    System.Console.WriteLine("TTH Leaves:" + FlowLib.Utils.Convert.Base32.Encode(bytes));
                                    firstTime = true;
                                }
                            }
                            if (!firstTime)
                            {
                                // We should not get here if file is in share.
                                con.Send(new STA(con, "251", "File not available", null));
                                con.Disconnect();
                            }
                            return;
                        default:            // We are not supporting type. Disconnect
                            con.Send(new STA(con, "251", "Type not known:" + get.ContentType, null));
                            con.Disconnect();
                            return;
                    }
                    trans.CurrentSegment = get.SegmentInfo;
                    byte[] bytesToSend = null;
                    try
                    {
                        // TODO : ZLib compression here doesnt work as we want. It takes much memory and much cpu
                        //Util.Compression.ZLib zlib = null;
                        //if (adcget.ZL1)
                        //    zlib = new Fmdc.Util.Compression.ZLib();
                        while (connectionStatus != TcpConnection.Disconnected && (bytesToSend = GetContent(System.Text.Encoding.UTF8, trans.CurrentSegment.Position, trans.CurrentSegment.Length - trans.CurrentSegment.Position)) != null)
                        {
                            if (firstTime)
                            {
                                con.Send(new SND(trans, get.ContentType, get.Identifier, new SegmentInfo(-1, get.SegmentInfo.Start, trans.CurrentSegment.Length)));
                                firstTime = false;
                            }

                            trans.CurrentSegment.Position += bytesToSend.Length;
                            // We want to compress content with ZLib
                            //if (zlib != null)
                            //{
                            //    zlib.Compress2(bytesToSend);
                            //    bytesToSend = zlib.Read();
                            //}
                            con.Send(new BinaryMessage(trans, bytesToSend, bytesToSend.Length));
                            bytesToSend = null;

                        }

                        // If we compressing data with zlib. We need to send ending bytes too.
                        //if (zlib != null && connectionStatus != Connection.Disconnected)
                        //    trans.Send(new ConMessage(trans, zlib.close()));
                    }
                    catch (System.Exception e) { System.Console.WriteLine("ERROR:" + e); }
                }
                trans.CurrentSegment = new SegmentInfo(-1);
                trans.Content = null;
                if (firstTime)
                {
                    // We should not get here if file is in share.
                    con.Send(new STA(con, "251", "File not available", null));
                    con.Disconnect();
                }
            }
            #endregion
            #region SND
            else if (message is SND)
            {
                SND snd = (SND)message;
                if (!trans.Content.Get(ContentInfo.REQUEST).Equals(snd.Identifier))
                {
                    trans.Disconnect("I want my bytes..");
                    return;
                }
                if (trans.DownloadItem.ContentInfo.Size == -1)
                {
                    trans.DownloadItem.ContentInfo.Size = snd.SegmentInfo.Length;
                    trans.DownloadItem.SegmentSize = snd.SegmentInfo.Length;
                    EnsureCurrentSegmentCancelation();
                    GetSegment(false);
                }
                else if (trans.CurrentSegment != null && trans.CurrentSegment.Length != snd.SegmentInfo.Length)
                {
                    trans.Disconnect("Why would i want to get a diffrent length of bytes then i asked for?");
                    return;
                }
                this.IsRawData = true;
                trans.ShouldBlockOnSend = true;
            }
            #endregion
        }