0

I want to build an Minecraft Webinterface using a NodeJs backend server which communicates with a Bash Shell Script on Debian 9.

1: I create a new Minecraft Server using screen -S server_name java -jar minecraft_server.jar

2: The NodeJs Backend sends a command to my Shell File, which works fine: e.g. screen -rd server_name -X stuff "whitelist add $3^M"

3: A String with the list of players will be put out in the server screen.

But my question is, how can I read this put out String and let the NodeJs Backend read it?

My NodeJs Backend: https://hastebin.com/adosiwiqiq.coffeescript

My Shell Script: https://hastebin.com/acijegupud.bash

  • The point of screen is to run commands detached. So you are sending the command to a detached session, you can't really interact with it. You could attach to it and run the command and then detach again. I'd have to test if and how that would work. A better solution may be to run the server in a Child Process of the node server and keep a pipe to it. Then you can interact better interact with it. A dodgy solution may be tee-ing/redirecting the output to a logfile and then reading it. (But that wouldn't be great as you have to keep track of where exactly the desired output starts). Do you – rudib Sep 24 '19 at 13:34
  • intend running multiple (mc)servers or just one? – rudib Sep 24 '19 at 13:35
0

I don't think this is possible in screen. You can use a fifo to get the output of a command in screen, but I doubt that the 'minecraft shell' will support that.

However this is 'doable' with tmux.

Process Status/Stack Trace

Stack Trace

To make it work properly, you'd have to detect at which point the program you are feeding commands is stuck at a relevant IO Operation. A way to do that would be running a stack trace and looking for that. Also see: How do I tell if a command is running or waiting for user input?.

That may be a bit tricky because it may be temporarily stuck at at another read before the desired one. It may also have to involve some guessing based on how long it is stuck and at which file descriptor. It could be combined with the line-counting proposal below for more accuracy.

Edit While testing this, I encountered read(10, (zsh) and select(1, [0], NULL, NULL, NULL (python3 cli interpreter). There may be few other possibilities, which is why I didn't limit the RegEx in the script below to just that. It is just looking for an open parenthesis now. Maybe someone knows a more precise way to do this?

Process Status A good indicator might be to check if the process is running or sleeping. You can do this with ps. This method is used in the proof-of-concept script below, in combination with the stack trace.

Counting Lines

Having the Server running as a Child Process in Node enables you to interact with the stdin and stdout of the process in Node. You could just look for newlines (\n) and if you know how many lines the output should have, you can count them and 'know' that it has finished running and is waiting for input again. You could combine it with a timeout.


Proof of Concept with Process Status/Strace

I moved the script and some docmentation to a github repository. I haven't tested this with mc, but it worked with python3 and zsh (As far I could test it, see section "Tests"). It's still not perfect as it still involves some waiting and may or may not get false positives.

How to use

You can start the server/tmux session like that:

tmux new-session -d -s server_name "java -jar minecraft_server.jar"

Sending a command to the server would look like that:

./trun.sh -s server_name -c "the command"

It should return the output of the server. You may have to adjust the -H and -T parameters.


Synchronicity

Beware that if you run this on a webserver, you can run into problems, especially if there are multiple users. You might have to implement a Lock to prevent multiple users accessing the shell at the same time. I'm sure that tmux itself wouldn't have a problem with that, but you can't really predict the ouput if another command may have been run while you try to read said output.

Security

If you intend to run this on a server exposed to the www, consider securing it (for example by using a password protected proxy via apache or nginx).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.