示例#1
0
        private void handleHelloMessage(HelloMessage msg, IPAddress sender)
        {
            // see if the peers list contains a SyncPeer with the same hostname
            SyncPeer found = _peers.Find((peer) => { return(peer.Hostname == msg.hostname); });

            if (found != null)
            { // we know about this peer, update its last seen time
                found.LastResponded = DateTime.Now;
            }
            else
            { // we don't know about this peer, add it
                SyncPeer newPeer = new SyncPeer();
                newPeer.Port          = msg.listenPort;
                newPeer.Hostname      = msg.hostname;
                newPeer.Address       = sender;
                newPeer.LastResponded = DateTime.Now;
                _peers.Add(newPeer);
                Debug.WriteLine("Added new peer " + msg.hostname);

                SyncPeerUpdatedEventHandler handler = OnSyncPeerUpdated;
                if (handler != null)
                {
                    handler(this, new SyncPeerUpdatedEventArgs(found, SyncPeerUpdatedAction.Added));
                }

                // send our hello message quickly (so the peer doesn't have to wait ~5 seconds to get our next hello)
                _udpAgent.HurrySendHello();

                // request the peer's applist
                Debug.WriteLine("Sending RequestAppList to " + sender.ToString());
                RequestAppListMessage sendMsg = new RequestAppListMessage();
                _tcpAgent.SendMessage(sendMsg, sender);
            }
        }
示例#2
0
        private void handleGoodbyeMessage(GoodbyeMessage msg, IPAddress sender)
        {
            // see if we know about this peer
            SyncPeer _found = _peers.Find((peer) => { return(peer.Address.Equals(sender)); });

            // if so, remove from our peer list
            if (_found != null)
            {
                removePeer(_found);
            }
        }
示例#3
0
        private void handleAppListMessage(AppListMessage msg, IPAddress sender)
        {
            SyncPeer found = _peers.Find((peer) => { return(peer.Address.Equals(sender)); });

            if (found == null)
            {
                Debug.WriteLine("Received AppList from unknown peer " + sender.ToString());
            }

            found.Apps = msg.availableApps;
            updateAvailableApps();
            Debug.WriteLine(String.Format("{0} has {1} available apps", found.Hostname, found.Apps.Count));
            SyncPeerUpdatedEventHandler handler = OnSyncPeerUpdated;

            if (handler != null)
            {
                handler(this, new SyncPeerUpdatedEventArgs(found, SyncPeerUpdatedAction.Updated));
            }
        }
示例#4
0
        private void removePeer(SyncPeer peer)
        {
            // remove the peers

            Debug.WriteLine("Removing " + peer.Hostname + " from peers list");
            if (_peers.Contains(peer))
            {
                _peers.Remove(peer);
            }

            // update list of available apps (i.e. remove any that are no longer available)
            updateAvailableApps();

            // notify listeners that the peers have been removed (need to do this after available apps has been updated)
            SyncPeerUpdatedEventHandler handler = OnSyncPeerUpdated;

            if (handler != null)
            {
                handler(this, new SyncPeerUpdatedEventArgs(peer, SyncPeerUpdatedAction.Removed));
            }
        }
示例#5
0
        public void RequestApp(AppInfo app)
        {
            if (app == null)
            {
                throw new ArgumentNullException("Cannot request null app");
            }

            if (app.InstallDir.Length == 0 || app.InstallDir.Contains(Path.DirectorySeparatorChar) || app.InstallDir.Contains(Path.AltDirectorySeparatorChar))
            {
                throw new ArgumentOutOfRangeException("Cannot request app with invalid install dir [" + app.InstallDir + "]");
            }

            // determine who has a copy of the app
            SyncPeer whoHasIt = null;

            foreach (SyncPeer peer in _peers)
            {
                if (peer.Apps.Contains(app))
                {
                    whoHasIt = peer;
                    break;
                }
            }

            if (whoHasIt == null)
            {
                throw new AppNotAvailableException();
            }

            // determine install dir
            string manifestRoot = Library.Path;

            Utility.EnsureEndsWithSlash(ref manifestRoot);
            manifestRoot += AppManifest.STEAM_COMMON_DIR + app.InstallDir;
            Utility.EnsureEndsWithSlash(ref manifestRoot);
            DirectoryInfo diManifest    = new DirectoryInfo(manifestRoot);
            AppManifest   existingFiles = null;

            if (!diManifest.Exists)
            {
                diManifest.Create();
            }
            else
            {
                // determine which files we already have for this app,
                // and send that as part of the request message
                // todo - build manifest async
                existingFiles = AppManifest.FromDirectory(diManifest.FullName, true);
            }

            // create a transfer
            TransferInfo transfer = new TransferInfo(); // generates a transferid

            transfer.IsSending    = false;
            transfer.Peer         = whoHasIt;
            transfer.App          = app;
            transfer.Port         = Properties.Settings.Default.ListenPort;
            transfer.ManifestRoot = diManifest;

            if (getReceiveTransfersInProgress() == 0)
            { // start immediately if we're not receiving anything else
                Debug.WriteLine("Starting transfer agent to receive " + transfer.App.Name);
                startReceiveApp(transfer, existingFiles);
            }
            else
            { // otherwise add to the queue
                Debug.WriteLine("Queuing transfer of " + transfer.App.Name);
                TransferQueue.Enqueue(transfer);
            }
        }
示例#6
0
 public SyncPeerUpdatedEventArgs(SyncPeer peer, SyncPeerUpdatedAction action)
 {
     Peer   = peer;
     Action = action;
 }
示例#7
0
        private void handleRequestAppTransferMessage(RequestAppTransferMessage msg, IPAddress sender)
        {
            // see if we have the app
            AppInfo theApp = Library.Apps[msg.appId];

            if (theApp == null)
            {
                Debug.WriteLine(String.Format("{1} requested AppId {0} but I don't have it", msg.appId, sender.ToString()));
                return;
            }

            // find the peer
            SyncPeer peer = _peers.Find((aPeer) => { return(aPeer.Address.Equals(sender)); });

            Debug.WriteLine(String.Format("I will transfer {0} to {1}", msg.appId, peer.Hostname));

            bool isUpdateRequest = msg.existingFiles != null;

            // build manifest
            AppManifest manifest = AppManifest.FromAppInfo(theApp, Library, isUpdateRequest); // todo - async/threaded

            // if peer provided a list of existing files, check our own
            if (isUpdateRequest)
            {
                manifest.RemoveMatchingFiles(msg.existingFiles);
            }

            // verify manifest is valid
            if (manifest == null)
            {
                Debug.WriteLine("Could not build manifest for AppId [" + msg.appId + "], aborting.");
                CancelAppTransferMessage cancelMsg = new CancelAppTransferMessage();
                cancelMsg.transferId = msg.transferId;
                cancelMsg.reason     = "Unable to build manifest";
                _tcpAgent.SendMessage(cancelMsg, sender);
                return;
            }

            // send "start transfer" message with manifest
            StartAppTransferMessage newMsg = new StartAppTransferMessage();

            newMsg.manifest   = manifest;
            newMsg.transferId = msg.transferId;

            _tcpAgent.SendMessage(newMsg, sender);

            // create transfer
            TransferInfo transfer = new TransferInfo(newMsg.transferId);

            transfer.Manifest  = newMsg.manifest;
            transfer.App       = theApp;
            transfer.IsSending = true;
            transfer.Peer      = peer;
            transfer.Port      = msg.listenPort;

            // determine install dir and write
            string manifestRoot = Library.Path;

            Utility.EnsureEndsWithSlash(ref manifestRoot);
            manifestRoot += AppManifest.STEAM_COMMON_DIR + theApp.InstallDir; // todo ensure no path chars in installdir
            Utility.EnsureEndsWithSlash(ref manifestRoot);
            DirectoryInfo diManifest = new DirectoryInfo(manifestRoot);

            if (!diManifest.Exists)
            {
                diManifest.Create();
            }
            transfer.ManifestRoot = diManifest;

            // subscribe to state change notifications (so we can update our status message)
            subscribeTransferEvents(transfer);

            // create agent to send the files
            TransferAgent agent = new TransferAgent();

            agent.StartSend(transfer);

            // fire event to notify listeners a transfer was created
            TransferCreatedEventHandler handler = OnTransferCreated;

            if (handler != null)
            {
                handler(this, new TransferEventArgs(transfer));
            }
        }