Inventory management focused game written in Godot / C#
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.

85 lines
2.1 KiB

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();
}
}