#region File Description //----------------------------------------------------------------------------- // SearchResultsScreen.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Net; #endregion namespace NetRumble { /// /// The search-results screen shows the results of a network-session /// search, allowing the player to pick the game to join. /// public class SearchResultsScreen : MenuScreen { #region Constants /// /// The maximum number of session results to display. /// const int maximumSessions = 8; #endregion #region Networking Data /// /// The type of networking session that was requested. /// private NetworkSessionType sessionType; /// /// The collection of search results. /// private AvailableNetworkSessionCollection availableSessions = null; #endregion #region Initialization /// /// Constructor fills in the menu contents. /// /// The type of session searched for. public SearchResultsScreen(NetworkSessionType sessionType) : base() { // apply the parameters this.sessionType = sessionType; // set the transition times TransitionOnTime = TimeSpan.FromSeconds(1.0); TransitionOffTime = TimeSpan.FromSeconds(0.0); } #endregion #region Updating Methods /// /// Updates the screen. This method checks the GameScreen.IsActive /// property, so the game will stop updating when the pause menu is active, /// or if you tab away to a different application. /// public override void Update(Microsoft.Xna.Framework.GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { bool signedIntoLive = false; if (Gamer.SignedInGamers.Count > 0) { foreach (SignedInGamer signedInGamer in Gamer.SignedInGamers) { if (signedInGamer.IsSignedInToLive) { signedIntoLive = true; break; } } if (!signedIntoLive && ((sessionType == NetworkSessionType.PlayerMatch) || (sessionType == NetworkSessionType.Ranked)) && !IsExiting) { ExitScreen(); } } else if (!IsExiting) { ExitScreen(); } if (coveredByOtherScreen && !IsExiting) { ExitScreen(); } base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen); } /// /// Responds to user menu selections. /// protected override void OnSelectEntry(int entryIndex) { if ((availableSessions != null) && (entryIndex >= 0) && (entryIndex < availableSessions.Count)) { // start to join try { IAsyncResult asyncResult = NetworkSession.BeginJoin( availableSessions[entryIndex], null, null); // create the busy screen NetworkBusyScreen busyScreen = new NetworkBusyScreen( "Joining the session...", asyncResult); busyScreen.OperationCompleted += LoadLobbyScreen; ScreenManager.AddScreen(busyScreen); } catch (NetworkException ne) { const string message = "Failed joining the session."; MessageBoxScreen messageBox = new MessageBoxScreen(message); messageBox.Accepted += FailedMessageBox; messageBox.Cancelled += FailedMessageBox; ScreenManager.AddScreen(messageBox); System.Console.WriteLine("Failed to join session: " + ne.Message); } catch (GamerPrivilegeException gpe) { const string message = "You do not have permission to join a session."; MessageBoxScreen messageBox = new MessageBoxScreen(message); messageBox.Accepted += FailedMessageBox; messageBox.Cancelled += FailedMessageBox; ScreenManager.AddScreen(messageBox); System.Console.WriteLine( "Insufficient privilege to join session: " + gpe.Message); } } } /// /// When the user cancels the screen. /// protected override void OnCancel() { if (availableSessions != null) { ExitScreen(); } } #endregion #region Drawing Methods /// /// Draw the screen. /// public override void Draw(GameTime gameTime) { string alternateString = String.Empty; // set an alternate string if there are no search results yet if (availableSessions == null) { alternateString = "Searching..."; } else if (availableSessions.Count <= 0) { alternateString = "No sessions found."; } if (String.IsNullOrEmpty(alternateString)) { base.Draw(gameTime); } else { Viewport viewport = ScreenManager.GraphicsDevice.Viewport; Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height); Vector2 position = new Vector2(0f, viewportSize.Y * 0.65f); // Make the menu slide into place during transitions, using a // power curve to make things look more interesting (this makes // the movement slow down as it nears the end). float transitionOffset = (float)Math.Pow(TransitionPosition, 2); if (ScreenState == ScreenState.TransitionOn) position.Y += transitionOffset * 256; else position.Y += transitionOffset * 512; // Draw each menu entry in turn. ScreenManager.SpriteBatch.Begin(); Vector2 origin = new Vector2(0, ScreenManager.Font.LineSpacing / 2); Vector2 size = ScreenManager.Font.MeasureString(alternateString); position.X = viewportSize.X / 2f - size.X / 2f; ScreenManager.SpriteBatch.DrawString(ScreenManager.Font, alternateString, position, Color.White, 0, origin, 1.0f, SpriteEffects.None, 0); ScreenManager.SpriteBatch.End(); } } #endregion #region Networking Methods /// /// Callback to receive the network-session search results. /// internal void SessionsFound(object sender, OperationCompletedEventArgs e) { try { availableSessions = NetworkSession.EndFind(e.AsyncResult); } catch (NetworkException ne) { const string message = "Failed searching for the session."; MessageBoxScreen messageBox = new MessageBoxScreen(message); messageBox.Accepted += FailedMessageBox; messageBox.Cancelled += FailedMessageBox; ScreenManager.AddScreen(messageBox); System.Console.WriteLine("Failed to search for session: " + ne.Message); } catch (GamerPrivilegeException gpe) { const string message = "You do not have permission to search for a session. "; MessageBoxScreen messageBox = new MessageBoxScreen(message + gpe.Message); messageBox.Accepted += FailedMessageBox; messageBox.Cancelled += FailedMessageBox; ScreenManager.AddScreen(messageBox); System.Console.WriteLine( "Insufficient privilege to search for session: " + gpe.Message); } MenuEntries.Clear(); if (availableSessions != null) { foreach (AvailableNetworkSession availableSession in availableSessions) { if (availableSession.CurrentGamerCount < World.MaximumPlayers) { MenuEntries.Add(availableSession.HostGamertag + " (" + availableSession.CurrentGamerCount.ToString() + "/" + World.MaximumPlayers.ToString() + ")"); } if (MenuEntries.Count >= maximumSessions) { break; } } } } /// /// Callback to load the lobby screen with the new session. /// private void LoadLobbyScreen(object sender, OperationCompletedEventArgs e) { NetworkSession networkSession = null; try { networkSession = NetworkSession.EndJoin(e.AsyncResult); } catch (NetworkException ne) { const string message = "Failed joining session."; MessageBoxScreen messageBox = new MessageBoxScreen(message); messageBox.Accepted += FailedMessageBox; messageBox.Cancelled += FailedMessageBox; ScreenManager.AddScreen(messageBox); System.Console.WriteLine("Failed joining session: " + ne.Message); } catch (GamerPrivilegeException gpe) { const string message = "You do not have permission to join a session."; MessageBoxScreen messageBox = new MessageBoxScreen(message); messageBox.Accepted += FailedMessageBox; messageBox.Cancelled += FailedMessageBox; ScreenManager.AddScreen(messageBox); System.Console.WriteLine( "Insufficient privilege to join session: " + gpe.Message); } if (networkSession != null) { LobbyScreen lobbyScreen = new LobbyScreen(networkSession); lobbyScreen.ScreenManager = this.ScreenManager; ScreenManager.AddScreen(lobbyScreen); } } /// /// Event handler for when the user selects ok on the "are you sure /// you want to exit" message box. /// private void FailedMessageBox(object sender, EventArgs e) { ExitScreen(); } #endregion } }