//----------------------------------------------------------------------------- // CreateOrFindSessionScreen.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.GamerServices; using System.Threading.Tasks; namespace NetworkStateManagement { /// /// This menu screen lets the user choose whether to create a new /// network session, or search for an existing session to join. /// class CreateOrFindSessionScreen : MenuScreen { NetworkSessionType sessionType; /// /// Constructor fills in the menu contents. /// public CreateOrFindSessionScreen(NetworkSessionType sessionType) : base(GetMenuTitle(sessionType)) { this.sessionType = sessionType; // Create our menu entries. MenuEntry createSessionMenuEntry = new MenuEntry(Resources.CreateSession); MenuEntry findSessionsMenuEntry = new MenuEntry(Resources.FindSessions); MenuEntry backMenuEntry = new MenuEntry(Resources.Back); // Hook up menu event handlers. createSessionMenuEntry.Selected += CreateSessionMenuEntrySelected; findSessionsMenuEntry.Selected += FindSessionsMenuEntrySelected; backMenuEntry.Selected += OnCancel; // Add entries to the menu. MenuEntries.Add(createSessionMenuEntry); MenuEntries.Add(findSessionsMenuEntry); MenuEntries.Add(backMenuEntry); } /// /// Helper chooses an appropriate menu title for the specified session type. /// static string GetMenuTitle(NetworkSessionType sessionType) { switch (sessionType) { case NetworkSessionType.PlayerMatch: return Resources.PlayerMatch; case NetworkSessionType.SystemLink: return Resources.SystemLink; default: throw new NotSupportedException(); } } /// /// Event handler for when the Create Session menu entry is selected. /// void CreateSessionMenuEntrySelected(object sender, PlayerIndexEventArgs e) { try { // Which local profiles should we include in this session? IEnumerable localGamers = NetworkSessionComponent.ChooseGamers(sessionType, ControllingPlayer.Value); // Begin an asynchronous create network session operation. var networkSession = NetworkSession.CreateAsync( sessionType, NetworkSessionComponent.MaxLocalGamers, NetworkSessionComponent.MaxGamers, 1, null); // Activate the network busy screen, which will display // an animation until this operation has completed. NetworkBusyScreen busyScreen = new NetworkBusyScreen(networkSession); busyScreen.OperationCompleted += CreateSessionOperationCompleted; ScreenManager.AddScreen(busyScreen, ControllingPlayer); } catch (Exception exception) { NetworkErrorScreen errorScreen = new NetworkErrorScreen(exception); ScreenManager.AddScreen(errorScreen, ControllingPlayer); } } enum SessionProperty { GameMode, SkillLevel, ScoreToWin } enum GameMode { Practice, Timed, CaptureTheFlag } enum SkillLevel { Beginner, Intermediate, Advanced } /// /// Event handler for when the asynchronous create network session /// operation has completed. /// void CreateSessionOperationCompleted(object sender, OperationCompletedEventArgs e) { try { // Use the result directly from the event args. NetworkSession networkSession = e.Result as NetworkSession; if (networkSession == null) throw new InvalidOperationException("NetworkSession result was null or invalid."); // Create a component that will manage the session we just created. NetworkSessionComponent.Create(ScreenManager, networkSession); // Go to the lobby screen. We pass null as the controlling player, // because the lobby screen accepts input from all local players // who are in the session, not just a single controlling player. ScreenManager.AddScreen(new LobbyScreen(networkSession), null); } catch (Exception exception) { NetworkErrorScreen errorScreen = new NetworkErrorScreen(exception); ScreenManager.AddScreen(errorScreen, ControllingPlayer); } } /// /// Event handler for when the Find Sessions menu entry is selected. /// void FindSessionsMenuEntrySelected(object sender, PlayerIndexEventArgs e) { try { // Which local profiles should we include in this session? IEnumerable localGamers = NetworkSessionComponent.ChooseGamers(sessionType, ControllingPlayer.Value); // Begin an asynchronous find network sessions operation. var availableNetworkSessions = NetworkSession.FindAsync( sessionType, NetworkSessionComponent.MaxLocalGamers, null); // Activate the network busy screen, which will display // an animation until this operation has completed. NetworkBusyScreen busyScreen = new NetworkBusyScreen(availableNetworkSessions); busyScreen.OperationCompleted += FindSessionsOperationCompleted; ScreenManager.AddScreen(busyScreen, ControllingPlayer); } catch (Exception exception) { NetworkErrorScreen errorScreen = new NetworkErrorScreen(exception); ScreenManager.AddScreen(errorScreen, ControllingPlayer); } } /// /// Event handler for when the asynchronous find network sessions /// operation has completed. /// void FindSessionsOperationCompleted(object sender, OperationCompletedEventArgs e) { GameScreen nextScreen; try { // Use the result directly from the event args. AvailableNetworkSessionCollection availableSessions = e.Result as AvailableNetworkSessionCollection; if (availableSessions == null) throw new InvalidOperationException("AvailableNetworkSessionCollection result was null or invalid."); if (availableSessions.Count == 0) { // If we didn't find any sessions, display an error. availableSessions.Dispose(); nextScreen = new MessageBoxScreen(Resources.NoSessionsFound, false); } else { // If we did find some sessions, proceed to the JoinSessionScreen. nextScreen = new JoinSessionScreen(availableSessions); } } catch (Exception exception) { nextScreen = new NetworkErrorScreen(exception); } ScreenManager.AddScreen(nextScreen, ControllingPlayer); } } }