dcsim-gameserver/Patchs/pack_multi/README_PACK_v7.1.md
2026-04-18 11:31:50 +00:00

7.8 KiB

DatacenterSim v7.1 — Pack multi complet

Pack de 3 patches qui corrigent les 3 bugs identifiés en multijoueur après reco :

  1. Portage d'équipements invisible pour les autres joueurs
  2. Câbles alim + RJ45 pendants après reco
  3. Serveurs éteints après reco

Ce qu'il y a dans le ZIP

Scripts_Modifies/ (remplacer dans Assets/Scripts/)

  • PlayerInteraction.cs — 3 changements

    • Revert de mon patch authority (plus de AssignClientAuthority/RemoveClientAuthority sur équipements)
    • CmdUpdateTransportPosition bouge maintenant l'objet côté serveur
    • Helper SetNetworkTransformActif() + désactivation NT local pendant portage + réactivation à la pose
    • CmdAppuyerBoutonPower appelle EtatEquipementNetworkSync.ServerSyncEtat pour le rejoin
  • CablageReseau.cs — 4 ajouts

    • CmdCreerCableRJ45 / CmdCreerCableAlim enregistrent dans le gestionnaire
    • CmdSupprimerCableRJ45 / CmdSupprimerCableAlim désenregistrent
  • BaieNetworkSetup.cs — 1 ajout

    • OnStartClient notifie le gestionnaire que la baie est prête
  • EtatEquipement.cs — 1 ajout

    • VerifierAlimentation appelle EtatEquipementNetworkSync.ServerSyncEtat quand l'état change

Scripts_Nouveaux/ (AJOUTER dans Assets/Scripts/)

  • GestionnaireCablesReseau.cs — NetworkBehaviour singleton qui tient 2 SyncLists (câbles alim + RJ45) et rejoue les câbles au rejoin des clients

  • EtatEquipementNetworkSync.cs — Composant à ajouter sur les prefabs d'équipements rackmount pour synchroniser l'état bouton/sous-tension au rejoin


Configuration Unity requise

1. Prefabs d'équipements : NetworkTransform en Server To Client

IMPORTANT : tu avais configuré Client To Server pour mon dernier patch raté. Remets-les en Server To Client :

Pour chaque prefab dans NetworkManager.spawnPrefabs (sauf Chariot et prefab joueur) :

  • Ouvrir le prefab
  • Le NetworkTransformReliable / NetworkTransformUnreliable :
    • Sync Direction : Server To Client ⚠️
    • Sync Position :
    • Sync Rotation :
    • Sync Scale :
    • Compress Rotation :
    • Only Sync On Change :
    • Interpolate Position :
    • Interpolate Rotation :
    • Send Interval Multiplier : 3 ou 5

Prefabs concernés : Serveur_1U, Switch_24P, Parefeu, PDU_APC_*, Baie_Procedurale, Toron_Base.

Ne PAS toucher : le chariot (Client To Server) et le prefab joueur (Client To Server).

2. Ajouter GestionnaireCablesReseau à la scène Datacenter_01

  1. Dans la scène, Hierarchy → clic droit → Create Empty
  2. Renommer : GestionnaireCables_Holder
  3. Add ComponentNetworkIdentity (laisser toutes les checkboxes décochées)
  4. Add ComponentGestionnaireCablesReseau
  5. Sauver la scène (Ctrl+S)

3. Ajouter EtatEquipementNetworkSync sur les prefabs d'équipements rackmount

Pour chaque prefab qui a un BoutonPower + EtatEquipement :

  • Ouvrir le prefab
  • Add ComponentEtatEquipementNetworkSync
  • Sauver

Prefabs concernés : Serveur_1U, Switch_24P, Parefeu. (Pas besoin sur PDU, Toron, Baie — ces prefabs n'ont pas de bouton power.)


Tests à faire

Test 1 — Non-régression solo

Lancer en éditeur Play. Tout doit fonctionner comme avant (pas de multi).

Test 2 — Portage visible en multi

  1. Host + 1 client connecté
  2. Client prend un serveur 1U depuis un carton → tu dois voir le serveur suivre le client
  3. Client le pose dans une baie → tu dois voir le snap
  4. Tu prends le même serveur pour le déracker → le client doit te voir le porter

Test 3 — Câbles alim au rejoin

  1. Client pose baie + 2 serveurs + 2 PDUs + 2 câbles alim
  2. Client allume les serveurs (bouton Power)
  3. Client déco + reco
  4. Attendu : câbles alim toujours connectés (non pendants), serveurs toujours allumés (ventilos tournent, LED verte)

Test 4 — Câbles RJ45 au rejoin

  1. Client pose baie + 2 serveurs + 1 switch + torons + câbles RJ45
  2. Client déco + reco
  3. Attendu : câbles RJ45 toujours branchés correctement

Test 5 — 2e joueur qui rejoint en cours

  1. Client 1 a tout câblé et allumé
  2. Client 2 se connecte
  3. Attendu : client 2 voit TOUT l'état (câbles + serveurs allumés)

Logs à surveiller

Côté serveur, quand un câble est créé :

[Serveur] Câble alim créé : PDU 10 prise 11 → equip 7 port 0
[GestionnaireCablesReseau] Cable alim enregistre (total : 1)

Côté client qui rejoint :

[GestionnaireCablesReseau] Client rejoint : 2 cables alim, 3 cables RJ45 a recreer
[BaieNetworkSetup] Baie regeneree cote client : Baie_Procedurale(Clone)
[GestionnaireCablesReseau] Baie prete : Baie_Procedurale(Clone), retry cables en attente
[GestionnaireCablesReseau] Cable alim recree : PDU 10 prise #11 -> PSU0
[GestionnaireCablesReseau] Tous les cables ont ete recrees

Si timeout (normalement jamais) :

[GestionnaireCablesReseau] Timeout : 1 cables alim + 0 cables RJ45 jamais recrees

→ ça veut dire qu'une baie ou un équipement ne s'est pas spawné correctement côté client.


Architecture du mécanisme "baie prête"

Le problème classique au rejoin : on tente de recréer un câble entre PDU X et serveur Y, mais X ou Y n'existent pas encore localement parce que leur parent (la baie) n'a pas fini de se régénérer.

Solution :

  1. Au OnStartClient du gestionnaire, on met tous les câbles à recréer en "liste d'attente"
  2. On tente une première passe après 0.5s (laisse le temps aux premiers spawn)
  3. Chaque BaieNetworkSetup.OnStartClient se termine par NotifierBaiePrete() qui déclenche un retry sur tous les câbles en attente
  4. En fallback, un retry périodique toutes les 0.5s pendant 15s max
  5. Timeout à 15s avec un warning dans les logs

C'est robuste aux ordres de spawn aléatoires et évite tout callback hell.


Remarques techniques

Pourquoi retirer l'authority pour le portage ?

NetworkTransform Client-to-Server exige l'authority. Le patch précédent transférait l'authority au ramassage, mais ça créait plein de race conditions (logs EntityStateMessage without authority, objets figés/dédoublés...).

La nouvelle approche : le serveur est TOUJOURS autoritaire. Le client porteur envoie des CmdUpdateTransportPosition qui bougent l'objet côté serveur, puis NetworkTransform Server-to-Client propage aux autres clients. Beaucoup plus simple, plus robuste.

Pourquoi désactiver NT local pour le porteur ?

Sans ça, le client porteur reçoit sa propre position serveur avec ~50ms de latence → son objet tremble. En désactivant le NT localement, son objet suit parfaitement ses mouvements (il est pilote par le Rigidbody local).

Quand il pose, on réactive NT → il reçoit alors la position "figée" du serveur (qui a fait rb.isKinematic=true + position snap).

Pourquoi un gestionnaire séparé pour les câbles ?

CablageReseau est sur le prefab joueur : chaque joueur a sa propre instance. Impossible d'y mettre une SyncList globale. On crée donc un singleton à part qui porte l'état global.

Pourquoi un composant séparé pour l'état power ?

Pour éviter de transformer EtatEquipement en NetworkBehaviour (ce qui casserait les équipements instanciés localement, par ex. pour les tests en éditeur). Composant séparé = découplage propre.


Si ça ne marche pas

  1. Serveur crash au lancement → probablement GestionnaireCablesReseau sans NetworkIdentity dans la scène. Vérifier.
  2. Câbles toujours pendants au reco → regarder les logs [GestionnaireCablesReseau]. Si "Timeout", c'est que les refs PDU/port sont toujours null. Ouvrir un ticket.
  3. Portage local trembantSetNetworkTransformActif pas appelé au ramassage. Vérifier logs console.
  4. Erreur EntityStateMessage without authority → il reste un NT en Client-to-Server quelque part. Vérifier tous les prefabs.