2

This question was deleted when I was just about to answer it with some relevant information. I thought that, although it was phrased in a way which made people dislike it, and no code was posted, it was a useful question. As such, I decided to post it here, along with my partial answer. The current code I have has a problem with it, if anyone knows a solution I would be glad to hear it. Also, if anyone knows a cleaner solution (e.g. using the communicate method of Popen objects), that would be good too.

As I remember it, the relevant part of the question was this:

How can I use Python to communicate with a Minecraft server? I have a user interface set up, but I am unsure how I can connect to the server and send commands through to it.

rlms
  • 10,650
  • 8
  • 44
  • 61

3 Answers3

1

Here is the code I'm using, I edited rlms' code a little bit to fix the readline problem:

import os, sys, time
import subprocess

server = subprocess.Popen('./start.sh',stdin=subprocess.PIPE,shell=True)
content = ''
previousContent = ''
while True:
#you can add a time.sleep() to reduce lag   
f = open('logs/latest.log')
    content = f.read()
    if previousContent in content:
        content.replace(previousContent,'')
        if content != '':
            print(content)

    command = input('')
    if command:
        server.stdin.write(bytes(command + '\r\n', 'ascii'))
        server.stdin.flush()
   previousContent = f.read()
Samuelzila
  • 117
  • 4
1

https://github.com/Fallen-Breath/MCDReforged

MCDReforged (abbreviated as MCDR) is a tool which provides the management ability of the Minecraft server using custom plugin system. It doesn't need to modify or mod the original Minecraft server at all

qreodium
  • 33
  • 6
0

Here is my current solution to this problem. It allows communication with the server easily, but has the problem of hanging on calls to readline when there are no more lines to read. If anyone knows how to solve this, I would be grateful for them telling me.:

from subprocess import Popen, PIPE, STDOUT
server = Popen("java -jar minecraft_server.1.7.4.jar nogui", stdin=PIPE, stdout=PIPE, stderr=STDOUT)
while True:
    print(server.stdout.readline())
    server.stdout.flush()
    command = input("> ")
    if command:
        server.stdin.write(bytes(command + "\r\n", "ascii"))
        server.stdin.flush()

Please note that for this code to work as is, the script must be in the same directory as the server.

rlms
  • 10,650
  • 8
  • 44
  • 61
  • Wouldn't you need use threads or something similar to continue without having to wait on readline? I don't have a solution to that question, but maybe that's worth asking here. – TankorSmash Jan 02 '14 at 22:14
  • @TankorSmash I think you might be able to use `select` on linux, but I'm not sure about on windows, where it is apparently dodgy with regards to file-like objects (although it works fine with sockets). Threading would also be an option, but by instinct is that that would be overkill. If there was a solution using `communicate`, then that could use the `timeout` argument, removing the problem. Or possibly waiting for the `asyncio` module in Python 3.4! – rlms Jan 02 '14 at 22:34
  • 1
    I know this is old but the best solution is just to read directly from latest.log as it updates, compare the previously read object with the newly read object and just print the difference. – Dan Alexander Feb 20 '18 at 03:29
  • Bit late, but you could move that while loop inside a thread. – Anteino Nov 26 '21 at 13:34