浏览代码

fix: Back to working 1-player lobby without relay lobby

/main/staging/2021_Upgrade/Async_Refactor
当前提交
ec24566e
共有 17 个文件被更改,包括 97 次插入112 次删除
  1. 29
      Assets/Scripts/GameLobby/Game/GameManager.cs
  2. 49
      Assets/Scripts/GameLobby/Game/LocalLobby.cs
  3. 25
      Assets/Scripts/GameLobby/Infrastructure/LogHandlerSettings.cs
  4. 2
      Assets/Scripts/GameLobby/Lobby/AsyncRequestLobby.cs
  5. 8
      Assets/Scripts/GameLobby/Lobby/LobbyConverters.cs
  6. 1
      Assets/Scripts/GameLobby/Lobby/LobbyManager.cs
  7. 28
      Assets/Scripts/GameLobby/Lobby/LobbySynchronizer.cs
  8. 2
      Assets/Scripts/GameLobby/NGO/InGameRunner.cs
  9. 30
      Assets/Scripts/GameLobby/NGO/SetupInGame.cs
  10. 4
      Assets/Scripts/GameLobby/Relay/AsyncRequestRelay.cs
  11. 4
      Assets/Scripts/GameLobby/Relay/RelayUtpClient.cs
  12. 12
      Assets/Scripts/GameLobby/UI/DisplayCodeUI.cs
  13. 5
      Assets/Scripts/GameLobby/UI/InLobbyUserUI.cs
  14. 8
      Assets/Scripts/GameLobby/UI/ShowWhenLobbyStateUI.cs
  15. 2
      Assets/Scripts/GameLobby/UI/LobbyUserListUI.cs
  16. 0
      /Assets/Scripts/GameLobby/UI/LobbyUserListUI.cs.meta
  17. 0
      /Assets/Scripts/GameLobby/UI/LobbyUserListUI.cs

29
Assets/Scripts/GameLobby/Game/GameManager.cs


try
{
LobbyConverters.RemoteToLocal(lobby, m_LocalLobby);
Debug.Log("Found Lobby");
Debug.Log("Didnt find Lobby");
SetGameState(GameState.JoinMenu);
}
}

{
if (string.IsNullOrWhiteSpace(name))
{
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup,
LogHandlerSettings.Instance.SpawnErrorPopup(
"Empty Name not allowed."); // Lobby error type, then HTTP error type.
return;
}

public void CompleteCountDown()
{
//Start game for everyone
if (m_RelayClient is RelayUtpHost)
(m_RelayClient as RelayUtpHost).SendInGameState();
Debug.Log("CountDown Complete!");
if (m_setupInGame)
m_setupInGame.OnGameEnd();
}
public void ConfirmIngameState()

public void BeginGame()
{
if (m_LocalUser.IsHost.Value)
m_LocalLobby.Locked.Value = true;
m_LocalLobby.LocalLobbyState.Value = LobbyState.InGame;
m_setupInGame?.MiniGameBeginning();
}
m_setupInGame?.OnGameEnd();
Debug.Log("Beginning Countdown.");
m_LocalLobby.LocalLobbyState.Value = LobbyState.CountDown;
m_countdown.StartCountDown();
}

Debug.Log("Countdown Cancelled.");
m_countdown.CancelCountDown();
m_LocalLobby.LocalLobbyState.Value = LobbyState.Lobby;
}

m_LocalLobby.LocalLobbyState.Value = LobbyState.InGame;
m_setupInGame.StartNetworkedGame(m_LocalLobby, m_LocalUser);
}
#region Setup

49
Assets/Scripts/GameLobby/Game/LocalLobby.cs


public LocalLobby()
{
LastUpdated.Value = DateTime.Now.ToFileTimeUtc();
LobbyID.onChanged = (s) => { SetValueChanged(); };
onUserListChanged = (dict) => { SetValueChanged(); };
LobbyID.onChanged = (s) => { SetValueChanged(); };
LobbyCode.onChanged = (s) => { SetValueChanged(); };
RelayCode.onChanged = (s) => { SetValueChanged(); };
RelayNGOCode.onChanged = (s) => { SetValueChanged(); };

/// <summary>Used only for visual output of the Relay connection info. The obfuscated Relay server IP is obtained during allocation in the RelayUtpSetup.</summary>
#endregion
public CallbackValue<string> LobbyID = new CallbackValue<string>();
public CallbackValue<string> LobbyCode = new CallbackValue<string>();

public CallbackValue<LobbyState> LocalLobbyState = new CallbackValue<LobbyState>();
public CallbackValue<bool> Locked = new CallbackValue<bool>();
public CallbackValue<bool> Private = new CallbackValue<bool>();
public CallbackValue<int> AvailableSlots = new CallbackValue<int>();

LobbyName.Value = "";
LobbyID.Value = "";
LobbyCode.Value = "";
Locked.Value = false;
Private.Value = false;
LocalLobbyColor.Value = LobbyRelaySample.LobbyColor.None;
AvailableSlots.Value = 4;

void SetValueChanged()
{
if(CanSetChanged)
if (CanSetChanged)
m_ValuesChanged = true;
}
bool m_ValuesChanged;

Debug.Log($"Adding User: {user.DisplayName} - {user.ID}");
m_LocalPlayers.Add(user.ID.Value, user);
user.Emote.onChanged += EmoteChangedCallback;
user.DisplayName.onChanged += StringChangedCallback;
user.IsHost.onChanged += BoolChangedCallback;
user.UserStatus.onChanged += EmoteChangedCallback;
DoRemoveUser(user);
onUserListChanged?.Invoke(m_LocalPlayers);
}
void DoRemoveUser(LocalPlayer user)
{
m_LocalPlayers.Remove(user.ID.Value);
user.Emote.onChanged -= EmoteChangedCallback;
user.DisplayName.onChanged -= StringChangedCallback;
user.IsHost.onChanged -= BoolChangedCallback;
user.UserStatus.onChanged -= EmoteChangedCallback;
onUserListChanged?.Invoke(m_LocalPlayers);
}
m_LocalPlayers.Remove(user.ID.Value);
void EmoteChangedCallback(EmoteType emote)
{
IsLobbyChanged();
void StringChangedCallback(string text)
{
IsLobbyChanged();
}
void BoolChangedCallback(bool changed)
{
IsLobbyChanged();
}
void EmoteChangedCallback(UserStatus status)
{
IsLobbyChanged();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder("Lobby : ");

sb.Append("Code: ");
sb.AppendLine(LobbyCode.Value);
sb.Append("Locked: ");
sb.AppendLine(Locked.Value.ToString());
sb.Append("Private: ");
sb.AppendLine(Private.Value.ToString());
sb.Append("AvailableSlots: ");

25
Assets/Scripts/GameLobby/Infrastructure/LogHandlerSettings.cs


/// <summary>
/// Acts as a buffer between receiving requests to display error messages to the player and running the pop-up UI to do so.
/// </summary>
public class LogHandlerSettings : MonoBehaviour, IReceiveMessages
public class LogHandlerSettings : MonoBehaviour
{
[SerializeField]
[Tooltip("Only logs of this level or higher will appear in the console.")]

private PopUpUI m_popUp;
public static LogHandlerSettings Instance
{
get
{
if (s_LogHandlerSettings != null) return s_LogHandlerSettings;
return s_LogHandlerSettings = FindObjectOfType<LogHandlerSettings>();
}
}
static LogHandlerSettings s_LogHandlerSettings;
Locator.Get.Messenger.Subscribe(this);
private void OnDestroy()
{
Locator.Get.Messenger.Unsubscribe(this);
}
/// <summary>
/// For convenience while in the Editor, update the log verbosity when its value is changed in the Inspector.

LogHandler.Get().mode = m_editorLogVerbosity;
}
public void OnReceiveMessage(MessageType type, object msg)
{
if (type == MessageType.DisplayErrorPopup && msg != null)
SpawnErrorPopup((string)msg);
}
private void SpawnErrorPopup(string errorMessage)
public void SpawnErrorPopup(string errorMessage)
{
m_popUp.ShowPopup(errorMessage);
}

2
Assets/Scripts/GameLobby/Lobby/AsyncRequestLobby.cs


var lobbyEx = e as LobbyServiceException;
if (lobbyEx.Reason == LobbyExceptionReason.RateLimited) // We have other ways of preventing players from hitting the rate limit, so the developer-facing 429 error is sufficient here.
return;
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, $"Lobby Error: {lobbyEx.Message} ({lobbyEx.InnerException.Message})"); // Lobby error type, then HTTP error type.
LogHandlerSettings.Instance.SpawnErrorPopup( $"Lobby Error: {lobbyEx.Message} ({lobbyEx.InnerException.Message})"); // Lobby error type, then HTTP error type.
}
}
}

8
Assets/Scripts/GameLobby/Lobby/LobbyConverters.cs


localLobby.MaxPlayerCount.Value = remoteLobby.MaxPlayers;
localLobby.LastUpdated.Value = remoteLobby.LastUpdated.ToFileTimeUtc();
//Custom Data Conversion
//Custom Lobby Data Conversions
localLobby.RelayCode.Value = remoteLobby.Data?.ContainsKey(key_RelayCode) == true
? remoteLobby.Data[key_RelayCode].Value
: localLobby.RelayCode.Value;

? (LobbyColor)int.Parse(remoteLobby.Data[key_LobbyColor].Value)
: LobbyColor.None;
//Custom User Data Conversions
List<string> remotePlayerIDs = new List<string>();
foreach (var player in remoteLobby.Players)
{

: default;
var emote = player.Data?.ContainsKey(key_Emote) == true
? (EmoteType)int.Parse(player.Data[key_Emote].Value)
: default;
: EmoteType.None;
: UserStatus.Connecting;
: UserStatus.Lobby;
LocalPlayer localPlayer;
//See if we have the remote player locally already

1
Assets/Scripts/GameLobby/Lobby/LobbyManager.cs


string uasId = AuthenticationService.Instance.PlayerId;
var playerData = CreateInitialPlayerData(localUser);
if (!string.IsNullOrEmpty(lobbyId))
{
JoinLobbyByIdOptions joinOptions = new JoinLobbyByIdOptions

28
Assets/Scripts/GameLobby/Lobby/LobbySynchronizer.cs


/// <summary>
/// Keep updated on changes to a joined lobby, at a speed compliant with Lobby's rate limiting.
/// </summary>
public class LobbySynchronizer : IReceiveMessages, IDisposable
public class LobbySynchronizer : IDisposable
{
LocalLobby m_LocalLobby;
LocalPlayer m_LocalUser;

const int
k_approvalMaxMS = 10000; // Used for determining if a user should timeout if they are unable to connect.
const int k_approvalMaxMS = 10000; // Used for determining if a user should timeout if they are unable to connect.
int m_lifetime = 0;
const int k_UpdateIntervalMS = 1000;

m_LocalLobby = localLobby;
m_LocalLobby.LobbyID.onChanged += OnLobbyIdChanged;
m_LocalChanges = true;
Locator.Get.Messenger.Subscribe(this);
#pragma warning disable 4014
#pragma warning disable 4014
#pragma warning restore 4014
#pragma warning restore 4014
Locator.Get.Messenger.Unsubscribe(this);
if (m_LocalLobby != null)
m_LocalLobby.LobbyID.onChanged -= OnLobbyIdChanged;

//TODO Stop players from joining lobby while game is underway.
public void OnReceiveMessage(MessageType type, object msg)
{
// if (type == MessageType.ClientUserSeekingDisapproval)
// {
// bool shouldDisapprove =
// m_LocalLobby.LocalLobbyState !=
// LocalLobbyState.Lobby; // By not refreshing, it's possible to have a lobby in the lobby list UI after its countdown starts and then try joining.
// if (shouldDisapprove)
// (msg as Action<relay.Approval>)?.Invoke(relay.Approval.GameAlreadyStarted);
// }
}
/// <summary>
/// If there have been any data changes since the last update, push them to Lobby. Regardless, pull for the most recent data.
/// (Unless we're already awaiting a query, in which case continue waiting.)

//Causing another pull, the RemoteToLocal converter ensures this does not happen by flagging the lobby.
LobbyConverters.RemoteToLocal(latestLobby, m_LocalLobby, false);
}
Debug.Log(m_LocalLobby.ToString());
if (!LobbyHasHost())
{

void LeaveLobbyBecauseNoHost()
{
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup,
LogHandlerSettings.Instance.SpawnErrorPopup(
"Host left the lobby! Disconnecting...");
Locator.Get.Messenger.OnReceiveMessage(MessageType.EndGame, null);
GameManager.Instance.ChangeMenuState(GameState.JoinMenu);

2
Assets/Scripts/GameLobby/NGO/InGameRunner.cs


private void BeginGame()
{
m_canSpawnInGameObjects = true;
Locator.Get.Messenger.OnReceiveMessage(MessageType.MinigameBeginning, null);
GameManager.Instance.BeginGame();
m_introOutroRunner.DoIntro();
}

30
Assets/Scripts/GameLobby/NGO/SetupInGame.cs


/// Once the local localPlayer is in a localLobby and that localLobby has entered the In-Game state, this will load in whatever is necessary to actually run the game part.
/// This will exist in the game scene so that it can hold references to scene objects that spawned prefab instances will need.
/// </summary>
public class SetupInGame : MonoBehaviour, IReceiveMessages
public class SetupInGame : MonoBehaviour
{
[SerializeField]
GameObject m_IngameRunnerPrefab = default;

private bool m_hasConnectedViaNGO = false;
private LocalLobby m_lobby;
public void Start()
{
Locator.Get.Messenger.Subscribe(this);
}
public void OnDestroy()
{
Locator.Get.Messenger.Unsubscribe(this);
}
private void SetMenuVisibility(bool areVisible)
{

public void ConfirmInGameState()
{
public void OnReceiveMessage(MessageType type, object msg)
public void MiniGameBeginning()
if (type == MessageType.MinigameBeginning)
if (!m_hasConnectedViaNGO)
if (!m_hasConnectedViaNGO)
{
// If this localPlayer hasn't successfully connected via NGO, forcibly exit the minigame.
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, "Failed to join the game.");
OnGameEnd();
}
// If this localPlayer hasn't successfully connected via NGO, forcibly exit the minigame.
LogHandlerSettings.Instance.SpawnErrorPopup( "Failed to join the game.");
OnGameEnd();
}
/// <summary>

4
Assets/Scripts/GameLobby/Relay/AsyncRequestRelay.cs


return;
var relayEx = e as RelayServiceException;
if (relayEx.Reason == RelayExceptionReason.Unknown)
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, "Relay Error: Relay service had an unknown error.");
LogHandlerSettings.Instance.SpawnErrorPopup( "Relay Error: Relay service had an unknown error.");
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, $"Relay Error: {relayEx.Message}");
LogHandlerSettings.Instance.SpawnErrorPopup( $"Relay Error: {relayEx.Message}");
}
}
}

4
Assets/Scripts/GameLobby/Relay/RelayUtpClient.cs


// if (approval == Approval.OK && !m_localUser.IsApproved)
// OnApproved(m_networkDriver, conn);
// else if (approval == Approval.GameAlreadyStarted)
// Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, "Rejected: Game has already started.");
// LogHandlerSettings.Instance.SpawnErrorPopup( "Rejected: Game has already started.");
}
else if (msgType == MsgType.PlayerName)
{

msg = "Connection to host was lost. Leaving the lobby.";
Debug.LogError(msg);
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, msg);
LogHandlerSettings.Instance.SpawnErrorPopup( msg);
Leave();
GameManager.Instance.ChangeMenuState(GameState.JoinMenu);
}

12
Assets/Scripts/GameLobby/UI/DisplayCodeUI.cs


void LobbyCodeChanged(string newCode)
{
if (!string.IsNullOrEmpty(newCode))
{
m_outputText.text = newCode;

Manager.LocalLobby.LobbyCode.onChanged += LobbyCodeChanged;
if(m_codeType==CodeType.Relay)
Manager.LocalLobby.RelayCode.onChanged += LobbyCodeChanged;
}
void OnDestroy()
{
if (Manager == null)
return;
if(m_codeType==CodeType.Lobby)
Manager.LocalLobby.LobbyCode.onChanged -= LobbyCodeChanged;
if(m_codeType==CodeType.Relay)
Manager.LocalLobby.RelayCode.onChanged -= LobbyCodeChanged;
}
}
}

5
Assets/Scripts/GameLobby/UI/InLobbyUserUI.cs


using System;
using JetBrains.Annotations;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

Show();
m_localPlayer = myLocalPlayer;
SubscribeToPlayerUpdates();
SetDisplayName(m_localPlayer.DisplayName.Value);
UserId = myLocalPlayer.ID.Value;
m_vivoxUserHandler.SetId(UserId);
}

8
Assets/Scripts/GameLobby/UI/ShowWhenLobbyStateUI.cs


base.Start();
Manager.LocalLobby.LocalLobbyState.onChanged += LobbyChanged;
}
public void OnDestroy()
{
if (Manager== null)
return;
Manager.LocalLobby.LocalLobbyState.onChanged -= LobbyChanged;
}
}
}

2
Assets/Scripts/GameLobby/UI/LobbyUserListUI.cs


namespace LobbyRelaySample.UI
{
public class InLobbyUserList : UIPanelBase
public class LobbyUserListUI : UIPanelBase
{
[SerializeField]
List<InLobbyUserUI> m_UserUIObjects = new List<InLobbyUserUI>();

/Assets/Scripts/GameLobby/UI/InLobbyUserList.cs.meta → /Assets/Scripts/GameLobby/UI/LobbyUserListUI.cs.meta

/Assets/Scripts/GameLobby/UI/InLobbyUserList.cs → /Assets/Scripts/GameLobby/UI/LobbyUserListUI.cs

正在加载...
取消
保存