using System; using System.Collections.Generic; using System.Threading.Tasks; using Sirenix.OdinInspector; using Unity.Netcode; using Unity.Netcode.Transports.UTP; using Unity.Networking.Transport.Relay; using Unity.Services.Lobbies; using Unity.Services.Lobbies.Models; using Unity.Services.Relay; using UnityEngine; using UnityEngine.SceneManagement; namespace LobbyScripts { public class GameRelay : MonoBehaviour { [SerializeField] private bool _createSessionOnStart; [ShowIf(nameof(_createSessionOnStart))] [SerializeField] private int _maxPlayers; public static GameRelay Instance { set; get; } public string RelayCode { get; private set; } public int MaxPlayers => _maxPlayers; public static event Action OnRelayCreated; public static event Action DelegateUI; public static event Action OnRelayFailedToCreated; public static event Action OnRelayJoined; public static event Action OnRelayFailedToJoined; public static event Action DoCreateDummyLobby; public static Action DoJoinRelay; public void OnEnable() { LobbyUI.DoCreateASession += CreateGameRelay; LobbyUI.DoJoinASession += JoinGameRelay; // DoJoinRelay += StartASession; } public void OnDisable() { LobbyUI.DoCreateASession -= CreateGameRelay; LobbyUI.DoJoinASession -= JoinGameRelay; // DoJoinRelay -= StartASession; } private void Awake() { if (Instance != null && Instance != this) { Destroy(Instance.gameObject); return; } Instance = this; } public void StartASession() { if(!_createSessionOnStart) return; CreateGameRelay(_maxPlayers); } public async void CreateGameRelay(int maxPlayer) { try { var lobbyData = new LobbyData { LobbyName = "DummyLobby", MaxPlayers = maxPlayer, IsPrivate = true, }; await CreateDummyLobby(lobbyData);//Getting Lobby code and lobby instanc var relayCode = await CreateRelay(maxPlayer); //Creating relay allocation and return relay code await AddRelayCodeToLobby(relayCode);//Update lobby according to the allocated relay code GameLobby.GameLobbyInstance.IsCreatedThroughRelay = true; OnRelayCreated?.Invoke(GameLobby.GameLobbyInstance.LobbyInstance.LobbyCode);//Set lobby code if(!_createSessionOnStart) DelegateUI?.Invoke(); } catch (RelayServiceException e) { Debug.Log(e); } } private async Task CreateDummyLobby(LobbyData lobbyData) { try { await GameLobby.GameLobbyInstance.CreateLobby(lobbyData, false); } catch (LobbyServiceException e) { Debug.Log(e); } } private async Task AddRelayCodeToLobby(string relayCode) { try { var updateLobby = await Lobbies.Instance.UpdateLobbyAsync(GameLobby.GameLobbyInstance.LobbyInstance.Id, new UpdateLobbyOptions { Data = new Dictionary { {"START_GAME", new DataObject(DataObject.VisibilityOptions.Member, relayCode)} } }); GameLobby.GameLobbyInstance.LobbyInstance = updateLobby; } catch (LobbyServiceException e) { Debug.Log(e); } } void has(ulong par,string s) { } public async Task CreateRelay(int maxPlayer) { try { var relay = await Relay.Instance.CreateAllocationAsync(maxPlayer); RelayCode = await Relay.Instance.GetJoinCodeAsync(relay.AllocationId); var serverData = new RelayServerData(relay, "dtls"); NetworkManager.Singleton.GetComponent().SetRelayServerData(serverData); NetworkManager.Singleton.StartHost(); return RelayCode; } catch (RelayServiceException e) { OnRelayFailedToCreated?.Invoke(); Debug.Log(e); } return null; } private void CheckIfAlreadyInSession() { if (!_createSessionOnStart) return; if (!NetworkManager.Singleton.IsHost) return; if(GameLobby.GameLobbyInstance.IsLobbyHost()) GameLobby.GameLobbyInstance.DestroyLobby(); NetworkManager.Singleton.Shutdown(); } private async void JoinGameRelay(string code) { try { CheckIfAlreadyInSession(); var relayCode= await JoinLobby(code); if (relayCode == null) { OnRelayFailedToJoined?.Invoke(); return; } await JoinRelay(relayCode); OnRelayJoined?.Invoke(code); if(!_createSessionOnStart) DelegateUI?.Invoke(); } catch (RelayServiceException e) { Debug.Log(e); } } private async Task JoinLobby(string code) { try { await GameLobby.GameLobbyInstance.JoinPrivateLobbyByCode(code, false); return GameLobby.GameLobbyInstance.LobbyInstance.Data["START_GAME"].Value; } catch (LobbyServiceException e) { OnRelayFailedToJoined?.Invoke(); Debug.Log(e); } return null; } public async Task JoinRelay(string relayCode) { try { var relayToJoin = await Relay.Instance.JoinAllocationAsync(relayCode); var serverData = new RelayServerData(relayToJoin, "dtls"); NetworkManager.Singleton.GetComponent().SetRelayServerData(serverData); Debug.Log("Starting client"); NetworkManager.Singleton.StartClient(); } catch (RelayServiceException e) { OnRelayFailedToJoined?.Invoke(); Debug.Log(e); } } } }