private void ProcessMessages()
        {
            NetIncomingMessage msg;

            while ((msg = _server.ReadMessage()) != null)
            {
                switch (msg.MessageType)
                {
                    #region Data
                case NetIncomingMessageType.Data:
                {
                    //Read Packet Header (Byte) and Convert It To PacketTypes Enum
                    byte          PacketHeader = msg.ReadByte();
                    Packets.Types PacketType   = (Packets.Types)Enum.ToObject(typeof(Packets.Types), PacketHeader);

                    //Switch Read Functionality Based on Packet Header
                    switch (PacketType)
                    {
                    case Packets.Types.MOVE:
                    {
                        //Read Move Packet
                        Packets.MovePacket movePacket = new Packets.MovePacket();
                        Packets.ReadPacket(ref msg, ref movePacket);

                        //Update Local Simulation
                        InvokePlayerMove(new PlayerMoveEventArgs(movePacket.uid, movePacket.posX, movePacket.posY, movePacket.facingDirection));
                        //Foward Move Packet
                        NetOutgoingMessage outMsg = _server.CreateMessage();
                        Packets.WritePacket(ref outMsg, ref movePacket);
                        SendPacketExcept(outMsg, msg.SenderConnection, NetDeliveryMethod.UnreliableSequenced, 1);
                        break;
                    }

                    case Packets.Types.ATTACK:
                    {
                        // Read attack packet.
                        Packets.AttackPacket attackPacket = new Packets.AttackPacket();
                        Packets.ReadPacket(ref msg, ref attackPacket);

                        // Update local simulation.
                        InvokePlayerAttack(new PlayerAttackEventArgs(attackPacket.uid, attackPacket.posX, attackPacket.posY, attackPacket.facingDirection));

                        // Forward Attack packet.
                        NetOutgoingMessage outMsg = _server.CreateMessage();
                        Packets.WritePacket(ref outMsg, attackPacket);
                        SendPacketExcept(outMsg, msg.SenderConnection, NetDeliveryMethod.ReliableUnordered);
                        break;
                    }
                    }
                    break;
                }
                    #endregion Data

                // If incoming message is Request for connection approval
                // This is the very first packet/message that is sent from client
                // Here you can do new player initialisation stuff
                case NetIncomingMessageType.ConnectionApproval:
                {
                    //Read Packet Header (Byte) and Convert It To PacketTypes Enum
                    byte          PacketHeader = msg.ReadByte();
                    Packets.Types PacketType   =
                        (Packets.Types)Enum.ToObject(typeof(Packets.Types), PacketHeader);

                    //Switch Read Functionality Based on Packet Header
                    if (PacketType == Packets.Types.LOGIN_REQUEST)
                    {
                        Packets.PlayerPacket packet;

                        //LoginRequestPacket
                        {
                            //Create Packet
                            Packets.LoginRequestPacket loginPacket = new Packets.LoginRequestPacket();

                            //Read Packet Data From Message
                            Packets.ReadPacket(ref msg, ref loginPacket);

                            // Approve clients connection ( Its sort of agreement. "You can be my client and i will host you" )
                            msg.SenderConnection.Approve();

                            //Create new Player Instance
                            packet = new Packets.PlayerPacket(loginPacket.name, msg.SenderConnection.RemoteUniqueIdentifier, 50, 50, Player.FacingDirections.N);

                            // Invoke Event Handler
                            InvokeOnPlayerConnected(new PlayerConnectedEventArgs()
                                {
                                    playerPacket = packet
                                });
                        }


                        //LoginResponcePacket
                        {
                            Packets.LoginResponcePacket loginResponcePacket = new Packets.LoginResponcePacket(0, packet);

                            NetOutgoingMessage outMsg = _server.CreateMessage();
                            Packets.WritePacket(ref outMsg, ref loginResponcePacket);

                            _loginResponceQueue.Add(new MessageQueue()
                                {
                                    connection = msg.SenderConnection,
                                    msg        = outMsg,
                                    target     = MessageTarget.GLOBAL_EXCEPT
                                });
                        }

                        //World Packet
                        {
                            Packets.WorldPacket worldPacket = new Packets.WorldPacket(0);

                            foreach (var player in Player.AllPlayers)
                            {
                                worldPacket.playerCount++;
                                worldPacket.playerPackets.Add(Packets.CreatePlayerPacket(player));
                            }

                            NetOutgoingMessage outMsg = _server.CreateMessage();
                            Packets.WritePacket(ref outMsg, ref worldPacket);

                            _loginResponceQueue.Add(new MessageQueue()
                                {
                                    connection = msg.SenderConnection,
                                    msg        = outMsg,
                                    target     = MessageTarget.DIRECT
                                });
                        }
                    }        //if request pecket
                }
                break;

                case NetIncomingMessageType.ConnectionLatencyUpdated:
                case NetIncomingMessageType.DebugMessage:
                case NetIncomingMessageType.DiscoveryRequest:
                case NetIncomingMessageType.DiscoveryResponse:
                case NetIncomingMessageType.Error:
                case NetIncomingMessageType.ErrorMessage:
                case NetIncomingMessageType.NatIntroductionSuccess:
                case NetIncomingMessageType.Receipt:
                case NetIncomingMessageType.StatusChanged:
                {
                    NetConnectionStatus status = (NetConnectionStatus)msg.ReadByte();
                    switch (status)
                    {
                    case NetConnectionStatus.Connected:
                    {
                        //Inform Clients of Connection Event
                        NetOutgoingMessage    outMsg        = _server.CreateMessage();
                        Packets.ConnectPacket connectPacket = new Packets.ConnectPacket();
                        connectPacket.uid = msg.SenderConnection.RemoteUniqueIdentifier;

                        //Write Packet
                        Packets.WritePacket(ref outMsg, ref connectPacket);
                        SendPacketExcept(outMsg, msg.SenderConnection, NetDeliveryMethod.ReliableOrdered);

                        break;
                    }

                    case NetConnectionStatus.Disconnected:
                    {
                        //Inform Clients of Disconnection Event
                        NetOutgoingMessage       outMsg           = _server.CreateMessage();
                        Packets.DisconnectPacket disconnectPacket = new Packets.DisconnectPacket();
                        disconnectPacket.uid = msg.SenderConnection.RemoteUniqueIdentifier;

                        //Write Packet
                        Packets.WritePacket(ref outMsg, ref disconnectPacket);
                        SendPacketExcept(outMsg, msg.SenderConnection, NetDeliveryMethod.ReliableOrdered);

                        //Invoke Disconnected Event Handler
                        InvokeOnPlayerDisconnected(new PlayerDisconnectedEventArgs(msg.SenderConnection.RemoteUniqueIdentifier));
                        break;
                    }

                    case NetConnectionStatus.Disconnecting:
                    {
                        break;
                    }

                    case NetConnectionStatus.InitiatedConnect:
                    {
                        break;
                    }

                    case NetConnectionStatus.None:
                    {
                        break;
                    }

                    case NetConnectionStatus.RespondedConnect:
                    {
                        break;
                    }
                    }
                    break;
                }

                case NetIncomingMessageType.UnconnectedData:
                case NetIncomingMessageType.VerboseDebugMessage:
                case NetIncomingMessageType.WarningMessage:
                default:
                {
                    //Console.WriteLine("Unhandled type: " + msg.MessageType);
                    break;
                }
                }
                _server.Recycle(msg);
            }
        }