public async Task BrowseInternalAsync_Returns_Expected_Response_On_Success(string username, IPAddress ip, int port, string localUsername, List <Directory> directories) { var response = new BrowseResponse(directories.Count, directories); var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(response)); waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.State) .Returns(ConnectionState.Connected); conn.Setup(m => m.WriteMessageAsync(It.IsAny <Message>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); var connManager = new Mock <IConnectionManager>(); connManager.Setup(m => m.GetOrAddUnsolicitedConnectionAsync(It.IsAny <ConnectionKey>(), localUsername, It.IsAny <EventHandler <Message> >(), It.IsAny <ConnectionOptions>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, connectionManager: connManager.Object); s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var result = await s.BrowseAsync(username); Assert.Equal(response, result); }
public async Task BrowseAsync_Throws_UserOfflineException_On_User_Not_Found(string username, IPEndPoint endpoint, string localUsername) { var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromException <UserAddressResponse>(new UserOfflineException())); var conn = new Mock <IMessageConnection>(); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var ex = await Record.ExceptionAsync(() => s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <UserOfflineException>(ex); } }
public async Task BrowseAsync_Throws_TimeoutException_On_Timeout(string username, IPEndPoint endpoint, string localUsername) { var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new UserAddressResponse(username, endpoint.Address, endpoint.Port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.State) .Returns(ConnectionState.Connected); conn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); waiter.Setup(m => m.Wait <(MessageReceivedEventArgs, IMessageConnection)>(It.IsAny <WaitKey>(), It.IsAny <int?>(), It.IsAny <CancellationToken?>())) .Returns(Task.FromException <(MessageReceivedEventArgs, IMessageConnection)>(new TimeoutException())); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var ex = await Record.ExceptionAsync(() => s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <TimeoutException>(ex); } }
public async Task BrowseAsync_Throws_BrowseException_On_Write_Exception(string username, IPEndPoint endpoint, string localUsername) { var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new UserAddressResponse(username, endpoint.Address, endpoint.Port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.WriteAsync(It.Is <byte[]>(n => new MessageReader <MessageCode.Peer>(n).ReadCode() == MessageCode.Peer.BrowseRequest), It.IsAny <CancellationToken>())) .Throws(new ConnectionWriteException()); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var ex = await Record.ExceptionAsync(() => s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <BrowseException>(ex); Assert.IsType <ConnectionWriteException>(ex.InnerException); } }
public async Task BrowseAsync_Throws_ArgumentException_Given_Bad_Username(string username) { var s = new SoulseekClient(); var ex = await Record.ExceptionAsync(async() => await s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <ArgumentException>(ex); }
public async Task BrowseAsync_Throws_InvalidOperationException_When_Not_Connected() { var s = new SoulseekClient(); var ex = await Record.ExceptionAsync(async() => await s.BrowseAsync("foo")); Assert.NotNull(ex); Assert.IsType <InvalidOperationException>(ex); Assert.Contains("Connected", ex.Message, StringComparison.InvariantCultureIgnoreCase); }
public async Task BrowseAsync_Throws_InvalidOperationException_When_Not_Logged_In() { using (var s = new SoulseekClient()) { s.SetProperty("State", SoulseekClientStates.Connected); var ex = await Record.ExceptionAsync(async() => await s.BrowseAsync("foo")); Assert.NotNull(ex); Assert.IsType <InvalidOperationException>(ex); Assert.Contains("logged in", ex.Message, StringComparison.InvariantCultureIgnoreCase); } }
public async Task BrowseAsync_Throws_ConnectionException_On_Unexpected_Disconnect(string username, IPEndPoint endpoint, string localUsername) { var tcs = new TaskCompletionSource <BrowseResponse>(); var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(tcs.Task); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new UserAddressResponse(username, endpoint.Address, endpoint.Port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.State) .Returns(ConnectionState.Connected); conn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); waiter.Setup(m => m.Wait <(MessageReceivedEventArgs, IMessageConnection)>(It.IsAny <WaitKey>(), It.IsAny <int?>(), It.IsAny <CancellationToken?>())) .Returns(Task.FromResult((new MessageReceivedEventArgs(1, new byte[] { 0x0 }), conn.Object))); waiter.Setup(m => m.Throw(It.IsAny <WaitKey>(), It.IsAny <Exception>())) .Callback <WaitKey, Exception>((key, ex) => tcs.SetException(ex)); using (var s = new SoulseekClient(waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var task = s.BrowseAsync(username); conn.Raise(m => m.Disconnected += null, new ConnectionDisconnectedEventArgs("foo")); var ex = await Record.ExceptionAsync(() => task); Assert.NotNull(ex); Assert.IsType <BrowseException>(ex); Assert.IsType <ConnectionException>(ex.InnerException); } }
public async Task BrowseAsync_Raises_BrowseProgressUpdated_Event_At_Least_Twice(string username, IPEndPoint endpoint, string localUsername, List <Directory> directories, int length) { var response = new BrowseResponse(directories.Count, directories); var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(response)); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new UserAddressResponse(username, endpoint.Address, endpoint.Port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.State) .Returns(ConnectionState.Connected); conn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); waiter.Setup(m => m.Wait <(MessageReceivedEventArgs, IMessageConnection)>(It.IsAny <WaitKey>(), It.IsAny <int?>(), It.IsAny <CancellationToken?>())) .Returns(Task.FromResult((new MessageReceivedEventArgs(length, new byte[] { 0x0 }), conn.Object))); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var events = new List <BrowseProgressUpdatedEventArgs>(); s.BrowseProgressUpdated += (sender, args) => events.Add(args); await s.BrowseAsync(username); Assert.NotEmpty(events); Assert.Equal(2, events.Count); Assert.Equal(0, events[0].PercentComplete); Assert.Equal(100, events[1].PercentComplete); } }
public async Task BrowseAsync_Returns_Expected_Response_On_Success(string username, IPEndPoint endpoint, string localUsername, List <Directory> directories) { var response = new BrowseResponse(directories.Count, directories); var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(response)); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new UserAddressResponse(username, endpoint.Address, endpoint.Port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.State) .Returns(ConnectionState.Connected); conn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); waiter.Setup(m => m.Wait <(MessageReceivedEventArgs, IMessageConnection)>(It.IsAny <WaitKey>(), It.IsAny <int?>(), It.IsAny <CancellationToken?>())) .Returns(Task.FromResult((new MessageReceivedEventArgs(1, new byte[] { 0x0 }), conn.Object))); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var result = await s.BrowseAsync(username); Assert.Equal(response.Directories, result); } }
public async Task BrowseAsync_Throws_BrowseException_On_Disconnect(string username, IPEndPoint endpoint, string localUsername) { var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new UserAddressResponse(username, endpoint.Address, endpoint.Port))); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(Task.FromException <BrowseResponse>(new ConnectionException("disconnected unexpectedly"))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask) .Raises(m => m.Disconnected += null, conn.Object, new ConnectionDisconnectedEventArgs(string.Empty)); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); waiter.Setup(m => m.Wait <(MessageReceivedEventArgs, IMessageConnection)>(It.IsAny <WaitKey>(), It.IsAny <int?>(), It.IsAny <CancellationToken?>())) .Returns(Task.FromResult((new MessageReceivedEventArgs(1, new byte[] { 0x0 }), conn.Object))); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); var ex = await Record.ExceptionAsync(() => s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <BrowseException>(ex); Assert.IsType <ConnectionException>(ex.InnerException); Assert.Contains("disconnected unexpectedly", ex.InnerException.Message, StringComparison.InvariantCultureIgnoreCase); } }
public async Task BrowseAsync_Uses_Given_CancellationToken(string username, IPEndPoint endpoint, string localUsername, List <Directory> directories, CancellationToken cancellationToken) { var response = new BrowseResponse(directories); var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(response)); waiter.Setup(m => m.Wait <UserAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new UserAddressResponse(username, endpoint.Address, endpoint.Port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.State) .Returns(ConnectionState.Connected); conn.Setup(m => m.WriteAsync(It.IsAny <IOutgoingMessage>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, endpoint, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); waiter.Setup(m => m.Wait <(MessageReceivedEventArgs, IMessageConnection)>(It.IsAny <WaitKey>(), It.IsAny <int?>(), It.IsAny <CancellationToken?>())) .Returns(Task.FromResult((new MessageReceivedEventArgs(1, new byte[] { 0x0 }), conn.Object))); using (var s = new SoulseekClient(waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); await s.BrowseAsync(username, cancellationToken : cancellationToken); } conn.Verify(m => m.WriteAsync(It.IsAny <IOutgoingMessage>(), cancellationToken), Times.AtLeastOnce); }
public async Task BrowseInternalAsync_Throws_BrowseException_On_Disconnect(string username, IPAddress ip, int port, string localUsername) { var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port))); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(Task.FromException <BrowseResponse>(new ConnectionException("disconnected unexpectedly"))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.WriteMessageAsync(It.IsAny <Message>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask) .Raises(m => m.Disconnected += null, conn.Object, string.Empty); var connManager = new Mock <IConnectionManager>(); connManager.Setup(m => m.GetOrAddUnsolicitedConnectionAsync(It.IsAny <ConnectionKey>(), localUsername, It.IsAny <EventHandler <Message> >(), It.IsAny <ConnectionOptions>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, connectionManager: connManager.Object); s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); BrowseResponse result = null; var ex = await Record.ExceptionAsync(async() => result = await s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <BrowseException>(ex); Assert.IsType <ConnectionException>(ex.InnerException); Assert.Contains("disconnected unexpectedly", ex.InnerException.Message, StringComparison.InvariantCultureIgnoreCase); }
public async Task BrowseInternalAsync_Throws_BrowseException_On_Write_Exception(string username, IPAddress ip, int port, string localUsername) { var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.WriteMessageAsync(It.IsAny <Message>(), It.IsAny <CancellationToken>())) .Throws(new ConnectionWriteException()); var connManager = new Mock <IConnectionManager>(); connManager.Setup(m => m.GetOrAddUnsolicitedConnectionAsync(It.IsAny <ConnectionKey>(), localUsername, It.IsAny <EventHandler <Message> >(), It.IsAny <ConnectionOptions>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, connectionManager: connManager.Object); s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); BrowseResponse result = null; var ex = await Record.ExceptionAsync(async() => result = await s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <BrowseException>(ex); Assert.IsType <ConnectionWriteException>(ex.InnerException); }
public async Task BrowseInternalAsync_Throws_BrowseException_On_Cancellation(string username, IPAddress ip, int port, string localUsername) { var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.WaitIndefinitely <BrowseResponse>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>())) .Returns(Task.FromException <BrowseResponse>(new OperationCanceledException())); waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port))); var conn = new Mock <IMessageConnection>(); conn.Setup(m => m.State) .Returns(ConnectionState.Connected); conn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); var connManager = new Mock <IPeerConnectionManager>(); connManager.Setup(m => m.GetOrAddMessageConnectionAsync(username, ip, port, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(conn.Object)); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object, serverConnection: conn.Object, peerConnectionManager: connManager.Object)) { s.SetProperty("Username", localUsername); s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn); BrowseResponse result = null; var ex = await Record.ExceptionAsync(async() => result = await s.BrowseAsync(username)); Assert.NotNull(ex); Assert.IsType <BrowseException>(ex); Assert.IsType <OperationCanceledException>(ex.InnerException); } }
static async Task Main(string[] args) { using (var client = new SoulseekClient(new SoulseekClientOptions(minimumDiagnosticLevel: DiagnosticLevel.Debug))) { client.StateChanged += Client_ServerStateChanged; client.SearchResponseReceived += Client_SearchResponseReceived; client.SearchStateChanged += Client_SearchStateChanged; client.DownloadProgressUpdated += Client_DownloadProgress; client.DownloadStateChanged += Client_DownloadStateChanged; client.DiagnosticGenerated += Client_DiagnosticMessageGenerated; client.PrivateMessageReceived += Client_PrivateMessageReceived; await client.ConnectAsync(); Console.WriteLine("Enter username and password:"******"disconnect") { client.Disconnect(); return; } else if (cmd.StartsWith("msg")) { var arr = cmd.Split(' '); var peer = arr.Skip(1).Take(1).FirstOrDefault(); var message = arr.Skip(2).Take(999); await client.SendPrivateMessageAsync(peer, string.Join(' ', message)); } else if (cmd.StartsWith("browse")) { var peer = cmd.Split(' ').Skip(1).FirstOrDefault(); var result = await client.BrowseAsync(peer); Console.WriteLine(JsonConvert.SerializeObject(result)); continue; } else if (cmd.StartsWith("search")) { using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(300))) { var search = string.Join(' ', cmd.Split(' ').Skip(1)); var token = new Random().Next(); var result = await client.SearchAsync(search, token, new SearchOptions( filterFiles : false, filterResponses : false, fileLimit : 10000), cts.Token); Console.WriteLine(JsonConvert.SerializeObject(result)); continue; } } else if (cmd.StartsWith("download-folder")) { var peer = cmd.Split(' ').Skip(1).FirstOrDefault(); var files = new[] { @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\01 - Bulls On Parade.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\02 - Down Rodeo.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\03 - People Of The Sun.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\04 - Revolver.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\05 - Roll Right.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\06 - Snakecharmer.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\07 - Tire Me.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\08 - Vietnow.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\09 - Wind Below.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\10 - Without A Face.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\11 - Year Of The Boomerang.mp3", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\Thumbs.db", @"@@djpnk\\Bootlegs\\Fear Is Your Only God\\album.nfo", }; var task = Task.Run(() => { var random = new Random(); Parallel.ForEach(files, async(file) => { Console.WriteLine($"Attempting to download {file}"); var bytes = await client.DownloadAsync(peer, file, random.Next()); var filename = $@"C:\tmp\{Path.GetFileName(file)}"; Console.WriteLine($"Bytes received: {bytes.Length}; writing to file {filename}..."); System.IO.File.WriteAllBytes(filename, bytes); Console.WriteLine("Download complete!"); }); }); await task; Console.WriteLine($"All files complete."); } else if (cmd.StartsWith("download")) { var peer = cmd.Split(' ').Skip(1).FirstOrDefault(); var file = string.Join(' ', cmd.Split(' ').Skip(2)); var bytes = await client.DownloadAsync(peer, file, new Random().Next()); var filename = $@"C:\tmp\{Path.GetFileName(file)}"; Console.WriteLine($"Bytes received: {bytes.Length}; writing to file {filename}..."); System.IO.File.WriteAllBytes(filename, bytes); Console.WriteLine("Download complete!"); } else { try { await client.LoginAsync(cmd.Split(' ')[0], cmd.Split(' ')[1]); Console.WriteLine($"Logged in."); } catch (Exception ex) { Console.WriteLine($"Login failed: {ex.Message}"); } } } } }