diff --git a/Dedicated_Server_Linux/DatacenterSim.x86_64 b/Dedicated_Server_Linux/DatacenterSim.x86_64 new file mode 100755 index 0000000..9021e73 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim.x86_64 differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/Plugins/lib_burst_generated.so b/Dedicated_Server_Linux/DatacenterSim_Data/Plugins/lib_burst_generated.so new file mode 100644 index 0000000..9c188d5 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/Plugins/lib_burst_generated.so differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/Resources/UnityPlayer.png b/Dedicated_Server_Linux/DatacenterSim_Data/Resources/UnityPlayer.png new file mode 100644 index 0000000..43897cf Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/Resources/UnityPlayer.png differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/Resources/unity default resources b/Dedicated_Server_Linux/DatacenterSim_Data/Resources/unity default resources new file mode 100644 index 0000000..7cf4261 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/Resources/unity default resources differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/Resources/unity_builtin_extra b/Dedicated_Server_Linux/DatacenterSim_Data/Resources/unity_builtin_extra new file mode 100644 index 0000000..5b39231 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/Resources/unity_builtin_extra differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/RuntimeInitializeOnLoads.json b/Dedicated_Server_Linux/DatacenterSim_Data/RuntimeInitializeOnLoads.json new file mode 100644 index 0000000..e648b56 --- /dev/null +++ b/Dedicated_Server_Linux/DatacenterSim_Data/RuntimeInitializeOnLoads.json @@ -0,0 +1 @@ +{"root":[{"assemblyName":"Assembly-CSharp","nameSpace":"Mirror","className":"GeneratedNetworkCode","methodName":"InitReadWriters","loadTypes":1,"isUnityClass":false},{"assemblyName":"Cinemachine","nameSpace":"Cinemachine","className":"CinemachineStoryboard","methodName":"InitializeModule","loadTypes":0,"isUnityClass":false},{"assemblyName":"Cinemachine","nameSpace":"Cinemachine","className":"CinemachineCore","methodName":"InitializeModule","loadTypes":0,"isUnityClass":false},{"assemblyName":"Cinemachine","nameSpace":"Cinemachine","className":"UpdateTracker","methodName":"InitializeModule","loadTypes":0,"isUnityClass":false},{"assemblyName":"Cinemachine","nameSpace":"Cinemachine","className":"CinemachineImpulseManager","methodName":"InitializeModule","loadTypes":0,"isUnityClass":false},{"assemblyName":"Cinemachine","nameSpace":"Cinemachine.PostFX","className":"CinemachineVolumeSettings","methodName":"InitializeModule","loadTypes":0,"isUnityClass":false},{"assemblyName":"glTFast","nameSpace":"","className":"$BurstDirectCallInitializer","methodName":"Initialize","loadTypes":2,"isUnityClass":false},{"assemblyName":"Mirror.Authenticators","nameSpace":"Mirror.Authenticators","className":"UniqueNameAuthenticator","methodName":"ResetStatics","loadTypes":0,"isUnityClass":false},{"assemblyName":"Mirror.Authenticators","nameSpace":"Mirror","className":"GeneratedNetworkCode","methodName":"InitReadWriters","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror.Components","nameSpace":"Mirror","className":"GeneratedNetworkCode","methodName":"InitReadWriters","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkClient","methodName":"Shutdown","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkDiagnostics","methodName":"ResetStatics","loadTypes":0,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkIdentity","methodName":"ResetStatics","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkLoop","methodName":"ResetStatics","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkLoop","methodName":"RuntimeInitializeOnLoad","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkManager","methodName":"ResetStatics","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkServer","methodName":"Shutdown","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"NetworkTime","methodName":"ResetStatics","loadTypes":0,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"ThreadLog","methodName":"Initialize","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror","nameSpace":"Mirror","className":"GeneratedNetworkCode","methodName":"InitReadWriters","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror.Examples","nameSpace":"Mirror.Examples.MultipleMatch","className":"CanvasController","methodName":"ResetStatics","loadTypes":1,"isUnityClass":false},{"assemblyName":"Mirror.Examples","nameSpace":"Mirror","className":"GeneratedNetworkCode","methodName":"InitReadWriters","loadTypes":1,"isUnityClass":false},{"assemblyName":"Unity.Burst","nameSpace":"","className":"$BurstDirectCallInitializer","methodName":"Initialize","loadTypes":2,"isUnityClass":true},{"assemblyName":"Unity.Collections","nameSpace":"","className":"$BurstDirectCallInitializer","methodName":"Initialize","loadTypes":2,"isUnityClass":true},{"assemblyName":"Unity.InputSystem","nameSpace":"UnityEngine.InputSystem","className":"InputSystem","methodName":"RunInitializeInPlayer","loadTypes":4,"isUnityClass":true},{"assemblyName":"Unity.InputSystem","nameSpace":"UnityEngine.InputSystem","className":"InputSystem","methodName":"RunInitialUpdate","loadTypes":1,"isUnityClass":true},{"assemblyName":"Unity.InputSystem","nameSpace":"UnityEngine.InputSystem.UI","className":"InputSystemUIInputModule","methodName":"ResetDefaultActions","loadTypes":4,"isUnityClass":true},{"assemblyName":"Unity.RenderPipelines.Core.Runtime","nameSpace":"UnityEngine.Experimental.Rendering","className":"XRSystem","methodName":"XRSystemInit","loadTypes":3,"isUnityClass":true},{"assemblyName":"Unity.RenderPipelines.Core.Runtime","nameSpace":"UnityEngine.Rendering","className":"DebugUpdater","methodName":"RuntimeInit","loadTypes":0,"isUnityClass":true},{"assemblyName":"Unity.VisualScripting.Core","nameSpace":"Unity.VisualScripting","className":"RuntimeVSUsageUtility","methodName":"RuntimeInitializeOnLoadBeforeSceneLoad","loadTypes":1,"isUnityClass":true}]} diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/ScriptingAssemblies.json b/Dedicated_Server_Linux/DatacenterSim_Data/ScriptingAssemblies.json new file mode 100644 index 0000000..c32c357 --- /dev/null +++ b/Dedicated_Server_Linux/DatacenterSim_Data/ScriptingAssemblies.json @@ -0,0 +1 @@ +{"names":["UnityEngine.dll","UnityEngine.AIModule.dll","UnityEngine.AccessibilityModule.dll","UnityEngine.AndroidJNIModule.dll","UnityEngine.AnimationModule.dll","UnityEngine.AssetBundleModule.dll","UnityEngine.AudioModule.dll","UnityEngine.ClothModule.dll","UnityEngine.ClusterInputModule.dll","UnityEngine.ClusterRendererModule.dll","UnityEngine.ContentLoadModule.dll","UnityEngine.CoreModule.dll","UnityEngine.CrashReportingModule.dll","UnityEngine.DSPGraphModule.dll","UnityEngine.DirectorModule.dll","UnityEngine.GIModule.dll","UnityEngine.GameCenterModule.dll","UnityEngine.GridModule.dll","UnityEngine.HotReloadModule.dll","UnityEngine.IMGUIModule.dll","UnityEngine.ImageConversionModule.dll","UnityEngine.InputModule.dll","UnityEngine.InputLegacyModule.dll","UnityEngine.JSONSerializeModule.dll","UnityEngine.LocalizationModule.dll","UnityEngine.ParticleSystemModule.dll","UnityEngine.PerformanceReportingModule.dll","UnityEngine.PhysicsModule.dll","UnityEngine.Physics2DModule.dll","UnityEngine.ProfilerModule.dll","UnityEngine.PropertiesModule.dll","UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll","UnityEngine.ScreenCaptureModule.dll","UnityEngine.SharedInternalsModule.dll","UnityEngine.SpriteMaskModule.dll","UnityEngine.SpriteShapeModule.dll","UnityEngine.StreamingModule.dll","UnityEngine.SubstanceModule.dll","UnityEngine.SubsystemsModule.dll","UnityEngine.TLSModule.dll","UnityEngine.TerrainModule.dll","UnityEngine.TerrainPhysicsModule.dll","UnityEngine.TextCoreFontEngineModule.dll","UnityEngine.TextCoreTextEngineModule.dll","UnityEngine.TextRenderingModule.dll","UnityEngine.TilemapModule.dll","UnityEngine.UIModule.dll","UnityEngine.UIElementsModule.dll","UnityEngine.UmbraModule.dll","UnityEngine.UnityAnalyticsModule.dll","UnityEngine.UnityAnalyticsCommonModule.dll","UnityEngine.UnityConnectModule.dll","UnityEngine.UnityCurlModule.dll","UnityEngine.UnityTestProtocolModule.dll","UnityEngine.UnityWebRequestModule.dll","UnityEngine.UnityWebRequestAssetBundleModule.dll","UnityEngine.UnityWebRequestAudioModule.dll","UnityEngine.UnityWebRequestTextureModule.dll","UnityEngine.UnityWebRequestWWWModule.dll","UnityEngine.VFXModule.dll","UnityEngine.VRModule.dll","UnityEngine.VehiclesModule.dll","UnityEngine.VideoModule.dll","UnityEngine.VirtualTexturingModule.dll","UnityEngine.WindModule.dll","UnityEngine.XRModule.dll","Assembly-CSharp.dll","glTFast.dots.dll","Unity.RenderPipelines.Core.Runtime.dll","Unity.ProBuilder.Stl.dll","Unity.ProBuilder.Csg.dll","Unity.RenderPipelines.Universal.Config.Runtime.dll","Unity.VisualScripting.Flow.dll","Telepathy.dll","glTFast.Newtonsoft.dll","Unity.RenderPipelines.Core.ShaderLibrary.dll","Mirror.Examples.dll","Unity.Collections.dll","Unity.ProBuilder.Poly2Tri.dll","glTFast.Documentation.Examples.dll","Unity.TextMeshPro.dll","kcp2k.dll","Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll","Unity.RenderPipelines.Universal.Runtime.dll","Unity.Burst.dll","Unity.ProBuilder.dll","Mirror.dll","Unity.VisualScripting.Core.dll","Mirror.Transports.dll","UnityEngine.UI.dll","Mirror.Components.dll","glTFast.Export.dll","Unity.RenderPipelines.Universal.2D.Internal.dll","Unity.RenderPipeline.Universal.ShaderLibrary.dll","Unity.Timeline.dll","Unity.InputSystem.dll","SimpleWebTransport.dll","Unity.InputSystem.ForUI.dll","Mirror.Authenticators.dll","glTFast.dll","Unity.ProBuilder.KdTree.dll","Unity.Mathematics.dll","Unity.RenderPipelines.Universal.Shaders.dll","Unity.VisualScripting.State.dll","Cinemachine.dll","Unity.Collections.LowLevel.ILSupport.dll","Mirror.BouncyCastle.Cryptography.dll","Unity.VisualScripting.Antlr3.Runtime.dll","Unity.Burst.Unsafe.dll","Newtonsoft.Json.dll"],"types":[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]} \ No newline at end of file diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/app.info b/Dedicated_Server_Linux/DatacenterSim_Data/app.info new file mode 100644 index 0000000..7a89685 --- /dev/null +++ b/Dedicated_Server_Linux/DatacenterSim_Data/app.info @@ -0,0 +1,2 @@ +MAURO Stéphane +DatacenterSim_Alpha \ No newline at end of file diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/boot.config b/Dedicated_Server_Linux/DatacenterSim_Data/boot.config new file mode 100644 index 0000000..131647a --- /dev/null +++ b/Dedicated_Server_Linux/DatacenterSim_Data/boot.config @@ -0,0 +1,6 @@ +gfx-enable-gfx-jobs=1 +gfx-enable-native-gfx-jobs=1 +wait-for-native-debugger=0 +hdr-display-enabled=0 +gc-max-time-slice=3 +build-guid=dda67375c968463c8faf660d4f2e44c6 diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/globalgamemanagers b/Dedicated_Server_Linux/DatacenterSim_Data/globalgamemanagers new file mode 100644 index 0000000..781e066 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/globalgamemanagers differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/globalgamemanagers.assets b/Dedicated_Server_Linux/DatacenterSim_Data/globalgamemanagers.assets new file mode 100644 index 0000000..78c0e7b Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/globalgamemanagers.assets differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/il2cpp_data/Metadata/global-metadata.dat b/Dedicated_Server_Linux/DatacenterSim_Data/il2cpp_data/Metadata/global-metadata.dat new file mode 100644 index 0000000..023191b Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/il2cpp_data/Metadata/global-metadata.dat differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/il2cpp_data/Resources/mscorlib.dll-resources.dat b/Dedicated_Server_Linux/DatacenterSim_Data/il2cpp_data/Resources/mscorlib.dll-resources.dat new file mode 100644 index 0000000..6d144fc Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/il2cpp_data/Resources/mscorlib.dll-resources.dat differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/level0 b/Dedicated_Server_Linux/DatacenterSim_Data/level0 new file mode 100644 index 0000000..0307471 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/level0 differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/resources.assets b/Dedicated_Server_Linux/DatacenterSim_Data/resources.assets new file mode 100644 index 0000000..fa2e8b7 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/resources.assets differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/sharedassets0.assets b/Dedicated_Server_Linux/DatacenterSim_Data/sharedassets0.assets new file mode 100644 index 0000000..1b4f488 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/sharedassets0.assets differ diff --git a/Dedicated_Server_Linux/DatacenterSim_Data/sharedassets0.resource b/Dedicated_Server_Linux/DatacenterSim_Data/sharedassets0.resource new file mode 100644 index 0000000..465cf10 Binary files /dev/null and b/Dedicated_Server_Linux/DatacenterSim_Data/sharedassets0.resource differ diff --git a/Dedicated_Server_Linux/GameAssembly.so b/Dedicated_Server_Linux/GameAssembly.so new file mode 100644 index 0000000..05bbfcc Binary files /dev/null and b/Dedicated_Server_Linux/GameAssembly.so differ diff --git a/Dedicated_Server_Linux/UnityPlayer.so b/Dedicated_Server_Linux/UnityPlayer.so new file mode 100644 index 0000000..50b14d6 Binary files /dev/null and b/Dedicated_Server_Linux/UnityPlayer.so differ diff --git a/Patchs/dcsim_patches_v4.zip b/Patchs/dcsim_patches_v4.zip deleted file mode 100644 index 021f288..0000000 Binary files a/Patchs/dcsim_patches_v4.zip and /dev/null differ diff --git a/Patchs/v4/README_PATCHES_V4.md b/Patchs/v4/README_PATCHES_V4.md new file mode 100644 index 0000000..8d67ba2 --- /dev/null +++ b/Patchs/v4/README_PATCHES_V4.md @@ -0,0 +1,100 @@ +# Patches v4 - VRAI fix du BoutonPower sur dedicated server + +## ⚠️ Remplace les patches v3 qui étaient partiellement corrects + +La v3 (patch de CableAlimentation + CableRJ45) n'était PAS la cause racine. +Le patch de v3 reste valide (évite des WARNINGS visuels), mais le vrai bug +était ailleurs. + +## 🎯 La vraie cause racine + +`CablageReseau.TrouverPortAlimentation()` cherchait les équipements dans +**`NetworkClient.spawned`** au lieu de `NetworkServer.spawned`. + +Sur un dedicated server (serveur pur, pas host), `NetworkClient` n'est pas +actif, donc `NetworkClient.spawned` est **vide**. Résultat : +- `TrouverPortAlimentation()` retournait toujours `null` +- La condition `if (prise != null && port != null && ...)` était fausse +- `port.Connecter()` n'était JAMAIS appelé +- `port.estConnecte` restait à `false` +- `BoutonPower` refusait d'allumer l'équipement + +Le message `[Serveur] Câble alim créé` était trompeur parce qu'il apparaît +AVANT la vérification, juste au moment de l'entrée dans la méthode. + +## ✅ Le fix + +Ajout d'un helper universel `TrouverGameObjectNetId(netId)` dans `CablageReseau.cs` +qui cherche dans le bon dictionnaire selon le contexte : +- `NetworkServer.spawned` si on est serveur (dedicated OU host) +- `NetworkClient.spawned` si on est purement client +- `null` sinon + +Les 3 helpers `TrouverPortRJ45`, `TrouverPriseC13`, `TrouverPortAlimentation` +utilisent maintenant ce helper universel. + +## 📄 Script patché (1) + +- **`CablageReseau.cs`** — helper universel + refacto des 3 méthodes Trouver* + +## 🚀 Actions à faire + +### 1. Remplacer le script dans Unity + +Copie `Scripts_Modifies/CablageReseau.cs` dans `Assets/Scripts/`, écrase +l'existant. + +### 2. Rebuild Dedicated Server + +File → Build Settings → Dedicated Server Linux → Build. + +⚠️ **Astuce** : si tu veux t'assurer que le build prend bien les derniers +scripts, supprime le contenu du dossier de build avant de rebuilder. Unity +fait parfois du cache agressif. + +### 3. Redéploie sur la Debian + +```bash +# Arrêter le service +sudo systemctl stop datacentersim-server + +# Remplacer le dossier +# (ou scp -r depuis ton Windows) + +# Relancer +sudo systemctl start datacentersim-server +sudo journalctl -u datacentersim-server -f +``` + +### 4. Test + +1. Commande PDU + serveur 1U +2. Branche l'alim PDU → serveur (même procédure qu'avant) +3. Appuie sur Power → **DOIT S'ALLUMER** ✅ + +Attendu dans les logs serveur : plus de `BoutonPower: aucun câble +d'alimentation branché !`. + +## 🐛 Bug annexe détecté (pour plus tard) + +Les câbles RJ45 ne font RIEN côté serveur actuellement (la méthode +`CmdCreerCableRJ45` broadcast juste aux clients sans créer d'état serveur). + +Conséquence : les logiques type "flux de paquets", "consommation bande +passante", etc. ne tourneront pas si elles dépendent de l'existence des +câbles RJ45 côté serveur. À réfléchir dans une future refonte quand tu +implémenteras ce genre de features. + +Pour l'instant c'est OK, le multi fonctionne et les câbles s'affichent +bien chez tous les clients via le Rpc. + +## 🖥️ Rappel Ctrl+C qui ne marche pas + +Ajoute `-batchmode -nographics` aux arguments quand tu lances manuellement : + +```bash +./DatacenterSim.x86_64 -server -port 7777 -batchmode -nographics +``` + +Ces flags forcent Unity à gérer proprement SIGINT. Ton service systemd les +utilise déjà (ils sont dans `datacentersim-server.service`). diff --git a/Patchs/v4/Scripts_Modifies/CablageReseau.cs b/Patchs/v4/Scripts_Modifies/CablageReseau.cs new file mode 100644 index 0000000..d699087 --- /dev/null +++ b/Patchs/v4/Scripts_Modifies/CablageReseau.cs @@ -0,0 +1,420 @@ +using UnityEngine; +using System.Collections.Generic; +using Mirror; + +/// +/// 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. +/// +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}"); + 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 chemin = ConstruireCheminAutoLocal( + portSource.GetPointConnexion(), portDest.GetPointConnexion()); + + string nom = "Cable_" + portSource.nomPort + "_vers_" + portDest.nomPort + "_distant"; + GameObject cableObj = new GameObject(nom); + CableRJ45 cable = cableObj.AddComponent(); + 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é"); + 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) + // ════════════════════════════════════════════════════════════ + + /// + /// 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. + /// + [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(); + 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(); + cable.couleurCable = couleur; + cable.Initialiser(prise, port); + prise.Connecter(cable, port); + port.Connecter(cable, prise); + } + + 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(); + 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é"); + + 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 + // ════════════════════════════════════════════════════════════ + // ════════════════════════════════════════════════════════════ + // HELPER UNIVERSEL : trouver un NetworkIdentity spawned + // Utilise NetworkServer.spawned cote serveur (dedicated inclus), + // NetworkClient.spawned cote client. Les deux sont remplis en mode Host. + // Sans ce helper, les [Command] executees sur un dedicated server ne + // trouvaient aucun objet car NetworkClient.spawned est vide sans client local. + // ════════════════════════════════════════════════════════════ + private static GameObject TrouverGameObjectNetId(uint netId) + { + if (Mirror.NetworkServer.active && + Mirror.NetworkServer.spawned.TryGetValue(netId, out var ni1) && + ni1 != null) + return ni1.gameObject; + + if (Mirror.NetworkClient.active && + Mirror.NetworkClient.spawned.TryGetValue(netId, out var ni2) && + ni2 != null) + return ni2.gameObject; + + return null; + } + + + + private PortRJ45 TrouverPortRJ45(uint equipNetId, int portIndex) + { + GameObject equipGO = TrouverGameObjectNetId(equipNetId); + if (equipGO == null) return null; + + PortRJ45[] ports = equipGO.GetComponentsInChildren(); + + 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) + { + GameObject pduGO = TrouverGameObjectNetId(pduNetId); + if (pduGO == null) return null; + + PDU pdu = pduGO.GetComponent(); + + if (pdu != null && indexPrise >= 0 && indexPrise < pdu.prises.Count) + return pdu.prises[indexPrise]; + + PriseC13[] prises = pduGO.GetComponentsInChildren(); + foreach (var p in prises) + if (p.indexPrise == indexPrise) return p; + + return null; + } + + private PortAlimentation TrouverPortAlimentation(uint equipNetId, int indexPort) + { + GameObject equipGO = TrouverGameObjectNetId(equipNetId); + if (equipGO == null) return null; + + PortAlimentation[] ports = equipGO.GetComponentsInChildren(); + + if (indexPort >= 0 && indexPort < ports.Length) + return ports[indexPort]; + + return null; + } + + private List ConstruireCheminAutoLocal(Vector3 posSource, Vector3 posDest) + { + List chemin = new List(); + PointAccroche[] tousPoints = FindObjectsOfType(); + + 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 gScore = new Dictionary(); + Dictionary cameFrom = new Dictionary(); + HashSet closedSet = new HashSet(); + List openSet = new List(); + + 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 result = new List { 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(); + 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(); + 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(); + 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(); + for (int i = 0; i < ports.Length; i++) + if (ports[i] == port) return i; + return 0; + } +} \ No newline at end of file