Пример #1
0
 public void AppendChatBoxListViewSeparateThread(T2SClientMessage message)
 {
     if (!string.IsNullOrEmpty(message.Message))
     {
         T2SUser sender = null;
         //Find profile picture from list of users
         foreach (T2SUser user in ConnectedUsers)
         {
             if (user.MacAddr == message.MacAddr)
             {
                 sender = user;
             }
         }
         ChatBox.Items.Add(new MessageTemplate
         {
             ProfilePicture = BitmapToImageSource(GetBitmapFromBytes(sender.ProfilePicture)),
             Message        = message.Message
         });
     }
 }
Пример #2
0
        /// <summary>
        /// Sends a bytes to the server, simply containing a T2SClientMessage and header
        /// </summary>
        public void SendMessage(string text, bool firstConnect, bool updateProfile)
        {
            T2SClientMessage message = new T2SClientMessage()
            {
                MacAddr        = this.MacAddr,
                ProfilePicture = (updateProfile) ? this.ProfilePicture : null,
                UpdateProfile  = updateProfile, //change to be a bool that is set when we add Profile settings
                Username       = this.Username,
                FirstConnect   = firstConnect,  //change to be a bool
                Message        = text
            };

            byte[] buffer = ObjectToByteArray(message), temp = ObjectToByteArray(message);

            string header = buffer.Length.ToString();

            //If the header length is larger than the maximum length, we're gonna assume that the dude is trying to destroy someone with a fat receive.
            //There's no reason for something to be this large
            //Therefore, just let the sender know that their message is waaaay too big
            if (header.Length < 32)
            {
                Console.WriteLine("Generating header...");
                for (int i = header.Length; i < 32; i++)
                {
                    header += " "; //Append empty spaces until header is max length (32)
                }
                byte[] headerBytes = Encoding.ASCII.GetBytes(header + "|");

                buffer = new byte[temp.Length + headerBytes.Length];

                Array.Copy(headerBytes, buffer, headerBytes.Length);
                Array.Copy(temp, 0, buffer, 33, temp.Length);
                //Append own text
                ChatBox.Dispatcher.Invoke(new AppendRTBSeparateThreadCallback(this.AppendChatBoxListViewSeparateThread), new object[] { message });
                ClientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);
            }
        }
Пример #3
0
 public void RemoveListViewConnecteduseresSeparateThread(T2SClientMessage message)
 {
     CollectionViewSource.GetDefaultView(ConnectedUsers).Refresh();
 }
Пример #4
0
        /// <summary>
        /// Receives byte array from server, converts to ASCII encoding to display
        /// Note that this is occurring on a separate thread
        ///
        /// HEADER AND BODY
        /// Header is defined as the zeroth index of a BAR | string split
        /// The header may also never be larger than 32 bytes (if it is, then this implies the message is SUPER long and we should probably just ignore it.
        ///     The server should also recognize this failure and send an error message to the sending client that the message sent is too large (like, honestly, 32 bytes is a 32 digit integer.
        ///     Who even would send something that big?
        ///     RIP that person's bandwidth lol))
        /// The header will represent the TOTAL LENGTH EXCLUSIVE of the header, thereby representing the buffer length of the NEXT receive, which should by protocol be a json file.
        /// The header will also always be length 32, append pipe separator to be 33
        ///
        /// The first index will be a byte array that is the object T2SClientMessage
        ///
        /// </summary>
        private void ReceiveResponse()
        {
            if (!IsConnected(ClientSocket))
            {
                Console.WriteLine("here");
                Disconnect();
            }
            int received = 0;
            var buffer   = new byte[33];

            try
            {
                received = ClientSocket.Receive(buffer, 33, SocketFlags.None);
            }
            catch (Exception e)
            {
                Console.WriteLine("EXCEPTION");
                return;
            }
            if (received == 0)
            {
                return;                                     //Nothing to receive
            }
            string text = Encoding.ASCII.GetString(buffer); //Hopefully the header

            Console.WriteLine(text);
            //If full header not grabbed, append the new bytes until header is grabbed
            while (received < 33)
            {
                byte[] tempBuffer      = new byte[33 - received];
                int    appendableBytes = ClientSocket.Receive(tempBuffer, 33 - received, SocketFlags.None);
                Array.Copy(tempBuffer, 0, buffer, received, tempBuffer.Length);
                received += appendableBytes;
            }
            Console.WriteLine("Received");
            int header;

            //Successfully got header
            if (Int32.TryParse(text.Split('|')[0], out header))
            {
                buffer   = new byte[header];
                received = ClientSocket.Receive(buffer, header, SocketFlags.None);
                while (received < header)
                {
                    byte[] tempBuffer      = new byte[header - received];
                    int    appendableBytes = ClientSocket.Receive(tempBuffer, header - received, SocketFlags.None);
                    Array.Copy(tempBuffer, 0, buffer, received, tempBuffer.Length);
                    received += appendableBytes;
                }

                T2SClientMessage message = (T2SClientMessage)ByteArrayToObject(buffer);
                //Perform logic
                //In order to do anything, the client must first be connected
                if (message.Connected)
                {
                    //If this is the first connection, we're not going to display anything new in the chat
                    if (message.FirstConnect)
                    {
                        ConnectedUsers.Add(new T2SUser()
                        {
                            MacAddr        = message.MacAddr,
                            Username       = message.Username,
                            ProfilePicture = message.ProfilePicture
                        });
                        ListView_ConnectedUsers.Dispatcher.Invoke(new AppendListViewConnectedUsersSeparateThreadCallback(this.AppendListViewConnecteduseresSeparateThread), new object[] { message });
                    }
                    else
                    {
                        if (message.UpdateProfile)
                        {
                            bool found = false;
                            //Modify user if macaddr exists. If not, add
                            foreach (T2SUser user in ConnectedUsers)
                            {
                                if (user.MacAddr == message.MacAddr)
                                {
                                    //exists. So update the user
                                    user.ProfilePicture = (message.ProfilePicture == null) ? user.ProfilePicture : message.ProfilePicture;
                                    user.Username       = message.Username; //Should never be null
                                    found = true;
                                    //Found, therefore look for the user in the ListView_ConnectedUsers and update the user
                                    ListView_ConnectedUsers.Dispatcher.Invoke(new UpdateUserListViewConnectedUsersSeparateThreadCallback(this.UpdateUserListViewConnecteduseresSeparateThread), new object[] { user });
                                    break;
                                }
                            }
                            //Not found, therefore add the user to ConnectedUser list and thingy
                            if (!found)
                            {
                                ConnectedUsers.Add(new T2SUser()
                                {
                                    MacAddr        = message.MacAddr,
                                    Username       = message.Username,
                                    ProfilePicture = message.ProfilePicture
                                });
                            }
                        }
                        //Append to visual and do TTS
                        speech.SpeakAsync(message.Message);
                        ChatBox.Dispatcher.Invoke(new AppendRTBSeparateThreadCallback(this.AppendChatBoxListViewSeparateThread), new object[] { message });
                    }
                }
                else
                {
                    T2SUser user = ConnectedUsers.Find(x => x.MacAddr == message.MacAddr);
                    if (user != null)
                    {
                        ConnectedUsers.Remove(user);
                    }
                    ListView_ConnectedUsers.Dispatcher.Invoke(new RemoveListViewConnectedUsersSeparateThreadCallback(this.RemoveListViewConnecteduseresSeparateThread), new object[] { message });
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Message callback function
        /// Send user data back based on first connect or message
        /// </summary>
        /// <param name="AR"></param>
        private static void ReceiveCallback(IAsyncResult AR)
        {
            Socket current = (Socket)AR.AsyncState;
            int    received;

            if (!current.Connected)
            {
                return;
            }
            try
            {
                received = current.EndReceive(AR);
            }
            catch (SocketException)
            {
                Console.WriteLine("Client forcefully disconnected");
                // Don't shutdown because the socket may be disposed and its disconnected anyway.
                current.Close();
                SocketPair socketToRemove = null;
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket.Equals(current))
                    {
                        socketToRemove = s;
                        break;
                    }
                }
                if (socketToRemove != null)
                {
                    clientSockets.Remove(socketToRemove);
                    T2SClientMessage otherClient = new T2SClientMessage()
                    {
                        Connected = false,
                        MacAddr   = socketToRemove.MacAddr
                    };
                    byte[] otherClientBuffer        = MainWindow.ObjectToByteArray(otherClient);
                    byte[] otherClientBufferMessage = new byte[otherClientBuffer.Length + 33]; //message to send; appends length of header
                    string otherClientHeader        = otherClientBuffer.Length.ToString();
                    for (int i = otherClientHeader.Length; i < 32; i++)
                    {
                        otherClientHeader += " "; //Append empty spaces until header is max length (32)
                    }
                    otherClientHeader += "|";

                    Array.Copy(Encoding.ASCII.GetBytes(otherClientHeader), otherClientBufferMessage, 33);
                    Array.Copy(otherClientBuffer, 0, otherClientBufferMessage, 33, otherClientBuffer.Length);

                    //Sendto everyone
                    foreach (SocketPair s in clientSockets)
                    {
                        s.socket.Send(otherClientBufferMessage);
                    }
                }
                return;
            }

            if (received == 0)
            {
                Console.WriteLine("No bytes received; closing socket");
                SocketPair socketToRemove = null;
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket.Equals(current))
                    {
                        socketToRemove = s;
                        break;
                    }
                }
                if (socketToRemove.socket.Connected)
                {
                    socketToRemove.socket.Close();
                }
                clientSockets.Remove(socketToRemove);
                T2SClientMessage otherClient = new T2SClientMessage()
                {
                    Connected = false,
                    MacAddr   = socketToRemove.MacAddr
                };
                byte[] otherClientBuffer        = MainWindow.ObjectToByteArray(otherClient);
                byte[] otherClientBufferMessage = new byte[otherClientBuffer.Length + 33]; //message to send; appends length of header
                string otherClientHeader        = otherClientBuffer.Length.ToString();
                for (int i = otherClientHeader.Length; i < 32; i++)
                {
                    otherClientHeader += " "; //Append empty spaces until header is max length (32)
                }
                otherClientHeader += "|";

                Array.Copy(Encoding.ASCII.GetBytes(otherClientHeader), otherClientBufferMessage, 33);
                Array.Copy(otherClientBuffer, 0, otherClientBufferMessage, 33, otherClientBuffer.Length);

                //Sendto everyone
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket.Connected)
                    {
                        s.socket.Send(otherClientBufferMessage);
                    }
                }
                return;
            }

            byte[] recBuf = new byte[received]; //Received buffer which should be the header to tell us the buffer length of the json message (should be length 33 with pipe at the end)
            Array.Copy(buffer, recBuf, received);

            //Get until header is filled
            while (received < 33)
            {
                byte[] tempBuffer      = new byte[33 - received];
                int    appendableBytes = current.Receive(tempBuffer, 33 - received, SocketFlags.None);
                Array.Copy(tempBuffer, 0, recBuf, received, tempBuffer.Length);
                received += appendableBytes;
            }

            int headerReceived;

            if (Int32.TryParse(Encoding.ASCII.GetString(recBuf).Split('|')[0], out headerReceived))
            {
                recBuf   = new byte[headerReceived];
                received = current.Receive(recBuf, headerReceived, SocketFlags.None);
                //Get until object is filled
                while (received < headerReceived)
                {
                    byte[] tempBuffer      = new byte[headerReceived - received];
                    int    appendableBytes = current.Receive(tempBuffer, headerReceived - received, SocketFlags.None);
                    Array.Copy(tempBuffer, 0, recBuf, received, tempBuffer.Length);
                    received += appendableBytes;
                }
            }
            byte[] temp = new byte[recBuf.Length];
            Array.Copy(recBuf, temp, temp.Length);
            string header = recBuf.Length.ToString();

            //If the header length is larger than the maximum length, we're gonna assume that the dude is trying to destroy someone with a fat receive.
            //There's no reason for something to be this large
            //Therefore, just let the sender know that their message is waaaay too big
            if (header.Length < 32)
            {
                for (int i = header.Length; i < 32; i++)
                {
                    header += " "; //Append empty spaces until header is max length (32)
                }

                byte[] headerBytes = Encoding.ASCII.GetBytes(header + "|");

                T2SClientMessage clientMessage = (T2SClientMessage)MainWindow.ByteArrayToObject(recBuf);
                temp   = MainWindow.ObjectToByteArray(clientMessage);
                recBuf = new byte[temp.Length + headerBytes.Length];

                Array.Copy(headerBytes, recBuf, headerBytes.Length);
                Array.Copy(temp, 0, recBuf, 33, temp.Length);

                byte[] message = recBuf; //Append message with the header

                //Send to all connected sockets except self
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket != current)
                    {
                        s.socket.Send(message);
                    }
                }
                if (clientMessage.UpdateProfile)
                {
                    foreach (SocketPair s in clientSockets)
                    {
                        if (s.MacAddr == clientMessage.MacAddr)
                        {
                            s.ProfilePicture = (clientMessage.ProfilePicture == null) ? s.ProfilePicture : clientMessage.ProfilePicture;
                            s.Username       = clientMessage.Username;
                            break;
                        }
                    }
                }
                //If this is the first connection, we need to update our socketpair MacAddr for audit (also just send back to client)
                if (clientMessage.FirstConnect)
                {
                    Console.WriteLine("First connect: " + clientMessage.Username);
                    foreach (SocketPair s in clientSockets)
                    {
                        if (s.socket == current)
                        {
                            s.MacAddr        = clientMessage.MacAddr;
                            s.Username       = clientMessage.Username;
                            s.ProfilePicture = clientMessage.ProfilePicture;
                        }
                        else
                        {
                            T2SClientMessage otherClient = new T2SClientMessage()
                            {
                                FirstConnect   = true,
                                ProfilePicture = s.ProfilePicture,
                                Username       = s.Username,
                                MacAddr        = s.MacAddr
                            };
                            byte[] otherClientBuffer        = MainWindow.ObjectToByteArray(otherClient);
                            byte[] otherClientBufferMessage = new byte[otherClientBuffer.Length + 33]; //message to send; appends length of header
                            string otherClientHeader        = otherClientBuffer.Length.ToString();
                            for (int i = otherClientHeader.Length; i < 32; i++)
                            {
                                otherClientHeader += " "; //Append empty spaces until header is max length (32)
                            }
                            otherClientHeader += "|";

                            Array.Copy(Encoding.ASCII.GetBytes(otherClientHeader), otherClientBufferMessage, 33);
                            Array.Copy(otherClientBuffer, 0, otherClientBufferMessage, 33, otherClientBuffer.Length);

                            current.Send(otherClientBufferMessage);
                        }
                    }
                    current.Send(message); //Send the profile back to themself
                }
            }
            else
            {
                Console.WriteLine("HEADER TOO LARGE!!! Header length: " + header.Length);
            }
            current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
        }