6

I'm just starting an AI bot for the game nethack, and I can't bypass the 'human-check' that's in source. The section of code I'm talking about is nethack/sys/unix/unixunix.c:

#ifdef TTY_GRAPHICS
    /* idea from rpick%ucqais@uccba.uc.edu
     * prevent automated rerolling of characters
     * test input (fd0) so that tee'ing output to get a screen dump still
     * works
     * also incidentally prevents development of any hack-o-matic programs
     */
    /* added check for window-system type -dlc */
    if (!strcmp(windowprocs.name, "tty"))
        if (!isatty(0))
        error("You must play from a terminal.");
#endif

I'm working in JavaScript, (more specifically Node.js), and due to the above, it won't let me play from the program, even though I'm spawning a bash shell child process and telling it to start nethack. I need to figure out a way to bypass the above without recompiling the source.

The current code I'm using is:

"use strict";

var env = { TERM: 'tty' };
for (var k in process.env) {
    env[k] = process.env[k];
}

var terminal = require('child_process').spawn('bash', [], {
    env: env,
});

terminal.stdout.on('data', function (data) {
    console.log('stdout: ' + data);
});

terminal.on('exit', function (code) {
        console.log('child process exited with code ' + code);
});

setTimeout(function() {
    terminal.stdin.write('nethack');
    terminal.stdin.end();
}, 1000);

The output of the program is:

stdout: You must play from a terminal.

child process exited with code 1

What Node.js/JavaScript (and not any other language or framework, if possible) black magic could I use to solve this problem?

chrisdotcode
  • 1,569
  • 2
  • 17
  • 22
  • 1
    I'm not sure about this, you might want to look into node's [TTY module](http://nodejs.org/api/tty.html). Also, [this thread](http://groups.google.com/group/nodejs/browse_thread/thread/6fd25d16b250aa7d) might be of interest. – Linus Thiel Mar 22 '12 at 11:16
  • Yeah, I've checked out the TTY module: it seems that v0.6+ deprecate the `tty.open()` method, which may be something that I may want, but that method uses a deprecated `process.binding('stdio')` call, which I can't find any documentation on. I'll check out the thread though. Thanks. – chrisdotcode Mar 22 '12 at 16:02
  • Curious how this turned out for you? I'm also looking to get started doing something with NetHack and JavaScript. – Jay Apr 21 '20 at 13:46
  • @Jay While this *was* several years ago, I unfortunately didn't make any progress before I abandoned the concept. What I would do now would likely be to compile nethack from source removing that line or fake a TTY from node somehow. Node may or may not have such capabilities built in at this point, but honestly compile nethack from source seems like a good solution if you want to just hack locally. – chrisdotcode Jul 21 '20 at 11:32

1 Answers1

3

That's kind of a lame check because ptys will return true in isatty(). Pty stands for Pseudo terminal which allows a program to pretend to be a terminal. This is how Xterm and Screen work. If that check didn't allow those programs through you wouldn't be able to play NetHack in them.

I've never used it but pty.js binds to exactly what you would use in C code and the interface makes sense.

Jeffery Grajkowski
  • 3,982
  • 20
  • 23