Implement RPC Node

This commit is contained in:
Aslan 2026-02-02 12:17:04 -05:00
parent f7ee533d5a
commit 605e43273e
13 changed files with 524 additions and 206 deletions

View file

@ -1,5 +1,171 @@
using System;
using System.Collections.Generic;
using Godot;
public partial class RPCNode : Node
{
public static RPCNode Instance { get; private set; }
private readonly HashSet<Guid> requestedFullGameObjects = [];
public override void _EnterTree()
{
Instance = this;
}
public override void _ExitTree()
{
Instance = null;
}
[Rpc(MultiplayerApi.RpcMode.Authority)]
public void RpcSyncGameObject(Godot.Collections.Dictionary gameObjectData)
{
GD.Print("READING: " + gameObjectData);
if (!GameManager.Instance.playerReady)
{
return;
}
if (!gameObjectData.TryGetValue("uuid", out var uuidData))
return;
Guid uuid = Guid.Parse((string)uuidData);
List<Sector> sectors = GameManager.Instance.GetCurrentSector().GetNeighbouringSectors();
foreach (Sector sector in sectors)
{
GameObject gameObject = sector.GetObjectById(uuid);
if (gameObject != null)
{
gameObject.NetworkRead(gameObjectData);
return;
}
}
if (!TrySyncFullGameObject(gameObjectData))
{
if (requestedFullGameObjects.Contains(uuid))
{
return;
}
requestedFullGameObjects.Add(uuid);
RpcId(1, nameof(RequestFullGameObject), NetworkManager.Instance.LocalNetId, (string)uuidData);
}
}
public bool TrySyncFullGameObject(Godot.Collections.Dictionary gameObjectData)
{
if (!gameObjectData.TryGetValue("type", out var typeData))
return false;
if (!gameObjectData.TryGetValue("sectorCoordinates", out var sectorCoordinatesData))
return false;
if (!gameObjectData.TryGetValue("localCoordinates", out var localCoordinatesData))
return false;
if (!gameObjectData.TryGetValue("uuid", out var uuidData))
return false;
string type = (string)typeData;
Vector3I sectorCoordinates = (Vector3I)sectorCoordinatesData;
Vector3 localCoordinates = (Vector3)localCoordinatesData;
Guid uuid = Guid.Parse((string)uuidData);
Sector sector = GameManager.GameUniverse.GetSector(sectorCoordinates);
if (sector == null)
return false;
GameObject gameObject;
switch (type)
{
case "Star":
gameObject = new Star(sector, localCoordinates);
break;
default:
return false;
}
gameObject.UUID = uuid;
gameObject.NetworkRead(gameObjectData);
requestedFullGameObjects.Remove(uuid);
sector.AssignObject(gameObject);
return true;
}
[Rpc(MultiplayerApi.RpcMode.AnyPeer)]
public void RequestFullGameObject(long id, string uuidString)
{
if (!Global.IsGameHost)
{
return;
}
Guid uuid = Guid.Parse(uuidString);
List<Sector> sectors = GameManager.Instance.GetPlayer(id).PlayerData.CurrentSector.GetNeighbouringSectors();
foreach (Sector sector in sectors)
{
GameObject gameObject = sector.GetObjectById(uuid);
if (gameObject != null)
{
gameObject.NetworkWrite(id, true);
return;
}
}
}
[Rpc(MultiplayerApi.RpcMode.AnyPeer)]
public void RpcSyncPlayer(long id, Vector3 position, Vector3I sectorCoordinates)
{
if (!GameManager.Instance.playerReady)
{
return;
}
GameManager.Instance.Players.TryGetValue(id, out Player player);
if (player == null || !player.IsInsideTree())
{
return;
}
Character playerData = player.PlayerData;
Sector sector = GameManager.GameUniverse.GetSector(sectorCoordinates);
if (sector == null)
{
return;
}
Vector3Dec newGlobal = playerData.CalculateGlobalCoordinates(sector.GlobalCenterCoordinates, position);
playerData.SetCoordinatesFromGlobal(newGlobal);
if (playerData.CurrentSector.Coordinates != sectorCoordinates)
{
sector.AssignObject(playerData);
}
player.GlobalPosition = position + playerData.SectorOffset;
}
[Rpc(MultiplayerApi.RpcMode.AnyPeer)]
public void RpcSyncPlayerPhysics(long id, Vector3 _movementVelocity, Vector3 _gravityVelocity, Vector3 rotation)
{
if (!GameManager.Instance.playerReady)
{
return;
}
GameManager.Instance.Players.TryGetValue(id, out Player player);
if (player == null || !player.IsInsideTree())
{
return;
}
player.MovementVelocity = _movementVelocity;
player.GravityVelocity = _gravityVelocity;
player.GlobalRotation = rotation;
}
}