lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I just used lpty http://tset.de/lpty/index.html for controlling a process as if in a separate terminal window in linux. It was quite easy and extremely useful.

Milind

On Wed, Sep 12, 2018, 10:33 PM Russell Haley <russ.haley@gmail.com> wrote:


On Wed, Sep 12, 2018 at 2:17 PM Sean Conner <sean@conman.org> wrote:
It was thus said that the Great Russell Haley once stated:
> Hello,
>
> Some months back I started running a Minecraft server (Java) on FreeBSD.
> There are two issues that I've run into:
> 1) The Minecraft client (game) automatically updates and will not run
> against servers of prior revisions without changing client settings.
> 2) The Minecraft 'server' jar uses stdin and stdout. That means (in my
> understanding) that the process must be kept in the foreground for
> interaction. The current solution I've found (on the Minecraft wiki)
> requires screen/tmux to allow one to run a server instance from ssh.

  No, you can run the process as:

  GenericUnixPrompt> java -jar BlahObjectThing </dev/null >/dev/null 2>/dev/null &

That will run your server in the background with stdin, stdout and stderr
all pointing to /dev/null (the bit bucket).  

> The solution I now envision is to use lua-http and cqueues to create a
> 'controller' that updates the server.jar file and runs the application
> without the need for the process to be in the foreground. The parts I see
> needing are:
> - A routine that checks for updates and downloads the jar files
> - A 'thread' for running the minecraft server.jar file in java. This
> 'thread' would re-direct stdin and stdout. This 'thread' should also be
> able to stop and start the running jar file.
> - A websocket server to funnel the captured IO to a webpage for
> interactivity.

  Avoid system level threads for this.  Mixing system level threads
(pthreads) and running another process (via fork()) do not mix [1].  So
you'll end up with Lua coroutines and a sepearate process.  Let's handle
that first.

        function start_minecraft()
          local pid,err = fork()

          if pid then
            if pid == 0 then -- child process
            redirect(stdin,"/dev/null") -- or a file or a pipe
            redirect(stdout,"/dev/null")
            redirect(stderr,"/dev/null")
            exec("java",{ "-jar" , "minecraft.jar" })
            _exit(1) -- exec() failed, we exit
          end

          -- mindcraft has PID of child
          -- it is running, and so are we.

          return pid,err
        end

  stdin, stdout and stderr can be redirected to a file, a pipe, a named
pipe, what have you.  I'm justing using "/dev/null" as an example for now.
You could use a file that you serve up through HTTP to see what happens; a
pipe to get the last N bytes of logging, etc.  That's up to you.

  I should note that the functions fork(), redirect(), exec() and _exit()
need to be adjusted to whatever module you use that provides such calls
(redirect() may be called dup() or dup2() or something like that).

  The main process (as I would do it) would then use coroutines (or Lua
threads) to handle things.  One coroutine to periodically check for an
updated jar file, and if so:

        while true do
          info = stat("myjarfile.jar")
          if info.st_mtime ~= original.st_mtime then
            raise(minecraft_pid,SIG_TERM)
            status = wait(minecraft_pid)
            minecraft_pid = start_minecraft()
            original.st_mtime = info.st_mtime
          end
          wait_for(some_amount_of_time)
        end

Thanks Conman! 
 
> So far, I have roughed in the server.jar checks and download, and the
> websocket server for communications. The code can be found here:
> https://github.com/RussellHaley/minecraft-runner/mc-runner.lua
>
> What I don't know/understand yet if it's possible to run/control a process
> from Lua so that I can grab stdin/stdout? I am hoping there is something in
> cqueues to do this, but once again thought I'd send out a general request
> for ideas.
>
> Any input would be grand.

  You need something that handles networking, coroutines and some POSIX
functions (fork(), wait(), etc). 

  -spc

[1]     It probably *can* be done, but it's certainly above my pay grade,
        and I write servers for a living.