예제 #1
0
        public void Parse_Returns_Expected_Data_When_User_Exists(string username, UserStatus status, int averageSpeed, long downloadCount, int fileCount, int directoryCount, string countryCode)
        {
            var msg = new MessageBuilder()
                      .WriteCode(MessageCode.Server.AddUser)
                      .WriteString(username)
                      .WriteByte(1) // exists = true
                      .WriteInteger((int)status)
                      .WriteInteger(averageSpeed)
                      .WriteLong(downloadCount)
                      .WriteInteger(fileCount)
                      .WriteInteger(directoryCount)
                      .WriteString(countryCode)
                      .Build();

            var r = AddUserResponse.Parse(msg);

            Assert.Equal(username, r.Username);
            Assert.True(r.Exists);
            Assert.Equal(status, r.Status);
            Assert.Equal(averageSpeed, r.AverageSpeed);
            Assert.Equal(downloadCount, r.DownloadCount);
            Assert.Equal(fileCount, r.FileCount);
            Assert.Equal(directoryCount, r.DirectoryCount);
            Assert.Equal(countryCode, r.CountryCode);
        }
예제 #2
0
        public void Parse_Throws_MessageReadException_On_Missing_Data()
        {
            var msg = new MessageBuilder()
                      .WriteCode(MessageCode.Server.AddUser)
                      .Build();

            var ex = Record.Exception(() => AddUserResponse.Parse(msg));

            Assert.NotNull(ex);
            Assert.IsType <MessageReadException>(ex);
        }
예제 #3
0
        public void Parse_Throws_MessageException_On_Code_Mismatch()
        {
            var msg = new MessageBuilder()
                      .WriteCode(MessageCode.Peer.BrowseRequest)
                      .Build();

            var ex = Record.Exception(() => AddUserResponse.Parse(msg));

            Assert.NotNull(ex);
            Assert.IsType <MessageException>(ex);
        }
예제 #4
0
        public void Parse_Returns_Expected_Data_When_User_Does_Not_Exist(string username)
        {
            var msg = new MessageBuilder()
                      .WriteCode(MessageCode.Server.AddUser)
                      .WriteString(username)
                      .WriteByte(0) // exists = false
                      .Build();

            var r = AddUserResponse.Parse(msg);

            Assert.Equal(username, r.Username);
            Assert.False(r.Exists);
            Assert.Null(r.Status);
            Assert.Null(r.AverageSpeed);
            Assert.Null(r.DownloadCount);
            Assert.Null(r.FileCount);
            Assert.Null(r.DirectoryCount);
            Assert.Null(r.CountryCode);
        }
예제 #5
0
        public void Parse_Does_Not_Throw_If_CountryCode_Is_Missing(string username, UserStatus status, int averageSpeed, long downloadCount, int fileCount, int directoryCount)
        {
            var msg = new MessageBuilder()
                      .WriteCode(MessageCode.Server.AddUser)
                      .WriteString(username)
                      .WriteByte(1) // exists = true
                      .WriteInteger((int)status)
                      .WriteInteger(averageSpeed)
                      .WriteLong(downloadCount)
                      .WriteInteger(fileCount)
                      .WriteInteger(directoryCount)
                      .Build();

            var r = AddUserResponse.Parse(msg);

            Assert.Equal(username, r.Username);
            Assert.True(r.Exists);
            Assert.Equal(status, r.Status);
            Assert.Equal(averageSpeed, r.AverageSpeed);
            Assert.Equal(downloadCount, r.DownloadCount);
            Assert.Equal(fileCount, r.FileCount);
            Assert.Equal(directoryCount, r.DirectoryCount);
            Assert.Null(r.CountryCode);
        }
예제 #6
0
        public async void HandleMessage(object sender, byte[] message)
        {
            var code = new MessageReader <MessageCode.Server>(message).ReadCode();

            Diagnostic.Debug($"Server message received: {code}");

            try
            {
                switch (code)
                {
                case MessageCode.Server.ParentMinSpeed:
                case MessageCode.Server.ParentSpeedRatio:
                case MessageCode.Server.WishlistInterval:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), IntegerResponse.Parse <MessageCode.Server>(message));
                    break;

                case MessageCode.Server.Login:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), LoginResponse.Parse(message));
                    break;

                case MessageCode.Server.RoomList:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), RoomList.Parse(message));
                    break;

                case MessageCode.Server.PrivilegedUsers:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), PrivilegedUserList.Parse(message));
                    break;

                case MessageCode.Server.NetInfo:
                    var netInfo = NetInfo.Parse(message);
                    foreach (var peer in netInfo.Parents)
                    {
                        Console.WriteLine($"{peer.Username} {peer.IPAddress} {peer.Port}");
                    }

                    break;

                case MessageCode.Server.ConnectToPeer:
                    var connectToPeerResponse = ConnectToPeerResponse.Parse(message);

                    if (connectToPeerResponse.Type == Constants.ConnectionType.Tranfer)
                    {
                        // ensure that we are expecting at least one file from this user before we connect. the response
                        // doesn't contain any other identifying information about the file.
                        if (!SoulseekClient.Downloads.IsEmpty && SoulseekClient.Downloads.Values.Any(d => d.Username == connectToPeerResponse.Username))
                        {
                            var(connection, remoteToken) = await SoulseekClient.PeerConnectionManager.GetTransferConnectionAsync(connectToPeerResponse).ConfigureAwait(false);

                            var download = SoulseekClient.Downloads.Values.FirstOrDefault(v => v.RemoteToken == remoteToken && v.Username == connectToPeerResponse.Username);

                            if (download != default(Transfer))
                            {
                                SoulseekClient.Waiter.Complete(new WaitKey(Constants.WaitKey.IndirectTransfer, download.Username, download.Filename, download.RemoteToken), connection);
                            }
                        }
                        else
                        {
                            throw new SoulseekClientException($"Unexpected transfer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPAddress}:{connectToPeerResponse.Port}); Ignored.");
                        }
                    }
                    else
                    {
                        await SoulseekClient.PeerConnectionManager.GetOrAddMessageConnectionAsync(connectToPeerResponse).ConfigureAwait(false);
                    }

                    break;

                case MessageCode.Server.AddUser:
                    var addUserResponse = AddUserResponse.Parse(message);
                    SoulseekClient.Waiter.Complete(new WaitKey(code, addUserResponse.Username), addUserResponse);
                    break;

                case MessageCode.Server.GetStatus:
                    var statsResponse = GetStatusResponse.Parse(message);
                    SoulseekClient.Waiter.Complete(new WaitKey(code, statsResponse.Username), statsResponse);
                    UserStatusChanged?.Invoke(this, new UserStatusChangedEventArgs(statsResponse));
                    break;

                case MessageCode.Server.PrivateMessage:
                    var pm = PrivateMessage.Parse(message);
                    PrivateMessageReceived?.Invoke(this, pm);

                    if (SoulseekClient.Options.AutoAcknowledgePrivateMessages)
                    {
                        await SoulseekClient.AcknowledgePrivateMessageAsync(pm.Id, CancellationToken.None).ConfigureAwait(false);
                    }

                    break;

                case MessageCode.Server.GetPeerAddress:
                    var peerAddressResponse = GetPeerAddressResponse.Parse(message);
                    SoulseekClient.Waiter.Complete(new WaitKey(code, peerAddressResponse.Username), peerAddressResponse);
                    break;

                default:
                    Diagnostic.Debug($"Unhandled server message: {code}; {message.Length} bytes");
                    break;
                }
            }
            catch (Exception ex)
            {
                Diagnostic.Warning($"Error handling server message: {code}; {ex.Message}", ex);
            }
        }