SearchResultsScreen.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. //-----------------------------------------------------------------------------
  2. // SearchResultsScreen.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using Microsoft.Xna.Framework;
  9. using Microsoft.Xna.Framework.GamerServices;
  10. using Microsoft.Xna.Framework.Graphics;
  11. using Microsoft.Xna.Framework.Net;
  12. namespace NetRumble
  13. {
  14. /// <summary>
  15. /// The search-results screen shows the results of a network-session
  16. /// search, allowing the player to pick the game to join.
  17. /// </summary>
  18. public class SearchResultsScreen : MenuScreen
  19. {
  20. /// <summary>
  21. /// The maximum number of session results to display.
  22. /// </summary>
  23. const int maximumSessions = 8;
  24. /// <summary>
  25. /// The type of networking session that was requested.
  26. /// </summary>
  27. private NetworkSessionType sessionType;
  28. /// <summary>
  29. /// The collection of search results.
  30. /// </summary>
  31. private AvailableNetworkSessionCollection availableSessions = null;
  32. /// <summary>
  33. /// Constructor fills in the menu contents.
  34. /// </summary>
  35. /// <param name="sessionType">The type of session searched for.</param>
  36. public SearchResultsScreen(NetworkSessionType sessionType) : base()
  37. {
  38. // apply the parameters
  39. this.sessionType = sessionType;
  40. // set the transition times
  41. TransitionOnTime = TimeSpan.FromSeconds(1.0);
  42. TransitionOffTime = TimeSpan.FromSeconds(0.0);
  43. }
  44. /// <summary>
  45. /// Updates the screen. This method checks the GameScreen.IsActive
  46. /// property, so the game will stop updating when the pause menu is active,
  47. /// or if you tab away to a different application.
  48. /// </summary>
  49. public override void Update(Microsoft.Xna.Framework.GameTime gameTime,
  50. bool otherScreenHasFocus, bool coveredByOtherScreen)
  51. {
  52. bool signedIntoLive = false;
  53. if (Gamer.SignedInGamers.Count > 0)
  54. {
  55. foreach (SignedInGamer signedInGamer in Gamer.SignedInGamers)
  56. {
  57. if (signedInGamer.IsSignedInToLive)
  58. {
  59. signedIntoLive = true;
  60. break;
  61. }
  62. }
  63. if (!signedIntoLive &&
  64. ((sessionType == NetworkSessionType.PlayerMatch) ||
  65. (sessionType == NetworkSessionType.Ranked)) && !IsExiting)
  66. {
  67. ExitScreen();
  68. }
  69. }
  70. else if (!IsExiting)
  71. {
  72. ExitScreen();
  73. }
  74. if (coveredByOtherScreen && !IsExiting)
  75. {
  76. ExitScreen();
  77. }
  78. base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  79. }
  80. /// <summary>
  81. /// Responds to user menu selections.
  82. /// </summary>
  83. protected override void OnSelectEntry(int entryIndex)
  84. {
  85. if ((availableSessions != null) && (entryIndex >= 0) &&
  86. (entryIndex < availableSessions.Count))
  87. {
  88. // start to join
  89. try
  90. {
  91. IAsyncResult asyncResult = NetworkSession.BeginJoin(
  92. availableSessions[entryIndex], null, null);
  93. // create the busy screen
  94. NetworkBusyScreen busyScreen = new NetworkBusyScreen(
  95. "Joining the session...", asyncResult);
  96. busyScreen.OperationCompleted += LoadLobbyScreen;
  97. ScreenManager.AddScreen(busyScreen);
  98. }
  99. catch (NetworkException ne)
  100. {
  101. const string message = "Failed joining the session.";
  102. MessageBoxScreen messageBox = new MessageBoxScreen(message);
  103. messageBox.Accepted += FailedMessageBox;
  104. messageBox.Cancelled += FailedMessageBox;
  105. ScreenManager.AddScreen(messageBox);
  106. System.Console.WriteLine("Failed to join session: " +
  107. ne.Message);
  108. }
  109. catch (GamerPrivilegeException gpe)
  110. {
  111. const string message =
  112. "You do not have permission to join a session.";
  113. MessageBoxScreen messageBox = new MessageBoxScreen(message);
  114. messageBox.Accepted += FailedMessageBox;
  115. messageBox.Cancelled += FailedMessageBox;
  116. ScreenManager.AddScreen(messageBox);
  117. System.Console.WriteLine(
  118. "Insufficient privilege to join session: " + gpe.Message);
  119. }
  120. }
  121. }
  122. /// <summary>
  123. /// When the user cancels the screen.
  124. /// </summary>
  125. protected override void OnCancel()
  126. {
  127. if (availableSessions != null)
  128. {
  129. ExitScreen();
  130. }
  131. }
  132. /// <summary>
  133. /// Draw the screen.
  134. /// </summary>
  135. public override void Draw(GameTime gameTime)
  136. {
  137. string alternateString = String.Empty;
  138. // set an alternate string if there are no search results yet
  139. if (availableSessions == null)
  140. {
  141. alternateString = "Searching...";
  142. }
  143. else if (availableSessions.Count <= 0)
  144. {
  145. alternateString = "No sessions found.";
  146. }
  147. if (String.IsNullOrEmpty(alternateString))
  148. {
  149. base.Draw(gameTime);
  150. }
  151. else
  152. {
  153. Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
  154. Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
  155. Vector2 position = new Vector2(0f, viewportSize.Y * 0.65f);
  156. // Make the menu slide into place during transitions, using a
  157. // power curve to make things look more interesting (this makes
  158. // the movement slow down as it nears the end).
  159. float transitionOffset = (float)Math.Pow(TransitionPosition, 2);
  160. if (ScreenState == ScreenState.TransitionOn)
  161. position.Y += transitionOffset * 256;
  162. else
  163. position.Y += transitionOffset * 512;
  164. // Draw each menu entry in turn.
  165. ScreenManager.SpriteBatch.Begin();
  166. Vector2 origin = new Vector2(0, ScreenManager.Font.LineSpacing / 2);
  167. Vector2 size = ScreenManager.Font.MeasureString(alternateString);
  168. position.X = viewportSize.X / 2f - size.X / 2f;
  169. ScreenManager.SpriteBatch.DrawString(ScreenManager.Font,
  170. alternateString, position,
  171. Color.White, 0, origin, 1.0f,
  172. SpriteEffects.None, 0);
  173. ScreenManager.SpriteBatch.End();
  174. }
  175. }
  176. /// <summary>
  177. /// Callback to receive the network-session search results.
  178. /// </summary>
  179. internal void SessionsFound(object sender, OperationCompletedEventArgs e)
  180. {
  181. try
  182. {
  183. availableSessions = NetworkSession.EndFind(e.AsyncResult);
  184. }
  185. catch (NetworkException ne)
  186. {
  187. const string message = "Failed searching for the session.";
  188. MessageBoxScreen messageBox = new MessageBoxScreen(message);
  189. messageBox.Accepted += FailedMessageBox;
  190. messageBox.Cancelled += FailedMessageBox;
  191. ScreenManager.AddScreen(messageBox);
  192. System.Console.WriteLine("Failed to search for session: " +
  193. ne.Message);
  194. }
  195. catch (GamerPrivilegeException gpe)
  196. {
  197. const string message =
  198. "You do not have permission to search for a session. ";
  199. MessageBoxScreen messageBox = new MessageBoxScreen(message + gpe.Message);
  200. messageBox.Accepted += FailedMessageBox;
  201. messageBox.Cancelled += FailedMessageBox;
  202. ScreenManager.AddScreen(messageBox);
  203. System.Console.WriteLine(
  204. "Insufficient privilege to search for session: " + gpe.Message);
  205. }
  206. MenuEntries.Clear();
  207. if (availableSessions != null)
  208. {
  209. foreach (AvailableNetworkSession availableSession in
  210. availableSessions)
  211. {
  212. if (availableSession.CurrentGamerCount < World.MaximumPlayers)
  213. {
  214. MenuEntries.Add(availableSession.HostGamertag + " (" +
  215. availableSession.CurrentGamerCount.ToString() + "/" +
  216. World.MaximumPlayers.ToString() + ")");
  217. }
  218. if (MenuEntries.Count >= maximumSessions)
  219. {
  220. break;
  221. }
  222. }
  223. }
  224. }
  225. /// <summary>
  226. /// Callback to load the lobby screen with the new session.
  227. /// </summary>
  228. private void LoadLobbyScreen(object sender, OperationCompletedEventArgs e)
  229. {
  230. NetworkSession networkSession = null;
  231. try
  232. {
  233. networkSession = NetworkSession.EndJoin(e.AsyncResult);
  234. }
  235. catch (NetworkException ne)
  236. {
  237. const string message = "Failed joining session.";
  238. MessageBoxScreen messageBox = new MessageBoxScreen(message);
  239. messageBox.Accepted += FailedMessageBox;
  240. messageBox.Cancelled += FailedMessageBox;
  241. ScreenManager.AddScreen(messageBox);
  242. System.Console.WriteLine("Failed joining session: " + ne.Message);
  243. }
  244. catch (GamerPrivilegeException gpe)
  245. {
  246. const string message =
  247. "You do not have permission to join a session.";
  248. MessageBoxScreen messageBox = new MessageBoxScreen(message);
  249. messageBox.Accepted += FailedMessageBox;
  250. messageBox.Cancelled += FailedMessageBox;
  251. ScreenManager.AddScreen(messageBox);
  252. System.Console.WriteLine(
  253. "Insufficient privilege to join session: " + gpe.Message);
  254. }
  255. if (networkSession != null)
  256. {
  257. LobbyScreen lobbyScreen = new LobbyScreen(networkSession);
  258. lobbyScreen.ScreenManager = this.ScreenManager;
  259. ScreenManager.AddScreen(lobbyScreen);
  260. }
  261. }
  262. /// <summary>
  263. /// Event handler for when the user selects ok on the "are you sure
  264. /// you want to exit" message box.
  265. /// </summary>
  266. private void FailedMessageBox(object sender, EventArgs e)
  267. {
  268. ExitScreen();
  269. }
  270. }
  271. }