IO Noyau Interface - medrimonia/PFA-Nethack GitHub Wiki

La communication avec le jeu peut prendre deux approches différentes :

  • Se brancher sur l'entrée et la sortie standard et interpréter les chaînes de caractères reçues.
  • La création d'un nouveau code intégré au jeu entre le noyau et l'affichage pour récupérer l'information.

Redirection des entrée/sortie du jeu

En essayant de capturer la sortie du jeu et de soumettre des commandes à l'aide d'un système de fifos, NetHack a le comportement suivant:

NetHack (gettty): Inappropriate ioctl for device
NetHack (settty): Inappropriate ioctl for device
You must play from a terminal.

En étudiant les quelques lignes de code responsables, il semblerait que ce soit une mesure pour empêcher une certaine forme de tricherie. La portion du code en cause peut facilement être désactivée mais les possibles conséquences sur le reste du fonctionnement du jeu sont inconnues.

Une solution consiste à 'tromper' le jeu en créant un pseudo-terminal contrôlé par un programme - voir PTY(7).

Infos supplémentaires : http://rachid.koucha.free.fr/tech_corner/pty_pdip.html

Parser

En jouant dans un terminal, le jeu indique où afficher quoi à l'aide de séquences d’échappement suivant la norme ANSI. Le "protocole" est implémenté dans dans win/tty/termcap.c. Voir : https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_code

Le parser créé un pseudo-terminal pour interagir avec le jeu. Cela permet de récupérer deux descripteur de fichier. L'étude de win/tty/termcap.c permet de créer un parser sachant décoder les chaînes de caractères envoyées au pseudo-terminal et ainsi de reconstruire l'état de la partie portée à connaissance d'un joueur ne trichant pas.

Et la portabilité ?

Les pseudo-terminaux sont supportés par (presque) tous les systèmes UNIX et les séquences d'échappement sont normalisés (partie de la norme ANSI). Windows ne supporte pas, à notre connaissance, cette fonctionnalité.

Nouvelle interface en utilisant winprocs.h

Une solution suggérée par le client était de définir une nouvelle interface en s'inspirant du code existant dans le répertoire win/. On y trouve le code permettant d'interagir avec le jeu via un terminal ou diverses interfaces graphiques. Le fichier include/winprocs.h recense les fonctions qui doivent être présentes dans chaque méthode d'affichage : il s'agit d'une interface.

Le noyau fait appel à ces fonctions pour mettre à jour l'affichage en passant des chaînes de caractères (win_putstr par exemple) sans communiquer la représentation interne des éléments du jeu. En somme, cette façon de faire permet de court-circuiter l'interprétation des caractères d'échappement de la méthode du parser mais ne permet pas de s'affranchir de la reconstruction manuelle des éléments du jeu dans l'interface (ex: structure WinDesc include/wintty.h). Développer une telle interface a le désavantage de ne pas permettre l'interaction de nos bots avec un jeu non modifié.

Conclusion

La solution du parser a été retenue pour permettre aux bots de jouer avec une version non modifiée du jeu (utile pour jouer sur un serveur faisant tourner la version officielle) et minimiser les changements apportées au code original.