private void ServerMsgCallBack(object peer)
        {
            NetIncomingMessage im;

            while ((im = this.Server.ReadMessage()) != null)
            {
                switch (im.MessageType)
                {
                case NetIncomingMessageType.VerboseDebugMessage:
                case NetIncomingMessageType.DebugMessage:
                case NetIncomingMessageType.WarningMessage:
                case NetIncomingMessageType.ErrorMessage:
                    //LogServer(im.ReadString());
                    break;

                case NetIncomingMessageType.ConnectionLatencyUpdated:
                    Console.WriteLine(im.ReadFloat());
                    //this.PlayerManager.Entites [im.SenderConnection.RemoteUniqueIdentifier].Ping = im.ReadFloat();

                    break;

                /**************************************************************/
                //Handle Discovery
                /**************************************************************/
                case NetIncomingMessageType.DiscoveryRequest:


                    LogServer(string.Format("     ------- Discovery Request Recieved from: {0}", im.SenderEndPoint));
                    vxNetServerEventDiscoverySignalRequest discoveryRequestEvent = new vxNetServerEventDiscoverySignalRequest(im.SenderEndPoint);

                    if (DiscoverySignalRequestRecieved != null)
                    {
                        DiscoverySignalRequestRecieved(this, discoveryRequestEvent);
                    }


                    if (discoveryRequestEvent.SendResponse == true)
                    {
                        // Create a response and write some example data to it
                        NetOutgoingMessage response = this.Server.CreateMessage();

                        //Send Back Connection Information, the client will still need to Authenticate with a Secret though
                        //response.Write(discoveryRequestEvent.Response);
                        var resp = new vxNetmsgServerInfo("Test Server",
                                                          this.Server.Configuration.BroadcastAddress.ToString(),
                                                          this.Server.Configuration.Port.ToString());

                        resp.EncodeMsg(response);

                        // Send the response to the sender of the request
                        this.Server.SendDiscoveryResponse(response, im.SenderEndPoint);
                    }
                    else
                    {
                        //The discovery response was blocked in the event. Notify on the server why but do not respond to the client.
                        LogServer(string.Format("\n--------------------------\nDISCOVERY REQUEST BLOCKED\n IPEndpoint: '{0}'\nREASON: '{1}' \n--------------------------\n", im.SenderEndPoint, discoveryRequestEvent.Response));
                    }


                    break;



                /**************************************************************/
                //Handle Connection Approval
                /**************************************************************/
                case NetIncomingMessageType.ConnectionApproval:
                    string s = im.ReadString();
                    if (s == "secret")
                    {
                        NetOutgoingMessage approve = Server.CreateMessage();
                        im.SenderConnection.Approve(approve);
                        LogServer(string.Format("{0} Connection Approved", im.SenderEndPoint));
                    }
                    else
                    {
                        im.SenderConnection.Deny();

                        LogServer(string.Format("{0} Connection DENIED!", im.SenderEndPoint));
                    }
                    break;


                case NetIncomingMessageType.StatusChanged:
                    switch ((NetConnectionStatus)im.ReadByte())
                    {
                    case NetConnectionStatus.Connected:
                        LogServer(string.Format(" \t\t {0} Connected", im.SenderEndPoint));

                        if (ClientConnected != null)
                        {
                            ClientConnected(this, new vxNetServerEventClientConnected(im.SenderConnection.RemoteUniqueIdentifier));
                        }

                        break;

                    case NetConnectionStatus.Disconnected:
                        LogServer(string.Format("{0} Disconnected", im.SenderEndPoint));

                        //For what ever reason, a player has disconnected, so we need to remove it from the player list

                        //Send a message to all clients to remove this client from their list.
                        var rmvMsg = new vxNetmsgRemovePlayer(PlayerManager.Players[im.SenderConnection.RemoteUniqueIdentifier]);

                        //Send the message to all clients.
                        SendMessage(rmvMsg);

                        //Fire the Server Event for any outside events
                        if (ClientDisconnected != null)
                        {
                            ClientDisconnected(this, new vxNetServerEventClientDisconnected(im.SenderConnection.RemoteUniqueIdentifier));
                        }

                        //Finally remove the player from the server's list
                        if (PlayerManager.Players.ContainsKey(im.SenderConnection.RemoteUniqueIdentifier))
                        {
                            PlayerManager.Players.Remove(im.SenderConnection.RemoteUniqueIdentifier);
                        }

                        break;

                    default:
                        LogServer(im.ReadString());
                        break;
                    }
                    break;

                case NetIncomingMessageType.Data:
                    var gameMessageType = (vxNetworkMessageTypes)im.ReadByte();
                    switch (gameMessageType)
                    {
                    /**************************************************************/
                    //Handle New Player Connection
                    /**************************************************************/
                    case vxNetworkMessageTypes.PlayerConnected:

                        //Decode the Message
                        var newPlayer = new vxNetmsgAddPlayer(im);

                        //Add the new player info to the Server List
                        PlayerManager.Add(newPlayer.PlayerInfo);

                        newPlayer.PlayerInfo.Status = vxEnumNetPlayerStatus.InServerLobbyNotReady;

                        //Now Update all clients with the Player list using the server Player List
                        var newPlayerList = new vxNetmsgUpdatePlayerList(this.PlayerManager);
                        SendMessage(newPlayerList);

                        break;



                    /**************************************************************/
                    //Handle Player Lobby Status Update
                    /**************************************************************/
                    case vxNetworkMessageTypes.UpdatePlayerLobbyStatus:

                        //Decode the list
                        var updatePlayerState = new vxNetmsgUpdatePlayerLobbyStatus(im);

                        //Update the internal server list
                        PlayerManager.Players[updatePlayerState.PlayerInfo.ID] = updatePlayerState.PlayerInfo;

                        //Now resend it back to all clients
                        SendMessage(updatePlayerState);

                        if (UpdatePlayerStatus != null)
                        {
                            UpdatePlayerStatus(this, new vxNetServerEventPlayerStatusUpdate(updatePlayerState.PlayerInfo));
                        }
                        break;



                    /**************************************************************/
                    //Handles an Update to a Player's Entity State
                    /**************************************************************/
                    case vxNetworkMessageTypes.UpdatePlayerEntityState:

                        //First decode the message
                        var updatePlayerEntityState = new vxNetmsgUpdatePlayerEntityState(im);

                        //get the time delay
                        var timeDelay = (float)(NetTime.Now - im.SenderConnection.GetLocalTime(updatePlayerEntityState.MessageTime));

                        //Then Update the Player in the Server List
                        PlayerManager.Players[updatePlayerEntityState.PlayerInfo.ID] = updatePlayerEntityState.PlayerInfo;

                        //Then fire any tied events in the server
                        if (UpdatePlayerEntityState != null)
                        {
                            UpdatePlayerEntityState(this, new vxNetServerEventPlayerStateUpdate(updatePlayerEntityState.PlayerInfo));
                        }


                        //Finally, relay the updated state too all clients.
                        SendMessage(updatePlayerEntityState);

                        break;


                    case vxNetworkMessageTypes.AddItem:

                        break;

                    case vxNetworkMessageTypes.RemoveItem:

                        break;

                    case vxNetworkMessageTypes.Other:

                        break;
                    }
                    break;


                default:
                    break;
                }

                this.Server.Recycle(im);
            }
        }
        /// <summary>
        /// Method for Receiving Messages kept in a Global Scope for the Engine.
        /// </summary>
        /// <param name="peer">Peer.</param>
        public void ClientMsgCallback(object peer)
        {
            NetIncomingMessage im;

            while ((im = this.Client.ReadMessage()) != null)
            {
                switch (im.MessageType)
                {
                case NetIncomingMessageType.VerboseDebugMessage:
                case NetIncomingMessageType.DebugMessage:
                case NetIncomingMessageType.WarningMessage:
                case NetIncomingMessageType.ErrorMessage:
                    //LogClient("DEBUG: " + im.ReadString());
                    break;

                /**************************************************************/
                //DiscoveryResponse
                /**************************************************************/
                case NetIncomingMessageType.DiscoveryResponse:

                    LogClient("     ------- Server found at: " + im.SenderEndPoint);

                    //Fire the RecieveDiscoverySignalResponse Event by passing down the decoded Network Message
                    if (DiscoverySignalResponseRecieved != null)
                    {
                        DiscoverySignalResponseRecieved(this, new vxNetClientEventDiscoverySignalResponse(new vxNetmsgServerInfo(im)));
                    }

                    break;

                case NetIncomingMessageType.StatusChanged:
                    switch ((NetConnectionStatus)im.ReadByte())
                    {
                    case NetConnectionStatus.Connected:
                    {
                        LogClient(string.Format("{0} Connected", im.SenderEndPoint));

                        //Fire the Connected Event
                        if (Connected != null)
                        {
                            Connected(this, new vxNetClientEventConnected());
                        }
                    }
                    break;

                    case NetConnectionStatus.Disconnected:
                    {
                        LogClient(string.Format("{0} Disconnected", im.SenderEndPoint));

                        //Fire the Connected Event
                        if (Disconnected != null)
                        {
                            Disconnected(this, new vxNetClientEventDisconnected());
                        }
                    }
                    break;

                    default:
                        LogClient(im.ReadString());
                        break;
                    }
                    break;

                case NetIncomingMessageType.Data:
                    var gameMessageType = (vxNetworkMessageTypes)im.ReadByte();
                    switch (gameMessageType)
                    {
                    case vxNetworkMessageTypes.UpdatePlayersList:

                        //Get the Message Containing the Updated Player List
                        var updatedPlayerList = new vxNetmsgUpdatePlayerList(im);

                        //Now Loop through each player in the list
                        foreach (vxNetPlayerInfo serverPlayer in updatedPlayerList.Players)
                        {
                            //First Check if the Server Player is in the clients list. If not, then add the server player to the clients list.
                            if (PlayerManager.Contains(serverPlayer))
                            {
                                PlayerManager.Players[serverPlayer.ID] = serverPlayer;
                            }
                            else
                            {
                                //Add Player to Player manager
                                PlayerManager.Add(serverPlayer);

                                //Now Fire the Event Handler
                                if (OtherPlayerConnected != null)
                                {
                                    OtherPlayerConnected(this, new vxNetClientEventPlayerConnected(serverPlayer));
                                }
                            }
                        }
                        break;

                    case vxNetworkMessageTypes.PlayerDisconnected:

                        //For what ever reason, a player has disconnected, so we need to remove it from the player list

                        //Send a message to all clients to remove this client from their list.
                        var rmvMsg = new vxNetmsgRemovePlayer(im);

                        //Fire the Connected Event
                        if (OtherPlayerDisconnected != null)
                        {
                            OtherPlayerDisconnected(this, new vxNetClientEventPlayerDisconnected(rmvMsg.PlayerInfo));
                        }

                        //Finally remove the player from the server's list
                        if (PlayerManager.Players.ContainsKey(rmvMsg.PlayerInfo.ID))
                        {
                            PlayerManager.Players.Remove(rmvMsg.PlayerInfo.ID);
                        }

                        break;

                    case vxNetworkMessageTypes.UpdatePlayerLobbyStatus:

                        //Decode the list
                        var updatePlayerState = new vxNetmsgUpdatePlayerLobbyStatus(im);

                        //Update the internal server list
                        PlayerManager.Players[updatePlayerState.PlayerInfo.ID] = updatePlayerState.PlayerInfo;

                        if (UpdatedPlayerInfoRecieved != null)
                        {
                            UpdatedPlayerInfoRecieved(this, new vxNetClientEventPlayerStatusUpdate(updatePlayerState.PlayerInfo));
                        }


                        break;

                    case vxNetworkMessageTypes.SessionStatus:

                        //Get Old Status for information
                        vxEnumSessionStatus oldStatus = this.SessionStatus;
                        var newSessionStatus          = new vxNetmsgUpdateSessionStatus(im);

                        //Set the new Session Status
                        this.SessionStatus = newSessionStatus.SessionStatus;

                        //Fire any connected events
                        if (UpdateSessionStatus != null)
                        {
                            UpdateSessionStatus(this, new vxNetClientEventSessionStatusUpdated(oldStatus, this.SessionStatus));
                        }

                        break;


                    case vxNetworkMessageTypes.UpdatePlayerEntityState:

                        //First decode the message
                        var updatePlayerEntityState = new vxNetmsgUpdatePlayerEntityState(im);

                        var timeDelay = (float)(NetTime.Now - im.SenderConnection.GetLocalTime(updatePlayerEntityState.MessageTime));

                        //Console.WriteLine("Client:" + timeDelay);

                        //Only set the information if it isn't our own info
                        if (this.PlayerInfo.ID != updatePlayerEntityState.PlayerInfo.ID)
                        {
                            //Then Update the Player in the client List
                            PlayerManager.Players[updatePlayerEntityState.PlayerInfo.ID] = updatePlayerEntityState.PlayerInfo;

                            //Then fire any connected events
                            if (UpdatePlayerEntityState != null)
                            {
                                UpdatePlayerEntityState(this, new vxNetClientEventPlayerStateUpdate(updatePlayerEntityState, timeDelay));
                            }
                        }
                        break;

                    case vxNetworkMessageTypes.RemoveItem:

                        break;

                    case vxNetworkMessageTypes.Other:

                        break;
                    }
                    break;
                }
                Recycle(im);
            }
        }