> For the complete documentation index, see [llms.txt](https://docs.edgegap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.edgegap.com/docs.edgegap.com-fr/unity/navigateur-de-serveurs.md).

# Navigateur de serveurs

Ce SDK est un kit de démarrage optionnel pour les utilisateurs de Unity, qui peut être étendu et personnalisé par la suite.

## 💡 Fonctionnalités

Accédez à des fonctionnalités automatisées prêtes à l'emploi en installant notre SDK :

{% columns %}
{% column %}

* Exemples complets
* Gestion du cycle de vie
* Gestion de capacité
  {% endcolumn %}

{% column width="33.33333333333333%" %}

* Compilateur de requêtes de filtre
* Définitions de types (C#)
* Tests de développement local
  {% endcolumn %}

{% column width="33.33333333333333%" %}

* Multiplateforme
* Facile à personnaliser
* Nouvelle tentative automatique
  {% endcolumn %}
  {% endcolumns %}

## ✔️ Préparation

Le SDK Unity contient des utilitaires d’intégration optionnels pour les déploiements, le matchmaking et le navigateur de serveurs. Ce plugin prend officiellement en charge les versions de Unity 2021.3.0f1 et ultérieures.

{% hint style="success" %}
Ce plugin est fourni 100 % gratuitement, conformément aux Conditions générales de l’offre gratuite.
{% endhint %}

#### Exigences

<details>

<summary>Installez un client Git (par exemple <a href="https://git-scm.com/">git-scm</a>)</summary>

Un client Git est nécessaire pour permettre à Unity de télécharger et d’installer automatiquement notre package Unity. Vous n’aurez pas besoin d’utiliser git directement une fois qu’il sera installé.

</details>

#### Installation

1. Ouvrez votre projet Unity,
2. Sélectionnez `Fenêtre > Gestion des packages > Gestionnaire de packages` ,
3. Cliquez sur l’ :heavy\_plus\_sign: icône et sélectionnez `Ajouter un package à partir d’une URL Git...` ,
4. Saisissez l’URL de notre SDK lorsque vous y êtes invité :

{% code title="" %}

```
https://github.com/edgegap/edgegap-unity-sdk.git
```

{% endcode %}

5. Cliquez sur `Ajouter`  et attendez que l’installation soit terminée.

#### Importer les exemples

Ce package inclut plusieurs exemples, destinés à être utilisés individuellement (ne combinez pas les exemples).

#### Sources vérifiées

Il s’agit du seul canal de distribution officiel pour ce SDK, ne faites pas confiance aux sources non vérifiées !

#### Mettre à jour le package

Accédez au SDK Edgegap dans Unity Package Manager et cliquez sur `Mettre à jour` .

{% hint style="warning" %}
**Les exemples importés ne sont pas mis à jour automatiquement !** Sauvegardez toutes les valeurs de propriétés personnalisées, supprimez les scripts d’exemple actuellement utilisés dans votre scène, puis réimportez les exemples.
{% endhint %}

{% hint style="info" %}
Certaines versions peuvent contenir des changements incompatibles. Cela sera indiqué par une nouvelle version MAJEURE.
{% endhint %}

#### Mise à jour vers v3

Cette mise à jour inclut de nombreux nouveaux [Navigateur de serveurs](/docs.edgegap.com-fr/unity/navigateur-de-serveurs.md) utilitaires et exemples, améliore la gestion des erreurs de matchmaking, et plus encore. Voir [Notes de version](/docs.edgegap.com-fr/docs/release-notes.md) pour la liste complète.

{% hint style="warning" %}
La mise à jour v3 du SDK Unity inclut quelques changements incompatibles. Veuillez retester soigneusement votre intégration.
{% endhint %}

## 🍀 Premiers pas

Ce guide suppose une connaissance de base des [Navigateur de serveurs](/docs.edgegap.com-fr/learn/navigateur-de-serveurs.md) concepts et d'un Server Browser en fonctionnement.

{% hint style="success" %}
**Nous vous recommandons vivement d'importer notre exemple d'assignation automatique** pour suivre le code en lisant ce document. Vous pouvez le faire dans `Unity Package Manager > Edgegap SDK > Samples` .
{% endhint %}

{% embed url="<https://youtu.be/P8xWrD4UCxg>" %}

### Vue d'ensemble

Notre SDK utilise largement [l’injection de dépendances](https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection/overview#the-concept) et [Observateur](https://learn.microsoft.com/en-us/dotnet/standard/events/observer-design-pattern) des modèles de programmation.

{% hint style="info" %}
Ce package intègre à la fois [Navigateur de serveurs](/docs.edgegap.com-fr/learn/navigateur-de-serveurs.md) et [Appariement](/docs.edgegap.com-fr/learn/appariement.md), qui peuvent être utilisés ensemble ou séparément. Vous pouvez librement réutiliser n’importe quels scripts pour vos propres forks et intégrations personnalisés.
{% endhint %}

Ce package comprend :

* Fichiers d'exécution - seront compilés et inclus dans vos builds client et serveur :
  * Utilitaires spécifiques au service :
    * [#server-agent](#server-agent "mention") - une intégration serveur complète à réutiliser/étendre.
    * [#client-agent](#client-agent "mention") - une intégration client complète à réutiliser/étendre.
    * Fonctions API - définitions de points de terminaison, gestion des erreurs et automatisations de journalisation.
    * Compilateur de filtres - utilitaires fortement typés pour construire des requêtes de filtre.
  * Spécifique au service DTO[^1] - conteneurs de données typés pour l'API Server Browser.
  * Utilitaires partagés - journalisation, HTTP, ping, observables, etc...
  * Partagé DTO[^1] - utilisés par plusieurs services Edgegap pour transmettre des données.
* Fichiers d'exemple - inclus et compilés UNIQUEMENT s'ils sont importés dans votre projet :
  * [#auto-assign](#auto-assign "mention") - exemples de gestionnaires avec réservations attribuées automatiquement,
  * [#custom-search](#custom-search "mention") - exemples de gestionnaires avec choix manuel de l'instance.

### Agent serveur

**La gestion du cycle de vie et de la capacité du serveur** sont effectuées par l'agent serveur.

Une fois instancié, le **MonoBehaviour parent (gestionnaire) doit initialiser l'agent** et fournir :

* `onMonitorUpdate`  callback - observer les changements d'état du service,
* `onInstanceUpdate`  callback - observer et réagir aux changements d'instance et de slot,
* `onConfirmationsUpdate`  callback - observer et réagir à l'authentification fédérée.

Une fois initialisé, cet agent fournira automatiquement des validations et connectera les observateurs de journalisation, en terminant par un seul appel au point de terminaison de l'API de surveillance pour indiquer l'état du service.

Le gestionnaire de l'agent est censé prendre le contrôle et appeler les fonctions de l'agent à partir de ce point :

* `DiscoverInstance`  pour créer l'instance serveur initiale et les slots et lancer le heartbeat,
* `DeleteInstance`  une fois le match terminé / pour empêcher de nouveaux joueurs de rejoindre,
* `ConfirmReservation`  lorsque des joueurs rejoignent, pour vérifier leur identité et l'attribution du slot,
* `UpdateSlot`  pour mettre à jour la capacité du slot (lorsqu'un joueur rejoint/quitte) ou modifier les métadonnées,
* `UpdateInstance`  pour modifier les métadonnées de l'instance,
* `Status`  pour vérifier l'état du service Server Browser.

{% hint style="success" %}
Les confirmations et les mises à jour de slot/instance sont **mises en file d'attente et effectuées par lots par défaut** (mode Heartbeat) pour maximiser la scalabilité. Pour itérer plus rapidement pendant les tests de développement, utilisez le mode Greedy.
{% endhint %}

{% hint style="warning" %}
**Lors de la mise à jour des métadonnées, tous les index doivent être définis.** Pour désactiver les clés non indexées, il suffit de les omettre.
{% endhint %}

L'agent maintient automatiquement un heartbeat pour garder le serveur détectable pendant son exécution. Si l'agent ne peut pas atteindre votre server browser pendant plusieurs heartbeats consécutifs (configurable) :

* inférieur au maximum - l'instance sera automatiquement redécouverte,
* supérieur au maximum - l'instance sera automatiquement supprimée.

Lorsqu'une nouvelle connexion de joueur est établie, le joueur est censé envoyer son ID de réservation (ID de joueur tiers) au serveur de jeu à l'aide de votre netcode, afin d'effectuer la confirmation de réservation.

Une fois `onConfirmationsUpdate`  déclenché, le gestionnaire doit effectuer des actions supplémentaires :

* appeler `UpdateSlot`  pour réduire les places disponibles pour tous les slots ayant des réservations confirmées,
* accepter ou refuser la connexion à l'aide de méthodes spécifiques au netcode.

Lorsqu'un joueur quitte la partie, le gestionnaire est censé augmenter les places disponibles pour ce slot.

{% hint style="info" %}
Accordez un court délai aux joueurs pour se reconnecter avant d'abandonner en cas de crash inattendu.
{% endhint %}

### Agent client

**La recherche d'instances, la pagination, le filtrage et les réservations** sont effectués par l'agent client.

Une fois instancié, le **MonoBehaviour parent (gestionnaire) doit initialiser l'agent** et fournir :

* `onMonitorUpdate`  callback - observer les changements d'état du service,
* `onInstancesUpdate`  callback - observer et réagir aux changements de la liste des instances.

Une fois initialisé, cet agent fournira automatiquement des validations et connectera les observateurs de journalisation, en terminant par un seul appel au point de terminaison de l'API de surveillance pour indiquer l'état du service.

Le gestionnaire de l'agent est censé prendre le contrôle et appeler les fonctions de l'agent à partir de ce point :

* `ReserveSeats`  pour créer une réservation de capacité pour une instance/slot particulière ou une assignation automatique,
* `ListInstances`  pour lister les instances avec un filtre, un tri, un curseur et une taille de page spécifiques,
* `GetNextPage`  pour récupérer davantage d'instances avec les paramètres actuels (filtres, etc.),
* `RefreshList`  pour vider le cache et recharger la première page, ou actualiser avec un curseur spécifique,
* `GetInstanceDetails`  pour récupérer les métadonnées de l'instance et les informations des slots pour une instance spécifique,
* `Status`  pour vérifier l'état du service Server Browser.

Lorsqu'une nouvelle connexion de joueur est établie, le joueur est censé envoyer son ID de réservation (ID de joueur tiers) au serveur de jeu à l'aide de votre netcode, afin d'effectuer la confirmation de réservation.

{% hint style="success" %}
Enregistrez les détails de connexion dans le client ou le backend du jeu pour vous reconnecter en cas de crash inattendu.
{% endhint %}

## 🧪 Exemples

Commencez avec des exemples incluant une intégration complète et fonctionnelle pour le serveur et le client.

### Assignation automatique

Utilise des réservations attribuées automatiquement, le client ne spécifiant que le nom de la politique. Le server browser choisit automatiquement une instance correspondant au filtre de la politique et un slot disposant d'un nombre de places suffisant.

### Recherche personnalisée

Inclut une implémentation complète démontrant comment rechercher des instances et des slots, connecter les éléments de l'interface utilisateur et laisser le joueur choisir manuellement où il souhaite réserver de la capacité.

## ⚙️ Personnalisation

Ce SDK est conçu pour être étendu et modifié, bien que certaines modifications puissent être risquées :

✅ Gestionnaire - connectez en toute sécurité les observateurs de l'interface utilisateur et effectuez de petites additions ou modifications,

⚠️ Agent - modifiez la gestion du cycle de vie et de la capacité à vos risques et périls,

⚠️ API - écrivez votre propre intégration à partir de zéro, en utilisant des utilitaires soigneusement sélectionnés.

Les gestionnaires peuvent observer tous les événements émis par les agents serveur et client, comme décrit ci-dessous.

{% hint style="warning" %}
Assurez-vous de vous familiariser avec [Server Browser en profondeur](/docs.edgegap.com-fr/learn/navigateur-de-serveurs.md) concepts avant d'apporter des personnalisations.
{% endhint %}

{% hint style="info" %}
Si vous avez besoin d’aide, [veuillez nous contacter sur Discord](https://discord.gg/MmJf8fWjnt). Pour l’assistance aux jeux en direct, consultez notre [système de tickets](https://edgegap.atlassian.net/servicedesk/customer/portal/3).
{% endhint %}

### Événements du serveur

L'agent serveur émet des événements (actions) que le gestionnaire parent peut observer et consommer.

{% hint style="success" %}
Lire les charges utiles des événements en accédant à  `.Current` état de n’importe quel observable. 🔴 `Erreur` les événements contiennent le message d’erreur complet délimité par un caractère de nouvelle ligne après le message principal de l’événement.
{% endhint %}

Aperçu des événements émis par l'observable `Surveiller` :

<table data-full-width="true"><thead><tr><th width="125">Type d'action</th><th width="450">Message de l'événement</th><th>Description</th></tr></thead><tbody><tr><td>🟢 <code>Mise à jour</code> </td><td><code>sain</code></td><td>Tous les systèmes sont OK.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>malsain</code></td><td>Problème inattendu.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la récupération du moniteur</code></td><td>Mauvaise configuration ou problème inattendu.</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>délai d'attente de la requête limité au heartbeat [{timeout}]</code></td><td>Évite les conditions de course.</td></tr></tbody></table>

Aperçu des événements (actions) émis par l'observable `Instance`:

<table data-full-width="true"><thead><tr><th width="125">Type d'action</th><th width="450">Message de l'événement</th><th>Description</th></tr></thead><tbody><tr><td>🟢 <code>Mise à jour</code> </td><td><code>découverte</code></td><td><a href="/pages/7a8a569cdd7738220b9ebc8162027e9dca4d1518#discover-instance">Découverte de l'instance</a> terminée avec succès. Peut être déclenchée si l'instance a perdu la connexion en raison d'une condition temporaire et a été redécouverte.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>doublon de découverte</code></td><td>Une instance avec cet ID de requête est déjà découverte.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la découverte</code></td><td>Problème inattendu lors de la découverte.</td></tr><tr><td>🔵 <code>Notifier</code></td><td><code>heartbeat OK</code></td><td>Le heartbeat s'est terminé avec succès.</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>échec du heartbeat [{consecutive}/{maximum}]</code></td><td>Échec du heartbeat, le serveur n'a pas pu atteindre Server Browser.</td></tr><tr><td>🔵 <code>Notifier</code></td><td><code>mise à jour de l'instance mise en file d'attente</code></td><td>Mise à jour de l'instance mise en file d'attente pour le prochain lot (heartbeat/greedy).</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>instance mise à jour</code></td><td>Les métadonnées de l'instance ont été mises à jour avec succès.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la mise à jour de l'instance, mise en file d'attente pour une nouvelle tentative</code></td><td>Échec de la mise à jour de l'instance, possiblement en raison d'une limitation de débit ou d'une erreur.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>instance supprimée</code></td><td>L'instance n'est plus détectable par les joueurs.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>échec de la suppression de l'instance (introuvable)</code></td><td>L'instance a peut-être expiré en raison d'un trop grand nombre de heartbeats manqués.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la suppression de l'instance</code></td><td>Échec de la suppression de l'instance, possiblement en raison d'une limitation de débit ou d'une erreur.</td></tr><tr><td>🔵 <code>Notifier</code></td><td><code>mise à jour du slot mise en file d'attente [{slot}]</code></td><td>Mise à jour du slot mise en file d'attente pour le prochain lot (heartbeat/greedy).</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>slot mis à jour [{slot}]</code></td><td>La capacité des places du slot et/ou les métadonnées ont été mises à jour avec succès.</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>l'agent a limité la mise à jour concurrente du slot</code></td><td>Tentative de mise à jour concurrente empêchée (condition de course).</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la mise à jour du slot (introuvable) [{slot}]</code></td><td>Un slot portant ce nom n'est pas encore défini pour cette instance.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la mise à jour du slot (places insuffisantes) [{slot}]</code></td><td>La mise à jour du slot a tenté de réduire les places disponibles en dessous de zéro.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la mise à jour du slot, mise en file d'attente pour une nouvelle tentative [{slot}]</code></td><td>Échec de la mise à jour du slot, possiblement en raison d'une limitation de débit ou d'une erreur.</td></tr></tbody></table>

Aperçu des événements (actions) émis par l'observable `Confirmations`:

<table data-full-width="true"><thead><tr><th width="125">Type d'action</th><th width="450">Message de l'événement</th><th>Description</th></tr></thead><tbody><tr><td>🔵 <code>Notifier</code></td><td><code>mis en file d'attente [{player}]</code></td><td>Confirmation mise en file d'attente pour le prochain lot (heartbeat/greedy).</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>doublon [{player}]</code></td><td>Tentative de confirmation en double empêchée (déjà en file d'attente).</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>confirmé</code></td><td>Réservations confirmées pour des slots individuels, inclut également les ID de joueur expirés et inconnus à résoudre par le gestionnaire (accepter/exclure).</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échoué</code></td><td>Problème inattendu avec les confirmations. Vérifiez l'état du service.</td></tr></tbody></table>

### Événements du client

L'agent client émet des événements (actions) que le gestionnaire parent peut observer et consommer.

{% hint style="success" %}
Lire les charges utiles des événements en accédant à  `.Current` état de n’importe quel observable. 🔴 `Erreur` les événements contiennent le message d’erreur complet délimité par un caractère de nouvelle ligne après le message principal de l’événement.
{% endhint %}

Aperçu des événements émis par l'observable `Surveiller` :

<table data-full-width="true"><thead><tr><th width="125">Type d'action</th><th width="450">Message de l'événement</th><th>Description</th></tr></thead><tbody><tr><td>🟢 <code>Mise à jour</code> </td><td><code>sain</code></td><td>Tous les systèmes sont OK.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>malsain</code></td><td>Problème inattendu.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la récupération du moniteur</code></td><td>Mauvaise configuration ou problème inattendu.</td></tr></tbody></table>

Aperçu des événements émis par l'observable `Instances`:

<table data-full-width="true"><thead><tr><th width="125">Type d'action</th><th width="450">Message de l'événement</th><th>Description</th></tr></thead><tbody><tr><td>🔵 <code>Notifier</code></td><td><code>places réservées</code></td><td>Réservation de places réussie.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la réservation de places (introuvable)</code></td><td><a data-mention href="#auto-assign">#auto-assign</a> - nom de politique introuvable (supprimée ou inactive).<br><a data-mention href="#custom-search">#custom-search</a> - instance ou slot introuvable.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la réservation de places (capacité atteinte)</code></td><td><a data-mention href="#auto-assign">#auto-assign</a> - la politique a atteint sa capacité maximale.<br><a data-mention href="#custom-search">#custom-search</a> - le slot a atteint sa capacité maximale.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la réservation de places</code></td><td>Échec de la réservation de places, possiblement en raison d'une politique, d'un ID de requête ou d'un ID de slot invalide.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>liste des instances récupérée</code></td><td>Liste des instances récupérée avec succès.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>page suivante de la liste des instances récupérée</code></td><td>Page suivante des instances récupérée avec succès.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>dernière page de la liste des instances atteinte</code></td><td>Échec de récupération de la page suivante, essayez d'actualiser ou de modifier les filtres.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de récupération de la page suivante de la liste des instances</code></td><td>Échec de récupération de la page suivante, possiblement en raison d'un curseur invalide.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>détails de l'instance récupérés</code></td><td>Détails d'une instance listée récupérés avec succès.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>instance non mise en cache, ajout en tête</code></td><td>Détails d'une instance hors de la liste actuelle récupérés.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de récupération des détails de l'instance</code></td><td>Échec de récupération des détails, possiblement en raison d'un ID de requête invalide.</td></tr></tbody></table>

[^1]: Objet de transfert de données
