launcher update scala EnderChest, un nouveau système de mise à jour.



  • Bonjour,
    je vais vous présenter aujourd'hui EnderChest. EnderChest est un système de mise à jour comme S-Update, très utilisé pour les launchers.

    Features

    Si S-Update existe déjà, pourquoi recréer un système d'update ? Tout simplement parce que ce dernier est très vieux et utilise des mécaniques obsolètes (comme l'algorithme MD5 pour les checksums, une des causes de sa lenteur).

    Après avoir parlé avec Litarvan, l'auteur du prédécesseur d'EC, j'en suis venu à créer mon propre système, avec le but qu'il soit rapide et performant.

    EnderChest est donc né, et possède avec lui les fonctionnalités suivantes:

    • Gestion de la concurrence et requêtes asynchrones, pour empêcher le blocage du thread d'exécution. Principalement faite grâce aux libraries akka-stream et akka-http
    • Utilisation de l'algorithme xxHash32, environ 16.35x plus rapide que MD5.
    • Chunking des données pour empêcher la taille des fichiers d'influer sur la consommation de mémoire vive.
    • Installation du serveur simple, de la même manière que Spigot, SpongeVanilla ou Forge: lancer un jar.
    • Configuration simple depuis un fichier YAML, créé lors du premier lancement
    • Utilisation du langage Scala, parfaitement adapté à ce genre de systèmes.

    Pourquoi Scala ?

    J'ai choisi d'utiliser pour EnderChest le langage Scala pour EnderChest. Pouvez vous l'utiliser avec Java malgré tout ? Oui, mais je conseille cependant fortement de faire votre launcher, ou du moins d'utiliser cette lib en Scala car ce langage permet énormément de choses concernant la gestion de la concurrence et la clarté du code.

    Installation

    Pour l'installation du serveur, vous devez simplement télécharger dans l'onglet releases le server-xxxx-withDependencies.jar et le lancer. Un fichier de config documenté sera généré. Plus d'informations ici.

    Pour le client, vous pouvez installer la library de 2 manières différentes.

    En utilisant un build tool

    Le client d'EnderChest est disponible sur le Maven Central et indexé par Scaladex. Vous pouvez donc l'importer comme n'importe quelle lib avec votre build tool préféré:

    Avec Gradle:

    repositories {
      mavenCentral()
    }
    
    dependencies {
      implementation 'io.github.iltotore:ec-client_2.13:version'
    }
    

    Étant donné que le MDK utilise Gradle, je pense qu'il s'agit de la solution à laquelle le plus de monde est habitué ici.

    Avec SBT:

    libraryDependencies += "io.github.iltotore" %% "ec-client" % "version"
    

    En utilisant le jar.

    Rendez vous sur les releases Github et téléchargez le fichier client-xxx-withDependencies. Vous pouvez ensuite l'importer dans votre IDE comme n'importe quelle autre library.

    Noter que vous devrez probablement incorporer la library à votre jar final. Avec Gradle je vous recommande d'utiliser le plugin shadowJar.

    Les bases

    Créer un FileAnalyzer

    Commençons d'abord par créer une nouvelle instance de FileAnalyzer, qui servira à indexer les fichiers du client Minecraft:

    val rootPath = Paths.get("blabla") //À noter que vous pouvez également résoudre le Path par rapport à la localisation de votre jar, ou le dossier utilisateur.
    
    val analyzer = new FileAnalyzer(rootPath)
    

    Si vous voulez exclure des fichiers ou augmenter le max depth, précisez le/les comme ceci:

    val analyzer = new FileAnalyzer(
      rootPath, //Le chemin vers le dossier racine des téléchargements.
      exclude = _.startWith("shaderpacks/"), //Exclu tous les fichiers qui sont dans le dossier `shaderpacks`, à la racine des téléchargements.
      maxDepth = Option(100) //La profondeur de recherche maximale est maintenant de 100.
    ) //Remarque: vous pouvez également déclarer les paramètres sur une ligne.
    

    À noter que les fichiers exclus seront téléchargés si manquants mais ne seront pas modifiés/supprimés. Les fichiers inconnus ne seront pas non plus effacés si exclus.

    Instancier le client

    Maintenant que nous avons créé notre FileAnalyzer, nous pouvons maintenant créer notre EnderClient qui servira à mettre à jour le système. Nous allons utiliser la méthode apply, qui utilise certaines valeurs par défaut. Notons que Foo.apply() en Scala est la même chose que Foo().

    val  client = EnderChest("https://localhost:8080/" /*L'adresse vers le serveur d'update*/, analyzer)
    

    Vous maintenant prêt à utiliser les fonctionnalités du client !

    Indexer les fichiers

    La première chose à faire est d'indexer les fichiers déjà existants de notre client Minecraft:

    client.checkFiles()
    

    Cette méthode a la particularité de renvoyer un Future[Int], qui va indexer les fichiers en parallèle. Le paramètre générique Int est utilisé pour symboliser le nombre de fichiers indexés.

    Utilisons maintenant une fonctionnalité de Scala qui vient tout droit de la programmation fonctionnelle: le Pattern Matching.

    client.checkFiles.onComplete {
      case Success(count) => println(count + " fichiers ont été indexés.")
    
      case Failure(exception) => exception.printStacktrace().
    } //Les paranthèses de la méthode ne sont pas obligatoires.
    

    Une fois les fichiers analysés, nous pouvons lancer la requête de mise à jour (vous pouvez également indexer les fichiers avant au lieu de juste avant d'update). Nous allons simplement utiliser client.update() et la méthode flatMap des futures pour pouvoir lancer l'update dès que l'indexation est finie:

    client.checkFiles.flatMap(_ => client.update()).onComplete {
      case Success(done) => println("Mise à jour terminée !")
    
      case Failure(exception) => exception.printStacktrace()
    }
    

    Voilà, vous avez maintenant les bases nécessaire (si tant est que vous avez appris le Scala =p) pour pouvoir utiliser EnderChest.

    Voici quelques liens utiles:

    Le projet est open-source et gratuit sous licence Apache 2.0. Si vous avez des questions/remarques, faites-moi savoir !

    Et si le projet vous a été utile, libre à vous de mettre une star sur Github 🤠

    PS: Je suis surtout actif sur Github et Discord.



  • Petite update car je ne peux pas edit: utilisez mainenant la 1.1.1 ^^


  • Moddeurs confirmés

    Salut,
    C'est bien, ton projet à l'air propre et ça l'est vachement plus que le vieux S-Update de Litarvan et je t'en félicite👍.
    Mais je ne crois pas que c'est très intéressant pour Minecraft. Je m'explique :
    Si on utilise ton système, on se retrouve avec le même soucis rencontré avec s-update : la loi. Qui dit utilisation de ton système dis distribution de fichiers. Dis illégalité si les fichiers de Mojang se retrouvent dessus. Bien sur, les chances que Mojang nous prennent en flagrant délit en France sont très minces, mais c'est toujours mieux de rester légal. C'est pourquoi je ne recommanderai pas ce système pour la mise à jour de fichier d'un launcher Minecraft.
    Flow



  • @Flow-Arg Tu peux poster les fichiers que tu veux donc tu peux exclure ceux qui pausent problème. Ensuite, je ne crois pas que FlowUpdate supporte les fichiers custom (corrige moi si je me trompe) et sinon rien ne t'empêche de pull les fichiers de mojang et d'aller chercher le reste ailleurs. Il faut aussi parler du fait que Mojang et Microsoft laissent maintenant ce genre de pratique tout simplement car elle est plus bénéfique que néfaste pour leur business. Mojang n'est pas Nintendo (qui au passage on d'autres qualité) =p

    Et sinon je ne crois pas que les CGU de mc interdisent les fichiers de sauvegarde dans le sens où tous les utilisateurs du jeu ont ces fichiers sur leur machine. Techniquement, les gens qui veulent mettre le contenu du .minecraft en règle puisqu'il s'agit de partager ces fichiers que tous ceux qui ont payés le jeux peuvent avoir. Si ton launcher est premium, on tombe dans le même cas où tu filerais une map à un ami 😉

    Ceci dit, une personne m'a déjà parlé de ça par rapport à ton système, et il est vrai que la possibilité d'aller chercher les fichiers de Minecraft Vanilla directement chez Mojang peut être une option que les futures releases méritent. Après si ta lib est exclusivement pour télécharger les fichiers vanilla, les gens peuvent toujours utiliser FlowUpdate pour la partie vanilla (et je pourrais dans ce cas faire un p'tit wrapper avec l'EnderClient)


  • Moddeurs confirmés

    Merci pour la mention de FlowUpdater XDD 😂 (Comment t'a connu ça d'ailleurs 🤔)

    Blague à part,

    Tu peux poster les fichiers que tu veux donc tu peux exclure ceux qui pausent problème.

    C'est nice ça 👍.

    Il faut aussi parler du fait que Mojang et Microsoft laissent maintenant ce genre de pratique tout simplement car elle est plus bénéfique que néfaste pour leur business.

    Bien qu'ils passent un peu l'éponge, ça reste pas très légal.

    Et sinon je ne crois pas que les CGU de mc interdisent les fichiers de sauvegarde dans le sens où tous les utilisateurs du jeu ont ces fichiers sur leur machine.

    c'est à dire, tu parles des fichiers de config ? les maps ? les resourcespack ? les options ? Si c'est ça c'est ok bien sur.

    (et je pourrais dans ce cas faire un p'tit wrapper avec l'EnderClient)

    Comme bon te semble, tu es libre sur ce point là 😉.

    je ne crois pas que FlowUpdate supporte les fichiers custom [...] exclusivement pour télécharger les fichiers vanilla

    C'est prévu, et ça a déjà commencé avec la possibilité d'ajouter une version MCP, des mods etc... il ne reste plus que des fichiers supplémentaires pour ce point là.

    👏 👏 👏 pour ton travail et tes réponses constructives (c'est rare ^^').
    Bonne journée/soirée

    Flow



  • @Flow-Arg a dit dans EnderChest, un nouveau système de mise à jour. :

    Merci pour la mention de FlowUpdater XDD (Comment t'a connu ça d'ailleurs )

    Un ami en avait parlé et aussi un peu parce que j'ai lu ta signature 😂 (d'ailleurs merci le correcteur automatique de virer le r de FlowUpdater)

    c 'est à dire, tu parles des fichiers de config ? les maps ? les resourcespack ? les options ? Si c'est ça c'est ok bien sur.

    Oui je parle de ça 😉 d'ailleurs S-Update est souvent utilisé uniquement pour ces fichiers + le client modifié.

    Sur ce, let me finish the 1.2 qui résoudra 2 bugs mineurs et ajoutera l'API de progression.

    EDIT: Je viens de me rendre compte que l'ami qui m'en a parlé est marqué comme contributeur de FlowUpdater.



  • Comme mff empêche toujours d'edit son post après 1 heure, voici sur une nouvelle réponse l'annonce de l'arrivée de la 1.2 qui va sortir dans la semaine, intégrant l'API de Progression. Il s'agit de pouvoir exécuter une action lorsqu'un fichier est téléchargé/supprimer ou quand une quantité d'octets est reçue.

    Cette feature est accessible sous forme de paramètres optionnels de EnderClient#update mais: les paramètres sont implicites, ce qui signifie que nous pouvons simplement déclarer les variables au dessus pour plus de lisibilité !

    implicit val onFileDownload: FileDownloadAction = file => println("Downloading " + file.getName)
    implicit val onFileDeletion: FileDeleteAction = file => println("Deleting " + file.getName)
    implicit val onBytesDownload: ByteDownloadAction = (downloaded, max) => println(s"Downloaded ${downloaded.doubleValue/max}%")
    
    ...
    
    client.update()
    

    Notons que les actions custom déclarées ci-dessus doivent être visibles lorsque vous appelez EnderClient#update.

    Bonne journée 😛