예제 #1
0
파일: App.xaml.cs 프로젝트: Kayomani/FAP
        protected override void OnStartup(StartupEventArgs e)
        {
            if(e.Args.Contains("WAIT"))
                Thread.Sleep(5000);

            SplashScreen appSplash = null;
            Fap.Foundation.SafeObservableStatic.Dispatcher = System.Windows.Application.Current.Dispatcher;
            SafeObservingCollectionManager.Start();
            this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
            FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

            base.OnStartup(e);
            if (Compose())
            {
                if (e.Args.Length == 1 && e.Args[0] == "WAIT")
                {
                    //Delay the application starting up, used when restarting.
                    Thread.Sleep(3000);
                }

                ApplicationCore core = container.Resolve<ApplicationCore>();

                if (!core.CheckSingleInstance())
                {
                    //An instance of fap is already running.

                    //If we got a download url then forward onto the runing instance of FAP
                    if (e.Args.Length == 2 && e.Args[0] == "-url")
                    {
                        Model model = new Model();
                        model.Load();

                        Client client = new Client(model.LocalNode);
                        AddDownload verb = new AddDownload();
                        verb.URL = e.Args[1];
                        if (client.Execute(verb, model.LocalNode))
                        {
                            //Download sent successfully
                            Shutdown(0);
                            return;
                        }
                        else
                        {
                            //Unsuccessful - Notify user
                            WPFMessageBox.Show("FAP", "Failed to add download via RPC!");
                            Shutdown(1);
                            return;
                        }
                    }
                    else
                    {
                        //Inform the user they cannot run multiple instances
                        WPFMessageBox.Show("FAP", "An instance of FAP is already running");
                        Shutdown(1);
                        return;
                    }
                }

                string img = GetImage();
                appSplash = new SplashScreen(img);
                appSplash.Show(true);

                if (core.Load(false))
                {

                    core.StartClient();
                    core.StartGUI(!(e.Args.Contains("STARTUP")));
                    //Was a url passed on startup?
                    if (e.Args.Length == 2 && e.Args[0] == "-url")
                    {
                        core.AddDownloadUrlWhenConnected(e.Args[1]);
                    }
                }
                else
                {
                    Shutdown(1);
                }
            }
            else
            {
                Shutdown(1);
            }
            if (null != appSplash)
                appSplash.Close(TimeSpan.FromSeconds(0));
        }
예제 #2
0
        private void process(object o)
        {
            try
            {
                while (true)
                {
                    DownloadRequest currentItem = null;

                    bool QueueEmpty = false;

                    lock (sync)
                        QueueEmpty = queue.Count == 0;
                    if (QueueEmpty && null != OnWorkerFinished)
                        OnWorkerFinished(this, EventArgs.Empty);

                    lock (sync)
                    {
                        if (queue.Count > 0)
                            currentItem = queue.Dequeue();
                        if (null == currentItem)
                        {
                            isComplete = true;
                            return;
                        }
                    }

                    currentItem.State = DownloadRequestState.Downloading;

                    if (currentItem.IsFolder)
                    {
                        length = 0;
                        position = 0;
                        status = "Downloading folder info for " + currentItem.FullPath;
                        //Item is a folder - Just get the folder items and add them to the queue.
                        var verb = new BrowseVerb(null);
                        verb.Path = currentItem.FullPath;
                        //Always get the latest info.
                        verb.NoCache = true;

                        var client = new Client(null);

                        if (client.Execute(verb, remoteNode))
                        {
                            currentItem.State = DownloadRequestState.Downloaded;
                            var newItems = new List<DownloadRequest>();

                            foreach (BrowsingFile item in verb.Results)
                            {
                                newItems.Add(new DownloadRequest
                                                 {
                                                     Added = DateTime.Now,
                                                     ClientID = remoteNode.ID,
                                                     FullPath = currentItem.FullPath + "/" + item.Name,
                                                     IsFolder = item.IsFolder,
                                                     LocalPath = currentItem.LocalPath + "\\" + currentItem.FileName,
                                                     NextTryTime = 0,
                                                     Nickname = remoteNode.Nickname,
                                                     Size = item.Size,
                                                     State = DownloadRequestState.None
                                                 });
                            }
                            model.DownloadQueue.List.AddRange(newItems);
                        }
                        else
                        {
                            currentItem.State = DownloadRequestState.Error;
                            currentItem.NextTryTime = Environment.TickCount + Model.DOWNLOAD_RETRY_TIME;
                        }
                    }
                    else
                    {
                        MemoryBuffer buffer = bufferService.GetBuffer();
                        buffer.SetDataLocation(0, buffer.Data.Length);
                        //Item is a file - download it
                        try
                        {
                            length = currentItem.Size;
                            position = 0;
                            status = currentItem.Nickname + " - " + currentItem.FileName + " - Connecting..";
                            currentItem.State = DownloadRequestState.Downloading;

                            string mainPath = string.Empty;
                            string mainFolder = string.Empty;
                            string incompletePath = string.Empty;
                            ;
                            string incompleteFolder = string.Empty;

                            //Build paths
                            var mainsb = new StringBuilder();
                            mainsb.Append(model.DownloadFolder);
                            if (!string.IsNullOrEmpty(currentItem.LocalPath))
                            {
                                mainsb.Append("\\");
                                mainsb.Append(currentItem.LocalPath);
                            }
                            mainFolder = mainsb.ToString();
                            mainsb.Append("\\");
                            mainsb.Append(currentItem.FileName);
                            mainPath = mainsb.ToString();

                            var incompletesb = new StringBuilder();
                            incompletesb.Append(model.IncompleteFolder);
                            if (!string.IsNullOrEmpty(currentItem.LocalPath))
                            {
                                incompletesb.Append("\\");
                                incompletesb.Append(currentItem.LocalPath);
                            }
                            incompleteFolder = incompletesb.ToString();
                            incompletesb.Append("\\");
                            incompletesb.Append(currentItem.FileName);
                            incompletePath = incompletesb.ToString();


                            FileStream fileStream = null;

                            //Check to see if the file already exists.
                            if (File.Exists(mainPath))
                            {
                                //File exists in the download directory.
                                fileStream = File.Open(mainPath, FileMode.Open, FileAccess.Write, FileShare.None);
                                incompletePath = mainPath;
                            }
                            else
                            {
                                if (!Directory.Exists(incompleteFolder))
                                    Directory.CreateDirectory(incompleteFolder);

                                //Else resume or just create
                                fileStream = File.Open(incompletePath, FileMode.OpenOrCreate, FileAccess.Write,
                                                       FileShare.None);
                            }

                            var req =
                                (HttpWebRequest)
                                WebRequest.Create(Multiplexor.Encode(getDownloadUrl(), "GET", currentItem.FullPath));
                            req.UserAgent = Model.AppVersion;
                            req.Headers.Add("FAP-SOURCE", model.LocalNode.ID);

                            // req.Timeout = 300000;
                            // req.ReadWriteTimeout = 3000000;
                            //If we are resuming then add range
                            long resumePoint = 0;
                            if (fileStream.Length != 0)
                            {
                                //Yes Micrsoft if you read this...  OH WHY IS ADDRANGE ONLY AN INT?? We live in an age where we might actually download more than 2gb
                                //req.AddRange(fileStream.Length);

                                //Hack
                                MethodInfo method = typeof (WebHeaderCollection).GetMethod("AddWithoutValidate",
                                                                                           BindingFlags.Instance |
                                                                                           BindingFlags.NonPublic);
                                string key = "Range";
                                string val = string.Format("bytes={0}", fileStream.Length);
                                method.Invoke(req.Headers, new object[] {key, val});
                                position = fileStream.Length;
                                resumePoint = fileStream.Length;
                                //Seek to the end of the file
                                fileStream.Seek(fileStream.Length, SeekOrigin.Begin);
                            }

                            var resp = (HttpWebResponse) req.GetResponse();

                            if (resp.StatusCode == HttpStatusCode.OK)
                            {
                                using (Stream responseStream = resp.GetResponseStream())
                                {
                                    var tokenizer = new StreamTokenizer(Encoding.ASCII, "|");
                                    var utilisedBuffers = new List<MemoryBuffer>();
                                    try
                                    {
                                        bool streamIncomplete = true;

                                        while (streamIncomplete)
                                        {
                                            MemoryBuffer tokenBuffer = bufferService.GetSmallBuffer();
                                            //utilisedBuffers.Add(tokenBuffer);
                                            //Receive data
                                            tokenBuffer.SetDataLocation(0,
                                                                        responseStream.Read(tokenBuffer.Data, 0,
                                                                                            tokenBuffer.DataSize));
                                            tokenizer.ReceiveData(tokenBuffer);

                                            if (tokenizer.ContainsCommand())
                                            {
                                                string data = tokenizer.GetCommand();
                                                int queuePosition = int.Parse(data);

                                                if (queuePosition == 0)
                                                {
                                                    if (tokenizer.Buffers.Count > 0)
                                                    {
                                                        LogManager.GetLogger("faplog").Warn(
                                                            "Queue info overlaps with file data.  File: {0}",
                                                            currentItem.FileName);
                                                        //Due to the way chunks are delivered we should never get here
                                                        //Just incase write left over data
                                                        foreach (MemoryBuffer buff in tokenizer.Buffers)
                                                            fileStream.Write(buff.Data, 0, buff.DataSize);
                                                    }

                                                    status = currentItem.Nickname + " - " + currentItem.FileName + " - " +
                                                             Utility.FormatBytes(currentItem.Size);

                                                    DateTime start = DateTime.Now;

                                                    while (true)
                                                    {
                                                        //Receive file
                                                        int read = responseStream.Read(buffer.Data, 0,
                                                                                       buffer.Data.Length);
                                                        if (read == 0)
                                                        {
                                                            streamIncomplete = false;
                                                            break;
                                                        }
                                                        else
                                                        {
                                                            fileStream.Write(buffer.Data, 0, read);
                                                            position += read;
                                                            netSpeed.PutData(read);
                                                        }
                                                    }

                                                    //Add log of transfer
                                                    double seconds = (DateTime.Now - start).TotalSeconds;
                                                    var rxlog = new TransferLog();
                                                    rxlog.Added = currentItem.Added;
                                                    rxlog.Completed = DateTime.Now;
                                                    rxlog.Filename = currentItem.FileName;
                                                    rxlog.Nickname = currentItem.Nickname;
                                                    rxlog.Path = currentItem.FolderPath;
                                                    rxlog.Size = currentItem.Size - resumePoint;
                                                    if (0 != seconds)
                                                        rxlog.Speed = (int) (rxlog.Size/seconds);
                                                    model.CompletedDownloads.Add(rxlog);
                                                }
                                                else
                                                {
                                                    //Queued
                                                    status = currentItem.Nickname + " - " + currentItem.FileName +
                                                             " - Queue position " + queuePosition;
                                                }
                                            }
                                        }
                                    }
                                    finally
                                    {
                                        foreach (MemoryBuffer buff in utilisedBuffers)
                                            bufferService.FreeBuffer(buff);
                                        tokenizer.Dispose();
                                    }
                                }
                            }

                            resp.Close();
                            model.DownloadQueue.List.Remove(currentItem);
                            currentItem.State = DownloadRequestState.Downloaded;
                            fileStream.Close();
                            fileStream.Dispose();
                            //Move from the incomplete folder.
                            if (mainPath != incompletePath)
                            {
                                if (!Directory.Exists(mainFolder))
                                    Directory.CreateDirectory(mainFolder);
                                File.Move(incompletePath, mainPath);
                            }
                            status = currentItem.Nickname + " - Complete: " + currentItem.FileName;
                            resp.Close();
                        }
                        catch
                        {
                            currentItem.State = DownloadRequestState.Error;
                            currentItem.NextTryTime = Environment.TickCount + Model.DOWNLOAD_RETRY_TIME;
                        }
                        finally
                        {
                            bufferService.FreeBuffer(buffer);
                        }
                    }
                }
            }
            catch
            {
                //Something went very wrong.  Clear the queue and die.
                lock (sync)
                {
                    isComplete = true;
                    foreach (DownloadRequest v in queue)
                        v.State = DownloadRequestState.None;
                    queue.Clear();
                }
            }
        }
예제 #3
0
        private void RunAsync(object o)
        {
            var param = o as AsyncSearchParam;
            if (null != param && null != param.Node)
            {
                var client = new Client(model.LocalNode);
                var verb = new SearchVerb(null);
                verb.SearchString = viewModel.SearchString;

                switch (viewModel.SizeSearchType)
                {
                    case "Any Size":
                        break;
                    case "Less than":
                        verb.SmallerThan = GetSearchSize();
                        break;
                    case "Greater than":
                        verb.LargerThan = GetSearchSize();
                        break;
                }

                switch (viewModel.ModifiedSearchType)
                {
                    case "Any":
                        break;
                    case "Before":
                        verb.ModifiedBefore = (DateTime) viewModel.ModifiedDate;
                        break;
                    case "After":
                        verb.ModifiedAfter = (DateTime) viewModel.ModifiedDate;
                        break;
                }

                if (client.Execute(verb, param.Node))
                {
                    if (null != verb.Results)
                    {
                        //Set name
                        foreach (SearchResult result in verb.Results)
                        {
                            result.User = param.Node.Nickname;
                            result.ClientID = param.Node.ID;
                        }
                        param.Results.AddRange(verb.Results);
                    }
                }
            }
            lock (sync)
            {
                //If we still on the same search then update the UI.
                if (param.Results == currentResults)
                {
                    outstandingrequests--;
                    if (outstandingrequests < 1)
                    {
                        viewModel.UpperStatusMessage = "Search complete in " + (Environment.TickCount - startTime) +
                                                       " ms";
                        viewModel.LowerStatusMessage = currentResults.Count + " results.";
                    }
                    else
                    {
                        viewModel.LowerStatusMessage = outstandingrequests + " peers remaining..";
                    }
                }
            }
        }
예제 #4
0
        private void RunAsync(object o)
        {
            lock (sync)
            {
                requests++;
            }

            var node = o as Node;
            if (null != node)
            {
                var client = new Client(model.LocalNode);
                var verb = new CompareVerb(model);

                if (client.Execute(verb, node))
                {
                    if (!verb.Allowed)
                    {
                        verb.Node.Nickname = node.Nickname;
                        verb.Node.Location = node.Location;
                        verb.Node.Status = "Denied";
                        data.Add(verb.Node);
                    }
                    else
                    {
                        verb.Node.Nickname = node.Nickname;
                        verb.Node.Location = node.Location;
                        verb.Node.Status = "OK";
                        data.Add(verb.Node);
                    }
                }
                else
                {
                    verb.Node = new CompareNode();
                    verb.Node.Nickname = node.Nickname;
                    verb.Node.Location = node.Location;
                    verb.Node.Status = "Error";
                    data.Add(verb.Node);
                }
            }

            lock (sync)
            {
                requests--;
                viewModel.Status = "Status: Waiting for a response from " + requests + " peers..";
                if (requests == 0)
                {
                    viewModel.EnableRun = true;
                    viewModel.Status =
                        "Status: All Information recieved, click start to refresh info (Note clients will cache information for 5 minutes).";
                }
            }
        }
예제 #5
0
 /// <summary>
 /// Whilst connected to a network 
 /// </summary>
 public void CheckModelChanges()
 {
     if (model.Network.State == ConnectionState.Connected)
     {
         UpdateVerb verb = null;
         lock (sync)
         {
             var data = new Dictionary<string, string>();
             foreach (var entry in model.LocalNode.Data)
             {
                 if (transmitted.IsKeySet(entry.Key))
                 {
                     if (transmitted.GetData(entry.Key) != entry.Value)
                     {
                         data.Add(entry.Key, entry.Value);
                     }
                 }
                 else
                 {
                     data.Add(entry.Key, entry.Value);
                 }
             }
             //Data has changed, transmit the changes.
             if (data.Count > 0)
             {
                 verb = new UpdateVerb();
                 var n = new Node();
                 n.ID = model.LocalNode.ID;
                 foreach (var change in data)
                 {
                     n.SetData(change.Key, change.Value);
                     transmitted.SetData(change.Key, change.Value);
                 }
                 verb.Nodes.Add(n);
             }
         }
         if (null != verb)
         {
             var c = new Client(model.LocalNode);
             if (!c.Execute(verb, model.Network.Overlord))
                 model.Network.State = ConnectionState.Disconnected;
         }
     }
 }
예제 #6
0
파일: Uplink.cs 프로젝트: Kayomani/FAP
        private void Process(object o)
        {
            try
            {
                while (running)
                {
                    while (pendingRequests.Count > 0)
                    {
                        NetworkRequest req = pendingRequests[0];
                        pendingRequests.RemoveAt(0);

                        destination.LastUpdate = Environment.TickCount;
                        var c = new Client(source);
                        if (!c.Execute(req, destination))
                        {
                            //Error
                            running = false;
                            return;
                        }
                    }

                    //Check for client time out
                    if ((Environment.TickCount - destination.LastUpdate) > Model.UPLINK_TIMEOUT)
                    {
                        //We havent recently sent/recieved so went a noop so check we are still connected.
                        var req = new NetworkRequest {Verb = "NOOP", SourceID = source.ID, AuthKey = destination.Secret};
                        var client = new Client(source);
                        if (!client.Execute(req, destination, 4000))
                        {
                            //Error
                            running = false;
                            return;
                        }
                    }

                    //Wait until there is work to do or 5 seconds have elapsed
                    workerEvent.WaitOne(5000);
                }
            }
            catch
            {
            }
            finally
            {
                if (null != OnDisconnect)
                    OnDisconnect(this);
            }
        }
예제 #7
0
        private void ProcessLanConnection(object o)
        {
            mserver.SendMessage(WhoVerb.CreateRequest());
            Domain.Entities.Network network = model.Network;
            network.PropertyChanged += network_PropertyChanged;
            while (run)
            {
                if (network.State != ConnectionState.Connected)
                {
                    //Not connected so connect automatically..

                    //Regenerate local secret to stop any updates if we reconnecting..
                    network.Overlord = new Node();
                    network.Overlord.Secret = IDService.CreateID();
                    //Clear old peers
                    network.Nodes.Clear();

                    //Build up a prioritised server list
                    var availibleNodes = new List<DetectedNode>();

                    List<DetectedNode> detectedPeers = peerFinder.Peers.ToList();

                    //Prioritise a server we havent connected to already
                    foreach (DetectedNode peer in detectedPeers)
                    {
                        if (attemptedPeers.Where(s => s.Node == peer).Count() == 0)
                            availibleNodes.Add(peer);
                    }
                    foreach (LanPeer peer in attemptedPeers.OrderByDescending(x => x.LastConnectionTime))
                    {
                        availibleNodes.Add(peer.Node);
                    }

                    while (network.State != ConnectionState.Connected && availibleNodes.Count > 0)
                    {
                        DetectedNode node = availibleNodes[0];
                        availibleNodes.RemoveAt(0);
                        if (!Connect(network, node))
                            peerFinder.RemovePeer(node);
                    }
                }
                if (network.State == ConnectionState.Connected)
                {
                    CheckModelChanges();
                    //Check for network timeout

                    if ((Environment.TickCount - model.Network.Overlord.LastUpdate) > Model.UPLINK_TIMEOUT)
                    {
                        //We havent recently sent/recieved so went a noop so check we are still connected.
                        var req = new NetworkRequest
                                      {
                                          Verb = "NOOP",
                                          SourceID = model.LocalNode.ID,
                                          AuthKey = model.Network.Overlord.Secret
                                      };
                        var client = new Client(model.LocalNode);
                        if (!client.Execute(req, model.Network.Overlord, 4000))
                        {
                            if (network.State == ConnectionState.Connected)
                            {
                                Disconnect();
                            }
                        }
                    }

                    workerEvent.WaitOne(10000);
                }
                else
                    workerEvent.WaitOne(100);
            }
        }
예제 #8
0
 private void item_Expanded_Async(object input)
 {
     var req = input as ExpandRequest;
     var c = new Client(model.LocalNode);
     var cmd = new BrowseVerb(shareInfo);
     cmd.Path = req.Path.FullPath;
     cmd.NoCache = bvm.NoCache;
     if (c.Execute(cmd, client))
     {
         /*  SafeObservableStatic.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
           delegate()
           {
               bvm.Status = "Download complete (" + cmd.Results.Count + " items).";
             bvm.CurrentDirectory.Clear();
               foreach (var result in cmd.Results)
               {
                   if (result.IsFolder)
                   {
                       TreeViewItem x = new TreeViewItem();
                       x.Items.Add(_dummyNode);
                       x.Expanded += new System.Windows.RoutedEventHandler(item_Expanded);
                       x.Selected += new System.Windows.RoutedEventHandler(item_Selected);
                       x.Header = result.Name;
                       x.Tag = result;
                       req.Item.Items.Add(x);
                   }
                   bvm.CurrentDirectory.Add(result);
               }
           }
          ));*/
     }
 }
예제 #9
0
        public void Disconnect()
        {
            //Notify log off
            if (model.Network.State == ConnectionState.Connected)
            {
                var c = new Client(model.LocalNode);
                var verb = new UpdateVerb();
                verb.Nodes.Add(new Node {ID = model.LocalNode.ID, Online = false});
                c.Execute(verb, model.Network.Overlord, 3000);

                //Remove peer so we dont reconnect straight away most likely
                DetectedNode peer =
                    peerFinder.Peers.Where(p => p.Address == model.Network.Overlord.Location).FirstOrDefault();
                if (null != peer)
                    peerFinder.RemovePeer(peer);
                model.Network.State = ConnectionState.Disconnected;
            }
        }
예제 #10
0
        private bool Connect(Domain.Entities.Network net, DetectedNode n)
        {
            try
            {
                LogManager.GetLogger("faplog").Info("Client connecting to {0}", n.Address);
                net.State = ConnectionState.Connecting;

                var verb = new ConnectVerb();
                verb.ClientType = ClientType.Client;
                verb.Address = model.LocalNode.Location;
                verb.Secret = IDService.CreateID();
                var client = new Client(model.LocalNode);

                transmitted.Data.Clear();
                foreach (var info in model.LocalNode.Data.ToList())
                    transmitted.SetData(info.Key, info.Value);

                net.Overlord = new Node();
                net.Overlord.Location = n.Address;
                net.Overlord.Secret = verb.Secret;
                LogManager.GetLogger("faplog").Debug("Client using secret {0}", verb.Secret);
                if (client.Execute(verb, n.Address))
                {
                    net.State = ConnectionState.Connected;
                    net.Overlord.ID = verb.OverlordID;
                    LogManager.GetLogger("faplog").Info("Client connected");
                    return true;
                }
                else
                {
                    net.Overlord = new Node();
                }
            }
            catch
            {
                net.State = ConnectionState.Disconnected;
            }
            return false;
        }
예제 #11
0
 private void TransmitRequest(NetworkRequest req)
 {
     var client = new Client(serverNode);
     req.AuthKey = destination.Secret;
     if (!client.Execute(req, destination))
         throw new Exception("Transmission failiure");
     destination.LastUpdate = Environment.TickCount;
 }
예제 #12
0
        private bool HandleConnect(NetworkRequest r, RequestEventArgs e)
        {
            string address = string.Empty;

            try
            {
                var iv = new ConnectVerb();
                iv.ProcessRequest(r);
                address = iv.Address;

                if (string.IsNullOrEmpty(iv.Secret))
                {
                    //Dont allow connections with no secret
                    return false;
                }

                //Dont allow connections to ourselves..
                if (iv.Address == serverNode.Location)
                    return false;

                //Only allow one connect attempt at once
                lock (sync)
                {
                    if (connectingIDs.Contains(address))
                        return false;
                    connectingIDs.Add(address);
                }

                //Connect to the remote client 
                var verb = new InfoVerb();
                var client = new Client(serverNode);

                if (!client.Execute(verb, address))
                    return false;
                //Connected ok
                var c = new ClientStream();
                c.OnDisconnect += c_OnDisconnect;
                Node n = verb.GetValidatedNode();
                if (null == n)
                    return false;
                n.Location = iv.Address;
                n.Online = true;
                n.NodeType = iv.ClientType;
                n.OverlordID = serverNode.ID;
                n.Secret = iv.Secret;

                lock (sync)
                {
                    //Notify other clients
                    var update = new UpdateVerb();

                    //Was this person already connected?
                    ClientStream search = connectedClientNodes.Where(xn => xn.Node.ID == n.ID).FirstOrDefault();
                    if (null != search)
                    {
                        connectedClientNodes.Remove(search);
                        search.Kill();
                    }
                    c.Start(n, serverNode);
                    connectedClientNodes.Add(c);
                    update.Nodes.Add(n);
                    NetworkRequest req = update.CreateRequest();
                    req.SourceID = serverNode.ID;
                    req.OverlordID = serverNode.ID;
                    req.AuthKey = iv.Secret;

                    SendToStandardClients(req);
                    //Dont send overlord logs to other overlords
                    if (n.NodeType != ClientType.Overlord)
                        SendToOverlordClients(req);
                }
                //Find client servers
                ThreadPool.QueueUserWorkItem(ScanClientAsync, n);
                //return ok

                //Add headers
                var headers = e.Response.Headers as HeaderCollection;
                if (null != headers)
                {
                    headers.Add("FAP-AUTH", iv.Secret);
                    headers.Add("FAP-SOURCE", serverNode.ID);
                    headers.Add("FAP-OVERLORD", serverNode.ID);
                }

                SendResponse(e, null);

                //Send network info
                if (n.NodeType == ClientType.Overlord)
                {
                    var update = new UpdateVerb();
                    //Only send local nodes
                    foreach (
                        ClientStream peer in
                            connectedClientNodes.ToList().Where(x => x.Node.NodeType == ClientType.Client))
                        update.Nodes.Add(peer.Node);
                    NetworkRequest req = update.CreateRequest();
                    req.SourceID = serverNode.ID;
                    req.OverlordID = serverNode.ID;
                    req.AuthKey = iv.Secret;
                    c.AddMessage(req);
                }
                else
                {
                    var update = new UpdateVerb();
                    //None overlord client.  Send local nodes and external ones.
                    update.Nodes = GetBestKnownClientList();

                    NetworkRequest req = update.CreateRequest();
                    req.SourceID = serverNode.ID;
                    req.OverlordID = serverNode.ID;
                    req.AuthKey = iv.Secret;
                    c.AddMessage(req);
                }
                return true;
            }
            catch
            {
            }
            finally
            {
                connectingIDs.Remove(address);
            }
            SendError(e);
            return false;
        }
예제 #13
0
        private void ProcessLanConnections(object no)
        {
            while (run)
            {
                List<DetectedNode> localNodes = peerFinder.Peers.ToList();

                foreach (DetectedNode peer in localNodes)
                {
                    if (peer.Address == serverNode.Location)
                        continue;

                    //If not already connected to that peer then connect
                    if (extOverlordServers.ToList().Where(o => o.Destination.Location == peer.Address).Count() == 0)
                    {
                        logger.Debug("Server connecting as client to external overlord at {0}", peer.Address);
                        var verb = new ConnectVerb();
                        verb.Address = serverNode.Location;
                        verb.ClientType = ClientType.Overlord;
                        verb.Secret = IDService.CreateID();

                        var uplink = new Uplink(model.LocalNode,
                                                new Node
                                                    {
                                                        ID = peer.OverlordID,
                                                        Location = peer.Address,
                                                        NodeType = ClientType.Overlord,
                                                        Secret = verb.Secret
                                                    });
                        extOverlordServers.Add(uplink);


                        var client = new Client(serverNode);
                        if (client.Execute(verb, peer.Address, 5000))
                        {
                            //Connected as client on an external overlord

                            uplink.OnDisconnect += uplink_OnDisconnect;

                            uplink.Start();
                            logger.Debug("Server connected to client to external overlord at {0}", peer.Address);
                            break;
                        }
                        else
                        {
                            //Failed to connect ot the external overlord
                            logger.Debug("Server failed to connect to external overlord at {0}", peer.Address);
                            peerFinder.RemovePeer(peer);
                            extOverlordServers.Remove(uplink);
                        }
                    }
                }
                Thread.Sleep(3000);
            }
        }
예제 #14
0
        private void SendMessageAsync(object ivm)
        {
            var vm = ivm as ConversationViewModel;
            if (null != vm && !string.IsNullOrEmpty(vm.CurrentChatMessage))
            {
                string message = vm.CurrentChatMessage;

                var c = new Client(model.LocalNode);
                var verb = new ConversationVerb();
                verb.Nickname = model.LocalNode.Nickname;
                verb.Message = message;
                verb.SourceID = model.LocalNode.ID;
                vm.CurrentChatMessage = string.Empty;

                if (!c.Execute(verb, vm.Conversation.OtherParty))
                    vm.Conversation.Messages.Add("The other party failed to receive your message, please try again.");
            }
        }
예제 #15
0
 private void SendMessageAsync(object o)
 {
     try
     {
         if (model.Network.State == ConnectionState.Connected)
         {
             var client = new Client(model.LocalNode);
             if (!client.Execute((NetworkRequest) o, model.Network.Overlord))
             {
                 if (model.Network.State == ConnectionState.Connected)
                     model.Network.State = ConnectionState.Disconnected;
             }
         }
         else
         {
             LogManager.GetLogger("faplog").Warn("Could not send message as you are not conencted");
         }
     }
     catch (Exception e)
     {
         LogManager.GetLogger("faplog").ErrorException("Failed to send chat message", e);
     }
 }
예제 #16
0
파일: Model.cs 프로젝트: Kayomani/FAP
        /// <summary>
        /// Create a new download queue item based on a url.  Takes URLs in the format fap://NodeID/path/to/file
        /// </summary>
        /// <param name="url"></param>
        public void AddDownloadURL(string url)
        {
            string parentDir = Utility.DecodeURL(url);
            //Strip protocol
            if (parentDir.StartsWith("fap://", StringComparison.InvariantCultureIgnoreCase))
                parentDir = parentDir.Substring(6);


            int index = parentDir.LastIndexOf('/');
            if (index == -1)
            {
                LogManager.GetLogger("faplog").Error("Unable to add download as an invalid url as passed!");
            }
            else
            {
                string fileName = parentDir.Substring(index + 1);
                parentDir = parentDir.Substring(0, index);

                string nodeId = parentDir.Substring(0, parentDir.IndexOf('/'));
                parentDir = parentDir.Substring(nodeId.Length + 1);
                Node node = network.Nodes.Where(n => n.ID == nodeId).FirstOrDefault();

                if (null == node)
                {
                    //Node not found
                    LogManager.GetLogger("faplog").Error("Unable to add download as node {0} was not found!", nodeId);
                }
                else
                {
                    //Node found - browse to get info
                    var verb = new BrowseVerb(null);
                    verb.NoCache = false;
                    verb.Path = parentDir;

                    var client = new Client(LocalNode);

                    if (client.Execute(verb, node))
                    {
                        BrowsingFile remoteFile = verb.Results.Where(f => f.Name == fileName).FirstOrDefault();
                        if (null != remoteFile)
                        {
                            downloadQueue.List.Add(new DownloadRequest
                                                       {
                                                           Added = DateTime.Now,
                                                           FullPath = parentDir + "/" + remoteFile.Name,
                                                           IsFolder = remoteFile.IsFolder,
                                                           Size = remoteFile.Size,
                                                           LocalPath = null,
                                                           State = DownloadRequestState.None,
                                                           ClientID = node.ID,
                                                           Nickname = node.Nickname
                                                       });
                        }
                        else
                        {
                            LogManager.GetLogger("faplog").Error(
                                "Unable to add download as {0} was not found on the remote server!", fileName);
                        }
                    }
                    else
                    {
                        LogManager.GetLogger("faplog").Error("Unable to add download as node {0} was not accessible!",
                                                             nodeId);
                    }
                }
            }
        }
예제 #17
0
        private void PopulateAsync(object o)
        {
            var fse = o as BrowsingFile;
            if (null != fse)
            {
                var c = new Client(model.LocalNode);
                var cmd = new BrowseVerb(shareInfo);
                cmd.Path = fse.FullPath;
                cmd.NoCache = bvm.NoCache;
                if (c.Execute(cmd, client))
                {
                    SafeObservableStatic.Dispatcher.Invoke(DispatcherPriority.Normal,
                                                           new Action(
                                                               delegate
                                                                   {
                                                                       bvm.Status = "Download complete (" +
                                                                                    cmd.Results.Count + ").";
                                                                       fse.IsPopulated = true;
                                                                       fse.ClearItems();

                                                                       foreach (BrowsingFile result in cmd.Results)
                                                                       {
                                                                           result.Path = fse.FullPath;
                                                                           fse.AddItem(result);
                                                                       }
                                                                       bvm.CurrentItem = fse;
                                                                       bvm.IsBusy = false;
                                                                   }
                                                               ));
                }
            }
            else
            {
                var c = new Client(model.LocalNode);
                var cmd = new BrowseVerb(shareInfo);
                cmd.NoCache = bvm.NoCache;

                if (c.Execute(cmd, client))
                {
                    SafeObservableStatic.Dispatcher.Invoke(DispatcherPriority.Normal,
                                                           new Action(
                                                               delegate
                                                                   {
                                                                       bvm.Status = "Download complete (" +
                                                                                    cmd.Results.Count + ").";
                                                                       var ent = new BrowsingFile();
                                                                       foreach (BrowsingFile result in cmd.Results)
                                                                       {
                                                                           bvm.Root.Add(result);
                                                                           ent.AddItem(result);
                                                                       }
                                                                       ent.IsPopulated = true;
                                                                       bvm.CurrentItem = ent;
                                                                       bvm.IsBusy = false;
                                                                   }
                                                               ));
                }
            }
        }