427 lines
17 KiB
C#
427 lines
17 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using Mirror;
|
|
|
|
/// <summary>
|
|
/// CablageReseau.cs - v6.7 Multijoueur
|
|
///
|
|
/// v6.7 : sync longueur toron
|
|
/// - CmdSyncLongueurToron : met à jour la SyncVar longueur sur le serveur
|
|
/// après consommation ou restitution de câble. Propage automatiquement
|
|
/// à tous les clients via le hook de ToronNetworkSync.
|
|
///
|
|
/// v6.4 : sync câbles RJ45 + alimentation + interrupteur prise
|
|
///
|
|
/// SETUP : Ajouter sur le prefab PlayerCapsule.
|
|
/// </summary>
|
|
public class CablageReseau : NetworkBehaviour
|
|
{
|
|
// ════════════════════════════════════════════════════════════
|
|
// CÂBLES RJ45
|
|
// ════════════════════════════════════════════════════════════
|
|
|
|
[Command]
|
|
public void CmdCreerCableRJ45(uint equipSourceNetId, int portSourceIndex,
|
|
uint equipDestNetId, int portDestIndex,
|
|
Color couleur, float longueur)
|
|
{
|
|
Debug.Log($"[Serveur] Câble RJ45 créé : equip {equipSourceNetId} port {portSourceIndex} → equip {equipDestNetId} port {portDestIndex}");
|
|
|
|
// v7.1 : enregistrer le cable dans le gestionnaire pour le rejoin des clients
|
|
if (GestionnaireCablesReseau.Instance != null)
|
|
{
|
|
GestionnaireCablesReseau.Instance.EnregistrerCableRJ45(
|
|
equipSourceNetId, portSourceIndex, equipDestNetId, portDestIndex, couleur, longueur);
|
|
}
|
|
|
|
RpcCreerCableRJ45(equipSourceNetId, portSourceIndex, equipDestNetId, portDestIndex, couleur, longueur);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcCreerCableRJ45(uint equipSourceNetId, int portSourceIndex,
|
|
uint equipDestNetId, int portDestIndex,
|
|
Color couleur, float longueur)
|
|
{
|
|
if (isLocalPlayer) return;
|
|
|
|
PortRJ45 portSource = TrouverPortRJ45(equipSourceNetId, portSourceIndex);
|
|
PortRJ45 portDest = TrouverPortRJ45(equipDestNetId, portDestIndex);
|
|
|
|
if (portSource == null || portDest == null)
|
|
{
|
|
Debug.LogWarning($"[CablageReseau] Ports introuvables pour câble RJ45 distant");
|
|
return;
|
|
}
|
|
|
|
List<PointAccroche> chemin = ConstruireCheminAutoLocal(
|
|
portSource.GetPointConnexion(), portDest.GetPointConnexion());
|
|
|
|
string nom = "Cable_" + portSource.nomPort + "_vers_" + portDest.nomPort + "_distant";
|
|
GameObject cableObj = new GameObject(nom);
|
|
CableRJ45 cable = cableObj.AddComponent<CableRJ45>();
|
|
cable.Initialiser(portSource, portDest, chemin, couleur, longueur, null);
|
|
|
|
portSource.Connecter(portDest, cable);
|
|
portDest.Connecter(portSource, cable);
|
|
|
|
Debug.Log($"[CablageReseau] Câble RJ45 distant créé : {portSource.nomPort} → {portDest.nomPort}");
|
|
}
|
|
|
|
[Command]
|
|
public void CmdSupprimerCableRJ45(uint equipSourceNetId, int portSourceIndex,
|
|
uint equipDestNetId, int portDestIndex)
|
|
{
|
|
Debug.Log($"[Serveur] Câble RJ45 supprimé");
|
|
|
|
// v7.1 : desinscrire du gestionnaire
|
|
if (GestionnaireCablesReseau.Instance != null)
|
|
{
|
|
GestionnaireCablesReseau.Instance.OublierCableRJ45(
|
|
equipSourceNetId, portSourceIndex, equipDestNetId, portDestIndex);
|
|
}
|
|
|
|
RpcSupprimerCableRJ45(equipSourceNetId, portSourceIndex, equipDestNetId, portDestIndex);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcSupprimerCableRJ45(uint equipSourceNetId, int portSourceIndex,
|
|
uint equipDestNetId, int portDestIndex)
|
|
{
|
|
if (isLocalPlayer) return;
|
|
|
|
PortRJ45 portSource = TrouverPortRJ45(equipSourceNetId, portSourceIndex);
|
|
PortRJ45 portDest = TrouverPortRJ45(equipDestNetId, portDestIndex);
|
|
|
|
if (portSource != null && portSource.cable != null)
|
|
{
|
|
portSource.cable.SupprimerComplet();
|
|
}
|
|
else if (portDest != null && portDest.cable != null)
|
|
{
|
|
portDest.cable.SupprimerComplet();
|
|
}
|
|
|
|
Debug.Log("[CablageReseau] Câble RJ45 distant supprimé");
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════
|
|
// SYNC LONGUEUR TORON (v6.7)
|
|
// ════════════════════════════════════════════════════════════
|
|
|
|
/// <summary>
|
|
/// v6.7 : Met à jour la SyncVar longueur du toron côté serveur.
|
|
/// Appelé par CableManager après consommation ou restitution de câble.
|
|
/// La SyncVar de ToronNetworkSync propage automatiquement la nouvelle
|
|
/// longueur à TOUS les clients via le hook.
|
|
/// </summary>
|
|
[Command]
|
|
public void CmdSyncLongueurToron(uint toronNetId, float longueurRestante, float longueurTotale)
|
|
{
|
|
if (!NetworkServer.spawned.ContainsKey(toronNetId)) return;
|
|
var obj = NetworkServer.spawned[toronNetId];
|
|
if (obj == null) return;
|
|
|
|
ToronNetworkSync sync = obj.GetComponent<ToronNetworkSync>();
|
|
if (sync != null)
|
|
{
|
|
sync.ServerSetLongueur(longueurTotale, longueurRestante);
|
|
Debug.Log($"[Serveur] Longueur toron sync : {obj.name} → {longueurRestante:F1}m / {longueurTotale:F1}m");
|
|
}
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════
|
|
// CÂBLES ALIMENTATION
|
|
// ════════════════════════════════════════════════════════════
|
|
|
|
[Command]
|
|
public void CmdCreerCableAlim(uint pduNetId, int indexPrise,
|
|
uint equipNetId, int indexPortAlim,
|
|
Color couleur)
|
|
{
|
|
Debug.Log($"[Serveur] Câble alim créé : PDU {pduNetId} prise {indexPrise} → equip {equipNetId} port {indexPortAlim}");
|
|
|
|
PriseC13 prise = TrouverPriseC13(pduNetId, indexPrise);
|
|
PortAlimentation port = TrouverPortAlimentation(equipNetId, indexPortAlim);
|
|
if (prise != null && port != null && !prise.estConnectee)
|
|
{
|
|
GameObject cableObj = new GameObject("CableAlim_serveur");
|
|
CableAlimentation cable = cableObj.AddComponent<CableAlimentation>();
|
|
cable.couleurCable = couleur;
|
|
cable.Initialiser(prise, port);
|
|
prise.Connecter(cable, port);
|
|
port.Connecter(cable, prise);
|
|
}
|
|
|
|
// v7.1 : enregistrer le cable dans le gestionnaire pour le rejoin des clients
|
|
if (GestionnaireCablesReseau.Instance != null)
|
|
{
|
|
GestionnaireCablesReseau.Instance.EnregistrerCableAlim(
|
|
pduNetId, indexPrise, equipNetId, indexPortAlim, couleur);
|
|
}
|
|
|
|
RpcCreerCableAlim(pduNetId, indexPrise, equipNetId, indexPortAlim, couleur);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcCreerCableAlim(uint pduNetId, int indexPrise,
|
|
uint equipNetId, int indexPortAlim,
|
|
Color couleur)
|
|
{
|
|
if (isLocalPlayer) return;
|
|
|
|
PriseC13 prise = TrouverPriseC13(pduNetId, indexPrise);
|
|
PortAlimentation port = TrouverPortAlimentation(equipNetId, indexPortAlim);
|
|
|
|
if (prise == null || port == null)
|
|
{
|
|
Debug.LogWarning("[CablageReseau] Prise/Port introuvables pour câble alim distant");
|
|
return;
|
|
}
|
|
|
|
GameObject cableObj = new GameObject("CableAlim_distant");
|
|
CableAlimentation cable = cableObj.AddComponent<CableAlimentation>();
|
|
cable.couleurCable = couleur;
|
|
cable.Initialiser(prise, port);
|
|
|
|
prise.Connecter(cable, port);
|
|
port.Connecter(cable, prise);
|
|
|
|
Debug.Log($"[CablageReseau] Câble alim distant créé : PDU prise #{indexPrise} → {port.nomPort}");
|
|
}
|
|
|
|
[Command]
|
|
public void CmdSupprimerCableAlim(uint pduNetId, int indexPrise,
|
|
uint equipNetId, int indexPortAlim)
|
|
{
|
|
Debug.Log($"[Serveur] Câble alim supprimé");
|
|
|
|
// v7.1 : desinscrire du gestionnaire
|
|
if (GestionnaireCablesReseau.Instance != null)
|
|
{
|
|
GestionnaireCablesReseau.Instance.OublierCableAlim(
|
|
pduNetId, indexPrise, equipNetId, indexPortAlim);
|
|
}
|
|
|
|
PriseC13 prise = TrouverPriseC13(pduNetId, indexPrise);
|
|
if (prise != null && prise.cableBranche != null)
|
|
prise.cableBranche.Supprimer();
|
|
|
|
RpcSupprimerCableAlim(pduNetId, indexPrise, equipNetId, indexPortAlim);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcSupprimerCableAlim(uint pduNetId, int indexPrise,
|
|
uint equipNetId, int indexPortAlim)
|
|
{
|
|
if (isLocalPlayer) return;
|
|
|
|
PriseC13 prise = TrouverPriseC13(pduNetId, indexPrise);
|
|
|
|
if (prise != null && prise.cableBranche != null)
|
|
{
|
|
prise.cableBranche.Supprimer();
|
|
}
|
|
else
|
|
{
|
|
PortAlimentation port = TrouverPortAlimentation(equipNetId, indexPortAlim);
|
|
if (port != null && port.cableBranche != null)
|
|
port.cableBranche.Supprimer();
|
|
}
|
|
|
|
Debug.Log("[CablageReseau] Câble alim distant supprimé");
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════
|
|
// INTERRUPTEUR PRISE
|
|
// ════════════════════════════════════════════════════════════
|
|
|
|
[Command]
|
|
public void CmdBasculerPrise(uint pduNetId, int indexPrise)
|
|
{
|
|
PriseC13 prise = TrouverPriseC13(pduNetId, indexPrise);
|
|
if (prise != null)
|
|
prise.BasculerInterrupteur();
|
|
|
|
RpcBasculerPrise(pduNetId, indexPrise);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcBasculerPrise(uint pduNetId, int indexPrise)
|
|
{
|
|
if (isLocalPlayer) return;
|
|
|
|
PriseC13 prise = TrouverPriseC13(pduNetId, indexPrise);
|
|
if (prise != null)
|
|
prise.BasculerInterrupteur();
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════
|
|
// HELPERS — Recherche de composants par netId + index
|
|
// ════════════════════════════════════════════════════════════
|
|
|
|
private PortRJ45 TrouverPortRJ45(uint equipNetId, int portIndex)
|
|
{
|
|
if (!NetworkClient.spawned.ContainsKey(equipNetId)) return null;
|
|
|
|
GameObject equipGO = NetworkClient.spawned[equipNetId].gameObject;
|
|
PortRJ45[] ports = equipGO.GetComponentsInChildren<PortRJ45>();
|
|
|
|
foreach (var port in ports)
|
|
{
|
|
if (port.numeroPort == portIndex)
|
|
return port;
|
|
}
|
|
|
|
if (portIndex >= 0 && portIndex < ports.Length)
|
|
return ports[portIndex];
|
|
|
|
return null;
|
|
}
|
|
|
|
private PriseC13 TrouverPriseC13(uint pduNetId, int indexPrise)
|
|
{
|
|
if (!NetworkClient.spawned.ContainsKey(pduNetId)) return null;
|
|
|
|
GameObject pduGO = NetworkClient.spawned[pduNetId].gameObject;
|
|
PDU pdu = pduGO.GetComponent<PDU>();
|
|
|
|
if (pdu != null && indexPrise >= 0 && indexPrise < pdu.prises.Count)
|
|
return pdu.prises[indexPrise];
|
|
|
|
PriseC13[] prises = pduGO.GetComponentsInChildren<PriseC13>();
|
|
foreach (var p in prises)
|
|
if (p.indexPrise == indexPrise) return p;
|
|
|
|
return null;
|
|
}
|
|
|
|
private PortAlimentation TrouverPortAlimentation(uint equipNetId, int indexPort)
|
|
{
|
|
if (!NetworkClient.spawned.ContainsKey(equipNetId)) return null;
|
|
|
|
GameObject equipGO = NetworkClient.spawned[equipNetId].gameObject;
|
|
PortAlimentation[] ports = equipGO.GetComponentsInChildren<PortAlimentation>();
|
|
|
|
if (indexPort >= 0 && indexPort < ports.Length)
|
|
return ports[indexPort];
|
|
|
|
return null;
|
|
}
|
|
|
|
private List<PointAccroche> ConstruireCheminAutoLocal(Vector3 posSource, Vector3 posDest)
|
|
{
|
|
List<PointAccroche> chemin = new List<PointAccroche>();
|
|
PointAccroche[] tousPoints = FindObjectsOfType<PointAccroche>();
|
|
|
|
if (tousPoints.Length == 0) return chemin;
|
|
|
|
PointAccroche ptDepart = null;
|
|
float bestDistDepart = 3f;
|
|
foreach (var p in tousPoints)
|
|
{
|
|
float d = Vector3.Distance(posSource, p.GetPosition());
|
|
if (d < bestDistDepart) { bestDistDepart = d; ptDepart = p; }
|
|
}
|
|
|
|
PointAccroche ptArrivee = null;
|
|
float bestDistArrivee = 3f;
|
|
foreach (var p in tousPoints)
|
|
{
|
|
float d = Vector3.Distance(posDest, p.GetPosition());
|
|
if (d < bestDistArrivee) { bestDistArrivee = d; ptArrivee = p; }
|
|
}
|
|
|
|
if (ptDepart == null || ptArrivee == null) return chemin;
|
|
if (ptDepart == ptArrivee) { chemin.Add(ptDepart); return chemin; }
|
|
|
|
float distanceVoisinage = 1.5f;
|
|
Dictionary<PointAccroche, float> gScore = new Dictionary<PointAccroche, float>();
|
|
Dictionary<PointAccroche, PointAccroche> cameFrom = new Dictionary<PointAccroche, PointAccroche>();
|
|
HashSet<PointAccroche> closedSet = new HashSet<PointAccroche>();
|
|
List<PointAccroche> openSet = new List<PointAccroche>();
|
|
|
|
gScore[ptDepart] = 0;
|
|
openSet.Add(ptDepart);
|
|
|
|
int maxIter = 500;
|
|
int iter = 0;
|
|
|
|
while (openSet.Count > 0 && iter < maxIter)
|
|
{
|
|
iter++;
|
|
PointAccroche current = null;
|
|
float bestF = float.MaxValue;
|
|
foreach (var n in openSet)
|
|
{
|
|
float g = gScore.ContainsKey(n) ? gScore[n] : float.MaxValue;
|
|
float f = g + Vector3.Distance(n.GetPosition(), ptArrivee.GetPosition());
|
|
if (f < bestF) { bestF = f; current = n; }
|
|
}
|
|
if (current == null) break;
|
|
if (current == ptArrivee)
|
|
{
|
|
List<PointAccroche> result = new List<PointAccroche> { current };
|
|
while (cameFrom.ContainsKey(current))
|
|
{
|
|
current = cameFrom[current];
|
|
result.Insert(0, current);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
openSet.Remove(current);
|
|
closedSet.Add(current);
|
|
|
|
foreach (var autre in tousPoints)
|
|
{
|
|
if (autre == current || closedSet.Contains(autre)) continue;
|
|
if (Vector3.Distance(current.GetPosition(), autre.GetPosition()) > distanceVoisinage) continue;
|
|
|
|
float tentG = gScore[current] + Vector3.Distance(current.GetPosition(), autre.GetPosition());
|
|
if (!openSet.Contains(autre)) openSet.Add(autre);
|
|
else if (gScore.ContainsKey(autre) && tentG >= gScore[autre]) continue;
|
|
|
|
cameFrom[autre] = current;
|
|
gScore[autre] = tentG;
|
|
}
|
|
}
|
|
|
|
chemin.Add(ptDepart);
|
|
chemin.Add(ptArrivee);
|
|
return chemin;
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════
|
|
// HELPERS PUBLICS
|
|
// ════════════════════════════════════════════════════════════
|
|
|
|
public static uint GetEquipNetId(PortRJ45 port)
|
|
{
|
|
if (port == null) return 0;
|
|
NetworkIdentity netId = port.GetComponentInParent<NetworkIdentity>();
|
|
return netId != null ? netId.netId : 0;
|
|
}
|
|
|
|
public static uint GetPDUNetId(PriseC13 prise)
|
|
{
|
|
if (prise == null || prise.pduParent == null) return 0;
|
|
NetworkIdentity netId = prise.pduParent.GetComponent<NetworkIdentity>();
|
|
return netId != null ? netId.netId : 0;
|
|
}
|
|
|
|
public static uint GetEquipNetIdFromPortAlim(PortAlimentation port)
|
|
{
|
|
if (port == null || port.equipement == null) return 0;
|
|
NetworkIdentity netId = port.equipement.GetComponent<NetworkIdentity>();
|
|
return netId != null ? netId.netId : 0;
|
|
}
|
|
|
|
public static int GetPortAlimIndex(PortAlimentation port)
|
|
{
|
|
if (port == null || port.equipement == null) return 0;
|
|
PortAlimentation[] ports = port.equipement.GetComponentsInChildren<PortAlimentation>();
|
|
for (int i = 0; i < ports.Length; i++)
|
|
if (ports[i] == port) return i;
|
|
return 0;
|
|
}
|
|
} |