You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
7.0 KiB
C#

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<string> OnRelayCreated;
public static event Action DelegateUI;
public static event Action OnRelayFailedToCreated;
public static event Action<string> OnRelayJoined;
public static event Action OnRelayFailedToJoined;
public static event Action<LobbyData, bool> 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<string, DataObject>
{
{"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<string> 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<UnityTransport>().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<string> 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<UnityTransport>().SetRelayServerData(serverData);
Debug.Log("Starting client");
NetworkManager.Singleton.StartClient();
}
catch (RelayServiceException e)
{
OnRelayFailedToJoined?.Invoke();
Debug.Log(e);
}
}
}
}