UnityJacob
2 年前
当前提交
efe29078
共有 10 个文件被更改,包括 6 次插入 和 305 次删除
-
12Assets/Scripts/GameLobby/Lobby/LobbyManager.cs
-
11Assets/Scripts/GameLobby/Infrastructure/AsyncRequest.cs.meta
-
48Assets/Scripts/GameLobby/Infrastructure/AsyncRequest.cs
-
11Assets/Scripts/GameLobby/Lobby/AsyncRequestLobby.cs.meta
-
31Assets/Scripts/GameLobby/Lobby/AsyncRequestLobby.cs
-
179Assets/Scripts/GameLobby/Lobby/LobbySynchronizer.cs
-
11Assets/Scripts/GameLobby/Lobby/LobbySynchronizer.cs.meta
-
8Assets/Scripts/GameLobby/Tests.meta
|
|||
fileFormatVersion: 2 |
|||
guid: 255a690fe68a18c438e160a118cd8a6b |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LobbyRelaySample |
|||
{ |
|||
/// <summary>
|
|||
/// Both Lobby and Relay have need for asynchronous requests with some basic safety wrappers. This is a shared place for that.
|
|||
/// This will also permit parsing incoming exceptions for any service-specific errors that should be displayed to the player.
|
|||
/// </summary>
|
|||
public abstract class AsyncRequest |
|||
{ |
|||
public async void DoRequest(Task task, Action onComplete) |
|||
{ |
|||
string currentTrace = System.Environment.StackTrace; // For debugging. If we don't get the calling context here, it's lost once the async operation begins.
|
|||
try |
|||
{ await task; |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
ParseServiceException(e); |
|||
UnityEngine.Debug.LogError($"AsyncRequest threw an exception. Call stack before async call:\n{currentTrace}\n"); // Note that we log here instead of creating a new Exception in case of a change in calling context during the async call. E.g. Relay has its own exception handling that would intercept this call stack.
|
|||
throw; |
|||
} |
|||
finally |
|||
{ onComplete?.Invoke(); |
|||
} |
|||
} |
|||
public async void DoRequest<T>(Task<T> task, Action<T> onComplete) |
|||
{ |
|||
T result = default; |
|||
string currentTrace = System.Environment.StackTrace; |
|||
try |
|||
{ result = await task; |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
ParseServiceException(e); |
|||
UnityEngine.Debug.LogError($"AsyncRequest threw an exception. Call stack before async call:\n{currentTrace}\n"); |
|||
throw; |
|||
} |
|||
finally |
|||
{ onComplete?.Invoke(result); |
|||
} |
|||
} |
|||
|
|||
protected abstract void ParseServiceException(Exception e); |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 06b074cf2a829884caf9f52a29d33e5b |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.Services.Lobbies; |
|||
|
|||
namespace LobbyRelaySample.lobby |
|||
{ |
|||
public class AsyncRequestLobby : AsyncRequest |
|||
{ |
|||
private static AsyncRequestLobby s_instance; |
|||
public static AsyncRequestLobby Instance |
|||
{ |
|||
get |
|||
{ if (s_instance == null) |
|||
s_instance = new AsyncRequestLobby(); |
|||
return s_instance; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The Lobby service will wrap HTTP errors in LobbyServiceExceptions. We can filter on LobbyServiceException.Reason for custom behavior.
|
|||
/// </summary>
|
|||
protected override void ParseServiceException(Exception e) |
|||
{ |
|||
if (!(e is LobbyServiceException)) |
|||
return; |
|||
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; |
|||
LogHandlerSettings.Instance.SpawnErrorPopup( $"Lobby Error: {lobbyEx.Message} ({lobbyEx.InnerException.Message})"); // Lobby error type, then HTTP error type.
|
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using LobbyRelaySample.lobby; |
|||
using Unity.Services.Lobbies.Models; |
|||
using UnityEngine; |
|||
|
|||
// namespace LobbyRelaySample
|
|||
// {
|
|||
// /// <summary>
|
|||
// /// Keep updated on changes to a joined lobby, at a speed compliant with Lobby's rate limiting.
|
|||
// /// </summary>
|
|||
// public class LobbySynchronizer : IDisposable
|
|||
// {
|
|||
// LocalLobby m_LocalLobby;
|
|||
// LocalPlayer m_LocalUser;
|
|||
// LobbyManager m_LobbyManager;
|
|||
// bool m_LocalChanges = false;
|
|||
//
|
|||
// 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;
|
|||
//
|
|||
// public LobbySynchronizer(LobbyManager lobbyManager)
|
|||
// {
|
|||
// m_LobbyManager = lobbyManager;
|
|||
// }
|
|||
//
|
|||
// public void StartSynch(LocalLobby localLobby, LocalPlayer localUser)
|
|||
// {
|
|||
// m_LocalUser = localUser;
|
|||
// m_LocalLobby = localLobby;
|
|||
// m_LocalLobby.LobbyID.onChanged += OnLobbyIdChanged;
|
|||
// m_LocalChanges = true;
|
|||
// #pragma warning disable 4014
|
|||
// UpdateLoopAsync();
|
|||
// #pragma warning restore 4014
|
|||
// m_lifetime = 0;
|
|||
// }
|
|||
//
|
|||
//
|
|||
// public void EndSynch()
|
|||
// {
|
|||
// m_LocalChanges = false;
|
|||
//
|
|||
// if (m_LocalLobby != null)
|
|||
// m_LocalLobby.LobbyID.onChanged -= OnLobbyIdChanged;
|
|||
//
|
|||
// m_LocalLobby = null;
|
|||
// }
|
|||
//
|
|||
// /// <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.)
|
|||
// /// </summary>
|
|||
// async Task UpdateLoopAsync()
|
|||
// {
|
|||
// Lobby latestLobby = null;
|
|||
//
|
|||
// while (m_LocalLobby != null)
|
|||
// {
|
|||
// latestLobby = await GetLatestRemoteLobby();
|
|||
//
|
|||
// if (IfRemoteLobbyChanged(latestLobby))
|
|||
// {
|
|||
// //Pulling remote changes, and applying them to the local lobby usually flags it as changed,
|
|||
// //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())
|
|||
// {
|
|||
// LeaveLobbyBecauseNoHost();
|
|||
// break;
|
|||
// }
|
|||
//
|
|||
// var areAllusersReady = AreAllUsersReady();
|
|||
// if (areAllusersReady && m_LocalLobby.LocalLobbyState.Value == LobbyState.Lobby)
|
|||
// {
|
|||
// GameManager.Instance.BeginCountDown();
|
|||
// }
|
|||
// else if (!areAllusersReady && m_LocalLobby.LocalLobbyState.Value == LobbyState.CountDown)
|
|||
// {
|
|||
// GameManager.Instance.CancelCountDown();
|
|||
// }
|
|||
//
|
|||
// m_lifetime += k_UpdateIntervalMS;
|
|||
// await Task.Delay(k_UpdateIntervalMS);
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// async Task<Lobby> GetLatestRemoteLobby()
|
|||
// {
|
|||
// Lobby latestLobby = null;
|
|||
// if (m_LocalLobby.IsLobbyChanged())
|
|||
// {
|
|||
// latestLobby = await PushDataToLobby();
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// latestLobby = await m_LobbyManager.GetLobbyAsync();
|
|||
// }
|
|||
//
|
|||
// return latestLobby;
|
|||
// }
|
|||
//
|
|||
// bool IfRemoteLobbyChanged(Lobby remoteLobby)
|
|||
// {
|
|||
// var remoteLobbyTime = remoteLobby.LastUpdated.ToFileTimeUtc();
|
|||
// var localLobbyTime = m_LocalLobby.LastUpdated.Value;
|
|||
// var isLocalOutOfDate = remoteLobbyTime > localLobbyTime;
|
|||
// return isLocalOutOfDate;
|
|||
// }
|
|||
//
|
|||
// async Task<Lobby> PushDataToLobby()
|
|||
// {
|
|||
// m_LocalChanges = false;
|
|||
//
|
|||
// if (m_LocalUser.IsHost.Value)
|
|||
// await m_LobbyManager.UpdateLobbyDataAsync(
|
|||
// LobbyConverters.LocalToRemoteLobbyData(m_LocalLobby));
|
|||
//
|
|||
// return await m_LobbyManager.UpdatePlayerDataAsync(
|
|||
// LobbyConverters.LocalToRemoteUserData(m_LocalUser));
|
|||
// }
|
|||
//
|
|||
// bool AreAllUsersReady()
|
|||
// {
|
|||
// foreach (var lobbyUser in m_LocalLobby.LocalPlayers.Values)
|
|||
// {
|
|||
// if (lobbyUser.PlayerStatus.Value != PlayerStatus.Ready)
|
|||
// {
|
|||
// return false;
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// return true;
|
|||
// }
|
|||
//
|
|||
// bool LobbyHasHost()
|
|||
// {
|
|||
// if (!m_LocalUser.IsHost.Value)
|
|||
// {
|
|||
// foreach (var lobbyUser in m_LocalLobby.LocalPlayers)
|
|||
// {
|
|||
// if (lobbyUser.Value.IsHost.Value)
|
|||
// return true;
|
|||
// }
|
|||
//
|
|||
// return false;
|
|||
// }
|
|||
//
|
|||
// return true;
|
|||
// }
|
|||
//
|
|||
// void LeaveLobbyBecauseNoHost()
|
|||
// {
|
|||
// LogHandlerSettings.Instance.SpawnErrorPopup(
|
|||
// "Host left the lobby! Disconnecting...");
|
|||
// Locator.Get.Messenger.OnReceiveMessage(MessageType.EndGame, null);
|
|||
// GameManager.Instance.UIChangeMenuState(GameState.JoinMenu);
|
|||
// }
|
|||
//
|
|||
// public void OnLobbyIdChanged(string lobbyID)
|
|||
// {
|
|||
// if (string.IsNullOrEmpty(lobbyID)
|
|||
// ) // When the player leaves, their LocalLobby is cleared out.
|
|||
// {
|
|||
// EndSynch();
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// public void Dispose()
|
|||
// {
|
|||
// EndSynch();
|
|||
// }
|
|||
// }
|
|||
// }
|
|
|||
fileFormatVersion: 2 |
|||
guid: c198580a376d8264e822d2ef5df1a656 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: ffbb68b232e2a9244aaad5c90a499069 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue