aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Metin2

Création d'un patcher Metin2 : launcher à mise à jour auto

La création d'un patcher Metin2 est l'un des chantiers d'infrastructure les plus importants lorsqu'on gère son propre serveur : au lieu de télécharger le client à la main et de copier des fichiers, les joueurs s'attendent à ce que le launcher qu'ils ouvrent gère les mises à jour en silence. Un launcher bien conçu compare la version du serveur avec celle présente sur le disque du joueur, ne télécharge que les fichiers modifiés et lance le jeu avec les bons paramètres. Dans ce guide, nous construisons une architecture de mise à jour automatique simple mais robuste, de A à Z.

Comment fonctionne un launcher : l'architecture en bref

La logique d'un patcher n'est au fond qu'un problème de synchronisation. Il y a trois parties :

  • Un manifeste côté serveur : un fichier qui liste le chemin, la taille et le hash (par exemple SHA-256) de chaque fichier du client publié.
  • Un dépôt de fichiers : un serveur HTTP(S) ou un CDN d'où l'on peut télécharger les fichiers actuels du client.
  • L'application cliente (launcher) : elle télécharge le manifeste, le compare aux fichiers locaux, récupère ceux qui manquent ou ont changé et lance le jeu.

L'idée clé ici est la comparaison basée sur le contenu. Au lieu de se fier à une date ou un numéro de version, on vérifie le hash de chaque fichier ; ainsi les fichiers à moitié téléchargés ou corrompus sont réparés automatiquement au lancement suivant.

Générer le fichier manifeste

D'abord, écrivez un petit script qui parcourt le dossier client à publier et produit un manifeste. Voici un exemple simple en PowerShell ; vous pouvez mettre en place la même logique en Python ou comme étape de CI :

$root = "C:\dist\metin2-client"
$items = Get-ChildItem $root -Recurse -File | ForEach-Object {
    $rel = $_.FullName.Substring($root.Length + 1).Replace('\','/')
    [pscustomobject]@{
        path = $rel
        size = $_.Length
        hash = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()
    }
}
$items | ConvertTo-Json -Depth 3 | Out-File "$root\manifest.json" -Encoding utf8

Le manifest.json obtenu ressemble à ceci :

[
  { "path": "metin2client.exe", "size": 5242880, "hash": "9f2c..." },
  { "path": "pack/root.eix",     "size": 184320,  "hash": "ab17..." },
  { "path": "pack/root.epk",     "size": 9437184, "hash": "5e0d..." }
]

Placez le manifeste dans le même répertoire que les fichiers du client, sous une URL fixe (par exemple https://cdn.monserveur.com/client/manifest.json). À chaque nouveau patch, il suffit de relancer ce script et de republier le manifeste.

Côté client : comparaison et téléchargement

Comme vous écrivez le launcher pour Windows, C# (.NET) est un choix pratique ; HttpClient, SHA256 et WPF/WinForms sont fournis d'origine. Le flux principal est : télécharger le manifeste, calculer le hash de chaque fichier local et télécharger ceux qui ne correspondent pas.

using System.Security.Cryptography;

string Sha256(string file)
{
    using var stream = File.OpenRead(file);
    using var sha = SHA256.Create();
    return Convert.ToHexString(sha.ComputeHash(stream)).ToLowerInvariant();
}

async Task SyncAsync(string baseUrl, string localRoot, List<Entry> manifest)
{
    using var http = new HttpClient();
    foreach (var entry in manifest)
    {
        var local = Path.Combine(localRoot, entry.path);
        bool needs = !File.Exists(local) || Sha256(local) != entry.hash;
        if (!needs) continue;

        Directory.CreateDirectory(Path.GetDirectoryName(local)!);
        var bytes = await http.GetByteArrayAsync($"{baseUrl}/{entry.path}");
        await File.WriteAllBytesAsync(local, bytes);
    }
}

Pour les gros paquets .epk/.eix, préférez l'écriture en flux (stream) sur le disque plutôt que GetByteArrayAsync, afin de ne pas saturer la mémoire et de pouvoir alimenter une barre de progression. Vous affichez un pourcentage en rapportant les octets téléchargés par fichier à la taille totale.

Lancer le jeu correctement

Une fois la synchronisation terminée, le launcher exécute le client. Définir le répertoire de travail sur le dossier du client est important, sinon le jeu ne trouvera pas ses paquets :

var psi = new ProcessStartInfo
{
    FileName = Path.Combine(localRoot, "metin2client.exe"),
    WorkingDirectory = localRoot,
    UseShellExecute = false
};
Process.Start(psi);

Si vous le souhaitez, le launcher peut passer un argument pour transmettre une session/un token au client ; mais évitez d'envoyer des données sensibles en clair sur la ligne de commande — utilisez plutôt un fichier temporaire ou un named pipe.

Notes sur la mise à jour et la sécurité

  • Utilisez HTTPS. Servir le manifeste et les fichiers en HTTP simple ouvre la porte à une altération de type man-in-the-middle (MITM).
  • Signez le manifeste. Pour une installation plus solide, signez le manifeste avec une clé privée et vérifiez-le avec une clé publique intégrée au launcher, afin qu'un faux manifeste ne puisse pas être injecté.
  • Auto-mise à jour. Le launcher lui-même doit aussi être mis à jour. Approche courante : télécharger la nouvelle version sous launcher.exe.new et échanger le fichier à la fermeture avec un petit script d'aide.
  • Reprise et réparation. Si un téléchargement est interrompu, le hash ne correspondra pas au lancement suivant, donc le fichier est récupéré à nouveau — la réparation est un sous-produit naturel de cette architecture.

Erreurs fréquentes dans la création d'un patcher Metin2

La plupart des problèmes ne viennent pas de l'architecture mais des détails. Les plus fréquents : mélanger les barres dans les chemins relatifs (Windows \ vs URL /), comparer des hashs avec une casse incohérente, et alourdir le launcher en chargeant d'énormes paquets entièrement en mémoire. Générez toujours le manifeste à la dernière étape de la distribution ; sinon un fichier que vous venez d'ajouter ne sera pas dans le manifeste et n'atteindra jamais les joueurs.

Questions fréquentes

Quel langage/technologie choisir ?

Si vous visez Windows, C# (.NET) est la voie la moins contraignante ; vous le livrez en publish mono-fichier. Si vous voulez le multiplateforme ou une interface plus soignée, C++/Qt ou Electron fonctionnent aussi, mais Electron a un coût en taille.

Pourquoi SHA-256 plutôt que MD5 ?

MD5 est déconseillé pour la sécurité car il est sujet aux collisions. Même si MD5 est rapide pour de simples contrôles d'intégrité, dès que vous ajoutez une couche de sécurité comme la signature du manifeste, il est plus propre de rester cohérent avec SHA-256.

Dois-je distribuer tout le client ou seulement le diff ?

Dans cette architecture, seuls les fichiers dont le hash a changé sont téléchargés ; vous obtenez donc de fait des mises à jour incrémentales. Pour la première installation, proposer aussi un lien pour télécharger le client complet une fois facilite la vie des joueurs.

Vous voulez un patcher solide pour votre propre serveur ? Je construis toute la pile du launcher, de la génération du manifeste à l'auto-mise à jour, et je la livre avec une interface à l'image de votre marque. Parlons de votre projet : contactez-moi.

Bu kategorideki tüm yazılar →

Devamı için