You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
314 lines
8.8 KiB
314 lines
8.8 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Unity.Services.Authentication;
|
|
using Unity.Services.Core;
|
|
using Unity.Services.Lobbies.Models;
|
|
using Unity.Services.Lobbies;
|
|
using UnityEngine;
|
|
using Unity.Netcode.Transports.UTP;
|
|
using Unity.Netcode;
|
|
using Unity.Services.Relay.Models;
|
|
using Unity.Services.Relay;
|
|
using Unity.Networking.Transport.Relay;
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
|
|
public class ConnectionManager : MonoBehaviour
|
|
{
|
|
public static ConnectionManager Instance { get; private set; }
|
|
private void Awake()
|
|
{
|
|
if (Instance == null) Instance = this;
|
|
}
|
|
|
|
private Lobby hostLobby;
|
|
private Lobby joinedLobby;
|
|
private float heartbeatTimer;
|
|
private string scene;
|
|
|
|
public async void Start()
|
|
{
|
|
await UnityServices.InitializeAsync();
|
|
|
|
AuthenticationService.Instance.SignedIn += () =>
|
|
{
|
|
Debug.Log("signed in " + AuthenticationService.Instance.PlayerId);
|
|
GameManager.Instance.Loaded();
|
|
};
|
|
|
|
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected;
|
|
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnected;
|
|
|
|
await AuthenticationService.Instance.SignInAnonymouslyAsync();
|
|
}
|
|
|
|
private Action onClientConnected;
|
|
private Action onClientDisconnected;
|
|
|
|
private void OnClientConnected(ulong cliendID)
|
|
{
|
|
onClientConnected?.Invoke();
|
|
}
|
|
|
|
private void OnClientDisconnected(ulong cliendID)
|
|
{
|
|
onClientDisconnected?.Invoke();
|
|
}
|
|
|
|
private Unity.Services.Lobbies.Models.Player GetPlayer()
|
|
{
|
|
return new Unity.Services.Lobbies.Models.Player()
|
|
{
|
|
Data = new Dictionary<string, PlayerDataObject>
|
|
{
|
|
{ "PlayerName", new PlayerDataObject(PlayerDataObject.VisibilityOptions.Public, LocalPlayerData.PlayerName) }
|
|
}
|
|
};
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
HandleLobbyHeartbeat();
|
|
}
|
|
|
|
private async void HandleLobbyHeartbeat()
|
|
{
|
|
if (hostLobby != null)
|
|
{
|
|
heartbeatTimer -= Time.deltaTime;
|
|
if (heartbeatTimer < 0f)
|
|
{
|
|
float heartbeatTimerMax = 10f;
|
|
heartbeatTimer = heartbeatTimerMax;
|
|
|
|
try
|
|
{
|
|
await LobbyService.Instance.SendHeartbeatPingAsync(hostLobby.Id);
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task<bool> LeaveLobbyAsync()
|
|
{
|
|
try
|
|
{
|
|
if (joinedLobby != null)
|
|
{
|
|
await LobbyService.Instance.RemovePlayerAsync(joinedLobby.Id, AuthenticationService.Instance.PlayerId);
|
|
}
|
|
if (hostLobby != null)
|
|
{
|
|
await LobbyService.Instance.DeleteLobbyAsync(hostLobby.Id);
|
|
hostLobby = null;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch (LobbyServiceException ex)
|
|
{
|
|
Debug.Log(ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Shutdown()
|
|
{
|
|
if (NetworkManager.Singleton != null && NetworkManager.Singleton.IsClient)
|
|
{
|
|
Debug.Log("Client already running, shutting down the existing client.");
|
|
NetworkManager.Singleton.Shutdown();
|
|
Debug.Log("Yay");
|
|
}
|
|
}
|
|
|
|
public async void JoinLocation(string locationName, Action onJoin)
|
|
{
|
|
try
|
|
{
|
|
QueryLobbiesOptions queryOptions = new QueryLobbiesOptions
|
|
{
|
|
Filters = new List<QueryFilter>
|
|
{
|
|
new QueryFilter(QueryFilter.FieldOptions.Name, locationName, QueryFilter.OpOptions.EQ)
|
|
}
|
|
};
|
|
|
|
QueryResponse response = await LobbyService.Instance.QueryLobbiesAsync(queryOptions);
|
|
|
|
if (response.Results.Count == 0)
|
|
{
|
|
Debug.Log("No lobby found. Let's create one!");
|
|
|
|
Debug.Log("CreateLobbyAndRelay Start");
|
|
await CreateLobbyAndRelayAsync(locationName, 20, false);
|
|
}
|
|
else
|
|
{
|
|
Lobby lobby = response.Results[0];
|
|
Debug.Log(lobby.Id);
|
|
Debug.Log(lobby.LobbyCode);
|
|
Debug.Log(lobby.Name);
|
|
|
|
await JoinLobbyAndRelayAsync(lobby.Id);
|
|
}
|
|
|
|
Debug.Log("JoinLocation CanInvoke");
|
|
onJoin?.Invoke();
|
|
}
|
|
catch (LobbyServiceException ex)
|
|
{
|
|
Debug.Log(ex);
|
|
}
|
|
}
|
|
|
|
public async void CreateLobbyAndRelay(string lobbyName, int maxPlayers, bool isPrivate, Action onCreated = null)
|
|
{
|
|
await CreateLobbyAndRelayAsync(lobbyName, maxPlayers, isPrivate);
|
|
onCreated?.Invoke();
|
|
}
|
|
|
|
public async void JoinLobbyAndRelay(string lobbyId, Action onJoined = null)
|
|
{
|
|
await JoinLobbyAndRelayAsync(lobbyId);
|
|
onJoined?.Invoke();
|
|
}
|
|
|
|
public async void JoinRelay(string joinCode, Action onJoined = null)
|
|
{
|
|
await JoinRelayAsync(joinCode);
|
|
onJoined?.Invoke();
|
|
}
|
|
|
|
private async Task<bool> CreateLobbyAndRelayAsync(string lobbyName, int maxPlayers, bool isPrivate)
|
|
{
|
|
try
|
|
{
|
|
await LeaveLobbyAsync();
|
|
string joinCode = await CreateRelayAsync(maxPlayers);
|
|
|
|
CreateLobbyOptions options = new CreateLobbyOptions
|
|
{
|
|
IsPrivate = isPrivate,
|
|
Player = GetPlayer(),
|
|
Data = new Dictionary<string, DataObject>
|
|
{
|
|
{ "joinCode", new DataObject(DataObject.VisibilityOptions.Public, joinCode) }
|
|
}
|
|
};
|
|
|
|
hostLobby = await LobbyService.Instance.CreateLobbyAsync(lobbyName, maxPlayers, options);
|
|
joinedLobby = hostLobby;
|
|
|
|
return true;
|
|
}
|
|
catch (LobbyServiceException ex)
|
|
{
|
|
Debug.Log(ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private async Task<bool> JoinLobbyAndRelayAsync(string lobbyId)
|
|
{
|
|
try
|
|
{
|
|
await LeaveLobbyAsync();
|
|
|
|
JoinLobbyByIdOptions options = new JoinLobbyByIdOptions
|
|
{
|
|
Player = GetPlayer()
|
|
};
|
|
|
|
Lobby lobby = await LobbyService.Instance.GetLobbyAsync(lobbyId);
|
|
//joinedLobby = await LobbyService.Instance.JoinLobbyByIdAsync(lobbyId, options);
|
|
await JoinRelayAsync(lobby.Data["joinCode"].Value);
|
|
return true;
|
|
}
|
|
catch (LobbyServiceException ex)
|
|
{
|
|
Debug.Log(ex);
|
|
return false;
|
|
}
|
|
}
|
|
//==============RELAY==============
|
|
private async Task<string> CreateRelayAsync(int maxPlayers)
|
|
{
|
|
try
|
|
{
|
|
ChatManager.Instance.ClearUsers();
|
|
ChatManager.Instance.ClearLocationChat();
|
|
Shutdown();
|
|
|
|
Allocation allocation = await RelayService.Instance.CreateAllocationAsync(maxPlayers);
|
|
|
|
string joinCode = await RelayService.Instance.GetJoinCodeAsync(allocation.AllocationId);
|
|
Debug.Log(joinCode);
|
|
|
|
RelayServerData relayServerData = new RelayServerData(allocation, "dtls");
|
|
NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(relayServerData);
|
|
|
|
NetworkManager.Singleton.StartHost();
|
|
return joinCode;
|
|
}
|
|
catch (RelayServiceException ex)
|
|
{
|
|
Debug.Log(ex);
|
|
return "";
|
|
}
|
|
}
|
|
|
|
private async Task<bool> JoinRelayAsync(string joinCode)
|
|
{
|
|
try
|
|
{
|
|
ChatManager.Instance.ClearUsers();
|
|
ChatManager.Instance.ClearLocationChat();
|
|
Shutdown();
|
|
|
|
JoinAllocation joinAllocation = await RelayService.Instance.JoinAllocationAsync(joinCode);
|
|
|
|
RelayServerData relayServerData = new RelayServerData(joinAllocation, "dtls");
|
|
NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(relayServerData);
|
|
|
|
NetworkManager.Singleton.StartClient();
|
|
return true;
|
|
|
|
}
|
|
catch (RelayServiceException ex)
|
|
{
|
|
Debug.Log(ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
private async void ListLobbies()
|
|
{
|
|
QueryLobbiesOptions options = new QueryLobbiesOptions()
|
|
{
|
|
Count = 25,
|
|
Filters = new List<QueryFilter>()
|
|
{
|
|
new QueryFilter(QueryFilter.FieldOptions.AvailableSlots, "0", QueryFilter.OpOptions.GT)
|
|
},
|
|
Order = new List<QueryOrder>()
|
|
{
|
|
new QueryOrder(false, QueryOrder.FieldOptions.Created)
|
|
}
|
|
};
|
|
|
|
QueryResponse lobbies = await Lobbies.Instance.QueryLobbiesAsync();
|
|
|
|
foreach (var lobbie in lobbies.Results)
|
|
{
|
|
Debug.Log($"{lobbie.Name} (${lobbie.Id})");
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|