使用子进程控制Minecraft服务器

问题描述 投票:1回答:1

[我在PC上为朋友运行了许多模块化的Minecraft服务器,我正在尝试构建一个程序,以使其更容易启动并将命令发送给他们。

我使用bat文件启动服务器,并且能够获得subprocess没问题,但是我不确定如何通过控制台向服务器添加发布命令的功能。

我曾考虑过使用stdin.write(),并且在交互式控制台中效果很好。问题是,当我将其添加到代码中时,它甚至在服务器启动之前执行了stop命令,因此服务器永不停止。我已经尝试过在单独的函数中执行此操作,但这也不起作用。

到目前为止是我的代码:

类文件:

import subprocess

class Server:
    def __init__(self, server_start_bat, dir):
        self.server_start_bat = server_start_bat
        self.dir =dir


    def start_server(self):
        server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)
        server.communicate()


    def stop_server(self):
        server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)
        server.stdin.write('stop\n')


    def command(self, command):
        server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)
        self.command = command
        server.stdin.write(f'{self.command}\n')

简单的GUI,我通过它运行:

from tkinter import *

import Servers

server = Servers.Server('path\\to\\bat\\file\\batfile.bat', 'dir\\to\\run\\command\\in')

main = Tk()
main.title('Server Commander')
server_title = Label(main, text="server, hosted on port ")
server_title.pack()
server_start = Button(main, text='Start', command=server.start_server)
server_start.pack()
server_stop = Button(main, text='Stop', command=server.stop_server)
server_stop.pack()

main.mainloop()
python python-3.x subprocess
1个回答
1
投票

我认为有两个问题:

  1. [stop_servercommand各自启动一个新的子过程,只能在start_server中完成。

  2. [start_server使用server.communicate()阻塞该子进程,直到子进程完成,阻止程序在服务器运行时向服务器发送任何其他命令。

相反,

  • [start_server应该创建子过程,然后将其存储在可由stop_servercommand访问的变量中,
  • [server.communicate应该在stop_server中完成。

stop_server也是command的特例。

import subprocess

class Server:
    def __init__(self, server_start_bat, dir):
        self.server_start_bat = server_start_bat
        self.dir = dir

    def start_server(self):
        self.server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)

    def stop_server(self):
        self.command('stop')
        self.server.communicate()

    def command(self, command):
        self.server.stdin.write(f'{command}\n')
© www.soinside.com 2019 - 2024. All rights reserved.