/// <summary> /// Child thread function. /// Handles a connection with a single client. /// </summary> /// <param name="client">The TcpClient object</param> private void HandleConnectionWithClient(object client) { TcpClient tcpClient = (TcpClient)client; NetworkStream networkStream = tcpClient.GetStream(); IPAddress address = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address; Log("Remote client connected", address, 0); object message = Message.Recieve(networkStream); while (tcpClient.Connected && message != null) { if (message is string && message as string == "Test") { // A test message was recieved. Send a response back. Log("Recieved a connection test request", address, 1); Message.TestMsg(networkStream); } else if (message is AuthRequest) { // An AuthRequest was receieved. Authenticate the user and reply with a UserToken. AuthRequest req = message as AuthRequest; Log("Recieved an authentication request", address, 1); UserToken token = null; if (req.register) { Log(" Registering New User: "******" Registration Successful", address, 2); } else { Log(" Registration Failed", address, 2); } } catch (DatabaseException ex) { Log("DATABASE ERROR: Registration could not proceed", address, 0); Log(ex.Message, 0); } } else { Log(" Authenticating User: "******" Authentication Successful", address, 2); } else { Log(" Authentication Failed", address, 2); } } catch (DatabaseException ex) { Log("DATABASE ERROR: Authentication could not proceed", address, 0); Log(ex.Message, 0); } } Message.Send(networkStream, new AuthResponse(token)); } else if (message is TokenVerifyRequest) { // A TokenVerifyRequest was recieved. Test the token for validity. Log("Recieved a token verification request", address, 1); TokenVerifyRequest req = message as TokenVerifyRequest; Log(" User: "******" Expires: " + req.token.expires, address, 2); Log(" Token: " + req.token.token, address, 2); try { bool valid; if (database.VerifyToken(req.token) != 0) { Log(" Verification Successful", address, 2); valid = true; } else { Log(" Verification Failed", address, 2); valid = false; } Message.Send(networkStream, new TokenVerifyResponse(valid)); } catch (DatabaseException ex) { Log("DATABASE ERROR: Could not process request", address, 0); Log(ex.Message, 0); Message.Send(networkStream, new BBResponse("Database", "An unknown database error occured. Could not process request.")); } } else if (message is BBRequest) { try { // A BBRequest was recieved. Process the request BBRequest bbmessage = message as BBRequest; Log("Received a " + bbmessage.requestType + " request", address, 1); // Authenticate the user int userID; if (bbmessage.requestType.userToken == null) { Log(" No user supplied. Processing as anonymous.", address, 2); userID = -1; } else { Log(" Username: "******" Expires: " + bbmessage.requestType.userToken.expires, address, 2); Log(" Token: " + bbmessage.requestType.userToken.token, address, 2); userID = database.VerifyToken(bbmessage.requestType.userToken); } if (userID == 0) { Log(" User Authentication failed", address, 1); Message.Send(networkStream, new BBResponse()); } else { if (bbmessage.requestType is BBRequest.UpDownVote) { // Upload and vote on a song BBRequest.UpDownVote req = bbmessage.requestType as BBRequest.UpDownVote; Log(" " + (req.vote ? "Upvote" : "Downvote") + " Request", address, 2); Log(" ID: " + req.song.ID, address, 3); Log(" Genre: " + req.song.genre, address, 3); Log(" Tempo: " + req.song.tempo, address, 3); Log(" Seed: " + req.song.seed, address, 3); SongParameters song = database.VoteOnSong(req.song, req.vote, userID); Message.Send(networkStream, new BBResponse(song)); Log(" Response has ID of " + song.ID + " and score of " + song.score, address, 2); } else if (bbmessage.requestType is BBRequest.RequestScore) { // Request the score of a song BBRequest.RequestScore req = bbmessage.requestType as BBRequest.RequestScore; Log(" ID: " + req.song.ID, address, 3); Log(" Genre: " + req.song.genre, address, 3); Log(" Tempo: " + req.song.tempo, address, 3); Log(" Seed: " + req.song.seed, address, 3); SongParameters song = database.RefreshSong(req.song); Message.Send(networkStream, new BBResponse(song)); Log(" Response has ID of " + song.ID + " and score of " + song.score, address, 2); } else if (bbmessage.requestType is BBRequest.RequestSongs) { // Request a list of songs BBRequest.RequestSongs req = bbmessage.requestType as BBRequest.RequestSongs; List <SongParameters> songList = database.GetSongList(req.num, req.genre, req.username); Message.Send(networkStream, new BBResponse(songList)); Log(" Returned " + songList.Count + " songs", address, 2); } else { Log("BBREQUEST ERROR: Unknown BBRequest type '" + bbmessage.GetType() + "'", address, 0); Message.Send(networkStream, new BBResponse("BBRequest", "Unknown BBRequest type '" + bbmessage.GetType() + "'")); } } } catch (DatabaseException ex) { Log("DATABASE ERROR: Could not process request", address, 0); Log(ex.Message, 0); Message.Send(networkStream, new BBResponse("Database", "An unknown database error occured. Could not process request.")); } catch (System.IO.IOException ex) { Log("IO ERROR: Could not send response", address, 0); Log(ex.Message, 0); } } else { Log("Unknown request type '" + message.GetType() + "'", address, 0); } message = Message.Recieve(networkStream); } Log("Remote client disconnected", address, 0); tcpClient.Close(); }