python - 使用子进程控制 Minecraft 服务器
问题描述
我在我的 PC 上为朋友运行了一些经过改装的 Minecraft 服务器,我正在尝试构建一个程序,使启动它们并向它们发送命令变得更加容易。
我使用 bat 文件启动服务器并且能够subprocess
做到这一点没有问题,但我不确定如何着手添加通过控制台向服务器发出命令的功能。
我考虑过stdin.write()
在交互式控制台中使用它,它的效果很好。问题是当我将它添加到代码中时,它甚至在服务器启动之前执行停止命令,因此服务器永远不会停止。我曾尝试在单独的函数中执行此操作,但这也不起作用。
到目前为止,这是我的代码:
类文件:
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()
解决方案
有两个问题,我觉得:
stop_server
并且command
每个都启动一个新的子流程,这应该只在start_server
.start_server
使用server.communicate()
which 阻塞直到子进程完成,防止程序在运行时向服务器发送任何其他命令。
反而,
start_server
应该创建子进程,然后将其存储在可以通过stop_server
and访问的变量中command
,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')
推荐阅读
- dictionary - Deferencing 类型映射
- android-studio - Android Studio 3.5.1 中的软包装编辑器
- react-native - 是否可以自定义 react-native-media-controls 样式?
- tastypie - 如何使用一个 URI 获取多个资源?
- c# - Crystal Reports - 连接到另一个项目中的数据源
- ibm-watson - IBM watson 助手:将 IBM watson 聊天机器人与 android API 17 集成
- python-3.x - django-restframework 中的图像上传 crud 操作
- amazon-web-services - 如何使用一个 ansible 命令重置多个 AWS 帐户的 IAM 用户密码
- android - CollapsingToolbarLayout 过度滚动并卡住
- c# - 如何将列表从方法传递到另一个方法