ProfileSignInScreen.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //-----------------------------------------------------------------------------
  2. // ProfileSignInScreen.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.Net;
  10. using Microsoft.Xna.Framework.GamerServices;
  11. namespace NetworkStateManagement
  12. {
  13. /// <summary>
  14. /// In order to play a networked game, you must have a player profile signed in.
  15. /// If you want to play on Live, that has to be a Live profile. Rather than just
  16. /// failing with an error message, it is nice if we can automatically bring up the
  17. /// Guide screen when we detect that no suitable profiles are currently signed in,
  18. /// so the user can easily correct the problem. This screen checks the sign in
  19. /// state, and brings up the Guide user interface if there is a problem with it.
  20. /// It then raises an event as soon as a valid profile has been signed in.
  21. ///
  22. /// There are two scenarios for how this can work. If no good profile is signed in:
  23. ///
  24. /// - MainMenuScreen activates the ProfileSignInScreen
  25. /// - ProfileSignInScreen activates the Guide user interface
  26. /// - User signs in a profile
  27. /// - ProfileSignInScreen raises the ProfileSignedIn event
  28. /// - This advances to the CreateOrFindSessionScreen
  29. ///
  30. /// Alternatively, there might already be a valid profile signed in. In this case:
  31. ///
  32. /// - MainMenuScreen activates the ProfileSignInScreen
  33. /// - ProfileSignInScreen notices everything is already good
  34. /// - ProfileSignInScreen raises the ProfileSignedIn event
  35. /// - This advances to the CreateOrFindSessionScreen
  36. ///
  37. /// In this second case, the ProfileSignInScreen is only active for a single
  38. /// Update, so the user just sees a transition directly from the MainMenuScreen
  39. /// to the CreateOrFindSessionScreen.
  40. /// </summary>
  41. class ProfileSignInScreen : GameScreen
  42. {
  43. NetworkSessionType sessionType;
  44. bool haveShownGuide;
  45. bool haveShownMarketplace;
  46. public event EventHandler<EventArgs> ProfileSignedIn;
  47. /// <summary>
  48. /// Constructs a new profile sign in screen.
  49. /// </summary>
  50. public ProfileSignInScreen(NetworkSessionType sessionType)
  51. {
  52. this.sessionType = sessionType;
  53. IsPopup = true;
  54. }
  55. /// <summary>
  56. /// Updates the profile sign in screen.
  57. /// </summary>
  58. public override void Update(GameTime gameTime, bool otherScreenHasFocus,
  59. bool coveredByOtherScreen)
  60. {
  61. base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  62. if (ValidProfileSignedIn())
  63. {
  64. // As soon as we detect a suitable profile is signed in,
  65. // we raise the profile signed in event, then go away.
  66. if (ProfileSignedIn != null)
  67. ProfileSignedIn(this, EventArgs.Empty);
  68. ExitScreen();
  69. }
  70. else if (IsActive && !Guide.IsVisible)
  71. {
  72. // If we are in trial mode, and they want to play online, and a profile
  73. // is signed in, take them to marketplace so they can purchase the game.
  74. if ((Guide.IsTrialMode) &&
  75. (NetworkSessionComponent.IsOnlineSessionType(sessionType)) &&
  76. (Gamer.SignedInGamers[(int)ControllingPlayer.Value] != null) &&
  77. (!haveShownMarketplace))
  78. {
  79. ShowMarketplace();
  80. haveShownMarketplace = true;
  81. }
  82. else if (!haveShownGuide && !haveShownMarketplace)
  83. {
  84. // No suitable profile is signed in, and we haven't already shown
  85. // the Guide. Let's show it now, so they can sign in a profile.
  86. Guide.ShowSignIn(1,
  87. NetworkSessionComponent.IsOnlineSessionType(sessionType));
  88. haveShownGuide = true;
  89. }
  90. else
  91. {
  92. // Hmm. No suitable profile is signed in, but we already showed
  93. // the Guide, and the Guide isn't still visible. There is only
  94. // one thing that can explain this: they must have cancelled the
  95. // Guide without signing in a profile. We'd better just exit,
  96. // which will leave us on the same menu as before.
  97. ExitScreen();
  98. }
  99. }
  100. }
  101. /// <summary>
  102. /// Helper checks whether a valid player profile is signed in.
  103. /// </summary>
  104. bool ValidProfileSignedIn()
  105. {
  106. // If there is no profile signed in, that is never good.
  107. SignedInGamer gamer = Gamer.SignedInGamers[(int)ControllingPlayer.Value];
  108. if (gamer == null)
  109. return false;
  110. // If we want to play in a Live session, also make sure the profile is
  111. // signed in to Live, and that it has the privilege for online gameplay.
  112. if (NetworkSessionComponent.IsOnlineSessionType(sessionType))
  113. {
  114. if (!gamer.IsSignedInToLive)
  115. return false;
  116. // TODO: Check if the compatibility layer supports Privileges
  117. // For now, assume online privileges are available if signed in to Live
  118. // if (!gamer.Privileges.AllowOnlineSessions)
  119. // return false;
  120. }
  121. // Okeydokey, this looks good.
  122. return true;
  123. }
  124. /// <summary>
  125. /// LIVE networking is not supported in trial mode. Rather than just giving
  126. /// the user an error, this function asks if they want to purchase the full
  127. /// game, then takes them to Marketplace where they can do that. Once the
  128. /// Guide is active, the user can either make the purchase, or cancel it.
  129. /// When the Guide closes, ProfileSignInScreen.Update will notice that
  130. /// Guide.IsVisible has gone back to false, at which point it will check if
  131. /// the game is still in trial mode, and either exit the screen or proceed
  132. /// forward accordingly.
  133. /// </summary>
  134. void ShowMarketplace()
  135. {
  136. MessageBoxScreen confirmMarketplaceMessageBox =
  137. new MessageBoxScreen(Resources.ConfirmMarketplace);
  138. confirmMarketplaceMessageBox.Accepted += delegate
  139. {
  140. Guide.ShowMarketplace(ControllingPlayer.Value);
  141. };
  142. ScreenManager.AddScreen(confirmMarketplaceMessageBox, ControllingPlayer);
  143. }
  144. }
  145. }