276 lines
7.1 KiB
C#
276 lines
7.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using BlockSpace.Worlds;
|
|
using Photon.Pun;
|
|
using Photon.Realtime;
|
|
using UnityEngine;
|
|
|
|
[DisallowMultipleComponent]
|
|
public sealed class NodeGraphPhotonSync : MonoBehaviourPunCallbacks
|
|
{
|
|
[Serializable]
|
|
private sealed class NodeRecordEnvelope
|
|
{
|
|
public WorldGroupsCodec.WorldNodeRecord record;
|
|
}
|
|
|
|
[SerializeField]
|
|
private NodeGraphManager nodeGraphManager;
|
|
|
|
[SerializeField]
|
|
private float lateJoinReplayDelay = 0.5f;
|
|
|
|
private PhotonView cachedPhotonView;
|
|
|
|
private void Reset()
|
|
{
|
|
nodeGraphManager = GetComponent<NodeGraphManager>();
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
cachedPhotonView = GetComponent<PhotonView>();
|
|
if (nodeGraphManager == null)
|
|
{
|
|
nodeGraphManager = GetComponent<NodeGraphManager>();
|
|
if (nodeGraphManager == null)
|
|
{
|
|
nodeGraphManager = UnityEngine.Object.FindAnyObjectByType<NodeGraphManager>();
|
|
}
|
|
}
|
|
nodeGraphManager?.RegisterNetworkSync(this);
|
|
}
|
|
|
|
public override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
nodeGraphManager?.RegisterNetworkSync(this);
|
|
}
|
|
|
|
public override void OnJoinedRoom()
|
|
{
|
|
base.OnJoinedRoom();
|
|
if (!(nodeGraphManager == null) && !PhotonNetwork.IsMasterClient)
|
|
{
|
|
nodeGraphManager.ClearAllNodesForNetworkSync();
|
|
}
|
|
}
|
|
|
|
public override void OnPlayerEnteredRoom(Player newPlayer)
|
|
{
|
|
base.OnPlayerEnteredRoom(newPlayer);
|
|
if (newPlayer != null)
|
|
{
|
|
nodeGraphManager?.NotifyPlayerJoined(newPlayer.ActorNumber);
|
|
}
|
|
if (PhotonNetwork.IsMasterClient && newPlayer != null && !(nodeGraphManager == null))
|
|
{
|
|
StartCoroutine(SendExistingGraphToPlayerAfterDelay(newPlayer));
|
|
}
|
|
}
|
|
|
|
public override void OnPlayerLeftRoom(Player otherPlayer)
|
|
{
|
|
base.OnPlayerLeftRoom(otherPlayer);
|
|
if (otherPlayer != null)
|
|
{
|
|
nodeGraphManager?.NotifyPlayerLeft(otherPlayer.ActorNumber);
|
|
}
|
|
}
|
|
|
|
public override void OnLeftRoom()
|
|
{
|
|
int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : 0);
|
|
if (num > 0)
|
|
{
|
|
nodeGraphManager?.NotifyPlayerLeft(num);
|
|
}
|
|
base.OnLeftRoom();
|
|
}
|
|
|
|
public void BroadcastUpsertNode(Node node, Player targetPlayer = null)
|
|
{
|
|
if (!(node == null) && CanSendRpc())
|
|
{
|
|
WorldGroupsCodec.WorldNodeRecord record = nodeGraphManager.BuildNetworkNodeRecord(node);
|
|
BroadcastUpsertRecord(record, targetPlayer);
|
|
}
|
|
}
|
|
|
|
public void BroadcastDeleteNode(int nodeId)
|
|
{
|
|
if (CanSendRpc() && nodeId > 0)
|
|
{
|
|
cachedPhotonView.RPC("RPC_DeleteNode", RpcTarget.Others, nodeId);
|
|
}
|
|
}
|
|
|
|
public void BroadcastConnectWire(WorldGroupsCodec.WorldWireRecord record, Player targetPlayer = null)
|
|
{
|
|
int groupId;
|
|
bool flag = WorldGroupsCodec.TryGetGroupRuntimeWireSourceId(record, out groupId) || WorldGroupsCodec.TryGetGroupSavedWireIndex(record, out groupId);
|
|
if (CanSendRpc() && record.inputNodeId > 0 && !string.IsNullOrEmpty(record.inputPortName) && (flag || record.outputNodeId > 0))
|
|
{
|
|
if (targetPlayer != null)
|
|
{
|
|
cachedPhotonView.RPC("RPC_ConnectWire", targetPlayer, record.outputNodeId, record.outputPortName, record.inputNodeId, record.inputPortName);
|
|
}
|
|
else
|
|
{
|
|
cachedPhotonView.RPC("RPC_ConnectWire", RpcTarget.Others, record.outputNodeId, record.outputPortName, record.inputNodeId, record.inputPortName);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void BroadcastDisconnectInput(int inputNodeId, string inputPortName)
|
|
{
|
|
if (CanSendRpc() && inputNodeId > 0 && !string.IsNullOrEmpty(inputPortName))
|
|
{
|
|
cachedPhotonView.RPC("RPC_DisconnectInput", RpcTarget.Others, inputNodeId, inputPortName);
|
|
}
|
|
}
|
|
|
|
public void BroadcastDisconnectOutput(int outputNodeId, string outputPortName)
|
|
{
|
|
if (CanSendRpc() && outputNodeId > 0 && !string.IsNullOrEmpty(outputPortName))
|
|
{
|
|
cachedPhotonView.RPC("RPC_DisconnectOutput", RpcTarget.Others, outputNodeId, outputPortName);
|
|
}
|
|
}
|
|
|
|
public void BroadcastTriggerRun(int outputNodeId, string outputPortName)
|
|
{
|
|
if (CanSendRpc() && outputNodeId > 0 && !string.IsNullOrEmpty(outputPortName))
|
|
{
|
|
cachedPhotonView.RPC("RPC_TriggerRun", RpcTarget.Others, outputNodeId, outputPortName);
|
|
}
|
|
}
|
|
|
|
public void BroadcastEventRun(int nodeId, string outputPortName)
|
|
{
|
|
if (CanSendRpc() && nodeId > 0 && !string.IsNullOrEmpty(outputPortName))
|
|
{
|
|
cachedPhotonView.RPC("RPC_EventRun", RpcTarget.Others, nodeId, outputPortName);
|
|
}
|
|
}
|
|
|
|
[PunRPC]
|
|
private void RPC_UpsertNode(string recordJson)
|
|
{
|
|
if (!(nodeGraphManager == null) && !string.IsNullOrEmpty(recordJson))
|
|
{
|
|
NodeRecordEnvelope nodeRecordEnvelope = JsonUtility.FromJson<NodeRecordEnvelope>(recordJson);
|
|
if (nodeRecordEnvelope != null)
|
|
{
|
|
nodeGraphManager.ApplyNetworkNodeRecord(nodeRecordEnvelope.record);
|
|
}
|
|
}
|
|
}
|
|
|
|
[PunRPC]
|
|
private void RPC_DeleteNode(int nodeId)
|
|
{
|
|
nodeGraphManager?.ApplyNetworkDelete(nodeId);
|
|
}
|
|
|
|
[PunRPC]
|
|
private void RPC_ConnectWire(int outputNodeId, string outputPortName, int inputNodeId, string inputPortName)
|
|
{
|
|
if (!(nodeGraphManager == null))
|
|
{
|
|
nodeGraphManager.ApplyNetworkWireRecord(new WorldGroupsCodec.WorldWireRecord
|
|
{
|
|
outputNodeId = outputNodeId,
|
|
outputPortName = outputPortName,
|
|
inputNodeId = inputNodeId,
|
|
inputPortName = inputPortName
|
|
});
|
|
}
|
|
}
|
|
|
|
[PunRPC]
|
|
private void RPC_DisconnectInput(int inputNodeId, string inputPortName)
|
|
{
|
|
nodeGraphManager?.ApplyNetworkDisconnectInput(inputNodeId, inputPortName);
|
|
}
|
|
|
|
[PunRPC]
|
|
private void RPC_DisconnectOutput(int outputNodeId, string outputPortName)
|
|
{
|
|
nodeGraphManager?.ApplyNetworkDisconnectOutput(outputNodeId, outputPortName);
|
|
}
|
|
|
|
[PunRPC]
|
|
private void RPC_TriggerRun(int outputNodeId, string outputPortName)
|
|
{
|
|
nodeGraphManager?.ApplyNetworkTriggerRun(outputNodeId, outputPortName);
|
|
}
|
|
|
|
[PunRPC]
|
|
private void RPC_EventRun(int nodeId, string outputPortName)
|
|
{
|
|
nodeGraphManager?.ApplyNetworkTriggerRun(nodeId, outputPortName);
|
|
}
|
|
|
|
private IEnumerator SendExistingGraphToPlayerAfterDelay(Player newPlayer)
|
|
{
|
|
float num = Mathf.Max(0f, lateJoinReplayDelay);
|
|
if (num > 0f)
|
|
{
|
|
yield return new WaitForSecondsRealtime(num);
|
|
}
|
|
else
|
|
{
|
|
yield return null;
|
|
}
|
|
if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && newPlayer != null && !(nodeGraphManager == null))
|
|
{
|
|
List<Node> allNodesSnapshot = nodeGraphManager.GetAllNodesSnapshot();
|
|
for (int i = 0; i < allNodesSnapshot.Count; i++)
|
|
{
|
|
BroadcastUpsertNode(allNodesSnapshot[i], newPlayer);
|
|
}
|
|
yield return null;
|
|
List<WorldGroupsCodec.WorldWireRecord> list = nodeGraphManager.BuildWorldWireRecords();
|
|
for (int j = 0; j < list.Count; j++)
|
|
{
|
|
BroadcastConnectWire(list[j], newPlayer);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void BroadcastUpsertRecord(WorldGroupsCodec.WorldNodeRecord record, Player targetPlayer)
|
|
{
|
|
if (CanSendRpc())
|
|
{
|
|
string text = JsonUtility.ToJson(new NodeRecordEnvelope
|
|
{
|
|
record = record
|
|
});
|
|
if (targetPlayer != null)
|
|
{
|
|
cachedPhotonView.RPC("RPC_UpsertNode", targetPlayer, text);
|
|
}
|
|
else
|
|
{
|
|
cachedPhotonView.RPC("RPC_UpsertNode", RpcTarget.Others, text);
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool CanSendRpc()
|
|
{
|
|
if (!PhotonNetwork.InRoom || cachedPhotonView == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (cachedPhotonView.ViewID == 0)
|
|
{
|
|
Debug.LogWarning("NodeGraphPhotonSync requires a valid PhotonView ViewID to send RPCs.", this);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|