Un autowalker DayZ en Java : décompiler, patcher en AZERTY, forker après
À l’époque de DayZ, je voulais un autowalker, ce petit utilitaire qui tient la touche d’avance pour toi pendant que ton personnage traverse une carte immense. Il en existait un, en Java, mais sans sources publiées et il était pensé pour un clavier QWERTY. Moi je joue en AZERTY, donc il avançait de travers et je voulais aussi qu’il gère proprement l’état de course plutôt que de bourriner une touche. Je ne me suis pas posé de question : je l’ai décompilé.
JavaDecompiler ou “compilé” ne veut pas dire “fermé”
Un .jar, c’est du bytecode et le bytecode Java se décompile presque jusqu’à la source d’origine.
Un passage dans JavaDecompiler
(JD, l’outil de l’époque) et je récupérais un code lisible, noms de méthodes compris, prêt à repatcher.
C’est la vraie leçon de l’histoire, la même que je ressasse ailleurs : livrer un binaire n’est pas livrer un secret, c’est livrer la source avec une étape en plus et confondre les deux est un pari (la sécurité par l’obscurité n’en est pas
).
Distribuer un autowalker en .jar “compilé”, c’était distribuer son code, point.
Ce que la bestiole faisait vraiment
En relisant le source, le montage est honnête pour l’usage :
- un hook clavier global via JNativeHook, pour capter une touche même quand le jeu a le focus ;
- un garde-fou de contexte via JNA sur
user32,GetForegroundWindowpuisGetWindowTextA, pour ne déclencher que si le titre de la fenêtre au premier plan contientDayZet rester inerte partout ailleurs ; - et un
java.awt.Robotqui fait lekeyPresspuis lekeyReleasede la touche de déplacement, piloté par un booléen d’état, un appui pour lancer l’avance, un autre pour l’arrêter.
Mes patchs, côté AZERTY
C’est là que mon fork diverge de l’original.
La touche d’avance tenue par le Robot devient walkKey = 90, soit la touche Z, l’avant du ZQSD en AZERTY, là où le QWERTY d’origine poussait un W.
J’ai ajouté la gestion séparée de la course, deux états distincts, marche et sprint, chacun son toggle et son keyPress/keyRelease, pour ne plus laisser une touche coincée.
Et j’ai refait l’interface en français, jusqu’au bouton Status: Actif qui passe au rouge Inactif, avec mon vieux domaine autowalker.vhalholl.info en dur dans le label de crédit, détail qui date la chose mieux qu’une signature.
Décompiler d’abord, forker ensuite
La fin de l’histoire est la plus bête et la plus instructive. Après avoir patché ma copie décompilée dans mon coin, j’ai fini par trouver la source d’origine publiée sur GitHub, celle de feonx , alors je l’ai forkée et j’ai poussé mes modifications par-dessus (mon fork ). Autrement dit, j’avais commencé par le pire chemin, un blob décompilé patché à la main sans histoire, avant de revenir au bon, un fork versionné d’une vraie source. C’est exactement l’anti-patron que je moque ailleurs, le code sans dépôt qui ne survit pas au poste qui l’a écrit, sauf que cette fois le coupable c’était moi et que la morale tient en une ligne : décompile si tu veux, mais finis toujours dans un dépôt.