using System.Collections.Immutable;
namespace LuckerParty;
///
/// Listens to Network events and creates Client GameObjects
///
public sealed class NetworkManager : Component, Component.INetworkListener
{
///
/// Map from Connection to Client GameObject
///
private readonly Dictionary _clientMap = new();
private readonly List _clients = new();
///
/// A GameObject used for organizational grouping of Clients
///
private GameObject _clientGroup;
public ImmutableList Clients => _clients.ToImmutableList();
public void OnActive( Connection channel )
{
// Set up the Client GameObject
var gameObject = new GameObject( _clientGroup ) { Name = $"{channel.DisplayName} ({channel.SteamId})" };
_clientMap.Add( channel, gameObject );
var client = gameObject.AddComponent();
client.Connection = channel;
// Spawn it on remote clients
gameObject.NetworkSpawn( channel );
_clients.Add( client );
IClientEvent.Post( e => e.OnConnected( client ) );
}
public void OnDisconnected( Connection channel )
{
if ( !_clientMap.TryGetValue( channel, out var clientGameObject ) )
{
Log.Warning( $"Disconnected client {channel.SteamId} has no associated GameObject." );
return;
}
var client = clientGameObject.GetComponent();
IClientEvent.Post( e => e.OnDisconnected( client ) );
clientGameObject.Destroy();
_clientMap.Remove( channel );
_clients.Remove( client );
}
protected override void OnAwake()
{
_clientGroup = new GameObject( Scene.Root ) { Name = "Clients", NetworkMode = NetworkMode.Object };
}
protected override void OnDestroy()
{
_clientGroup.Destroy();
}
public interface IClientEvent : ISceneEvent
{
void OnConnected( Client client )
{
}
void OnDisconnected( Client client ) { }
}
}