imperfect-space/scripts/NetworkManager.cs
2026-01-29 09:43:15 -05:00

101 lines
2.2 KiB
C#

using System.Threading.Tasks;
using Godot;
public partial class NetworkManager : Node
{
[Export] public RPCNode RPCNode { get; private set; }
public static NetworkManager Singleton { get; private set; }
public int LocalNetId { get; private set; } = -1;
public override void _Ready()
{
Singleton = this;
if (Global.IsGameHost)
{
CreateServer();
}
else
{
CreateClient();
}
GetTree().GetMultiplayer().PeerConnected += OnPlayerConnected;
GetTree().GetMultiplayer().PeerDisconnected += OnPlayerDisconnected;
GetTree().GetMultiplayer().ServerDisconnected += OnServerClosed;
}
public override void _ExitTree()
{
GetTree().GetMultiplayer().MultiplayerPeer.Close();
GetTree().GetMultiplayer().MultiplayerPeer = null;
}
public void CreateServer()
{
ENetMultiplayerPeer peer = new();
peer.CreateServer(2142, 128);
GetTree().GetMultiplayer().MultiplayerPeer = peer;
LocalNetId = GetTree().GetMultiplayer().GetUniqueId();
_ = SpawnNetPlayer(LocalNetId);
}
public void CreateClient()
{
ENetMultiplayerPeer peer = new();
peer.CreateClient("127.0.0.1", 2142);
GetTree().GetMultiplayer().MultiplayerPeer = peer;
LocalNetId = GetTree().GetMultiplayer().GetUniqueId();
_ = SpawnNetPlayer(LocalNetId);
}
public void OnServerClosed()
{
GetTree().ChangeSceneToFile("res://scenes/main_menu.tscn");
}
public void OnPlayerConnected(long id)
{
if (Global.IsGameHost)
{
GameManager.Singleton.SendUniverseToClient(id);
}
_ = SpawnNetPlayer(id);
}
public void OnPlayerDisconnected(long id)
{
Player player = GetNode<Player>($"/root/Game/Space/Player-{id}");
GameManager.Singleton.DespawnPlayer(player);
}
private async Task SpawnNetPlayer(long id)
{
while (GameManager.Loading)
{
await Task.Delay(10);
}
bool isMainPlayer = LocalNetId == id;
Character character = new(GameManager.GameUniverse.Sectors[5, 5, 5], new(0, 0, 0));
Player player = GameManager.Singleton.SpawnPlayer(character, isMainPlayer);
player.Name = $"Player-{id}";
player.SetMultiplayerAuthority((int)id);
if (isMainPlayer && !Global.IsGameHost)
{
GameManager.Singleton.RpcId(1, nameof(GameManager.Singleton.RpcSendNearbySectors), character.CurrentSector.Coordinates, id);
}
}
}