258 lines
8.1 KiB
C#
258 lines
8.1 KiB
C#
using _PROJECT.NewHandPresence;
|
|
using FishNet;
|
|
using FishNet.Discovery;
|
|
using FishNet.Managing.Scened;
|
|
using FishNet.Object;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using TMPro;
|
|
using Unity.XR.CoreUtils;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class NetworkMenuUI : MonoBehaviour
|
|
{
|
|
|
|
|
|
private ConcurrentQueue<System.Action> mainThreadQueue = new();
|
|
[Header("UI References")]
|
|
public Toggle VRToggle;
|
|
|
|
public Button startPlayingButton;
|
|
public Button reloadButton;
|
|
public Button joinMultiplayerButton;
|
|
public Transform serverListContainer;
|
|
public GameObject serverListItemPrefab;
|
|
public TMP_Text statusText;
|
|
public Button quitButton;
|
|
|
|
[Header("Networking")]
|
|
public NetworkDiscovery networkDiscovery;
|
|
public Camera uiCamera;
|
|
public AudioListener placeholderAudioListener;
|
|
private bool _useVR;
|
|
|
|
//public Image coverImage;
|
|
|
|
private readonly List<IPEndPoint> foundServers = new();
|
|
|
|
private void Start()
|
|
{
|
|
|
|
if (networkDiscovery == null)
|
|
networkDiscovery = FindObjectOfType<NetworkDiscovery>();
|
|
|
|
_useVR = PlayerPrefs.GetInt("UseVR", 0) == 1;
|
|
VRToggle.isOn = _useVR;
|
|
|
|
// React to UI toggle changes
|
|
VRToggle.onValueChanged.AddListener((isOn) =>
|
|
{
|
|
_useVR = isOn;
|
|
PlayerPrefs.SetInt("UseVR", _useVR ? 1 : 0);
|
|
PlayerPrefs.Save();
|
|
Debug.Log($"UseVR set to {_useVR}");
|
|
});
|
|
|
|
startPlayingButton.onClick.AddListener(OnStartPlaying);
|
|
reloadButton.onClick.AddListener(OnReload);
|
|
joinMultiplayerButton.onClick.AddListener(OnJoinMultiplayer);
|
|
quitButton.onClick.AddListener(OnQuit);
|
|
|
|
networkDiscovery.ServerFoundCallback += (endPoint) =>
|
|
{
|
|
Debug.Log("Found a server");
|
|
// Only queue the endpoint for main-thread processing
|
|
mainThreadQueue.Enqueue(() =>
|
|
{
|
|
StartCoroutine(ProcessServerFound(endPoint));
|
|
});
|
|
};
|
|
}
|
|
private void Update()
|
|
{
|
|
while (mainThreadQueue.TryDequeue(out var action))
|
|
{
|
|
action.Invoke(); // safely runs on main thread
|
|
}
|
|
}
|
|
private void OnStartPlaying()
|
|
{
|
|
statusText.text = "Starting host...";
|
|
StartCoroutine(HostAndSearchRoutine());
|
|
}
|
|
|
|
|
|
private void OnReload()
|
|
{
|
|
/*if (!InstanceFinder.IsClient)
|
|
{
|
|
Debug.LogWarning("Reload can only be called from a client!");
|
|
return;
|
|
}
|
|
|
|
// Use the ClientManager.Objects dictionary
|
|
foreach (NetworkObject obj in InstanceFinder.ClientManager.Objects.)
|
|
{
|
|
if (obj.IsOwner) // This ensures it's YOUR local player
|
|
{
|
|
var xr = obj.GetComponentInChildren<XROrigin>();
|
|
if (xr != null)
|
|
{
|
|
Debug.Log("Found my XR Origin player.");
|
|
|
|
TutorialController tutorial = xr.GetComponent<TutorialController>();
|
|
if (tutorial != null)
|
|
{
|
|
tutorial._state = TutorialController.TutorialState.Initializing;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("My local player is not an XR Origin.");
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
|
|
private void OnJoinMultiplayer()
|
|
{
|
|
statusText.text = "Searching for servers...";
|
|
networkDiscovery.StopSearchingForServers();
|
|
ClearServerList();
|
|
//Debug.Log(foundServers.Count);
|
|
foundServers.Clear();
|
|
//Debug.Log(foundServers.Count);
|
|
networkDiscovery.StartSearchingForServers();
|
|
}
|
|
|
|
private void OnQuit()
|
|
{
|
|
Debug.Log("Quitting application");
|
|
Application.Quit();
|
|
}
|
|
|
|
private IEnumerator ProcessServerFound(IPEndPoint endPoint)
|
|
{
|
|
Debug.Log("server found");
|
|
//Debug.Log(endPoint.Address.ToString());
|
|
//Debug.Log(foundServers.Count);
|
|
if (foundServers.Contains(endPoint)) yield return null;
|
|
foundServers.Add(endPoint);
|
|
|
|
Debug.Log($"Server found {endPoint}");
|
|
// Auto-join if started as host
|
|
if (InstanceFinder.IsServer)
|
|
{
|
|
Debug.Log("Server is local");
|
|
//networkDiscovery.StopAdvertisingServer();
|
|
networkDiscovery.StopSearchingForServers();
|
|
|
|
uiCamera.enabled = false;
|
|
Debug.Log("Disabled placeholder audio source");
|
|
placeholderAudioListener.enabled = false;
|
|
//coverImage.gameObject.SetActive(false);
|
|
|
|
InstanceFinder.ClientManager.StartConnection(endPoint.Address.ToString());
|
|
statusText.text = $"Joined server: {endPoint.Address}";
|
|
yield return null;
|
|
}
|
|
|
|
Debug.Log("Server is foregin");
|
|
GameObject item = Instantiate(serverListItemPrefab, serverListContainer);
|
|
|
|
|
|
|
|
TMP_Text label = item.GetComponentInChildren<TMP_Text>();
|
|
if (label != null)
|
|
label.text = endPoint.Address.ToString();
|
|
|
|
Button btn = item.GetComponent<Button>();
|
|
btn.onClick.RemoveAllListeners(); // clear any old listener
|
|
btn.onClick.AddListener(() =>
|
|
{
|
|
networkDiscovery.StopSearchingForServers();
|
|
if (uiCamera != null) uiCamera.enabled = false;
|
|
if (placeholderAudioListener != null)
|
|
{
|
|
Debug.Log("Disabled placeholder audio source");
|
|
placeholderAudioListener.enabled = false;
|
|
}
|
|
//coverImage.gameObject.SetActive(false);
|
|
InstanceFinder.ClientManager.StartConnection(endPoint.Address.ToString());
|
|
statusText.text = $"Joined server: {endPoint.Address}";
|
|
});
|
|
|
|
}
|
|
private Coroutine joinRoutine;
|
|
|
|
private IEnumerator HostAndSearchRoutine()
|
|
{
|
|
// Step 1: Start hosting
|
|
InstanceFinder.ServerManager.StartConnection();
|
|
|
|
// Step 2: Start advertising
|
|
yield return new WaitForSeconds(0.5f); // Let the server settle
|
|
networkDiscovery.StartAdvertisingServer();
|
|
|
|
// Step 3: Begin searching
|
|
yield return new WaitForSeconds(0.5f); // Let advertisement initialize
|
|
networkDiscovery.StartSearchingForServers();
|
|
|
|
// Step 4: Try to find and join a better server
|
|
yield return new WaitForSeconds(0.5f); // Give discovery a moment
|
|
StartJoinRoutine();
|
|
}
|
|
|
|
|
|
public void StartJoinRoutine()
|
|
{
|
|
if (joinRoutine != null) StopCoroutine(joinRoutine);
|
|
joinRoutine = StartCoroutine(TryJoinServerRepeatedly());
|
|
}
|
|
|
|
private IEnumerator TryJoinServerRepeatedly()
|
|
{
|
|
float timeout = 10f;
|
|
float timer = 0f;
|
|
|
|
while (timer < timeout)
|
|
{
|
|
if (foundServers.Count > 0)
|
|
{
|
|
var firstServer = foundServers[0];
|
|
//networkDiscovery.StopAdvertisingServer();
|
|
if (uiCamera != null) uiCamera.enabled = false;
|
|
if (placeholderAudioListener != null)
|
|
{
|
|
Debug.Log("Disabled placeholder audio source");
|
|
placeholderAudioListener.enabled = false;
|
|
}
|
|
networkDiscovery.StopSearchingForServers();
|
|
InstanceFinder.ClientManager.StartConnection(firstServer.Address.ToString());
|
|
statusText.text = $"Joined server: {firstServer.Address}";
|
|
//coverImage.gameObject.SetActive(false);
|
|
yield break;
|
|
}
|
|
|
|
statusText.text = $"Searching for servers... ({Mathf.FloorToInt(timer)}s)";
|
|
yield return new WaitForSeconds(1f);
|
|
timer += 1f;
|
|
}
|
|
|
|
|
|
statusText.text = "No servers found. Acting as host.";
|
|
// You can optionally start your own server here
|
|
}
|
|
|
|
private void ClearServerList()
|
|
{
|
|
foreach (Transform child in serverListContainer)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
}
|
|
}
|