Compiler son mod
-
Ce tutoriel est également disponible en vidéo.
Sommaire
- Introduction
- Pré-requis
- Compiler avec gradle
- Générer un jar pour le développement
- Obfusquer son mod
- En vidéo
- Crédits
Introduction
Vous avez maintenant un mod bien complet, cependant seul vous êtes capable de l’utiliser depuis Eclipse. Votre mod est prêt pour une beta public voir pour une version stable ou pour votre serveur. Il faut le compiler afin d’avoir un .jar que nous allons placer dans le dossier mods. Heureusement avec Forge Gradle cette opération se fait en une commande (bien plus simple qu’avant où il fallait faire le zip/jar manuellement, ajouter les ressources, etc …). Pour que ce tutoriel ne soit pas trop court nous allons aussi voir quelques modifications possibles dans le build.gradle.
Pré-requis
- Un espace de travail Forge Gradle
- Un mod prêt pour une release ou une pre-release
Compiler son mod avec Gradle
Comme dit dans l’introduction, il n’y a rien de plus simple. Dans un premier temps rendez-vous dans une console ouverte dans le dossier de Forge. La manipulation a déjà été vu dans le tutoriel sur l’installation de l’espace de travail de Forge. Pour ce qui aurait oublié, sous Windows il faut appuyer sur la touche shift puis faire un clic droit dans le dossier.
Ouvrir une fenêtre de commande ici
apparaîtra dans la liste. Cliquez dessus, une invite de commande va s’ouvrir avec le chemin du dossier de Forge écrit. Sous Linux la plupart des distributions intègre de base un menuOuvrir un terminal ici
lorsqu’on fait un clic droit dans un dossier. Pour les distributions n’intégrant pas ce menu ou pour OS X, ouvrez normalement un terminal puis tapez cd suivis du chemin du dossier (glisser déposer le dossier met automatiquement le chemin du dossier dans le terminal). Sous Mac OS X il semblerai que depuis la version 10.9 en faisant un clic droit dans un dossier une option pour ouvrir un terminal dans le dossier actuel se trouve dans le menu service (à confirmer, je n’ai pas de Mac).Dans la console tapez simplement la commande suivant :
Windows :gradlew build
Linux & Mac OS X :
./gradlew build
Une fois le build terminé le fichier jar se trouvera dans le dossier forge/build/libs et par défaut sera nommé modid-1.0.jar. Le nom ainsi que la version peuvent être changé dans le fichier build.gradle (“archivesBaseName” est le nom et “version” est la version).
Générer un jar pour le développement
Si votre mod contient un api pour ajouter du contenu à votre mod (exemple l’api d’IndustrialCraft2 permet d’ajouter des recettes aux différentes machines de ce mod, celui de buildcraft permet d’ajouter des machines qui se connectent aux tuyaux, etc …), ou bien que votre mod est une bibliothèque contenant un certain nombre de fonctions utilitaires (exemple FFMT libs, codechicken core / code chicken libs), mettre à disposition des autres développeurs une archive pour le développement (donc une version du mod faite pour fonctionner sur Eclipse) leur sera très utile.
En effet Minecraft étant obfusqué, le jar conçu pour fonctionner avec le jeu n’est pas compatible avec un environnement de développement.
Pour cela rendez-vous dans le fichier build.gradle et ajoutez ceci (en dessous de processResources) :task devJar(type: Jar) { from(sourceSets.main.output) { include '**' } classifier = 'dev' }
Si vous souhaitez que votre jar de dev contienne aussi les sources du mod, ajoutez entre l’accolade de la task et le from :
from(sourceSets.main.allSource) { include 'nomDeVotrePackage/**/**' }
Ce qui donne :
task devJar(type: Jar) { from(sourceSets.main.allSource) { include 'nomDeVotrePackage/**/**' } from(sourceSets.main.output) { include '**' } classifier = 'dev' }
Pensez bien à remplacer nomDeVotrePackage par ce qui correspond.
Pour finir à la fin du fichier ajoutez ceci :build.dependsOn devJar artifacts { archives devJar }
Maintenant lorsque vous aller faire la commande gradlew build vous aurez un second fichier dans le dossier buil/libs/ qui aura en plus dans son nom : “dev”.
Obfusquer son mod
Lorsque vous compilez votre mod celui-ci se retrouve à moitié obfusqué afin d’être compatible avec Minecraft (qui est de base obfusqué). Si vous utilisez un logiciel comme JD-gui (logiciel permettant de décompiler un fichier java) vous pourrez constaté que toutes les fonctions et les fields de Minecraft que vous utilisez dans votre mod sont renommés en func_xxxx et field_xxxx. Cela protège un peu votre mod des potentielles personnes cherchant à voler votre mod, cependant c’est loin d’être incontournable. Au contraire avec de la patience et la liste des mappings de mcp il est facile d’avoir un code utilisable sur Eclipse.
Pour protéger un peu plus votre mod je vous propose d’obfusquer une seconde fois votre mod. Cependant gardez à l’esprit qu’avec même beaucoup de patiente on pourra toujours décompiler votre mod. En effet Java est un langage qui est très facilement décompilable. Le but de cette partie va être d’obfusquer les variables propres à votre mod.
Ajoutez à la fin du fichier build.gradle ceci :task obfJar(type: proguard.gradle.ProGuardTask, dependsOn: reobf) { inputs.file jar.archivePath ext { outDir = file("${buildDir}/proguard") obfuscatedJar = "${outDir}/${jar.baseName}-${jar.version}.jar" } outDir.mkdirs() injars jar.archivePath outjars obfuscatedJar libraryjars configurations.compile configuration 'proguard.pro' } task obfOutput(type: Jar, dependsOn: obfJar) { appendix = 'obf' from zipTree(obfJar.obfuscatedJar) } artifacts { archives obfOutput } build.dependsOn obfJar, obfOutput
Au début du build.gradle, dans buildscript{ […] dependencies{, en dessous de la ligne :
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
Ajoutez :
classpath 'net.sf.proguard:proguard-gradle:5.2.1'
Maintenant dans le dossier de votre projet créez un fichier nommé proguard.pro. Ouvrez-le avec un éditeur de texte puis ajoutez ceci dedans :
-libraryjars <java.home>/lib/rt.jar -dontoptimize -dontpreverify -dontwarn ** -keepattributes *Annotation* -keep public class fr.minecraftforgefrance.tutoriel.** { public protected <methods>; } -keepclassmembers !public class fr.minecraftforgefrance.tutoriel.** { public protected <methods>; } -keep public class net.minecraft.** { *; } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
Remplacez bien le package fr.minecraftforgefrance.tutoriel par le votre ! Pour plus d’information sur ce fichier rendez-vous ici.
Maintenant lancez la commande gradlew build, dans le dossier build/libs vous devrez retrouvez deux fichiers jar, dont un avec -obf dans son nom.
Voila une petite comparaison de la classe principale décompilé avec jd-gui :
Comme vous pouvez le voir le code est bien plus difficile à comprendre sur le fichier de droite (donc celui obfusqué).En vidéo
https://www.youtube.com/watch?v=oa2ZK3x6E60
Crédits
*Rédaction :
Correction :
Ce tutoriel de Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International -
Bonjour, est il possible de desobfuscer un mods après avoir perdu la source ?
Cordialement -
Oui, regarde le BON2 (bearded octo nemesis) : https://github.com/Parker8283/BON2
Attention : ton mod sera juste dé-obfusqué, ce qui veut dire que même une fois décompilé, les sources ne seront pas exactement les mêmes.
-
Bonjour, quand je fais gradlew build, une erreur est mise:
FAILURE: Build failed with an exception.
*What went wrong:
Execution failed for task ‘:reobf’MALFORMED
*Try:
Run with –stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.Build FAILED
Vous pouvez m’aider ?
-
Salut,
Tu as surement des accents dans le nom des tes fichiers de textures voire pire dans le nom de tes classes.
Ce n’est pas bon du tout.
Seuls les caractères de A à Z, de a à z, de 0 à 9, les tirets et les tirets du bas doivent être utilisé. -
Bonjour/bonsoir, j’ai une erreur pour l’étape obfOutput : http://prntscr.com/cthcwq
Si vous pouviez m’aider, merci !
-
les espaces et les ? dans le nom de la texture ce n’est pas du tout une bonne idée.
-
@‘robin4002’:
les espaces et les ? dans le nom de la texture ce n’est pas du tout une bonne idée.
Yep enfaite j’ai réussi ::p c’était le nom des textures qui étaient bug j’avais pas vu :')
Mais j’ai encore un problème mais au lancement du mod obfusqué.
http://prntscr.com/cthvzt -
Visiblement le byte code est corrompu.
Je peux voir ton fichier proguard.pro ? -
@‘robin4002’:
Visiblement le byte code est corrompu.
Je peux voir ton fichier proguard.pro ?Le voici :
-libraryjars 'C:\Program Files\Java\jre1.8.0_101\lib\rt.jar' -dontoptimize -overloadaggressively -useuniqueclassmembernames -keepattributes *Annotation* -adaptclassstrings -dontpreverify -dontwarn ** -keep public class proxy.** { public protected <methods>; } -keep public class api.** { public protected <methods>; } -keepclassmembers !public class proxy.** { public protected <methods>; } -keepclassmembers !public class api.** { public protected <methods>; } -keep public class net.minecraft.** # Also keep - Enumerations. Keep the special static methods that are required in # enumeration classes. -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } ```</methods></methods></methods></methods>
-
Ajoutes :
-keep public class ta.classe.principale -
Toujours la même erreur
-
Je ne sais pas d’où ça vient alors
-
Tu peux teamviewer pour m’aider?
-
Désolé mais j’ai d’être priorité actuellement.
Je n’ai pas vraiment le temps pour faire du support au cas par cas à distance. -
J’ai réussi a réglé mon premier problème, mais j’ai ce problème maintenant :
http://prntscr.com/cttdxq -
La version non obfusqué fonctionne-t-elle ?
-
@‘robin4002’:
La version non obfusqué fonctionne-t-elle ?
oui elle fonctionne
-
Le problème est ici :
String apiPackage = data.getClassName().substring(0,data.getClassName().indexOf(“.package-info”));
data.getClassName().indexOf(“.package-info”) renvoies -1 (donc il n’a pas trouvé .package-info) en revanche je ne sais pas du tout à quoi cela correspond et donc je ne sais pas non plus comment corriger ça -
Moi ça me fait ça… Une idée ?