649 lines
21 KiB
C#
649 lines
21 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using BlockSpace.Account;
|
|
using BlockSpace.Voxels;
|
|
using ExitGames.Client.Photon;
|
|
using Photon.Pun;
|
|
using Photon.Realtime;
|
|
using Photon.VR;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
using UnityEngine.UI;
|
|
|
|
namespace BlockSpace.Worlds
|
|
{
|
|
[DisallowMultipleComponent]
|
|
public sealed class WorldCommandPoller : MonoBehaviourPunCallbacks
|
|
{
|
|
[Serializable]
|
|
private sealed class PollRequest
|
|
{
|
|
public string playerId;
|
|
}
|
|
|
|
[Serializable]
|
|
private sealed class PollResponse
|
|
{
|
|
public bool ok;
|
|
|
|
public Command command;
|
|
|
|
public string error;
|
|
}
|
|
|
|
[Serializable]
|
|
private sealed class Command
|
|
{
|
|
public string type;
|
|
|
|
public string worldName;
|
|
|
|
public string roomName;
|
|
}
|
|
|
|
[Serializable]
|
|
private sealed class PresencePingRequest
|
|
{
|
|
public string playerId;
|
|
|
|
public string roomName;
|
|
}
|
|
|
|
[SerializeField]
|
|
private bool enable = true;
|
|
|
|
[SerializeField]
|
|
private string backendBaseUrl = "https://blockspacebackend-production.up.railway.app";
|
|
|
|
[SerializeField]
|
|
private float pollIntervalSeconds = 2f;
|
|
|
|
[SerializeField]
|
|
private float onlinePingIntervalSeconds = 5f;
|
|
|
|
[Header("Loading Screen")]
|
|
[SerializeField]
|
|
private GameObject loadingScreenObject;
|
|
|
|
[SerializeField]
|
|
private Slider loadingProgressSlider;
|
|
|
|
[SerializeField]
|
|
private WorldLoadingScreenController loadingScreen;
|
|
|
|
private const string DefaultLobbyWorldName = "Lobby";
|
|
|
|
private const string DefaultLobbyWorldId = "ZT5HjbaGAT5adlkvAirJ0A";
|
|
|
|
private const int PublicWorldJoinRetryCount = 5;
|
|
|
|
private const string RoomWorldVersionKey = "worldVersion";
|
|
|
|
private Coroutine pollCoroutine;
|
|
|
|
private Coroutine pingCoroutine;
|
|
|
|
private bool joinInProgress;
|
|
|
|
private bool joinResultReady;
|
|
|
|
private bool joinSucceeded;
|
|
|
|
private bool leftRoomReady;
|
|
|
|
private bool lobbyReady;
|
|
|
|
private bool startupLobbyJoinRequested;
|
|
|
|
private new void OnEnable()
|
|
{
|
|
StartLoopsIfNeeded();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
Debug.Log("[WorldCommandPoller] Start: beginning lobby startup sequence.");
|
|
StartCoroutine(JoinLobbyWhenBackendReady());
|
|
}
|
|
|
|
private IEnumerator JoinLobbyWhenBackendReady()
|
|
{
|
|
BeginLoadingScreen(0.02f);
|
|
float connectStart = Time.realtimeSinceStartup;
|
|
while (PhotonNetwork.NetworkClientState != ClientState.ConnectedToMasterServer && Time.realtimeSinceStartup - connectStart < 15f)
|
|
{
|
|
yield return null;
|
|
}
|
|
Debug.Log($"[WorldCommandPoller] JoinLobbyWhenBackendReady: Photon state={PhotonNetwork.NetworkClientState} after wait.");
|
|
SetLoadingProgress(0.08f);
|
|
if (startupLobbyJoinRequested)
|
|
{
|
|
yield break;
|
|
}
|
|
string playerId = BlockSpaceAccountPrefs.GetUserFolderId();
|
|
WorldBackendClient client = new WorldBackendClient(backendBaseUrl);
|
|
float backendStart = Time.realtimeSinceStartup;
|
|
while (Time.realtimeSinceStartup - backendStart < 20f)
|
|
{
|
|
WorldBackendClient.ResolveWorldResponse resolve = null;
|
|
yield return client.ResolveWorld("Lobby", playerId, delegate(WorldBackendClient.ResolveWorldResponse r)
|
|
{
|
|
resolve = r;
|
|
});
|
|
if (resolve != null && resolve.ok)
|
|
{
|
|
Debug.Log("[WorldCommandPoller] JoinLobbyWhenBackendReady: backend resolve succeeded for Lobby.");
|
|
SetLoadingProgress(0.14f);
|
|
break;
|
|
}
|
|
if (resolve != null)
|
|
{
|
|
Debug.LogWarning($"[WorldCommandPoller] JoinLobbyWhenBackendReady: backend responded but resolve failed. Continuing to lobby join. ok={resolve.ok}, error={resolve.error}");
|
|
SetLoadingProgress(0.14f);
|
|
break;
|
|
}
|
|
Debug.LogWarning("[WorldCommandPoller] JoinLobbyWhenBackendReady: backend resolve returned null.");
|
|
yield return new WaitForSecondsRealtime(1f);
|
|
}
|
|
startupLobbyJoinRequested = true;
|
|
Debug.Log("[WorldCommandPoller] JoinLobbyWhenBackendReady: proceeding to join default Lobby world.");
|
|
SetLoadingProgress(0.2f);
|
|
yield return JoinWorldInstance("Lobby");
|
|
yield return IncrementVisitForCurrentWorldIfMatches("Lobby");
|
|
}
|
|
|
|
private IEnumerator IncrementVisitForCurrentWorldIfMatches(string baseWorldName)
|
|
{
|
|
if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || !string.Equals(GetBaseWorldName(PhotonNetwork.CurrentRoom.Name), baseWorldName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
yield break;
|
|
}
|
|
string userFolderId = BlockSpaceAccountPrefs.GetUserFolderId();
|
|
if (!string.IsNullOrEmpty(userFolderId))
|
|
{
|
|
WorldBackendClient client = new WorldBackendClient(backendBaseUrl);
|
|
WorldBackendClient.ResolveWorldResponse resolve = null;
|
|
yield return client.ResolveWorld(baseWorldName, userFolderId, delegate(WorldBackendClient.ResolveWorldResponse r)
|
|
{
|
|
resolve = r;
|
|
});
|
|
if (resolve != null && resolve.ok && resolve.exists && !string.IsNullOrEmpty(resolve.worldId))
|
|
{
|
|
yield return client.IncrementVisit(resolve.worldId, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static string RandomPrivateCode()
|
|
{
|
|
char c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[UnityEngine.Random.Range(0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".Length)];
|
|
char c2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[UnityEngine.Random.Range(0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".Length)];
|
|
char c3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[UnityEngine.Random.Range(0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".Length)];
|
|
return new string(new char[3] { c, c2, c3 });
|
|
}
|
|
|
|
private IEnumerator JoinPrivateWorldInstance(string worldName)
|
|
{
|
|
for (int attempt = 0; attempt < 10; attempt++)
|
|
{
|
|
string text = RandomPrivateCode();
|
|
string roomName = worldName + "|" + text;
|
|
yield return JoinExactRoom(roomName);
|
|
if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && string.Equals(PhotonNetwork.CurrentRoom.Name, roomName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private new void OnDisable()
|
|
{
|
|
StopAllCoroutines();
|
|
pollCoroutine = null;
|
|
pingCoroutine = null;
|
|
SetLoadingScreen(visible: false, 0f);
|
|
}
|
|
|
|
private void StartLoopsIfNeeded()
|
|
{
|
|
if (enable)
|
|
{
|
|
if (pollCoroutine == null)
|
|
{
|
|
pollCoroutine = StartCoroutine(PollLoop());
|
|
}
|
|
if (pingCoroutine == null)
|
|
{
|
|
pingCoroutine = StartCoroutine(PresencePingLoop());
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SetLoadingScreen(bool visible, float progress)
|
|
{
|
|
WorldLoadingScreenController worldLoadingScreenController = ResolveLoadingScreen();
|
|
if (!(worldLoadingScreenController == null))
|
|
{
|
|
worldLoadingScreenController.SetLoading(visible);
|
|
worldLoadingScreenController.SetProgress(progress);
|
|
}
|
|
}
|
|
|
|
private void BeginLoadingScreen(float progress)
|
|
{
|
|
WorldLoadingScreenController worldLoadingScreenController = ResolveLoadingScreen();
|
|
if (!(worldLoadingScreenController == null))
|
|
{
|
|
worldLoadingScreenController.BeginLoading(progress);
|
|
}
|
|
}
|
|
|
|
private void SetLoadingProgress(float progress)
|
|
{
|
|
WorldLoadingScreenController worldLoadingScreenController = ResolveLoadingScreen();
|
|
if (!(worldLoadingScreenController == null))
|
|
{
|
|
worldLoadingScreenController.SetCheckpoint(progress);
|
|
}
|
|
}
|
|
|
|
private WorldLoadingScreenController ResolveLoadingScreen()
|
|
{
|
|
if (loadingScreen == null)
|
|
{
|
|
loadingScreen = ((WorldLoadingScreenController.Instance != null) ? WorldLoadingScreenController.Instance : UnityEngine.Object.FindFirstObjectByType<WorldLoadingScreenController>());
|
|
}
|
|
if (loadingScreen == null && loadingScreenObject != null)
|
|
{
|
|
loadingScreen = base.gameObject.AddComponent<WorldLoadingScreenController>();
|
|
}
|
|
if (loadingScreen != null)
|
|
{
|
|
loadingScreen.Configure(loadingScreenObject, loadingProgressSlider);
|
|
}
|
|
return loadingScreen;
|
|
}
|
|
|
|
private IEnumerator PresencePingLoop()
|
|
{
|
|
while (enable)
|
|
{
|
|
yield return new WaitForSecondsRealtime(Mathf.Clamp(onlinePingIntervalSeconds, 1f, 60f));
|
|
if (!BlockSpaceAccountPrefs.IsLinked)
|
|
{
|
|
continue;
|
|
}
|
|
string linkedPlayerId = BlockSpaceAccountPrefs.GetLinkedPlayerId();
|
|
if (!string.IsNullOrEmpty(linkedPlayerId))
|
|
{
|
|
string url = (backendBaseUrl ?? string.Empty).Trim().TrimEnd('/') + "/api/presence/ping";
|
|
string roomName = ((PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) ? PhotonNetwork.CurrentRoom.Name : "");
|
|
string s = JsonUtility.ToJson(new PresencePingRequest
|
|
{
|
|
playerId = linkedPlayerId,
|
|
roomName = roomName
|
|
});
|
|
using UnityWebRequest request = new UnityWebRequest(url, "POST");
|
|
byte[] bytes = Encoding.UTF8.GetBytes(s);
|
|
request.uploadHandler = new UploadHandlerRaw(bytes);
|
|
request.downloadHandler = new DownloadHandlerBuffer();
|
|
request.SetRequestHeader("Content-Type", "application/json");
|
|
yield return request.SendWebRequest();
|
|
}
|
|
}
|
|
}
|
|
|
|
private IEnumerator PollLoop()
|
|
{
|
|
while (enable)
|
|
{
|
|
yield return new WaitForSecondsRealtime(Mathf.Clamp(pollIntervalSeconds, 0.5f, 30f));
|
|
if (!BlockSpaceAccountPrefs.IsLinked || joinInProgress)
|
|
{
|
|
continue;
|
|
}
|
|
string linkedPlayerId = BlockSpaceAccountPrefs.GetLinkedPlayerId();
|
|
if (string.IsNullOrEmpty(linkedPlayerId))
|
|
{
|
|
continue;
|
|
}
|
|
string text = (backendBaseUrl ?? string.Empty).Trim().TrimEnd('/');
|
|
if (string.IsNullOrEmpty(text))
|
|
{
|
|
continue;
|
|
}
|
|
string url = text + "/api/commands/poll";
|
|
string s = JsonUtility.ToJson(new PollRequest
|
|
{
|
|
playerId = linkedPlayerId
|
|
});
|
|
PollResponse response = null;
|
|
using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
|
|
{
|
|
byte[] bytes = Encoding.UTF8.GetBytes(s);
|
|
request.uploadHandler = new UploadHandlerRaw(bytes);
|
|
request.downloadHandler = new DownloadHandlerBuffer();
|
|
request.SetRequestHeader("Content-Type", "application/json");
|
|
yield return request.SendWebRequest();
|
|
if (request.result == UnityWebRequest.Result.Success)
|
|
{
|
|
try
|
|
{
|
|
response = JsonUtility.FromJson<PollResponse>(request.downloadHandler.text);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|
|
if (response == null || !response.ok || response.command == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (!string.Equals(response.command.type, "join_world", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
if (string.Equals(response.command.type, "world_reload", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string text2 = (response.command.worldName ?? string.Empty).Trim();
|
|
if (!string.IsNullOrEmpty(text2))
|
|
{
|
|
yield return JoinWorldInstance(text2);
|
|
}
|
|
}
|
|
else if (string.Equals(response.command.type, "world_force_save", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string text3 = (response.command.worldName ?? string.Empty).Trim();
|
|
if (!string.IsNullOrEmpty(text3))
|
|
{
|
|
yield return ForceSaveWorld(text3);
|
|
}
|
|
}
|
|
else if (string.Equals(response.command.type, "join_room", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string text4 = (response.command.roomName ?? string.Empty).Trim();
|
|
if (!string.IsNullOrEmpty(text4))
|
|
{
|
|
yield return JoinExactRoom(text4);
|
|
}
|
|
}
|
|
else if (string.Equals(response.command.type, "join_world_private", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string text5 = (response.command.worldName ?? string.Empty).Trim();
|
|
if (!string.IsNullOrEmpty(text5))
|
|
{
|
|
yield return JoinPrivateWorldInstance(text5);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string text6 = (response.command.worldName ?? string.Empty).Trim();
|
|
if (!string.IsNullOrEmpty(text6))
|
|
{
|
|
yield return JoinWorldInstance(text6);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static string GetBaseWorldName(string roomName)
|
|
{
|
|
string text = (roomName ?? string.Empty).Trim();
|
|
if (string.IsNullOrEmpty(text))
|
|
{
|
|
return text;
|
|
}
|
|
int num = text.LastIndexOf('|');
|
|
if (num <= 0)
|
|
{
|
|
return text;
|
|
}
|
|
string text2 = text.Substring(num + 1);
|
|
if (text2.Length == 3 && Regex.IsMatch(text2, "^[A-Za-z0-9]{3}$"))
|
|
{
|
|
return text.Substring(0, num);
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private IEnumerator ForceSaveWorld(string baseWorldName)
|
|
{
|
|
if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && string.Equals(GetBaseWorldName(PhotonNetwork.CurrentRoom.Name), baseWorldName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
VoxelGroupPhotonSync voxelGroupPhotonSync = UnityEngine.Object.FindFirstObjectByType<VoxelGroupPhotonSync>();
|
|
if (!(voxelGroupPhotonSync == null))
|
|
{
|
|
yield return voxelGroupPhotonSync.ForceSaveNow();
|
|
}
|
|
}
|
|
}
|
|
|
|
private IEnumerator JoinWorldInstance(string worldName)
|
|
{
|
|
Debug.Log("[WorldCommandPoller] JoinWorldInstance: starting join for world '" + worldName + "'.");
|
|
joinInProgress = true;
|
|
BeginLoadingScreen(0.2f);
|
|
if (PhotonNetwork.InRoom)
|
|
{
|
|
SetLoadingProgress(0.24f);
|
|
Debug.Log("[WorldCommandPoller] JoinWorldInstance: leaving current room '" + PhotonNetwork.CurrentRoom?.Name + "'.");
|
|
leftRoomReady = false;
|
|
PhotonNetwork.LeaveRoom();
|
|
float start = Time.realtimeSinceStartup;
|
|
while (!leftRoomReady && Time.realtimeSinceStartup - start < 10f)
|
|
{
|
|
yield return null;
|
|
}
|
|
SetLoadingProgress(0.3f);
|
|
Debug.Log($"[WorldCommandPoller] JoinWorldInstance: left room ready={leftRoomReady}, inRoom={PhotonNetwork.InRoom}.");
|
|
}
|
|
SetLoadingProgress(0.34f);
|
|
float masterStart = Time.realtimeSinceStartup;
|
|
while (PhotonNetwork.NetworkClientState != ClientState.ConnectedToMasterServer && Time.realtimeSinceStartup - masterStart < 10f)
|
|
{
|
|
yield return null;
|
|
}
|
|
SetLoadingProgress(0.4f);
|
|
if (PhotonNetwork.NetworkClientState != ClientState.ConnectedToMasterServer)
|
|
{
|
|
joinInProgress = false;
|
|
SetLoadingScreen(visible: false, 0f);
|
|
yield break;
|
|
}
|
|
WorldBackendClient client = new WorldBackendClient(backendBaseUrl);
|
|
int maxPlayers = ((PhotonVRManager.Manager != null) ? PhotonVRManager.Manager.DefaultRoomLimit : 16);
|
|
for (int attempt = 0; attempt < 5; attempt++)
|
|
{
|
|
SetLoadingProgress(0.46f);
|
|
WorldBackendClient.LobbyTargetResponse target = null;
|
|
yield return client.ResolveLobbyTarget(worldName, maxPlayers, delegate(WorldBackendClient.LobbyTargetResponse r)
|
|
{
|
|
target = r;
|
|
});
|
|
if (target == null || !target.ok || string.IsNullOrEmpty(target.roomName))
|
|
{
|
|
Debug.LogWarning(string.Format("[WorldCommandPoller] JoinWorldInstance: lobby target failed for '{0}' [attempt {1}/{2}]. error={3}", worldName, attempt + 1, 5, (target != null) ? target.error : "<null>"));
|
|
yield return new WaitForSecondsRealtime(1f);
|
|
continue;
|
|
}
|
|
joinResultReady = false;
|
|
joinSucceeded = false;
|
|
SetLoadingProgress(0.54f);
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
if (!string.IsNullOrEmpty(target.worldVersion))
|
|
{
|
|
hashtable["worldVersion"] = target.worldVersion;
|
|
}
|
|
RoomOptions roomOptions = new RoomOptions();
|
|
roomOptions.IsVisible = true;
|
|
roomOptions.IsOpen = true;
|
|
roomOptions.MaxPlayers = (byte)Mathf.Clamp(maxPlayers, 1, 255);
|
|
roomOptions.CustomRoomProperties = hashtable;
|
|
roomOptions.CustomRoomPropertiesForLobby = new string[1] { "worldVersion" };
|
|
RoomOptions roomOptions2 = roomOptions;
|
|
Debug.Log($"[WorldCommandPoller] JoinWorldInstance: backend selected {target.action}('{target.roomName}') worldVersion='{target.worldVersion}' roomsSeen={target.roomsSeen} [attempt {attempt + 1}/{5}].");
|
|
if (string.Equals(target.action, "join", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
SetLoadingProgress(0.6f);
|
|
PhotonNetwork.JoinRoom(target.roomName);
|
|
}
|
|
else
|
|
{
|
|
SetLoadingProgress(0.6f);
|
|
PhotonNetwork.JoinOrCreateRoom(target.roomName, roomOptions2, null);
|
|
}
|
|
float start = Time.realtimeSinceStartup;
|
|
while (!joinResultReady && Time.realtimeSinceStartup - start < 12f)
|
|
{
|
|
yield return null;
|
|
}
|
|
if (!joinResultReady && PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && string.Equals(PhotonNetwork.CurrentRoom.Name, target.roomName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
joinSucceeded = true;
|
|
joinResultReady = true;
|
|
Debug.Log("[WorldCommandPoller] JoinWorldInstance: detected successful join by current room '" + target.roomName + "' without callback.");
|
|
}
|
|
Debug.Log($"[WorldCommandPoller] JoinWorldInstance: room '{target.roomName}' join result ready={joinResultReady}, succeeded={joinSucceeded}, inRoom={PhotonNetwork.InRoom}, currentRoom={PhotonNetwork.CurrentRoom?.Name}.");
|
|
if (joinSucceeded && PhotonNetwork.InRoom)
|
|
{
|
|
Debug.Log("[WorldCommandPoller] JoinWorldInstance: successfully joined room '" + target.roomName + "'.");
|
|
joinInProgress = false;
|
|
SetLoadingProgress(0.66f);
|
|
yield break;
|
|
}
|
|
if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && !string.Equals(PhotonNetwork.CurrentRoom.Name, target.roomName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Debug.LogWarning("[WorldCommandPoller] JoinWorldInstance: still in different room '" + PhotonNetwork.CurrentRoom.Name + "' after attempting '" + target.roomName + "', leaving before next attempt.");
|
|
leftRoomReady = false;
|
|
PhotonNetwork.LeaveRoom();
|
|
float leaveStart = Time.realtimeSinceStartup;
|
|
while (!leftRoomReady && Time.realtimeSinceStartup - leaveStart < 10f)
|
|
{
|
|
yield return null;
|
|
}
|
|
SetLoadingProgress(0.3f);
|
|
}
|
|
yield return new WaitForSecondsRealtime(0.5f);
|
|
}
|
|
joinInProgress = false;
|
|
SetLoadingScreen(visible: false, 0f);
|
|
}
|
|
|
|
private IEnumerator JoinExactRoom(string roomName)
|
|
{
|
|
Debug.Log("[WorldCommandPoller] JoinExactRoom: starting join for exact room '" + roomName + "'.");
|
|
joinInProgress = true;
|
|
BeginLoadingScreen(0.2f);
|
|
if (PhotonNetwork.InRoom)
|
|
{
|
|
SetLoadingProgress(0.24f);
|
|
Debug.Log("[WorldCommandPoller] JoinExactRoom: leaving current room '" + PhotonNetwork.CurrentRoom?.Name + "'.");
|
|
leftRoomReady = false;
|
|
PhotonNetwork.LeaveRoom();
|
|
float start = Time.realtimeSinceStartup;
|
|
while (!leftRoomReady && Time.realtimeSinceStartup - start < 10f)
|
|
{
|
|
yield return null;
|
|
}
|
|
SetLoadingProgress(0.3f);
|
|
Debug.Log($"[WorldCommandPoller] JoinExactRoom: left room ready={leftRoomReady}, inRoom={PhotonNetwork.InRoom}.");
|
|
}
|
|
SetLoadingProgress(0.34f);
|
|
float masterStart = Time.realtimeSinceStartup;
|
|
while (PhotonNetwork.NetworkClientState != ClientState.ConnectedToMasterServer && Time.realtimeSinceStartup - masterStart < 10f)
|
|
{
|
|
yield return null;
|
|
}
|
|
SetLoadingProgress(0.4f);
|
|
if (PhotonNetwork.NetworkClientState != ClientState.ConnectedToMasterServer)
|
|
{
|
|
joinInProgress = false;
|
|
SetLoadingScreen(visible: false, 0f);
|
|
yield break;
|
|
}
|
|
if (!PhotonNetwork.InLobby)
|
|
{
|
|
lobbyReady = false;
|
|
PhotonNetwork.JoinLobby();
|
|
float start = Time.realtimeSinceStartup;
|
|
while (!lobbyReady && Time.realtimeSinceStartup - start < 10f)
|
|
{
|
|
yield return null;
|
|
}
|
|
SetLoadingProgress(0.5f);
|
|
if (!PhotonNetwork.InLobby)
|
|
{
|
|
joinInProgress = false;
|
|
SetLoadingScreen(visible: false, 0f);
|
|
yield break;
|
|
}
|
|
}
|
|
joinResultReady = false;
|
|
joinSucceeded = false;
|
|
RoomOptions roomOptions = new RoomOptions
|
|
{
|
|
IsVisible = true,
|
|
IsOpen = true,
|
|
MaxPlayers = ((PhotonVRManager.Manager != null) ? ((byte)PhotonVRManager.Manager.DefaultRoomLimit) : 16)
|
|
};
|
|
Debug.Log("[WorldCommandPoller] JoinExactRoom: requesting JoinOrCreateRoom('" + roomName + "').");
|
|
SetLoadingProgress(0.6f);
|
|
PhotonNetwork.JoinOrCreateRoom(roomName, roomOptions, null);
|
|
float waitStart = Time.realtimeSinceStartup;
|
|
while (!joinResultReady && Time.realtimeSinceStartup - waitStart < 10f)
|
|
{
|
|
yield return null;
|
|
}
|
|
Debug.Log($"[WorldCommandPoller] JoinExactRoom: room '{roomName}' join result ready={joinResultReady}, succeeded={joinSucceeded}, inRoom={PhotonNetwork.InRoom}.");
|
|
joinInProgress = false;
|
|
if (joinSucceeded && PhotonNetwork.InRoom)
|
|
{
|
|
SetLoadingProgress(0.66f);
|
|
}
|
|
else
|
|
{
|
|
SetLoadingScreen(visible: false, 0f);
|
|
}
|
|
}
|
|
|
|
public override void OnLeftRoom()
|
|
{
|
|
leftRoomReady = true;
|
|
base.OnLeftRoom();
|
|
}
|
|
|
|
public override void OnJoinedRoom()
|
|
{
|
|
joinSucceeded = true;
|
|
joinResultReady = true;
|
|
Debug.Log("[WorldCommandPoller] OnJoinedRoom: joined room '" + PhotonNetwork.CurrentRoom?.Name + "' successfully.");
|
|
base.OnJoinedRoom();
|
|
}
|
|
|
|
public override void OnJoinedLobby()
|
|
{
|
|
lobbyReady = true;
|
|
Debug.Log("[WorldCommandPoller] OnJoinedLobby: Photon lobby joined successfully.");
|
|
base.OnJoinedLobby();
|
|
}
|
|
|
|
public override void OnJoinRoomFailed(short returnCode, string message)
|
|
{
|
|
joinSucceeded = false;
|
|
joinResultReady = true;
|
|
Debug.LogWarning($"[WorldCommandPoller] OnJoinRoomFailed: code={returnCode}, message={message}, state={PhotonNetwork.NetworkClientState}.");
|
|
base.OnJoinRoomFailed(returnCode, message);
|
|
}
|
|
|
|
public override void OnCreateRoomFailed(short returnCode, string message)
|
|
{
|
|
joinSucceeded = false;
|
|
joinResultReady = true;
|
|
Debug.LogWarning($"[WorldCommandPoller] OnCreateRoomFailed: code={returnCode}, message={message}, state={PhotonNetwork.NetworkClientState}.");
|
|
base.OnCreateRoomFailed(returnCode, message);
|
|
}
|
|
}
|
|
}
|