示例#1
0
 /// <summary>
 /// Show new user notification window
 /// </summary>
 public static void ShowUserNotification(ChatUserMessage message)
 {
     new NotificationWindow()
     {
         UserMessage = message,
         User        = message.FromUser,
         Message     = string.Format(HylandMedConfig.Properties.Resources.STR_USER_SENT_MESSAGE, message.FromUser.DisplayNameResolved)
     }.Show();
 }
        private bool messagesViewUser_Filter(object obj)
        {
            ChatUserMessage message = obj as ChatUserMessage;

            List <ChatUser> users = message.ToUsers.Union(new List <ChatUser> {
                message.FromUser
            }).Where(u => u != ApplicationViewModel.Current.ChatProxy.CurrentUser).ToList();
            List <ChatUser> users2 = FixedToUsers.Union(new List <ChatUser> {
                message.FromUser
            }).Where(u => u != ApplicationViewModel.Current.ChatProxy.CurrentUser).ToList();

            return(message != null && users.SequenceEqualAnyOrder(users2));
        }
示例#3
0
        public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string        text = System.Convert.ToString(value);
            List <string> tags;

            ChatUserMessage.GetWhisperUsers(text, ApplicationViewModel.Current.UsersView.SourceCollection.OfType <ChatUser>().ToList(), out text);
            ChatUserMessage.TryGetTags(text, out tags, out text);
            if (text.StartsWith(string.Format("/{0} ", ChatUserMessage.Commands.ASCII)))
            {
                return(new FontFamily("Consolas"));
            }
            return(Settings.Default.FontFamily);
        }
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ChatUserMessage message = value as ChatUserMessage;

            if (message != null)
            {
                StringBuilder sb = new StringBuilder();
                foreach (string tag in ApplicationViewModel.Current.ChatProxy.TagService.GetHiddenTags(message.Tags))
                {
                    sb.AppendFormat("#{0} ", tag);
                }
                return(sb.ToString().TrimEnd());
            }
            return("");
        }
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ChatUserMessage message = value as ChatUserMessage;

            if (message != null && message.FromUser != ApplicationViewModel.Current.ChatProxy.CurrentUser && message.Tags != null && message.Tags.Count > 0)
            {
                foreach (string hiddenTag in Settings.Default.HiddenTags)
                {
                    if (message.Tags.Contains(hiddenTag))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
示例#6
0
        private void txtMessage_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && !Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
            {
                txtMessage.GetBindingExpression(TextBox.TextProperty).UpdateSource();

                if (!string.IsNullOrWhiteSpace(txtMessage.Text))
                {
                    ChatUserMessage message = ChatUserMessage.Parse(ApplicationViewModel.Current.ChatProxy.CurrentUser, txtMessage.Text, ApplicationViewModel.Current.ChatProxy.Users, FixedFilterTag, FixedToUsers);
                    _sentMessageID = message.ID;
                    ApplicationViewModel.Current.ChatProxy.SendMessage(message);
                }
                e.Handled = true;
            }
            else if (e.Key == Key.Up)
            {
                if (ViewModel.CopyPreviousMessageCommand.CanExecute(null))
                {
                    ViewModel.CopyPreviousMessageCommand.Execute(null);
                    txtMessage.CaretIndex = int.MaxValue;
                    e.Handled             = true;
                }
            }
            else if (e.Key == Key.Down)
            {
                if (ViewModel.CopyNextMessageCommand.CanExecute(null))
                {
                    ViewModel.CopyNextMessageCommand.Execute(null);
                }
                txtMessage.CaretIndex = int.MaxValue;
                e.Handled             = true;
            }
            else if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.V)
            {
                if (PasteImageCommand_CanExecute(null))
                {
                    PasteImageCommand_Execute(null);
                    e.Handled = true;
                }
            }
        }
示例#7
0
        private void sv_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            bool enableShit = true;

            if (enableShit)
            {
                ScrollViewer sv               = sender as ScrollViewer;
                var          visibleItems     = new List <int>();
                Rect         svViewportBounds = new Rect(sv.HorizontalOffset, sv.VerticalOffset, sv.ViewportWidth, sv.ViewportHeight);

                for (int i = 0; i < Items.Count; ++i)
                {
                    ContentPresenter container = this.ItemContainerGenerator.ContainerFromIndex(i) as ContentPresenter;

                    if (container != null)
                    {
                        var             offset  = VisualTreeHelper.GetOffset(container);
                        var             bounds  = new Rect(offset.X, offset.Y, container.ActualWidth, container.ActualHeight);
                        ChatUserMessage message = container.Content as ChatUserMessage;

                        if (message != null)
                        {
                            MessageBubble messageBubble = VisualTreeHelper.GetChild(container, 0) as MessageBubble;

                            if (messageBubble != null)
                            {
                                if (svViewportBounds.IntersectsWith(bounds))
                                {
                                    ImageBehavior.SetIsInView(messageBubble, true);
                                }
                                else
                                {
                                    ImageBehavior.SetIsInView(messageBubble, false);
                                }
                            }
                        }
                    }
                }
            }
        }
        private bool messagesView_Filter(object obj)
        {
            ChatUserMessage message = obj as ChatUserMessage;

            return(message != null && message.Tags.Contains(FilterTag));
        }
示例#9
0
        public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ChatUserMessage message = value as ChatUserMessage;

            if (message == null)
            {
                return(string.Empty);
            }
            bool isFromCurrentUser = ApplicationViewModel.Current.ChatProxy.CurrentUser == message.FromUser;


            // •
            StackPanel sp = new StackPanel
            {
                Orientation = Orientation.Horizontal,
            };


            sp.Children.Add(new TextBlock {
                Text = message.Date.ToString("t"), VerticalAlignment = VerticalAlignment.Center
            });

            int toUserCount = message.ToUsers == null ? 0 : message.ToUsers.Count;

            if (toUserCount == 1)
            {
                sp.Children.Add(new TextBlock
                {
                    Text = "  •  To ",
                });
                TextBlock toUser = new TextBlock();
                toUser.SetBinding(TextBlock.TextProperty, new Binding(nameof(ChatUser.DisplayNameResolved)));
                Interaction.GetBehaviors(toUser).Add(new FrameworkElementWhisperBehavior()
                {
                    User = message.ToUsers[0]
                });
                sp.Children.Add(toUser);
            }

            if (toUserCount > 1)
            {
                TextBlock toUser = new TextBlock
                {
                    Text        = "  •  Group Message",
                    ContextMenu = Application.Current.Resources["GroupMessageContextMenu"] as ContextMenu,
                };

                List <ChatUser> replyUsers = new List <ChatUser>();

                if (message.FromUser != ApplicationViewModel.Current.ChatProxy.CurrentUser)
                {
                    replyUsers.Add(message.FromUser);
                }

                foreach (ChatUser user in message.ToUsers)
                {
                    if (user != ApplicationViewModel.Current.ChatProxy.CurrentUser)
                    {
                        replyUsers.Add(user);
                    }
                }

                toUser.ToolTip = string.Join(Environment.NewLine, message.ToUsers.Union(new List <ChatUser> {
                    message.FromUser
                }).Select(u => u.DisplayNameResolved).OrderBy(u => u));
                Interaction.GetBehaviors(toUser).Add(new FrameworkElementWhisperUsers()
                {
                    Users = replyUsers
                });
                sp.Children.Add(toUser);
            }

            sp.Children.Add(new TextBlock {
                Text = "  •  "
            });

            ThumbsUp thumbsUp        = new ThumbsUp();
            Binding  fontSizeBinding = new Binding("SystemFontSize")
            {
                Source = Settings.Default
            };

            thumbsUp.Command          = ApplicationViewModel.Current.ToggleThumbsUpCommand;
            thumbsUp.CommandParameter = message;
            MultiBinding thumbsUpCheckedBinding = new MultiBinding {
                Converter = new IsMessageThumbedUpByCurrentUserConverter()
            };

            thumbsUpCheckedBinding.Bindings.Add(new Binding("VotesFor")
            {
                Source = message
            });
            thumbsUpCheckedBinding.Bindings.Add(new Binding("VotesFor.Count")
            {
                Source = message
            });
            thumbsUp.SetBinding(ThumbsUp.IsCheckedProperty, thumbsUpCheckedBinding);
            thumbsUp.SetBinding(ThumbsUp.HeightProperty, fontSizeBinding);
            thumbsUp.SetBinding(ThumbsUp.WidthProperty, fontSizeBinding);
            sp.Children.Add(thumbsUp);

            ItemsControl thumbsUpVotes = new ItemsControl();

            thumbsUpVotes.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("VotesFor")
            {
                Source = message
            });
            ToolTip thumbsUpTooltip = new ToolTip()
            {
                Content = thumbsUpVotes
            };

            TextBlock txtThumbsUp = new TextBlock {
                Margin = new Thickness(5, 0, 10, 0)
            };
            Binding b = new Binding("VotesFor.Count")
            {
                Source = message
            };

            txtThumbsUp.SetBinding(TextBlock.TextProperty, b);
            txtThumbsUp.ToolTip = thumbsUpTooltip;
            sp.Children.Add(txtThumbsUp);

            ThumbsDown thumbsDown = new ThumbsDown();

            thumbsDown.Command          = ApplicationViewModel.Current.ToggleThumbsDownCommand;
            thumbsDown.CommandParameter = message;
            MultiBinding thumbsDownCheckedBinding = new MultiBinding {
                Converter = new IsMessageThumbedUpByCurrentUserConverter()
            };

            thumbsDownCheckedBinding.Bindings.Add(new Binding("VotesAgainst")
            {
                Source = message
            });
            thumbsDownCheckedBinding.Bindings.Add(new Binding("VotesAgainst.Count")
            {
                Source = message
            });
            thumbsDown.SetBinding(ThumbsDown.IsCheckedProperty, thumbsDownCheckedBinding);
            thumbsDown.SetBinding(ThumbsDown.HeightProperty, fontSizeBinding);
            thumbsDown.SetBinding(ThumbsDown.WidthProperty, fontSizeBinding);
            sp.Children.Add(thumbsDown);

            ItemsControl thumbsDownVotes = new ItemsControl();

            thumbsDownVotes.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("VotesAgainst")
            {
                Source = message
            });
            ToolTip thumbsDownTooltip = new ToolTip()
            {
                Content = thumbsDownVotes
            };

            TextBlock txtThumbsDown = new TextBlock {
                Margin = new Thickness(5, 0, 0, 0)
            };
            Binding b2 = new Binding("VotesAgainst.Count")
            {
                Source = message
            };

            txtThumbsDown.SetBinding(TextBlock.TextProperty, b2);
            txtThumbsDown.ToolTip = thumbsDownTooltip;
            sp.Children.Add(txtThumbsDown);

            return(sp);
        }
示例#10
0
        public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ChatUserMessage message = value as ChatUserMessage;

            if (message == null)
            {
                return(string.Empty);
            }
            bool isFromCurrentUser = ApplicationViewModel.Current.ChatProxy.CurrentUser == message.FromUser;


            // •
            StackPanel sp = new StackPanel
            {
                Orientation = Orientation.Horizontal,
            };

            if (!isFromCurrentUser)
            {
                TextBlock fromUser = new TextBlock
                {
                    ToolTip           = Application.Current.Resources["UserTooltip"],
                    ContextMenu       = Application.Current.Resources["UserContextMenu"] as ContextMenu,
                    DataContext       = message.FromUser,
                    VerticalAlignment = VerticalAlignment.Center,
                };

                fromUser.SetBinding(TextBlock.TextProperty, new Binding(nameof(ChatUser.DisplayNameResolved)));

                Interaction.GetBehaviors(fromUser).Add(new FrameworkElementWhisperBehavior()
                {
                    User = message.FromUser
                });
                sp.Children.Add(fromUser);
                sp.Children.Add(new TextBlock {
                    Text = "  •  "
                });
            }

            sp.Children.Add(new TextBlock {
                Text = message.Date.ToString("t"), VerticalAlignment = VerticalAlignment.Center
            });

            if (message.ToUsers.Count == 1)
            {
                sp.Children.Add(new TextBlock
                {
                    Text = "  •  To ",
                    VerticalAlignment = VerticalAlignment.Center,
                });
                TextBlock toUser = new TextBlock
                {
                    ToolTip           = Application.Current.Resources["UserTooltip"],
                    ContextMenu       = Application.Current.Resources["UserContextMenu"] as ContextMenu,
                    DataContext       = message.ToUsers[0],
                    VerticalAlignment = VerticalAlignment.Center,
                };
                toUser.SetBinding(TextBlock.TextProperty, new Binding(nameof(ChatUser.DisplayNameResolved)));
                Interaction.GetBehaviors(toUser).Add(new FrameworkElementWhisperBehavior()
                {
                    User = message.ToUsers[0]
                });
                sp.Children.Add(toUser);
            }

            if (message.ToUsers.Count > 1)
            {
                TextBlock toUser = new TextBlock
                {
                    Text = "  •  Group Message",
                    VerticalAlignment = VerticalAlignment.Center,
                    ContextMenu       = Application.Current.Resources["GroupMessageContextMenu"] as ContextMenu,
                };

                List <ChatUser> replyUsers = new List <ChatUser>();

                if (message.FromUser != ApplicationViewModel.Current.ChatProxy.CurrentUser)
                {
                    replyUsers.Add(message.FromUser);
                }

                foreach (ChatUser user in message.ToUsers)
                {
                    if (user != ApplicationViewModel.Current.ChatProxy.CurrentUser)
                    {
                        replyUsers.Add(user);
                    }
                }

                toUser.ToolTip = string.Join(Environment.NewLine, message.ToUsers.Union(new List <ChatUser> {
                    message.FromUser
                }).Select(u => u.DisplayNameResolved).OrderBy(u => u));
                Interaction.GetBehaviors(toUser).Add(new FrameworkElementWhisperUsers()
                {
                    Users = replyUsers
                });
                sp.Children.Add(toUser);
            }

            Binding fontSizeBinding = new Binding("SystemFontSize")
            {
                Source = Settings.Default
            };

            if (message.Tags.Count > 0)
            {
                TextBlock separator = new TextBlock {
                    Text = "  •  ", VerticalAlignment = VerticalAlignment.Center
                };
                sp.Children.Add(separator);

                if (message.Tags.Count > 1)
                {
                    TagListButton tagListButton = new TagListButton()
                    {
                        Height           = Settings.Default.SystemFontSize,
                        Width            = Settings.Default.SystemFontSize,
                        Margin           = new Thickness(2),
                        Command          = ApplicationViewModel.Current.ReplyAllTagsCommand,
                        CommandParameter = message,
                    };

                    tagListButton.SetBinding(ThumbsUp.HeightProperty, fontSizeBinding);
                    tagListButton.SetBinding(ThumbsUp.WidthProperty, fontSizeBinding);

                    sp.Children.Add(tagListButton);
                }

                foreach (string tag in message.Tags)
                {
                    EmoticonRichTextBox toUser = new EmoticonRichTextBox
                    {
                        ImageSize         = Size.Parse("20,20"),
                        RawText           = "#" + tag,
                        ContextMenu       = Application.Current.Resources["TagContextMenu"] as ContextMenu,
                        Margin            = new Thickness(2),
                        DataContext       = ApplicationViewModel.Current.GetTag(tag),
                        VerticalAlignment = VerticalAlignment.Center,
                    };
                    Interaction.GetBehaviors(toUser).Add(new EmoticonRichTextBoxSendTaggedMessage()
                    {
                        Tag = tag
                    });
                    sp.Children.Add(toUser);
                }
            }

            sp.Children.Add(new TextBlock {
                Text = "  •  ", VerticalAlignment = VerticalAlignment.Center
            });

            // If this is a combined message, the rating system will apply to the first message
            CombinedNormalChatUserMessages combinedMessage = message as CombinedNormalChatUserMessages;
            ChatUserMessage firstMessage = message;

            if (combinedMessage != null)
            {
                firstMessage = combinedMessage.Messages.First();
            }

            ThumbsUp thumbsUp = new ThumbsUp {
                Height = Settings.Default.SystemFontSize, Width = Settings.Default.SystemFontSize
            };

            thumbsUp.Command          = ApplicationViewModel.Current.ToggleThumbsUpCommand;
            thumbsUp.CommandParameter = firstMessage;
            MultiBinding thumbsUpCheckedBinding = new MultiBinding {
                Converter = new IsMessageThumbedUpByCurrentUserConverter()
            };

            thumbsUpCheckedBinding.Bindings.Add(new Binding("VotesFor")
            {
                Source = firstMessage
            });
            thumbsUpCheckedBinding.Bindings.Add(new Binding("VotesFor.Count")
            {
                Source = firstMessage
            });
            thumbsUp.SetBinding(ThumbsUp.IsCheckedProperty, thumbsUpCheckedBinding);
            thumbsUp.SetBinding(ThumbsUp.HeightProperty, fontSizeBinding);
            thumbsUp.SetBinding(ThumbsUp.WidthProperty, fontSizeBinding);
            sp.Children.Add(thumbsUp);

            ItemsControl thumbsUpVotes = new ItemsControl();

            thumbsUpVotes.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("VotesFor")
            {
                Source = firstMessage
            });
            ToolTip thumbsUpTooltip = new ToolTip()
            {
                Content = thumbsUpVotes
            };

            TextBlock txtThumbsUp = new TextBlock {
                Margin = new Thickness(5, 0, 10, 0), VerticalAlignment = VerticalAlignment.Center
            };
            Binding b = new Binding("VotesFor.Count")
            {
                Source = firstMessage
            };

            txtThumbsUp.SetBinding(TextBlock.TextProperty, b);
            txtThumbsUp.ToolTip = thumbsUpTooltip;
            sp.Children.Add(txtThumbsUp);

            ThumbsDown thumbsDown = new ThumbsDown {
                Height = Settings.Default.SystemFontSize, Width = Settings.Default.SystemFontSize
            };

            thumbsDown.Command          = ApplicationViewModel.Current.ToggleThumbsDownCommand;
            thumbsDown.CommandParameter = firstMessage;
            MultiBinding thumbsDownCheckedBinding = new MultiBinding {
                Converter = new IsMessageThumbedUpByCurrentUserConverter()
            };

            thumbsDownCheckedBinding.Bindings.Add(new Binding("VotesAgainst")
            {
                Source = firstMessage
            });
            thumbsDownCheckedBinding.Bindings.Add(new Binding("VotesAgainst.Count")
            {
                Source = firstMessage
            });
            thumbsDown.SetBinding(ThumbsDown.IsCheckedProperty, thumbsDownCheckedBinding);
            thumbsDown.SetBinding(ThumbsDown.HeightProperty, fontSizeBinding);
            thumbsDown.SetBinding(ThumbsDown.WidthProperty, fontSizeBinding);
            sp.Children.Add(thumbsDown);

            ItemsControl thumbsDownVotes = new ItemsControl();

            thumbsDownVotes.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("VotesAgainst")
            {
                Source = firstMessage
            });
            ToolTip thumbsDownTooltip = new ToolTip()
            {
                Content = thumbsDownVotes
            };

            TextBlock txtThumbsDown = new TextBlock {
                Margin = new Thickness(5, 0, 0, 0), VerticalAlignment = VerticalAlignment.Center
            };
            Binding b2 = new Binding("VotesAgainst.Count")
            {
                Source = firstMessage
            };

            txtThumbsDown.SetBinding(TextBlock.TextProperty, b2);
            txtThumbsDown.ToolTip = thumbsDownTooltip;
            sp.Children.Add(txtThumbsDown);

            return(sp);
        }
示例#11
0
        private void Receiver()
        {
            ConsoleMessage("{0} Logged In", _User.Username);

            try
            {
                while (_TcpClient.Client.Connected)
                {
                    CanReceive = true;
                    ClearLog();

                    AppendLog("reading int");
                    TcpCommands command = (TcpCommands)_br.ReadInt32();
                    _Connection.LastActivity = DateTime.Now;

                    lock ( _lock )
                    {
                        AppendLog("entering lock");
                        Stopwatch      sw = Stopwatch.StartNew();
                        ChatUser       user;
                        string         username;
                        ChatUser[]     users;
                        string         mood;
                        string         pollID;
                        string         messageID;
                        string         choiceID;
                        string         error;
                        MessageRating  voteStatus;
                        string         pointData;
                        string         whiteboardBrush;
                        double         whiteboardThickness;
                        UserConnection userConnection;

                        if (_User.Status == UserStatus.Inactive)
                        {
                            AppendLog("setting user status back to active");
                            _User.Status = UserStatus.Active;
                            SendArgsToAllUsers((int)TcpCommands.UserActive, _User.Username);
                        }

                        TraceInformation("{0} command received from {1}", command, _User.Username);

                        switch (command)
                        {
                        case TcpCommands.SendMessage:

                            ChatUserMessage message = _br.ReadObject <ChatUserMessage>();

                            if (_proxyUsers.ContainsKey(message.FromUser.Username))
                            {
                                message.FromUser = _Program.Users.FirstOrDefault(u => u.Key.Username == _proxyUsers[message.FromUser.Username]).Key;
                            }

                            if (message != null)
                            {
                                error = string.Empty;

                                // Ensure that the 'FromUser' is actually this user
                                //if( _User != message.FromUser )
                                //{
                                //	error = "You are not who you say you are";
                                //}

                                // Ensure that the IP address is the same as when they logged on
                                var fromUser = _Program.Users.FirstOrDefault(u => u.Key == message.FromUser);
                                //IPAddress thisAddress = ( (IPEndPoint)_TcpClient.Client.RemoteEndPoint ).Address;
                                //IPAddress fromAddress = ( (IPEndPoint)fromUser.Value.Client._TcpClient.Client.RemoteEndPoint ).Address;
                                //if( thisAddress != fromAddress )
                                //{
                                //	error = "You are not who you say you are";
                                //}

                                // Must re-stamp the date to avoid messages having differing dates based on clients
                                message.Date = DateTime.Now;

                                foreach (MessageValidator rule in _Program.RuleConfiguration.Rules)
                                {
                                    if (!rule.Validate(message, _Program.Messages, out error))
                                    {
                                        break;
                                    }
                                }

                                foreach (string tag in message.Tags)
                                {
                                    if (tag.Length < 2 || tag.Length > 30)
                                    {
                                        error = "Tags must be between 2 and 30 characters";
                                        break;
                                    }
                                }

                                if (string.IsNullOrEmpty(error))
                                {
                                    bool isPublic = message.ToUsers == null || message.ToUsers.Count == 0;

                                    if (isPublic)
                                    {
                                        _Program.Stats.GetStats(User.Username).PublicMessagesSent++;
                                    }
                                    else
                                    {
                                        _Program.Stats.GetStats(User.Username).PrivateMessagesSent++;
                                    }

                                    foreach (var recipient in _Program.Users)
                                    {
                                        if (recipient.Value.Client != null)
                                        {
                                            // This is sent to all users
                                            if (isPublic)
                                            {
                                                if (message.FromUser != recipient.Key)
                                                {
                                                    _Program.Stats.GetStats(recipient.Key.Username).PublicMessagesReceived++;
                                                    recipient.Value.SendArgs((int)TcpCommands.Received, message);
                                                }
                                            }
                                            // Whisper, send to 'ToUsers' and to the 'FromUser'
                                            else if (message.ToUsers.Contains(recipient.Key))
                                            {
                                                _Program.Stats.GetStats(recipient.Key.Username).PrivateMessagesReceived++;
                                                recipient.Value.SendArgs((int)TcpCommands.Received, message);
                                            }
                                        }
                                    }

                                    _Connection.SendArgs((int)TcpCommands.SendMessageSuccess, message);

                                    _User.IsTyping = false;
                                    _Program.Stats.Save();
                                    _Program.Messages.Add(message);
                                }
                                else
                                {
                                    _Connection.SendError(error);
                                }
                            }
                            break;

                        case TcpCommands.SendWhiteboardPoints:

                            messageID           = _br.ReadString();
                            pointData           = _br.ReadString();
                            whiteboardBrush     = _br.ReadString();
                            whiteboardThickness = _br.ReadDouble();
                            users = _br.ReadObject <ChatUser[]>();

                            if (users == null || users.Length == 0)
                            {
                                SendArgsToAllUsers(
                                    (int)TcpCommands.WhiteboardPointsReceived,
                                    User.Username,
                                    messageID,
                                    pointData,
                                    whiteboardBrush,
                                    whiteboardThickness);
                            }
                            else
                            {
                                SendArgsToUsers(
                                    users,
                                    (int)TcpCommands.WhiteboardPointsReceived,
                                    User.Username,
                                    messageID,
                                    pointData,
                                    whiteboardBrush,
                                    whiteboardThickness);
                            }

                            break;

                        case TcpCommands.EnteredText:

                            username = _br.ReadString();
                            user     = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);
                            users    = _br.ReadObject <ChatUser[]>();

                            if (user != null && !user.IsTyping)
                            {
                                user.IsTyping = true;

                                foreach (var recipient in _Program.Users.Values)
                                {
                                    if (recipient.Client != null)
                                    {
                                        if (users == null || users.Length == 0)
                                        {
                                            recipient.SendCommand(username, TcpCommands.UserEnteredText);
                                        }
                                        else if (users.Contains(recipient.Client.User))
                                        {
                                            recipient.SendCommand(username, TcpCommands.UserEnteredText);
                                        }
                                    }
                                }
                            }
                            break;

                        case TcpCommands.UserRemote:

                            username = _br.ReadString();
                            user     = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);

                            if (user != null)
                            {
                                user.IsRemote = true;
                                SendArgsToAllUsers((int)TcpCommands.OnUserRemote, username);
                            }
                            break;

                        case TcpCommands.UserNotRemote:

                            username = _br.ReadString();
                            user     = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);

                            if (user != null)
                            {
                                user.IsRemote = false;
                                SendArgsToAllUsers((int)TcpCommands.OnUserNotRemote, username);
                            }
                            break;

                        case TcpCommands.ClearedText:

                            username = _br.ReadString();
                            user     = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);
                            users    = _br.ReadObject <ChatUser[]>();

                            if (user != null && user.IsTyping)
                            {
                                user.IsTyping = false;

                                foreach (var recipient in _Program.Users.Values)
                                {
                                    if (recipient.Client != null)
                                    {
                                        if (users == null || users.Length == 0)
                                        {
                                            recipient.SendCommand(username, TcpCommands.UserClearedText);
                                        }
                                        else if (users.Contains(recipient.Client.User))
                                        {
                                            recipient.SendCommand(username, TcpCommands.UserClearedText);
                                        }
                                    }
                                }
                            }
                            break;

                        case TcpCommands.ChangeMood:

                            AppendLog("ChangeMood | reading username");
                            username = _br.ReadString();
                            AppendLog("ChangeMood | reading mood");
                            mood = _br.ReadString();
                            AppendLog("ChangeMood | finding user from list");
                            user = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);

                            if (user != null)
                            {
                                if (mood.Length > _MAX_MOOD_LENGTH)
                                {
                                    _Connection.SendError("Mood must be {0} characters or less", _MAX_MOOD_LENGTH);
                                    break;
                                }

                                user.Mood = mood;

                                AppendLog("ChangeMood | getting stats");
                                _Program.Stats.GetStats(User.Username).ChangedMood++;

                                AppendLog("ChangeMood | saving stats");
                                _Program.Stats.Save();

                                SendArgsToOtherUsers((int)TcpCommands.MoodChanged, username, mood);
                            }
                            break;

                        case TcpCommands.UserReadyForFooz:

                            username = _br.ReadString();
                            user     = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);

                            if (user != null && !user.IsFoozReady)
                            {
                                List <UserConnection> readyUsers = _Program.Users.Select(u => u.Value).Where(u => u.Client != null && u.Client.User.IsFoozReady).ToList();
                                if (readyUsers.Count < 4)
                                {
                                    UserConnection info;
                                    if (_Program.Users.TryGetValue(user, out info))
                                    {
                                        bool gameReady = readyUsers.Count == 3 && !readyUsers.Select(u => u.Client.User.Username).Contains(info.Client.User.Username);
                                        info.Client.User.IsFoozReady = true;
                                        ChatUserStats stats = _Program.Stats.GetStats(info.Client.User.Username);
                                        stats.FoozGameAttempts++;

                                        if (gameReady)
                                        {
                                            readyUsers.Add(info);
                                            readyUsers.Shuffle();

                                            readyUsers.ForEach(u =>
                                            {
                                                _Program.Stats.GetStats(u.Client.User.Username).FoozGamesRegistered++;
                                            });
                                        }

                                        foreach (var recipient in _Program.Users.Values)
                                        {
                                            if (recipient.Client != null)
                                            {
                                                recipient.SendCommand(username, TcpCommands.UserReadyForFooz);

                                                if (gameReady)
                                                {
                                                    users = readyUsers.Select(u => u.Client.User).ToArray();
                                                    recipient.SendArgs((int)TcpCommands.FoozGameReady, users);
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    _Connection.SendError("There are already 4 players ready for foosball");
                                }
                            }

                            break;

                        case TcpCommands.UserNotReadyForFooz:

                            username = _br.ReadString();
                            user     = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);

                            if (user != null && user.IsFoozReady)
                            {
                                user.IsFoozReady = false;
                                SendArgsToAllUsers((int)TcpCommands.UserNotReadyForFooz, username);
                            }
                            break;

                        case TcpCommands.LockWhiteboard:

                            messageID = _br.ReadString();

                            SendArgsToAllUsers((int)TcpCommands.WhiteboardLocked, messageID);

                            break;

                        case TcpCommands.UnlockWhiteboard:

                            messageID = _br.ReadString();

                            SendArgsToAllUsers((int)TcpCommands.WhiteboardUnlocked, messageID);

                            break;

                        case TcpCommands.ClearWhiteboard:

                            messageID = _br.ReadString();

                            SendArgsToAllUsers((int)TcpCommands.WhiteboardCleared, messageID);

                            break;

                        case TcpCommands.RequestUserStats:

                            username = _br.ReadString();
                            user     = _Program.Users.Keys.FirstOrDefault(u => u.Username == username);

                            if (user != null)
                            {
                                ChatUserStats stats = _Program.Stats.GetStats(username);
                                _Connection.SendArgs((int)TcpCommands.UserStatsReceived, user, stats);
                            }
                            else
                            {
                                _Connection.SendError("Could not find user");
                            }

                            break;

                        case TcpCommands.UserVotedOnPoll:
                            username = _br.ReadString();
                            pollID   = _br.ReadString();
                            choiceID = _br.ReadString();

                            SendArgsToAllUsers((int)TcpCommands.UserVotedOnPoll, username, pollID, choiceID);

                            break;

                        case TcpCommands.ClosePoll:

                            pollID = _br.ReadString();

                            SendArgsToAllUsers((int)TcpCommands.ClosePoll, pollID);

                            break;

                        case TcpCommands.UserRatedMessage:
                            username   = _br.ReadString();
                            messageID  = _br.ReadString();
                            voteStatus = (MessageRating)_br.ReadInt32();

                            userConnection = _Program.Users.Where(u => u.Key.Username == username).Select(u => u.Value).FirstOrDefault();
                            if (voteStatus == MessageRating.ThumbsDown)
                            {
                                _Program.Stats.GetStats(username).ThumbsDownGiven++;
                            }
                            else if (voteStatus == MessageRating.ThumbsUp)
                            {
                                _Program.Stats.GetStats(username).ThumbsUpGiven++;
                            }


                            // Find the message that they rated
                            ChatUserMessage messageRated = _Program.Messages.FirstOrDefault(m => m.ID == Guid.Parse(messageID));
                            if (messageRated != null)
                            {
                                UserConnection ratedUserConnection = _Program.Users.Where(u => u.Key.Username == messageRated.FromUser.Username).Select(u => u.Value).FirstOrDefault();
                                if (voteStatus == MessageRating.ThumbsDown)
                                {
                                    _Program.Stats.GetStats(messageRated.FromUser.Username).ThumbsDownReceived++;
                                }
                                else if (voteStatus == MessageRating.ThumbsUp)
                                {
                                    _Program.Stats.GetStats(messageRated.FromUser.Username).ThumbsUpReceived++;
                                }

                                SendArgsToAllUsers((int)TcpCommands.UserRatedMessage, username, messageID, (int)voteStatus);
                            }
                            break;

                        default:

                            break;
                        }
                        if (sw.ElapsedMilliseconds > 500)
                        {
                            ConsoleMessage("{0} from user {1} took {2}ms", command, _User.Username, sw.ElapsedMilliseconds);
                            ConsoleMessage(_detailedMessage.ToString());
                        }
                    }
                }
            }
            catch (IOException) { }
            catch (Exception ex)
            {
                TraceError("Unexpected Error 487546: {0}", ex.Message);
            }

            if (!_Program.ShuttingDown)
            {
                _User.IsFoozReady = false;
                _User.Status      = UserStatus.Offline;
                _User.IsTyping    = false;
                _Connection.SetClient(null);

                lock ( _lock )
                {
                    if (_User.IsBot)
                    {
                        _Program.Users.Remove(_User);
                    }

                    SendArgsToAllUsers((int)TcpCommands.UserLoggedOut, _User.Username);
                }

                ConsoleMessage("{0} Logged Out", _User.Username);
            }

            CloseConn();
        }