|
|
|
public partial class MultiplayerManager : Node
|
|
|
|
{
|
|
|
|
[Export] public Player LocalPlayer { get; set; }
|
|
|
|
[Export] public Node3D Players { get; set; }
|
|
|
|
[Export] public PackedScene PlayerScene { get; set; }
|
|
|
|
|
|
|
|
public event Action<Player> PlayerJoined;
|
|
|
|
public event Action<Player> PlayerLeft;
|
|
|
|
|
|
|
|
public override void _Ready()
|
|
|
|
{
|
|
|
|
Multiplayer.ConnectedToServer += OnMultiplayerReady;
|
|
|
|
Multiplayer.ServerDisconnected += OnMultiplayerDisconnected;
|
|
|
|
Multiplayer.PeerConnected += OnPeerConnected;
|
|
|
|
Multiplayer.PeerDisconnected += OnPeerDisconnected;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Player GetPlayerByPeerId(int peerId)
|
|
|
|
=> Players.GetNode<Player>(peerId.ToString());
|
|
|
|
|
|
|
|
|
|
|
|
public void Connect(string address, ushort port)
|
|
|
|
{
|
|
|
|
var peer = new ENetMultiplayerPeer();
|
|
|
|
peer.CreateClient(address, port);
|
|
|
|
Multiplayer.MultiplayerPeer = peer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool CreateServer(ushort port)
|
|
|
|
{
|
|
|
|
var peer = new ENetMultiplayerPeer();
|
|
|
|
if (peer.CreateServer(port) == Error.Ok) {
|
|
|
|
Multiplayer.MultiplayerPeer = peer;
|
|
|
|
OnMultiplayerReady();
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Disconnect()
|
|
|
|
=> OnMultiplayerDisconnected();
|
|
|
|
|
|
|
|
|
|
|
|
void OnMultiplayerReady()
|
|
|
|
{
|
|
|
|
var localId = Multiplayer.GetUniqueId();
|
|
|
|
LocalPlayer.PeerId = localId;
|
|
|
|
LocalPlayer.SetMultiplayerAuthority(localId);
|
|
|
|
|
|
|
|
if (!Multiplayer.IsServer())
|
|
|
|
// Spawn players for all the other peers. This excludes the server,
|
|
|
|
// since `OnPeerConnected` will already be called for it on connecting.
|
|
|
|
foreach (var peerId in Multiplayer.GetPeers())
|
|
|
|
if (peerId != 1) OnPeerConnected(peerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OnMultiplayerDisconnected()
|
|
|
|
{
|
|
|
|
foreach (var player in Players.GetChildren().Cast<Player>()) {
|
|
|
|
if (player.IsLocal) player.PeerId = 0;
|
|
|
|
else OnPeerDisconnected(player.PeerId);
|
|
|
|
}
|
|
|
|
Multiplayer.MultiplayerPeer.Close();
|
|
|
|
Multiplayer.MultiplayerPeer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnPeerConnected(long peerId)
|
|
|
|
{
|
|
|
|
var player = PlayerScene.Instantiate<Player>();
|
|
|
|
player.SetMultiplayerAuthority((int)peerId);
|
|
|
|
player.PeerId = (int)peerId;
|
|
|
|
Players.AddChild(player);
|
|
|
|
PlayerJoined?.Invoke(player);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OnPeerDisconnected(long peerId)
|
|
|
|
{
|
|
|
|
var player = GetPlayerByPeerId((int)peerId);
|
|
|
|
PlayerLeft?.Invoke(player);
|
|
|
|
player.QueueFree();
|
|
|
|
}
|
|
|
|
}
|