public async Task<byte[]> SaveStateAsync () { await MainLoop; var state = new BEncodedDictionary { {nameof (Settings), Serializer.Serialize (Settings) }, }; state[nameof (Torrents)] = new BEncodedList (Torrents.Select (t => { var dict = new BEncodedDictionary { { nameof (t.MagnetLink), (BEncodedString) t.MagnetLink.ToV1String () }, { nameof(t.SavePath), (BEncodedString) t.SavePath }, { nameof(t.Settings), Serializer.Serialize (t.Settings) }, { "Streaming", (BEncodedString) (t.StreamProvider != null).ToString ()}, }; if (t.HasMetadata) { dict[nameof (t.Files)] = new BEncodedList (t.Files.Select (file => new BEncodedDictionary { { nameof(file.FullPath), (BEncodedString) file.FullPath }, { nameof(file.Path), (BEncodedString) file.Path }, { nameof(file.Priority), (BEncodedString) file.Priority.ToString () }, } )); dict[nameof (t.MetadataPath)] = (BEncodedString) t.MetadataPath; } else { } return dict; })); foreach (var v in Torrents) await v.MaybeWriteFastResumeAsync (); return state.Encode (); }
async Task UpdateSettingsAsync(EngineSettings oldSettings, EngineSettings newSettings) { await DiskManager.UpdateSettingsAsync(newSettings); if (newSettings.DiskCacheBytes != oldSettings.DiskCacheBytes) { await Task.WhenAll(Torrents.Select(t => DiskManager.FlushAsync(t))); } ConnectionManager.Settings = newSettings; if (oldSettings.AllowPortForwarding != newSettings.AllowPortForwarding) { if (newSettings.AllowPortForwarding) { await PortForwarder.StartAsync(CancellationToken.None); } else { await PortForwarder.StopAsync(removeExistingMappings : true, CancellationToken.None); } } if (oldSettings.DhtPort != newSettings.DhtPort) { if (DhtListener.EndPoint != null) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Udp, DhtListener.EndPoint.Port), CancellationToken.None); } else if (oldSettings.DhtPort > 0) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Udp, oldSettings.DhtPort), CancellationToken.None); } DhtListener = DhtListenerFactory.CreateUdp(newSettings.DhtPort); if (oldSettings.DhtPort == -1) { await RegisterDht(DhtEngineFactory.Create(DhtListener)); } else if (newSettings.DhtPort == -1) { await RegisterDht(new NullDhtEngine()); } DhtEngine.SetListener(DhtListener); if (IsRunning) { DhtListener.Start(); if (Listener is ISocketListener newDhtListener) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Udp, newDhtListener.EndPoint.Port)); } else { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Udp, newSettings.DhtPort)); } } } if (oldSettings.ListenPort != newSettings.ListenPort) { if (Listener is ISocketListener oldListener) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Tcp, oldListener.EndPoint.Port), CancellationToken.None); } else if (oldSettings.ListenPort > 0) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Tcp, oldSettings.ListenPort), CancellationToken.None); } Listener.Stop(); Listener = PeerListenerFactory.CreateTcp(newSettings.ListenPort); listenManager.SetListener(Listener); if (IsRunning) { Listener.Start(); // The settings could say to listen at port 0, which means 'choose one dynamically' if (Listener is ISocketListener peerListener) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Tcp, peerListener.EndPoint.Port)); } else { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Tcp, newSettings.ListenPort)); } } } // This depends on the Listener binding to it's local port. var localPort = newSettings.ListenPort; if (Listener is ISocketListener newListener) { localPort = newListener.EndPoint.Port; } if ((oldSettings.AllowLocalPeerDiscovery != newSettings.AllowLocalPeerDiscovery) || (oldSettings.ListenPort != newSettings.ListenPort)) { RegisterLocalPeerDiscovery(newSettings.AllowLocalPeerDiscovery && localPort > 0 ? new LocalPeerDiscovery(localPort) : null); } }
async Task UpdateSettingsAsync(EngineSettings oldSettings, EngineSettings newSettings) { await DiskManager.UpdateSettingsAsync(newSettings); if (newSettings.DiskCacheBytes != oldSettings.DiskCacheBytes) { await Task.WhenAll(Torrents.Select(t => DiskManager.FlushAsync(t))); } ConnectionManager.Settings = newSettings; if (oldSettings.UsePartialFiles != newSettings.UsePartialFiles) { foreach (var manager in Torrents) { await manager.UpdateUsePartialFiles(newSettings.UsePartialFiles); } } if (oldSettings.AllowPortForwarding != newSettings.AllowPortForwarding) { if (newSettings.AllowPortForwarding) { await PortForwarder.StartAsync(CancellationToken.None); } else { await PortForwarder.StopAsync(removeExistingMappings : true, CancellationToken.None); } } if (oldSettings.DhtEndPoint != newSettings.DhtEndPoint) { if (DhtListener.LocalEndPoint != null) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Udp, DhtListener.LocalEndPoint.Port), CancellationToken.None); } DhtListener.Stop(); if (newSettings.DhtEndPoint == null) { DhtListener = new NullDhtListener(); await RegisterDht(new NullDhtEngine()); } else { DhtListener = Factories.CreateDhtListener(Settings.DhtEndPoint) ?? new NullDhtListener(); if (IsRunning) { DhtListener.Start(); } if (oldSettings.DhtEndPoint == null) { var dht = Factories.CreateDht(); await dht.SetListenerAsync(DhtListener); await RegisterDht(dht); } else { await DhtEngine.SetListenerAsync(DhtListener); } } if (DhtListener.LocalEndPoint != null) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Udp, DhtListener.LocalEndPoint.Port)); } } if (!Equals(oldSettings.ListenEndPoint, newSettings.ListenEndPoint)) { if (PeerListener.LocalEndPoint != null) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Tcp, PeerListener.LocalEndPoint.Port), CancellationToken.None); } PeerListener.Stop(); PeerListener = (newSettings.ListenEndPoint == null ? null : Factories.CreatePeerConnectionListener(newSettings.ListenEndPoint)) ?? new NullPeerListener(); listenManager.SetListener(PeerListener); if (IsRunning) { PeerListener.Start(); // The settings could say to listen at port 0, which means 'choose one dynamically' if (PeerListener.LocalEndPoint != null) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Tcp, PeerListener.LocalEndPoint.Port)); } } } if (oldSettings.AllowLocalPeerDiscovery != newSettings.AllowLocalPeerDiscovery) { RegisterLocalPeerDiscovery(!newSettings.AllowLocalPeerDiscovery ? null : Factories.CreateLocalPeerDiscovery()); } }