Linkpearl Sync

Under the hood

How two games find each other, what gets encrypted and how, what a server can and cannot see, and how to run your own rendezvous service for your circle.

Sous le capot

Comment deux jeux se trouvent, ce qui est chiffré et comment, ce qu'un serveur peut voir ou non, et comment faire tourner son propre service de rendez-vous pour un cercle d'amis.

How two players connect

No server holds your files. Your game talks straight to your friend's game. A small rendezvous service only helps the two of you find each other, and relays encrypted bytes when a direct connection is impossible.

rendezvous introduces relays if needed you your friend direct, end-to-end encrypted
  1. Discovery. Each plugin opens a mailbox on the rendezvous. Its address is computed from the character's name and world: SHA-256("linkpearl:mbox:v1" ‖ name@world ‖ window), truncated. Anyone who sees your character can compute it; that is how the orange glyph appears next to players who use Linkpearl.
  2. Pairing. A request lands in the target's mailbox. They accept in game, and each side stores the other's public key in its local peer book. Nobody ever has to see a key. Request and reply each carry a one-time key: the secret the pair shares comes from their exchange, so the service that carried them cannot compute it.
  3. Connection. Every ten minutes, both sides announce a ticket derived from a secret only the pair shares: HMAC-SHA256(secret, "linkpearl:rv:v1" ‖ ⌊unix / 600⌋). When two announcements match, the service swaps the two addresses. The address lists are sealed under a key derived from that same secret, so the service can't read them. The plugins then try each other's addresses in priority order (local network, then the public address the service observed) and punch through the NAT.

When no direct path exists (some strict NATs), the session goes through the relay of the service that introduced you, still end-to-end encrypted: it only sees sealed bytes. Your peers list shows whether each session is direct or relayed.

A direct connection shows your IP address to your peer, as in any peer-to-peer game or voice chat. Only people you paired with ever get it. A session relayed after a failed direct attempt does not hide it either: the addresses were exchanged during the attempt.

Comment deux joueurs se connectent

Aucun serveur ne détient les fichiers. Le jeu d'un joueur parle directement à celui de son ami. Un petit service de rendez-vous les aide seulement à se trouver, et relaie des octets chiffrés quand la connexion directe est impossible.

rendez-vous présente relaie au besoin joueur ami direct, chiffré de bout en bout
  1. Détection. Chaque plugin ouvre une boîte aux lettres sur le rendez-vous. Son adresse se calcule depuis le nom et le monde du personnage : SHA-256("linkpearl:mbox:v1" ‖ nom@monde ‖ fenêtre), tronqué. Quiconque voit le personnage peut la calculer ; c'est ainsi que le glyphe orange apparaît à côté des joueurs qui utilisent Linkpearl.
  2. Pairage. Une demande arrive dans la boîte de la cible. Elle accepte en jeu, et chacun range la clé publique de l'autre dans son carnet local. Personne n'a jamais à voir une clé. La demande et la réponse portent chacune une clé à usage unique : le secret que partage la paire vient de leur accord, et le service qui les a transportées ne peut pas le calculer.
  3. Connexion. Toutes les dix minutes, chacun annonce un ticket dérivé d'un secret que seule la paire connaît : HMAC-SHA256(secret, "linkpearl:rv:v1" ‖ ⌊unix / 600⌋). Quand deux annonces correspondent, le service échange les deux adresses. Les listes d'adresses sont scellées sous une clé dérivée de ce même secret, donc le service ne peut pas les lire. Les plugins essaient alors les adresses de l'autre par ordre de priorité (réseau local, puis l'adresse publique que le service a observée) et percent le NAT.

Quand aucun chemin direct n'existe (certains NAT stricts), la session passe par le relais du service qui a mis les deux joueurs en relation, toujours chiffrée de bout en bout : il ne voit que des octets scellés. La liste des pairs indique si chaque session est directe ou relayée.

Une connexion directe montre l'adresse IP de chaque joueur à son pair, comme tout jeu ou chat vocal en pair à pair. Seuls les pairs établis l'obtiennent. Une session relayée après un essai direct raté ne la cache pas non plus : les adresses ont été échangées pendant l'essai.


Encryption

Everything comes from .NET's standard library, with no third-party cryptography.

RolePrimitive
Identity, signaturesECDSA P-256, SHA-256
Key agreementECDH P-256, ephemeral for every session
Key derivationHKDF-SHA256
Authenticated encryptionAES-256-GCM
Content addressingSHA-256
  • One identity per character, generated on your PC. The private key never leaves it, except inside the backup file you choose to make.
  • SIGMA-I handshake: mutual authentication over a transcript that includes both ephemeral keys, and forward secrecy. Stealing an identity key later does not decrypt past sessions. Both sides contribute fresh one-time keys, so a replayed handshake leads nowhere.
  • Authorization comes from your local peer book only. The received public key must be exactly the one stored for that peer, and it is checked before any cryptographic work.
  • Data channel: each message is sealed with AES-256-GCM. The nonce carries the channel index, so two channels can never reuse one, and counters only advance after authentication.

A custom construction. The full protocol, its trust model and its known limits are written up in docs/protocol.md (French).

Chiffrement

Tout vient de la bibliothèque standard de .NET, sans cryptographie tierce.

RôlePrimitive
Identité, signaturesECDSA P-256, SHA-256
Accord de cléECDH P-256, éphémère à chaque session
DérivationHKDF-SHA256
Chiffrement authentifiéAES-256-GCM
Adressage de contenuSHA-256
  • Une identité par personnage, engendrée sur le PC du joueur. La clé privée ne le quitte jamais, sauf dans un fichier de sauvegarde fait à la demande.
  • Handshake SIGMA-I : authentification mutuelle sur un transcript qui contient les deux clés éphémères, et confidentialité persistante. Voler une clé d'identité plus tard ne déchiffre pas les sessions passées. Chaque côté apporte des clés neuves à usage unique, donc un handshake rejoué ne mène nulle part.
  • L'autorisation vient du seul carnet local. La clé publique reçue doit être exactement celle rangée pour ce pair, et elle est comparée avant tout travail cryptographique.
  • Canal de données : chaque message est scellé en AES-256-GCM. Le nonce porte l'index du canal, donc deux canaux ne peuvent jamais en réutiliser un, et les compteurs n'avancent qu'après authentification.

Une construction maison. Le protocole complet, son modèle de confiance et ses limites connues sont décrits dans docs/protocol.md.


Transfers and cache

  • Files are named by their content. Each one is stored under the SHA-256 of its bytes, recomputed on receipt. Nothing that comes from the network ever becomes a file name.
  • Deduplication for free. If three peers use the same skin texture, it is downloaded once. A peer seen again the next day with no change costs zero bytes: only their manifest travels.
  • Built for heavy looks. An average modded appearance weighs around 800 MB. Files are cut into 4 MiB segments spread over 32 parallel channels, because a single LiteNetLib channel caps out around 1.5 MB/s at 60 ms of latency.
  • Everything received is checked before it reaches Penumbra or your disk: game paths, extensions, sizes, number of entries. A manifest that breaks a single rule is rejected as a whole. Animations are also checked against the skeleton they target.
  • The cache speeds things up; it never stands in for consent. A peer you can't reach keeps their default look, even if their last appearance is still cached.
Simulated latency0 ms20 ms60 ms
Throughput, 405 MB look53.8 MB/s33.0 MB/s17.5 MB/s

Measured on a test bench, on one machine, with the real transfer engine on both sides. Real networks will vary. The upload limiter exists but is off by default.

Transferts et cache

  • Les fichiers sont nommés par leur contenu. Chacun est rangé sous le SHA-256 de ses octets, recalculé à la réception. Rien de ce qui vient du réseau ne devient jamais un nom de fichier.
  • Déduplication gratuite. Si trois pairs utilisent la même texture de peau, elle n'est téléchargée qu'une fois. Un pair revu le lendemain sans changement coûte zéro octet : seul son manifeste voyage.
  • Pensé pour les apparences lourdes. Une apparence moddée moyenne pèse environ 800 Mo. Les fichiers sont découpés en tronçons de 4 Mio répartis sur 32 canaux parallèles, parce qu'un canal LiteNetLib seul plafonne vers 1,5 Mo/s à 60 ms de latence.
  • Tout ce qui est reçu est contrôlé avant d'atteindre Penumbra ou le disque : chemins de jeu, extensions, tailles, nombre d'entrées. Un manifeste qui viole une seule règle est rejeté en entier. Les animations sont aussi vérifiées contre le squelette qu'elles visent.
  • Le cache accélère, il ne remplace pas le consentement. Un pair injoignable garde son apparence par défaut, même si sa dernière apparence est encore en cache.
Latence simulée0 ms20 ms60 ms
Débit, apparence de 405 Mo53,8 Mo/s33,0 Mo/s17,5 Mo/s

Mesuré sur un banc d'essai, sur une seule machine, avec le vrai moteur de transfert des deux côtés. Un vrai réseau donnera autre chose. Le limiteur d'envoi existe mais il est désactivé par défaut.


What a rendezvous service sees

It sees It never sees
IP addressesYour files and appearances
Which characters are online, if they are discoverableManifests and private keys
Who is paired with whom: pairing requests and IP addresses give it awayThe secret each pair shares
Pairing requests: name, world and public keysSessions, direct or relayed: only sealed bytes
That two tickets match in a ten-minute windowWhat peers exchange once connected

Being discoverable means being discoverable. For a stranger to recognise you in game, your mailbox address has to derive from your name, and FFXIV names can be enumerated. So the operator of a service can tell which characters are online. You can opt out with Me signaler aux autres joueurs (let other players see me) in Réglages › Visibilité; then nobody can spot you or send you a request.

What a service keeps: nothing on disk, and little for long in memory. A pairing request is never stored: it is delivered at once, or dropped if the target is not connected. A mailbox exists only while your game is connected, an announcement lives ten minutes at most, an invitation twenty-four hours and vanishes as soon as it is used. Your IP address is kept only for the length of the connection. By default the log says what happens, never to whom: no IP addresses, no names. It goes to the host's system journal, whose retention the operator sets.

A rendezvous is not an authority. It can make a connection fail; it cannot read your files or pass itself off as a peer you already paired with. One caveat, stated plainly: a pairing request goes through the target's mailbox, so a malicious operator could slip in at that moment, without either of you noticing. That is why the choice of services matters, and why a circle running its own is the strongest setup: the operator is one of you.

Ce que voit un service de rendez-vous

Il voit Il ne voit jamais
Les adresses IPLes fichiers et les apparences
Quels personnages sont en ligne, s'ils sont détectablesLes manifestes et les clés privées
Qui est pairé avec qui : les demandes de pairage et les adresses IP le trahissentLe secret que partage chaque paire
Les demandes de pairage : nom, monde et clés publiquesLes sessions, directes ou relayées : seulement des octets scellés
Que deux tickets correspondent dans une fenêtre de dix minutesCe que les pairs échangent une fois connectés

Être détectable, c'est être détectable. Pour qu'un inconnu reconnaisse un joueur en jeu, l'adresse de sa boîte doit dériver de son nom, et les noms de FFXIV s'énumèrent. L'opérateur d'un service peut donc savoir quels personnages sont en ligne. Le réglage Me signaler aux autres joueurs, dans Réglages › Visibilité, permet de s'en retirer ; personne ne peut alors repérer le personnage ni lui envoyer de demande.

Ce qu'un service conserve : rien sur disque, et peu de temps en mémoire. Une demande de pairage n'est jamais stockée : elle est remise aussitôt, ou abandonnée si la cible n'est pas connectée. Une boîte n'existe que tant que le jeu est connecté, une annonce vit dix minutes au plus, une invitation vingt-quatre heures et disparaît dès qu'elle sert. L'adresse IP n'est gardée que le temps de la connexion. Par défaut, le journal dit ce qui se passe, jamais à qui : ni adresse IP, ni nom. Il part dans le journal système de l'hébergeur, dont l'opérateur règle la durée de conservation.

Un rendez-vous n'est pas une autorité. Il peut faire échouer une connexion ; il ne peut ni lire les fichiers ni se faire passer pour un pair déjà établi. Une réserve, dite franchement : une demande de pairage passe par la boîte de la cible, donc un opérateur malveillant pourrait s'intercaler à ce moment-là, sans que ni l'un ni l'autre ne s'en aperçoive. C'est pourquoi le choix des services compte, et pourquoi un cercle qui fait tourner le sien est la configuration la plus sûre : l'opérateur fait partie du réseau.


Federation

There is no central server. Anyone can run a rendezvous service, and the plugin talks to every service in your list at once (Réglages › Réseau › Services de rendez-vous, Settings › Network › Rendezvous services).

A B C AliceBobChloé
Alice and Bob share service B, so they see each other. Chloé shares none with them.
  • You see the players you share at least one service with.
  • A pairing survives the loss of a server. Each pair remembers the services both sides used when pairing, and announces on all of them in parallel; the first match wins.
  • Servers ignore each other. None queries, relays for, or vouches for another. This is deliberate: if servers answered for each other, one your operator quietly added could claim someone's mailbox and slip into their pairings.
  • Directories inform, they never decide. A service can publish the list of services it knows. The refresh button next to a service in your list shows it, and nothing is added until you tick it. A new service can apply to be listed, and waits for a human to approve.
  • The open network. From version 0.5.0, once two players are paired, their announcements and relay also go through two services run by volunteers; the pairing itself stays on the services you pick. They are admitted automatically after 72 hours of reliable answers, on a list signed by a single authority that never sees a player. Who is in it.
  • The price. Each active service learns that your character is online and who is around you. More services means more people you can see, and more operators who know. Keep the list short.

Fédération

Il n'y a pas de serveur central. N'importe qui peut faire tourner un service de rendez-vous, et le plugin parle à tous les services de la liste à la fois (Réglages › Réseau › Services de rendez-vous).

A B C AliceBobChloé
Alice et Bob partagent le service B, donc ils se voient. Chloé n'en partage aucun avec eux.
  • Deux joueurs se voient s'ils partagent au moins un service.
  • Un pairage survit à la perte d'un serveur. Chaque paire retient les services des deux côtés au moment du pairage, et s'annonce sur tous en parallèle ; le premier qui apparie gagne.
  • Les serveurs s'ignorent. Aucun n'en interroge, n'en relaie ni ne répond pour un autre. C'est voulu : si les serveurs répondaient les uns pour les autres, un serveur ajouté en douce par un opérateur pourrait revendiquer la boîte de quelqu'un et s'intercaler dans ses pairages.
  • Les annuaires informent, ils ne décident jamais. Un service peut publier la liste de ceux qu'il connaît. Le bouton d'actualisation à côté d'un service de la liste l'affiche, et rien n'est ajouté sans une case cochée. Un nouveau service peut demander à y figurer, et attend qu'un humain l'approuve.
  • Le réseau ouvert. Depuis la version 0.5.0, une fois deux joueurs pairés, leurs annonces et leur relais passent aussi par deux services tenus par des bénévoles ; le pairage lui-même reste sur les services choisis. Ils y entrent d'office après 72 heures de réponses fiables, sur une liste signée par une seule autorité qui ne voit aucun joueur. Qui en fait partie.
  • Le prix. Chaque service actif apprend que le personnage est en ligne et qui se tient autour. Plus de services, c'est plus de monde à voir, et plus d'opérateurs qui savent. Mieux vaut garder la liste courte.

Host your own rendezvous

Why host your own

  • The operator is one of you. The one real weakness of the protocol, a service slipping into a pairing, goes away: nobody else stands between you.
  • Your circle's metadata stays in the circle. Who is online, who is paired with whom, IP addresses: your server sees them, a public service does not.
  • You depend on no one. If the public service goes down or closes, your circle keeps seeing each other.
  • Relays go through a server you chose, close to you if you like, with bandwidth you know.

One condition for the first two: pair with your service alone in the list. A pairing request goes through every service in the list, and the pair then announces on all of them. You can add the public service back afterwards to meet players outside the circle: existing pairs will not announce there, though it will see you online if you stay discoverable.

The cost: a small server and a few minutes of setup, detailed below. And whoever runs it sees what a service sees: pick someone the circle trusts.

The service is one self-contained binary, lprdv. It needs no .NET runtime and no database.

You need a Linux x86-64 server with a public IP address and systemd (a small VPS is enough; the provided unit caps the service at 512 MB of RAM), SSH access with sudo, and one port open in both TCP and UDP, 47900 by default.

Bandwidth: introducing peers costs almost nothing. Relaying is what costs: two players who can't connect directly send their whole appearance, often hundreds of megabytes, through your server.

In one command. The generator writes it for you: download, check, install, open the port and start. The steps below do the same by hand.

Checking by hand proves less. The checksum below comes from the same release as the binary: it proves the download is intact, not that the project published it. The generator's script also checks the release signature against the project key it carries, which a replaced release file cannot fake.

  1. Install the service

    # system account that runs the service
    sudo useradd --system --home-dir /var/lib/lprdv --shell /usr/sbin/nologin lprdv
    
    # latest release and its unit; this checksum only catches a damaged download
    cd /tmp
    curl -fLO https://github.com/LinkPearl-Sync/linkpearl-sync-rendezvous/releases/latest/download/lprdv
    curl -fLO https://github.com/LinkPearl-Sync/linkpearl-sync-rendezvous/releases/latest/download/lprdv.service
    curl -fLO https://github.com/LinkPearl-Sync/linkpearl-sync-rendezvous/releases/latest/download/lprdv.sha256
    sha256sum -c --ignore-missing lprdv.sha256
    sudo install -D -m 0755 lprdv /opt/lprdv/lprdv
    
    # hardened systemd unit, restarts on its own
    sudo install -m 0644 lprdv.service /etc/systemd/system/lprdv.service
    sudo systemctl daemon-reload
    sudo systemctl enable --now lprdv
  2. Open the port

    In TCP and UDP, on the server and in your host's firewall panel if it has one.

    sudo ufw allow 47900
  3. Check that it runs

    This should print 200. The log never contains IP addresses unless you start the service with --verbose.

    curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:47901/healthz
    journalctl -u lprdv -f
  4. Add it in the plugin

    In game: Réglages › Réseau › Services de rendez-vous, type your server's address (rdv.example.org, or rdv.example.org:47900 if you changed the port), then Ajouter (Add). Each friend does the same. Keep the default service in the list if you still want to see players outside your circle.

  5. Open the console (optional)

    The console shows the service's health, counters and history, and lets you approve directory applications. It only answers the server itself: reach it through an SSH tunnel, open http://localhost:47901, and log in with any user name and the token as password.

    ssh -L 47901:127.0.0.1:47901 you@your-server
    sudo cat /var/lib/lprdv/admin.token
  6. The open network and federation

    Out of the box, the service applies to the open network at startup and every day, under the IPv4 address it connects from. It joins after 72 hours of reliable answers. Add --no-announce to stay out, or give it a name and a label as below.

    To let your users discover other services, list them in /var/lib/lprdv/peers.txt, one address  label per line. The file is re-read live. To appear in another service's directory instead, pass it to --announce-to; its operator decides.

    sudo systemctl edit lprdv

    Then, in the editor that opens:

    [Service]
    ExecStart=
    ExecStart=/opt/lprdv/lprdv --port 47900 --public-address rdv.example.org --label "My Free Company"
  7. Update

    Servers installed with the generator update themselves, 24 hours after each signed release. By hand, rerun its command, or download and check the new binary as in step 1, then:

    sudo install -m 0755 /tmp/lprdv /opt/lprdv/lprdv
    sudo systemctl restart lprdv

Back up /var/lib/lprdv. It holds your settings, your directory, and the ban list with its salt, which cannot be rebuilt. Nothing about your users is stored there.

Moderation. The console keeps a ban list of characters, published as slow hashes at /api/bans so it can't serve as a directory of modders. The plugin does not apply these lists yet.

Every option is documented in the rendezvous repository (and in lprdv --help, in French).

Héberger son propre rendez-vous

Pourquoi auto-héberger

  • L'opérateur fait partie du réseau. La seule vraie faiblesse du protocole, un service qui s'intercale au moment du pairage, disparaît : personne d'autre ne se tient entre les pairs.
  • Les métadonnées du cercle restent dans le cercle. Qui est en ligne, qui est pairé avec qui, les adresses IP : le serveur du réseau les voit, un service public non.
  • Aucune dépendance. Si le service public tombe ou ferme, le cercle continue de se voir.
  • Les relais passent par un serveur choisi, proche des joueurs si besoin, avec une bande passante connue.

Une condition pour les deux premiers points : se pairer avec le service du cercle seul dans la liste. Une demande de pairage passe par tous les services de la liste, et la paire s'annonce ensuite sur chacun. Le service public peut être rajouté ensuite, pour croiser des joueurs hors du cercle : les pairages déjà formés ne s'y annonceront pas, mais il verra le personnage en ligne s'il reste détectable.

Ce que ça coûte : un petit serveur et quelques minutes d'installation, détaillés ci-dessous. Et qui le fait tourner voit ce que voit un service : mieux vaut quelqu'un en qui le cercle a confiance.

Le service est un seul binaire autonome, lprdv. Il n'a besoin ni du runtime .NET ni de base de données.

Il faut un serveur Linux x86-64 avec une adresse IP publique et systemd (un petit VPS suffit ; l'unité fournie plafonne le service à 512 Mo de mémoire), un accès SSH avec sudo, et un port ouvert en TCP et en UDP, 47900 par défaut.

La bande passante : mettre les pairs en relation ne coûte presque rien. C'est le relais qui coûte : deux joueurs qui ne peuvent pas se connecter directement font passer toute leur apparence, souvent des centaines de mégaoctets, par le serveur.

En une commande. Le générateur l'écrit pour vous : téléchargement, vérification, installation, ouverture du port et démarrage. Les étapes ci-dessous font la même chose à la main.

À la main, la vérification prouve moins. L'empreinte ci-dessous vient de la même version que le binaire : elle prouve que le téléchargement est intact, pas que le projet l'a publié. Le script du générateur vérifie en plus la signature de la version avec la clé du projet qu'il embarque, ce qu'un fichier de version remplacé ne peut pas imiter.

  1. Installer le service

    # compte système qui fait tourner le service
    sudo useradd --system --home-dir /var/lib/lprdv --shell /usr/sbin/nologin lprdv
    
    # dernière version et son unité ; cette empreinte n'attrape qu'un téléchargement abîmé
    cd /tmp
    curl -fLO https://github.com/LinkPearl-Sync/linkpearl-sync-rendezvous/releases/latest/download/lprdv
    curl -fLO https://github.com/LinkPearl-Sync/linkpearl-sync-rendezvous/releases/latest/download/lprdv.service
    curl -fLO https://github.com/LinkPearl-Sync/linkpearl-sync-rendezvous/releases/latest/download/lprdv.sha256
    sha256sum -c --ignore-missing lprdv.sha256
    sudo install -D -m 0755 lprdv /opt/lprdv/lprdv
    
    # unité systemd durcie, qui redémarre seule
    sudo install -m 0644 lprdv.service /etc/systemd/system/lprdv.service
    sudo systemctl daemon-reload
    sudo systemctl enable --now lprdv
  2. Ouvrir le port

    En TCP et en UDP, sur le serveur et dans le pare-feu de l'hébergeur s'il en a un.

    sudo ufw allow 47900
  3. Vérifier qu'il tourne

    Ceci doit afficher 200. Le journal ne contient jamais d'adresse IP, sauf si le service est lancé avec --verbose.

    curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:47901/healthz
    journalctl -u lprdv -f
  4. L'ajouter dans le plugin

    En jeu : Réglages › Réseau › Services de rendez-vous, saisir l'adresse du serveur (rdv.exemple.fr, ou rdv.exemple.fr:47900 si le port a changé), puis Ajouter. Chaque ami fait de même. Garder le service par défaut dans la liste permet de continuer à voir les joueurs hors du cercle.

  5. Ouvrir la console (facultatif)

    La console montre la santé du service, ses compteurs et leur historique, et permet d'approuver les candidatures à l'annuaire. Elle ne répond qu'au serveur lui-même : passer par un tunnel SSH, ouvrir http://localhost:47901, et se connecter avec n'importe quel identifiant et le jeton comme mot de passe.

    ssh -L 47901:127.0.0.1:47901 utilisateur@serveur
    sudo cat /var/lib/lprdv/admin.token
  6. Le réseau ouvert et la fédération

    Sans rien configurer, le service se porte candidat au réseau ouvert au démarrage puis chaque jour, sous l'adresse IPv4 d'où il se connecte. Il y entre après 72 heures de réponses fiables. --no-announce l'en tient à l'écart ; on peut aussi lui donner un nom et un libellé, comme ci-dessous.

    Pour que les utilisateurs découvrent d'autres services, les lister dans /var/lib/lprdv/peers.txt, une ligne adresse  libellé par service. Le fichier est relu à chaud. Pour figurer plutôt dans l'annuaire d'un autre service, le donner à --announce-to ; son opérateur décide.

    sudo systemctl edit lprdv

    Puis, dans l'éditeur qui s'ouvre :

    [Service]
    ExecStart=
    ExecStart=/opt/lprdv/lprdv --port 47900 --public-address rdv.exemple.fr --label "Ma compagnie libre"
  7. Mettre à jour

    Les serveurs installés par le générateur se mettent à jour seuls, 24 heures après chaque release signée. À la main, relancer sa commande, ou télécharger et vérifier le nouveau binaire comme à l'étape 1, puis :

    sudo install -m 0755 /tmp/lprdv /opt/lprdv/lprdv
    sudo systemctl restart lprdv

Sauvegarder /var/lib/lprdv. Il contient les réglages, l'annuaire, et la liste de bannissement avec son sel, qui ne se reconstruit pas. Rien des utilisateurs n'y est stocké.

Modération. La console tient une liste de personnages bannis, publiée sous forme d'empreintes lentes sur /api/bans pour qu'elle ne puisse pas servir d'annuaire des joueurs moddés. Le plugin n'applique pas encore ces listes.

Toutes les options sont décrites dans le dépôt du rendez-vous et dans lprdv --help.