private void ProximityDeviceDeparted(object sender) { if (this.publishedMessageID != -1) { AppServices.myProximityDevice.StopPublishingMessage(this.publishedMessageID); this.publishedMessageID = -1; } if (this.subscribedMessageID != -1) { AppServices.myProximityDevice.StopSubscribingForMessage(this.subscribedMessageID); this.subscribedMessageID = -1; } AppServices.myProximityDevice.DeviceArrived -= ProximityDeviceArrived; AppServices.myProximityDevice.DeviceDeparted -= ProximityDeviceDeparted; this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Set the binding variables to the data from the current friend we are chatting with and hide the chat buttons AppServices.friendsData.currFriendsName = lastSelected.username; AppServices.friendsData.chatHistory = lastSelected.history; AppServices.friendsData.sendButtonEnabled = true; lastSelected.chatButtonsVisible = false; lastSelected = null; this.Frame.Navigate(typeof(ChatPage)); }); }
public async void OnSuccess(object response) { Session friendSession = (Session)response; await AppServices.friendsData._page.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { FriendsListEntry myFriend = AppServices.friendsData.FindFriend(_friendUsername); myFriend.isOnline = true; myFriend.sessionID = friendSession.GetSessionId(); }); // Attempt to get the mutex to update the number of friends sessions processed AppServices.friendCountMutex.WaitOne(); AppServices.numFriendsProcessed++; AppServices.numOnlineFriends++; // If all friends have been processed we signify the main thread we are done if (AppServices.numFriendsProcessed == AppServices.friendsData.friendsList.Count) { AppServices.friendCountMutex.ReleaseMutex(); AppServices.operationSuccessful = true; AppServices.app42LoadedFriends = true; return; } AppServices.friendCountMutex.ReleaseMutex(); }
public async void OnSuccess(object response) { // If the callback is called with a username we are trying to update an entry or add a new friend if (string.IsNullOrWhiteSpace(_friendUsername) == false) { Session friendSession = (Session)response; await AppServices.mainPage.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { FriendsListEntry myFriend = AppServices.friendsData.FindFriend(_friendUsername); if (myFriend == null) { AppServices.friendsData.friendsList.Add(new FriendsListEntry() { encryptedUsername = _friendUsername, isOnline = true, sessionID = friendSession.GetSessionId() }); } else { myFriend.isOnline = true; myFriend.sessionID = friendSession.GetSessionId(); } }); } AppServices.operationSuccessful = true; AppServices.isFriendOnline = true; AppServices.operationComplete = true; }
private void friendsListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (friendsListView.SelectionMode == ListViewSelectionMode.Single) { // If selected item is null (no selection) do nothing if (friendsListView.SelectedItem == null) { return; } // Retrieve the selected friend and toggle the chat buttons FriendsListEntry selectedFriend = friendsListView.SelectedItem as FriendsListEntry; // Setup the chat variables and open the chat window if we already have a session if (selectedFriend.sessionEstablished) { // Set the binding variables to the data from the current friend we are chatting with and hide the chat buttons AppServices.friendsData.currFriendsName = selectedFriend.username; AppServices.friendsData.chatHistory = selectedFriend.history; AppServices.friendsData.sendButtonEnabled = true; selectedFriend.chatButtonsVisible = false; lastSelected = null; friendsListView.SelectedItem = null; Frame.Navigate(typeof(ChatPage)); } else { // Stop showing the chat buttons for the last selected friend. If the last selected and current selected are the same toggle the buttons // and return if (lastSelected != null) { if (lastSelected.Equals(friendsListView.SelectedItem)) { lastSelected.chatButtonsVisible = !lastSelected.chatButtonsVisible; friendsListView.SelectedItem = null; return; } else { lastSelected.chatButtonsVisible = false; } } selectedFriend.chatButtonsVisible = true; lastSelected = selectedFriend; } friendsListView.SelectedItem = null; return; } else if (friendsListView.SelectionMode == ListViewSelectionMode.Multiple) { return; } }
// Compute the encryption keys and load the chat page private void webChatButton_Click(object sender, RoutedEventArgs e) { // Tell the user we selected that a session is being established if (lastSelected.isOnline && string.IsNullOrWhiteSpace(lastSelected.sessionID) == false) { AppServices.appWarpLastSentToUsername = lastSelected.username; AppServices.warpClient.sendPrivateUpdate(lastSelected.username, MessageBuilder.bulidSessionEstablishedBytes(AppServices.defaultEncryptionKey)); } else if (lastSelected.isOnline == false) { return; } // No session exists so we create a session int compareResult = string.Compare(AppServices.localUsernameEncrypted, lastSelected.encryptedUsername); this.keyBuff = null; // My username is greater so we use my sessionID as the encryptionKey if (compareResult > 0) { keyBuff = CryptographicBuffer.ConvertStringToBinary(AppServices.localSessionId, BinaryStringEncoding.Utf8); } else { keyBuff = CryptographicBuffer.ConvertStringToBinary(lastSelected.sessionID, BinaryStringEncoding.Utf8); } lastSelected.encryptionKey = AppServices.encryptionAlgorithim.CreateSymmetricKey(keyBuff); // Set the binding variables to the data from the current friend we are chatting with and hide the chat buttons AppServices.friendsData.currFriendsName = lastSelected.username; AppServices.friendsData.chatHistory = lastSelected.history; AppServices.friendsData.sendButtonEnabled = true; lastSelected.chatButtonsVisible = false; lastSelected = null; this.Frame.Navigate(typeof(ChatPage)); }
private void nfcChatButton_Click(object sender, RoutedEventArgs e) { if (lastSelected.isOnline == false) { this.PrintMessage("User is not online, cannot start chat."); return; } if (lastSelected.sessionEstablished) { lastSelected.chatButtonsVisible = false; lastSelected = null; this.Frame.Navigate(typeof(ChatPage)); return; } if (AppServices.myProximityDevice == null) { AppServices.myProximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault(); if (AppServices.myProximityDevice == null) { this.PrintMessage("Unable to get NFC chip. This device might not be capable of proximity interactions or NFC is disabled in settings"); return; } AppServices.myProximityDevice.DeviceArrived += ProximityDeviceArrived; AppServices.myProximityDevice.DeviceDeparted += ProximityDeviceDeparted; } int compareResult = string.Compare(AppServices.localUsernameEncrypted, lastSelected.encryptedUsername); this.keyBuff = null; // My username is greater so I generate a key if (compareResult > 0) { keyBuff = CryptographicBuffer.GenerateRandom(256); } PrintMessage("Please close this message and then tap and hold the devices together"); }
/// <summary> /// Gets the view model for this <see cref="Page"/>. /// This can be changed to a strongly typed view model. /* </summary> * public ObservableDictionary DefaultViewModel * { * get { return this.defaultViewModel; } * } */ /// <summary> /// Populates the page with content passed during navigation. Any saved state is also /// provided when recreating a page from a prior session. /// </summary> /// <param name="sender"> /// The source of the event; typically <see cref="NavigationHelper"/> /// </param> /// <param name="e">Event data that provides both the navigation parameter passed to /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested and /// a dictionary of state preserved by this page during an earlier /// session. The state will be null the first time a page is visited.</param> private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) { this.ScrollToBottom(); this.currFriend = AppServices.friendsData.FindFriend(AppServices.friendsData.currFriendsName); this.currFriend.unreadCount = "0"; }
public async void onSendPrivateUpdateDone(byte result) { string errorMsg; // If the connection was successful remove the progress indicator and return if (result == WarpResponseResultCode.SUCCESS) { AppServices.errorMessage = "Send successful"; AppServices.operationSuccessful = true; AppServices.appWarpUpdateSent = true; return; } else if (result == WarpResponseResultCode.AUTH_ERROR) { errorMsg = "UPDATE SEND Authentication Error: Attempting to connect with initializing with API keys."; } else if (result == WarpResponseResultCode.BAD_REQUEST) { errorMsg = "Bad Request: The entered username does not exist."; } else if (result == WarpResponseResultCode.CONNECTION_ERR) { errorMsg = "Send Update Network Connection Error: Please check your network connection and try again."; } // Trying to send a message to an offline user so not exactly an error we just need to update the friends list to reflect this but // dont print an error message else if (result == WarpResponseResultCode.RESOURCE_NOT_FOUND) { AppServices.errorMessage = "Update failed (RESOURCE_NOT_FOUND): Friend is not really online."; await AppServices.friendsData._page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { FriendsListEntry friend = AppServices.friendsData.FindFriend(AppServices.appWarpLastSentToUsername); friend.isOnline = false; }); AppServices.operationSuccessful = true; AppServices.appWarpUpdateSent = true; return; } // Trying to send a message to an offline user so not exactly an error we just need to update the friends list to reflect this but // dont print an error message else if (result == WarpResponseResultCode.RESOURCE_MOVED) { AppServices.errorMessage = "Update failed (RESOURCE_NOT_FOUND): Friend is not really online."; await AppServices.friendsData._page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { FriendsListEntry friend = AppServices.friendsData.FindFriend(AppServices.appWarpLastSentToUsername); friend.isOnline = false; }); AppServices.operationSuccessful = true; AppServices.appWarpUpdateSent = true; return; } else { errorMsg = "Unknown Error: Please check your network connection and the entered username and try again."; } AppServices.operationSuccessful = false; AppServices.errorMessage = errorMsg; AppServices.appWarpUpdateSent = true; }
/* This function will be used to send JSON objects (JObjects) with the following format Keys: * string updateType: This will be one of the following choices: * "chat" if we are receiving a new chat message. * "onlineStatus" if a friend is notifying us of an online status change * "ipInfo" if this contains information about the friends IP address and port * "request" if this contains information about a new friend request or update to a friend request or friend relationship * * var data: This will be different types of data depending on the update type: * "chat" - this will be a string containing the message * "onlineStatus" - this will be a bool onlineStatus and a string sessionID * "ipInfo" - this will be 2 strings ipAddr and port. * "request" - this will be a string requestStatus, if we have no pending requests already from the sender (either ones we sent or received) * then this is a new friend request and the string will be "new". If a friend accepted our request this will be "accepted" * If a friend removed us from their list then this will be "removed" */ public async void onPrivateUpdateReceived(string sender, byte[] update, bool fromUdp) { FriendsListEntry sendingFriend = AppServices.friendsData.FindFriend(sender); JObject updateData; // Decrypt the data using the session key if we have one already or the default if we have no session with the sender if (sendingFriend != null && sendingFriend.sessionEstablished) { updateData = MessageBuilder.decodeMessageBytes(update, sendingFriend.encryptionKey); } else { updateData = MessageBuilder.decodeMessageBytes(update, AppServices.defaultEncryptionKey); } string updateType = updateData["updateType"].ToString(); if (updateType.Equals("chat")) { string chatMessage = updateData["message"].ToString(); // The currently open chat is the one we are receiving a message from we do not need to update the unread count if (sender.Equals(AppServices.friendsData.currFriendsName)) { await AppServices.friendsData._page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { FriendsListEntry currFriend = AppServices.friendsData.FindFriend(sender); currFriend.history.Add(new ChatEntry() { message = chatMessage, sender = sender }); }); } else { await AppServices.friendsData._page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { FriendsListEntry currFriend = AppServices.friendsData.FindFriend(sender); int currUnreadCount = System.Convert.ToInt32(currFriend.unreadCount); currUnreadCount++; currFriend.unreadCount = currUnreadCount.ToString(); currFriend.history.Add(new ChatEntry() { message = chatMessage, sender = sender }); }); } } // A friend has sent a change in their online status so we get the data and update the friendsList in the ViewModel else if (updateType.Equals("onlineStatus")) { bool friendOnlineStatus = (bool)JsonConvert.DeserializeObject(updateData["onlineStatus"].ToString(), typeof(bool)); string friendSessionID = updateData["sessionID"].ToString(); //_page.PrintMessageAsync("Received new status update\n" + "Sender: " + sender + "\nOnline: " + friendOnlineStatus.ToString()); await AppServices.friendsData._page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { FriendsListEntry friend = AppServices.friendsData.FindFriend(sender); friend.isOnline = friendOnlineStatus; friend.sessionID = friendSessionID; // If we are chatting with the current user and they logout then we disable the send button if (AppServices.friendsData.currFriendsName != null && AppServices.friendsData.currFriendsName.Equals(friend.username)) { if (friendOnlineStatus == false) { AppServices.friendsData.sendButtonEnabled = false; } } }); } else if (updateType.Equals("ipInfo")) { } else if (updateType.Equals("request")) { string requestStatus = updateData["requestStatus"].ToString(); // This is a new friend request so add it to the request list if (requestStatus.Equals("new")) { await AppServices.mainPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { AppServices.friendsData.friendRequests.Add(new FriendRequest() { username = sender }); AppServices.mainPage.DisplayFriendRequestsList(); }); } // This will be an accepted friend request so add them to the friends list and check if they are online else if (requestStatus.Equals("accepted")) { AppServices.operationComplete = false; AppServices.isFriendOnline = false; string encryptedName = AppServices.EncryptString(sender, AppServices.secretKey); AppServices.sessionService.GetSession(encryptedName, false, new GetFriendSessionCallback(encryptedName)); while (AppServices.operationComplete == false) { ; } // The friend is online if (AppServices.operationSuccessful && AppServices.isFriendOnline) { await AppServices.mainPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { //AppServices.friendsData.friendsList.Add(new FriendsListEntry() { username = sender, isOnline = true }); AppServices.mainPage.DisplayFriendsList(); }); } // The friend is offline else { await AppServices.mainPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { AppServices.friendsData.friendsList.Add(new FriendsListEntry() { username = sender, isOnline = false }); AppServices.mainPage.DisplayFriendsList(); }); } } // This is a remove request when a friend has removed the local user from their friends list else { await AppServices.mainPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { AppServices.friendsData.friendsList.Remove(AppServices.friendsData.FindFriend(sender)); AppServices.mainPage.DisplayFriendsList(); }); } } // A friend is informing us that they are establishing a secure session with us so we should generate an encryption key else if (updateType.Equals("session")) { // If I already have a session this is a duplicate if (sendingFriend.sessionEstablished) { return; } int compareResult = string.Compare(AppServices.localUsernameEncrypted, sendingFriend.encryptedUsername); // Use my session ID as the encryption key if (compareResult > 0) { IBuffer keyBuff = CryptographicBuffer.ConvertStringToBinary(AppServices.localSessionId, BinaryStringEncoding.Utf8); await AppServices.friendsData._page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { sendingFriend.encryptionKey = AppServices.encryptionAlgorithim.CreateSymmetricKey(keyBuff); sendingFriend.sessionEstablished = true; sendingFriend.chatButtonsVisible = false; }); } // Use friend's session ID as the encryption key else { IBuffer keyBuff = CryptographicBuffer.ConvertStringToBinary(sendingFriend.sessionID, BinaryStringEncoding.Utf8); CoreDispatcher dispatcher = AppServices.friendsData._page.Dispatcher; await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { sendingFriend.encryptionKey = AppServices.encryptionAlgorithim.CreateSymmetricKey(keyBuff); sendingFriend.sessionEstablished = true; sendingFriend.chatButtonsVisible = false; }); } } }
private async void acceptRequestButton_Click(object sender, RoutedEventArgs e) { FriendRequest selectedRequest = null; FriendsListEntry newFriend = null; int i = 0; // Find the request which has it's buttons showing, this must be the one that has been pressed foreach (FriendRequest friendRequest in AppServices.friendsData.friendRequests) { if (friendRequest.showRequestButtons == Windows.UI.Xaml.Visibility.Visible) { selectedRequest = friendRequest; break; } i++; } // If a request exists then we accept it if (selectedRequest != null) { this.StartAsyncOperations("Accepting request..."); AppServices.operationComplete = false; AppServices.buddyService.AcceptFriendRequest(AppServices.localUsernameEncrypted, selectedRequest.encryptedUsername, new AcceptRequestCallback()); await Task.Run(() => { while (AppServices.operationComplete == false) { ; } }); // If the accept was successful we now remove them from the request list and add them to the friends list if (AppServices.operationSuccessful) { AppServices.friendsData.friendsList.Add(new FriendsListEntry { username = selectedRequest.username, isOnline = false }); newFriend = AppServices.friendsData.friendsList.ElementAt(AppServices.friendsData.friendsList.Count); AppServices.friendsData.friendRequests.RemoveAt(i); // Update the friends list XAML in case this was the last request this.DisplayFriendRequestsList(); // Now check if the new friend is online this.StartAsyncOperations("Checking if new friend is online..."); AppServices.operationComplete = false; AppServices.isFriendOnline = false; AppServices.sessionService.GetSession(selectedRequest.encryptedUsername, false, new GetFriendSessionCallback(selectedRequest.encryptedUsername)); await Task.Run(() => { while (AppServices.operationComplete == false) { ; } }); // An error occured and the friend may or may not be online. This is needed because the App42 callback will call the onException callback // even if no error occured but the friend is offline. We just use isFriendOnline to either mark an error occuring if the operation // wasn't successful. Or the friend's online status if the operation was successful if (AppServices.operationSuccessful == false && AppServices.isFriendOnline == true) { this.EndAsyncOperationsError(); return; } // The friend is online if (AppServices.operationSuccessful && AppServices.isFriendOnline) { newFriend.isOnline = true; AppServices.appWarpLastSentToUsername = newFriend.username; AppServices.warpClient.sendPrivateUpdate(newFriend.username, MessageBuilder.buildAcceptedFriendRequestBytes(AppServices.defaultEncryptionKey)); //bool sendSuccessful = await AppServices.SendDataToUser(selectedRequest.username, MessageBuilder.buildAcceptedFriendRequestBytes()); //if (sendSuccessful == false) //{ // this.EndAsyncOperationsError(); // return; //} } // The friend is offline this.EndAsyncOperationsSuccess(); return; } else { this.EndAsyncOperationsError(); return; } } }