/// <summary> /// Initializes a new instance of the <see cref="SoulseekClientOptions"/> class. /// </summary> /// <param name="enableListener">A value indicating whether to listen for incoming connections.</param> /// <param name="listenPort">The port on which to listen for incoming connections.</param> /// <param name="enableDistributedNetwork">A value indicating whether to establish distributed network connections.</param> /// <param name="acceptDistributedChildren">A value indicating whether to accept distributed child connections.</param> /// <param name="distributedChildLimit">The number of allowed distributed children.</param> /// <param name="maximumConcurrentUploads">The number of allowed concurrent uploads.</param> /// <param name="maximumUploadSpeed">The total maximum allowable upload speed, in kibibytes per second.</param> /// <param name="maximumConcurrentDownloads">The number of allowed concurrent downloads.</param> /// <param name="maximumDownloadSpeed">The total maximum allowable download speed, in kibibytes per second.</param> /// <param name="deduplicateSearchRequests"> /// A value indicating whether duplicated distributed search requests should be discarded. /// </param> /// <param name="messageTimeout"> /// The message timeout, in milliseconds, used when waiting for a response from the server. /// </param> /// <param name="autoAcknowledgePrivateMessages"> /// A value indicating whether to automatically send a private message acknowledgement upon receipt. /// </param> /// <param name="autoAcknowledgePrivilegeNotifications"> /// A value indicating whether to automatically send a privilege notification acknowledgement upon receipt. /// </param> /// <param name="acceptPrivateRoomInvitations">A value indicating whether to accept private room invitations.</param> /// <param name="minimumDiagnosticLevel">The minimum level of diagnostic messages to be generated by the client.</param> /// <param name="startingToken">The starting value for download and search tokens.</param> /// <param name="serverConnectionOptions">The options for the server message connection.</param> /// <param name="peerConnectionOptions">The options for peer message connections.</param> /// <param name="transferConnectionOptions">The options for peer transfer connections.</param> /// <param name="incomingConnectionOptions">The options for incoming connections.</param> /// <param name="distributedConnectionOptions">The options for distributed message connections.</param> /// <param name="userEndPointCache">The user endpoint cache to use when resolving user endpoints.</param> /// <param name="searchResponseResolver"> /// The delegate used to resolve the <see cref="SearchResponse"/> for an incoming <see cref="SearchRequest"/>. /// </param> /// <param name="searchResponseCache"> /// The search response cache to use when a response is not able to be delivered immediately. /// </param> /// <param name="browseResponseResolver"> /// The delegate used to resolve the <see cref="BrowseResponse"/> for an incoming <see cref="BrowseRequest"/>. /// </param> /// <param name="directoryContentsResolver"> /// The delegate used to resolve the <see cref="Directory"/> for an incoming <see cref="FolderContentsRequest"/>. /// </param> /// <param name="userInfoResolver">The delegate used to resolve the <see cref="UserInfo"/> for an incoming <see cref="UserInfoRequest"/>.</param> /// <param name="enqueueDownload">The delegate invoked upon an receipt of an incoming <see cref="QueueDownloadRequest"/>.</param> /// <param name="placeInQueueResolver"> /// The delegate used to resolve the <see cref="int"/> response for an incoming request. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown when the value supplied for <paramref name="listenPort"/> is not between 1024 and 65535. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown when the value supplied for <paramref name="distributedChildLimit"/> is less than zero. /// </exception> public SoulseekClientOptions( bool enableListener = true, int listenPort = 50000, bool enableDistributedNetwork = true, bool acceptDistributedChildren = true, int distributedChildLimit = 25, int maximumConcurrentUploads = 10, int maximumUploadSpeed = int.MaxValue, int maximumConcurrentDownloads = int.MaxValue, int maximumDownloadSpeed = int.MaxValue, bool deduplicateSearchRequests = true, int messageTimeout = 5000, bool autoAcknowledgePrivateMessages = true, bool autoAcknowledgePrivilegeNotifications = true, bool acceptPrivateRoomInvitations = false, DiagnosticLevel minimumDiagnosticLevel = DiagnosticLevel.Info, int startingToken = 0, ConnectionOptions serverConnectionOptions = null, ConnectionOptions peerConnectionOptions = null, ConnectionOptions transferConnectionOptions = null, ConnectionOptions incomingConnectionOptions = null, ConnectionOptions distributedConnectionOptions = null, IUserEndPointCache userEndPointCache = null, Func <string, int, SearchQuery, Task <SearchResponse> > searchResponseResolver = null, ISearchResponseCache searchResponseCache = null, Func <string, IPEndPoint, Task <BrowseResponse> > browseResponseResolver = null, Func <string, IPEndPoint, int, string, Task <Directory> > directoryContentsResolver = null, Func <string, IPEndPoint, Task <UserInfo> > userInfoResolver = null, Func <string, IPEndPoint, string, Task> enqueueDownload = null, Func <string, IPEndPoint, string, Task <int?> > placeInQueueResolver = null) { EnableListener = enableListener; ListenPort = listenPort; if (ListenPort < 1024 || ListenPort > IPEndPoint.MaxPort) { throw new ArgumentOutOfRangeException(nameof(listenPort), $"Must be between 1024 and {IPEndPoint.MaxPort}"); } EnableDistributedNetwork = enableDistributedNetwork; AcceptDistributedChildren = acceptDistributedChildren; DistributedChildLimit = distributedChildLimit; if (DistributedChildLimit < 0) { throw new ArgumentOutOfRangeException(nameof(distributedChildLimit), "Must be greater than or equal to zero"); } MaximumConcurrentUploads = maximumConcurrentUploads; if (MaximumConcurrentUploads < 1) { throw new ArgumentOutOfRangeException(nameof(maximumConcurrentUploads), "Must be greater than or equal to one"); } MaximumUploadSpeed = maximumUploadSpeed; MaximumConcurrentDownloads = maximumConcurrentDownloads; if (MaximumConcurrentDownloads < 1) { throw new ArgumentOutOfRangeException(nameof(maximumConcurrentDownloads), "Must be greater than or equal to one"); } MaximumDownloadSpeed = maximumDownloadSpeed; DeduplicateSearchRequests = deduplicateSearchRequests; MessageTimeout = messageTimeout; AutoAcknowledgePrivateMessages = autoAcknowledgePrivateMessages; AutoAcknowledgePrivilegeNotifications = autoAcknowledgePrivilegeNotifications; AcceptPrivateRoomInvitations = acceptPrivateRoomInvitations; MinimumDiagnosticLevel = minimumDiagnosticLevel; StartingToken = startingToken; ServerConnectionOptions = (serverConnectionOptions ?? new ConnectionOptions()).WithoutInactivityTimeout(); PeerConnectionOptions = peerConnectionOptions ?? new ConnectionOptions(); TransferConnectionOptions = (transferConnectionOptions ?? new ConnectionOptions()).WithoutInactivityTimeout(); IncomingConnectionOptions = incomingConnectionOptions ?? new ConnectionOptions(); DistributedConnectionOptions = distributedConnectionOptions ?? new ConnectionOptions(); UserEndPointCache = userEndPointCache; SearchResponseResolver = searchResponseResolver; SearchResponseCache = searchResponseCache; BrowseResponseResolver = browseResponseResolver ?? defaultBrowseResponseResolver; DirectoryContentsResolver = directoryContentsResolver; UserInfoResolver = userInfoResolver ?? defaultUserInfoResolver; EnqueueDownload = enqueueDownload ?? defaultEnqueueDownload; PlaceInQueueResolver = placeInQueueResolver ?? defaultPlaceInQueueResolver; }