Запустить скрипт для отправки внутриигровых команд сервера Terraria - PullRequest
1 голос
/ 21 апреля 2020

На прошлой неделе я установил сервер Terraria 1.3.5.3 в ОС Ubuntu v18.04 для игры в сети с друзьями. Этот сервер должен быть включен 24/7 без каких-либо GUI, доступ к нему осуществлялся только S SH во внутренней локальной сети.

Мои друзья спрашивают меня, есть ли у них способ управления сервером, Например, отправьте сообщение через внутренний игровой чат, поэтому я подумал, что нужно использовать специальный символ ($) перед желаемой командой (например, «$ say what» или «$ 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)

останавливает команду в символе пробела, ou tput это на терминале:

: say

Вместо желаемого:

: say something
<Server>something

Что я могу сделать, чтобы решить эту проблему? Я столько всего перепробовал, но получаю тот же результат.

PS Если я посылаю команду вручную в терминале замазки s sh, она работает!

Редактировать 1:

Я отказался от решения python, сейчас я попробую его с bash вместо этого, похоже, больше логики c для этого.

Редактировать 2:

Я обнаружил, что скрипт «terrariad» ожидает только один аргумент, но 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, я мог бы понять, что происходит, когда я посылаю команду ... Обычно она использует команду "stuff" из экранной программы для отправки символов на сеанс экрана terraria:

screen -S terraria -X stuff $send

$ send is printf команда:

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

И мне кажется, что если я запускаю файл bash из Python, он будет иметь другой результат, чем запуск из командной строки. Как это возможно? Это ошибка или плохая реализация функции?

Спасибо!

1 Ответ

0 голосов
/ 03 мая 2020

Я наконец-то пришел к решению этой проблемы, используя каналы вместо решения Popen.

Мне кажется, что Popen - не лучшее решение для запуска bash сценариев, как описано в Как сделать несколько аргументов с Python Popen? , ссылка, которую SiHa отправляет в комментариях (Спасибо!):

"Однако использование Python в качестве оболочки для многих системных команд не очень хорошая идея. По крайней мере, вы должны разбивать свои команды на отдельные Popens, чтобы ненулевые выходы могли быть обработаны адекватно. В действительности, этот сценарий кажется, что он будет намного лучше подходить в качестве оболочки script. ".

Итак, я пришел с решением, используя файл fifo:

Сначала создайте fifo для использования в качестве канала в нужном каталоге (например, / samba). / terraria / config):

mkfifo cmdOutput

* / samba / terraria - это каталог, который я создаю, чтобы легко редактировать сценарии, сохранять и загружать карты на сервер с помощью другого компьютера, который используется совместно с самба (https://linuxize.com/post/how-to-install-and-configure-samba-on-ubuntu-18-04/* 1 016 *)

Затем я создаю сценарий 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 / terraria / scripts / allowCommands.py - где мой сценарий.

** / samba / terraria / config / errorLog.txt - сохранить журнал ошибок в файле.

Теперь я могу отправлять команды, такие как «полдень» или «рассвет» так что я могу изменить игровое время, сохранить мир и сделать его резервную копию с помощью сервера samba перед боем с боссом, сделать что-нибудь еще, если у меня будет какое-то время XD, и заставить терминал показывать, что происходит с сервером.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...