运行用于发送ingame Terraria服务器命令的脚本

2024-06-12 01:33:01 发布

您现在位置:Python中文网/ 问答频道 /正文

在过去的一周里,我在UbuntuV18.04操作系统中安装了Terraria1.3.5.3服务器,用于与朋友在线玩。该服务器应全天候供电,没有任何GUI,只能通过内部LAN上的SSH访问

我的朋友问我他们是否有办法控制服务器,例如通过内部游戏聊天发送消息,所以我想在所需命令(例如,$say something或$save)前面使用一个特殊字符($)和一个python程序,该程序通过管道读取终端输出,解释该命令并使用bash命令将其发送回

我按照以下说明安装服务器:

https://www.linode.com/docs/game-servers/host-a-terraria-server-on-your-linode

并将我的路由器配置为将专用端口转发到terraria服务器

一切正常,但我确实很难让python通过上面链接中描述的“terrariad”bash脚本发送命令

以下是用于发送命令的python代码:

import subprocess

subprocess.Popen("terrariad save", shell=True)

这很好,但如果我尝试输入带空格的字符串:

import subprocess

subprocess.Popen("terrariad \"say something\"", shell=True)

它在空格字符中停止命令,在终端上输出:

: say

而不是期望的:

: say something
<Server>something

我能做些什么来解决这个问题? 我尝试了很多东西,但都得到了同样的结果

另外,如果我在ssh putty终端中手动发送命令,它就会工作

编辑1:

我放弃了python解决方案,现在我将用bash代替它,这样做似乎更符合逻辑

编辑2:

<>我发现“TrAlad”脚本只希望有一个参数,但是不管我使用的方法是什么,Popen都把我的论点分解成两个,因为我的输入字符串在中间有一个空间字符。像这样:

预期:

terrariad "say\ something"

$1 = "say something"

但我从python Popen那里得到了以下信息:

subprocess.Popen("terrariad \"say something\"", shell=True)

$1 = "say
$2 = something"

无论我如何尝试列出它:

subprocess.Popen(["terrariad", "say something"])

$1 = "say
$2 = something"

或者在空格字符之前使用\ quote,如果到达空格字符,则始终拆分变量

编辑3:

通过查看bash脚本,我可以理解在发送命令时发生了什么。。。基本上,它使用screen程序中的“stuff”命令向terraria screen会话发送字符:

screen -S terraria -X stuff $send

$send是一个printf命令:

send="`printf \"$*\r\"`"

在我看来,如果从Python运行bash文件,它的结果与从命令行运行的结果不同。这怎么可能?这是一个bug还是函数的错误实现

谢谢


Tags: 命令程序服务器脚本bash终端shell字符
1条回答
网友
1楼 · 发布于 2024-06-12 01:33:01

我终于想出了一个解决方案,用管道代替Popen解决方案

在我看来,Popen并不是运行bash脚本的最佳解决方案,正如SiHa在评论中发送的链接How to do multiple arguments with Python Popen?中所述(谢谢!):

“然而,使用Python作为许多系统命令的包装器并不是一个好主意。至少,您应该将命令分解为单独的popen,以便能够充分处理非零出口。实际上,这个脚本似乎更适合作为shell脚本。”

因此我提出了解决方案,使用fifo文件:

首先,在所需目录(例如,/samba/terria/config)中创建一个fifo用作管道:

mkfifo cmdOutput

*/samba/terraria-这是我创建的目录,以便使用另一台计算机轻松编辑脚本、保存并将映射加载到服务器,这些都与samba(https://linuxize.com/post/how-to-install-and-configure-samba-on-ubuntu-18-04/)共享

然后,我创建一个python脚本,从屏幕输出读取,然后写入管道文件(我知道,可能还有其他方法):

import shlex, os

outputFile = os.open("/samba/terraria/config/cmdOutput", os.O_WRONLY )


print("python script has started!")
while 1:
    line = input()
    print(line)
    cmdPosition = line.find("&")
    if( cmdPosition != -1 ):
        cmd = slice(cmdPosition+1,len(line))
        cmdText = line[cmd]
        os.write(outputFile, bytes( cmdText + "\r\r", 'utf-8'))
        os.write(outputFile, bytes("say Command executed!!!\r\r", 'utf-8'))

然后我编辑terraria.service文件以调用从terrariaServer通过管道传输的脚本,并将错误重定向到另一个文件:

ExecStart=/usr/bin/screen -dmS terraria /bin/bash -c "/opt/terraria/TerrariaServer.bin.x86_64 -config /samba/terraria/config/serverconfig.txt < /samba/terraria/config/cmdOutput 2>/samba/terraria/config/errorLog.txt | python3 /samba/terraria/scripts/allowCommands.py"

*/samba/terria/scripts/allowCommands.py-我的脚本所在的位置

***/samba/terria/config/errorLog.txt-将错误日志保存在文件中

现在我可以发送命令,比如“中午”或“黎明”,这样我就可以改变游戏时间,在老板打架之前保存世界并用samba服务器备份,如果我有时间做其他事情XD,并让终端显示服务器的运行情况

相关问题 更多 >