711 lines
28 KiB
Python
Executable File
711 lines
28 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
import os
|
||
import re
|
||
import struct
|
||
import shutil
|
||
import datetime
|
||
import subprocess
|
||
|
||
import yaml
|
||
import click
|
||
import colorama
|
||
|
||
from pathlib import Path
|
||
from rcon.source import Client
|
||
|
||
home_dir = Path.home()
|
||
|
||
|
||
def find_file(path):
|
||
"""Находим все конфиги в зависимости от пути"""
|
||
arr = next(os.walk(path), (None, None, []))[2] # [] if no file
|
||
x = arr.count('.directory')
|
||
y = arr.count('logs')
|
||
if x > 0:
|
||
arr.remove('.directory')
|
||
if y > 0:
|
||
arr.remove('logs')
|
||
return arr
|
||
|
||
|
||
dir_config = f"{home_dir}/.config/hlna/"
|
||
dir_maps_ark = f"{dir_config}/ARK/"
|
||
dir_deactivated = f"{dir_maps_ark}deactivated/"
|
||
list_config = find_file(dir_maps_ark)
|
||
delist_config = find_file(dir_deactivated)
|
||
|
||
|
||
def path_server():
|
||
dir_server = input(f"""Укажите путь до каталога, где будут храниться файлы сервера. По-умолчанию {home_dir}/Servers/
|
||
:""")
|
||
if dir_server == "":
|
||
dir_server = f"{home_dir}/Servers/"
|
||
yaml_create(game := "path_server", dir_server)
|
||
return dir_server
|
||
|
||
@click.group()
|
||
def hlna():
|
||
pass
|
||
|
||
|
||
def create_dir(directory):
|
||
"""Проверка и создание директории"""
|
||
if not os.path.exists(directory):
|
||
os.makedirs(directory)
|
||
|
||
|
||
def print_line(text):
|
||
"""Добавление тире вокруг текста, покраска"""
|
||
print(colorama.Fore.YELLOW + "-" * 30)
|
||
print(f"{colorama.Fore.GREEN} + {text}")
|
||
print(colorama.Fore.YELLOW + "-" * 30 + colorama.Style.RESET_ALL)
|
||
|
||
|
||
def check_int(number=""):
|
||
"""Проверка на ввод числа"""
|
||
while True:
|
||
try:
|
||
x = input(number)
|
||
if x == "":
|
||
return 0
|
||
x = int(x)
|
||
return x
|
||
except ValueError:
|
||
print_line("Введите число")
|
||
|
||
|
||
@hlna.command(help='Сбор настроек для сервера или кластера')
|
||
def config():
|
||
while True:
|
||
count_game = check_int("""Выберите игру для конфигурирования
|
||
1. ARK Survival Evolved
|
||
2. 7 Days to Die
|
||
: """)
|
||
if count_game == 1:
|
||
config_ark()
|
||
break
|
||
elif count_game == 2:
|
||
config_7daystodie()
|
||
break
|
||
else:
|
||
print_line("Пока есть только ARK и 7Days xD")
|
||
|
||
|
||
def config_ark(list_config=list_config):
|
||
create_dir(dir_server_ark)
|
||
create_dir(dir_maps_ark)
|
||
"""Сбор данных для конфига"""
|
||
data = {}
|
||
port_s = []
|
||
rcon_p = []
|
||
query_p = []
|
||
|
||
cluster_id = ""
|
||
cluster_dir_override = ""
|
||
|
||
count_cluster = check_int("""Укажите требуется ли кластер? default: Нет
|
||
1. Да
|
||
2. Нет
|
||
: """)
|
||
if count_cluster == 1:
|
||
cluster_server = True
|
||
cluster_id = input("Укажите id для кластера, любое сочетание символов: \n")
|
||
create_dir(dir_server_ark + cluster_id)
|
||
cluster_dir_override = (dir_server_ark + cluster_id)
|
||
else:
|
||
cluster_server = False
|
||
|
||
if list_config:
|
||
print("Уже установленные карты: ")
|
||
for i in list_config:
|
||
data = read_yaml(i, game="ARK")
|
||
print(f"{i} : {data['map']}")
|
||
|
||
count_maps = check_int("Укажите количество карт: \n")
|
||
if count_maps == 0: # 0 возвращает check_int когда, ничего не было введено
|
||
count_maps = 1
|
||
|
||
for i in range(count_maps):
|
||
while True:
|
||
"Проверка на выбор карты из списка"
|
||
amount_map = check_int("""Выберите карту из списка указав номер
|
||
1. The Island
|
||
2. The Center
|
||
3. Scorched Earth
|
||
4. Ragnarok
|
||
5. Aberration
|
||
6. Extinction
|
||
7. Valguero
|
||
8. Genesis: Part 1
|
||
9. Crystal Isles
|
||
10. Genesis: Part 2
|
||
11. Lost Island
|
||
12. Fjordur
|
||
: """)
|
||
if amount_map == 0: # 0 возвращает check_int когда, ничего не было введено
|
||
amount_map = i + 1
|
||
if 0 < amount_map <= 12:
|
||
break
|
||
|
||
if list_config:
|
||
for i in list_config:
|
||
data = read_yaml(i, game="ARK")
|
||
port_s.append(data['Port'])
|
||
rcon_p.append(data['RCONPort'])
|
||
query_p.append(data['QueryPort'])
|
||
|
||
if amount_map == 1:
|
||
map_s = "TheIsland"
|
||
elif amount_map == 2:
|
||
map_s = "TheCenter"
|
||
elif amount_map == 3:
|
||
map_s = "ScorchedEarth_P"
|
||
elif amount_map == 4:
|
||
map_s = "Ragnarok"
|
||
elif amount_map == 5:
|
||
map_s = "Aberration_P"
|
||
elif amount_map == 6:
|
||
map_s = "Extinction"
|
||
elif amount_map == 7:
|
||
map_s = "Valguero_P"
|
||
elif amount_map == 8:
|
||
map_s = "Genesis"
|
||
elif amount_map == 9:
|
||
map_s = "CrystalIsles"
|
||
elif amount_map == 10:
|
||
map_s = "Gen2"
|
||
elif amount_map == 11:
|
||
map_s = "LostIsland"
|
||
elif amount_map == 12:
|
||
map_s = "Fjordur"
|
||
else:
|
||
# Если вдруг каким-то боком проверка не отработает и не будет нужной цифры
|
||
map_s = 'TheIsland'
|
||
|
||
def ports(ports_arr):
|
||
while True:
|
||
port = check_int("")
|
||
if not port:
|
||
if not ports_arr:
|
||
return 0
|
||
else:
|
||
port = max(ports_arr) + 2
|
||
if port in ports_arr:
|
||
print("Порт уже занят")
|
||
else:
|
||
return port
|
||
|
||
if list_config:
|
||
data = read_yaml(list_config[-1], game="ARK")
|
||
while True:
|
||
name_server = input("Укажите название Сервера: \n")
|
||
if name_server == "":
|
||
if map_s in list_config:
|
||
count = 1
|
||
new_name = map_s
|
||
while new_name in list_config:
|
||
new_name = f"{map_s}{str(count)}"
|
||
count += 1
|
||
list_config.append(new_name)
|
||
print(list_config)
|
||
break
|
||
else:
|
||
list_config.append(map_s)
|
||
break
|
||
else:
|
||
if name_server in list_config:
|
||
print_line("Имя занято")
|
||
else:
|
||
list_config.append(name_server) # если enter, то ставим последним элементом карту
|
||
break
|
||
|
||
print("Укажите порт сервера: ")
|
||
port_server = ports(port_s)
|
||
if port_server == 0:
|
||
port_server = 7777
|
||
print("Порт Сервера=", port_server)
|
||
print("Укажите query порт сервера: ")
|
||
query_port = ports(query_p)
|
||
if query_port == 0:
|
||
query_port = 27015
|
||
print("Query Port=", query_port)
|
||
|
||
rcon_enabled = True
|
||
if rcon_p == []:
|
||
rcon_port = 27020
|
||
else:
|
||
rcon_port = max(rcon_p) + 1
|
||
|
||
password_server = input("Укажите пароль Сервера: \n")
|
||
adminpassword_server = 123
|
||
max_players = check_int("Укажите максимальное количество игроков: \n")
|
||
if max_players == 0:
|
||
max_players = 70
|
||
|
||
print("Передавать сервер в глобальный список серверов steam?")
|
||
listen_server_amount = check_int("""\n
|
||
1. Да
|
||
2. Нет
|
||
:""")
|
||
if listen_server_amount == 1:
|
||
listen_server = True
|
||
elif listen_server_amount == 2:
|
||
listen_server = False
|
||
else:
|
||
listen_server = True
|
||
|
||
yaml_create(game := "ARK", dir_server := "", cluster_server, map_s, list_config[-1], port_server, query_port, rcon_enabled, rcon_port, adminpassword_server, password_server, max_players, cluster_id, cluster_dir_override, listen_server)
|
||
|
||
|
||
def config_7daystodie():
|
||
list_simvols = "$@-.%{}+/".split()
|
||
create_dir(dir_server_7days)
|
||
print("Введите имя конфига (serverconfig):\n")
|
||
config_7days = input()
|
||
if config_7days == "":
|
||
config_7days = "serverconfig"
|
||
elif config_7days == "serverconfig":
|
||
config_7days = "serverconfig"
|
||
elif config_7days in list_simvols:
|
||
print_line("Запрещённые символы")
|
||
else:
|
||
xml_parser()
|
||
systemd_unit_create(game := "7Days", config_7days)
|
||
|
||
|
||
def xml_parser():
|
||
print("Я не умею парсить))")
|
||
|
||
|
||
def yaml_create(game, dir_server="", cluster_server="", map_s="", name_server="", port_server="", query_port="", rcon_enabled="", rcon_port="",
|
||
adminpassword_server="", password_server="", max_players="", id_mods_ark="", cluster_id="", cluster_dir_override="", listen_server=""):
|
||
if game == "ARK":
|
||
print_line(dir_maps_ark)
|
||
print_line(name_server)
|
||
path_yaml = dir_maps_ark + name_server
|
||
settings = [
|
||
{
|
||
'map': map_s,
|
||
'Cluster': cluster_server,
|
||
'SessionName': name_server,
|
||
'Port': port_server,
|
||
'QueryPort': query_port,
|
||
'RCONEnabled': rcon_enabled,
|
||
'RCONPort': rcon_port,
|
||
'ServerAdminPassword': adminpassword_server,
|
||
'ServerPassword': password_server,
|
||
'MaxPlayers': max_players,
|
||
'ModsId': id_mods_ark,
|
||
'Listen': listen_server,
|
||
'ServerPath': dir_server_ark,
|
||
'clusterid': cluster_id,
|
||
'clusterdir': cluster_dir_override
|
||
}
|
||
]
|
||
elif game == "path_server":
|
||
path_yaml = dir_config + "config"
|
||
settings = [
|
||
{
|
||
'path_server': dir_server
|
||
}
|
||
]
|
||
elif game != "":
|
||
systemd_unit_create(game)
|
||
with open(path_yaml, 'w') as yamlfile:
|
||
yaml.dump(settings, yamlfile)
|
||
print(colorama.Fore.GREEN + "Конфиг создан" + colorama.Style.RESET_ALL)
|
||
|
||
def systemd_unit_create(game, config_7days="", name_server=list_config):
|
||
if game == "ARK":
|
||
id_game = "376030"
|
||
for i in name_server:
|
||
data = read_yaml(i, game="ARK")
|
||
ntff = "" if not data['Cluster'] else "-NoTransferFromFiltering"
|
||
unit_dir_server = dir_server_ark
|
||
systemd_unit_exec = f"{dir_server_exec}ShooterGameServer {data['map']}?listen={data['Listen']}?GameModIds=2967069515?SessionName={data['SessionName']}?Port={data['Port']}?QueryPort={data['QueryPort']}?RCONEnabled={data['RCONEnabled']}?RCONPort={data['RCONPort']}?ServerAdminPassword={data['ServerAdminPassword']}??MaxPlayers={data['MaxPlayers']} -clusterid={data['clusterid']} -ClusterDirOverride={data['clusterdir']} {ntff}"
|
||
unit_file = f"{dir_unit}ark_{data['SessionName']}.service".lower()
|
||
elif game == "7Days":
|
||
id_game = "294420"
|
||
# сюда дописать обращение к xml для получения уникального имени сервера
|
||
unit_dir_server = dir_server_7days
|
||
systemd_unit_exec = f"{dir_server_7days}startserver.sh -configfile={config_7days}.xml"
|
||
unit_file = f"{dir_unit}7days.service".lower()
|
||
|
||
unit_text = f'''[Unit]
|
||
Description={game}: Server
|
||
Wants=network-online.target
|
||
After=syslog.target network.target nss-lookup.target network-online.target
|
||
|
||
[Service]
|
||
ExecStartPre=/usr/bin/steamcmd +force_install_dir {unit_dir_server} +login anonymous +app_update {id_game} +quit
|
||
TimeoutStartSec=99999
|
||
ExecStart={systemd_unit_exec}
|
||
LimitNOFILE=100000
|
||
ExecReload=/bin/kill -s HUP $MAINPID
|
||
ExecStop=/bin/kill -s INT $MAINPID
|
||
|
||
[Install]
|
||
WantedBy=default.target
|
||
'''
|
||
with open(unit_file, 'w') as systemd_unit:
|
||
systemd_unit.write(unit_text)
|
||
unit_name = unit_file.split("/")[-1]
|
||
os.system(f"systemctl --user unmask {unit_name}")
|
||
os.system('systemctl --user daemon-reload')
|
||
os.system(f"systemctl --user enable {unit_name}")
|
||
|
||
|
||
@hlna.command(help='Для скачивания и установки модов')
|
||
@click.option('-g', help="Название игры для запуска. (ark, 7days")
|
||
@click.option('-m', default='all', help="Название карты для запуска или all для запуска все карт")
|
||
def modinstall(g, m):
|
||
if g == "ark":
|
||
id_game_workshop = "346110"
|
||
if not os.path.isdir(dir_workshop_ark):
|
||
create_dir(dir_workshop_ark)
|
||
id_mods_ark = input("""Укажите id модов через запятую
|
||
:""").split(",")
|
||
for id_mod in id_mods_ark:
|
||
os.system(f"steamcmd +login anonymous +workshop_download_item {id_game_workshop} {id_mod} +quit")
|
||
modextract(id_mod, id_game_workshop)
|
||
|
||
|
||
def modextract(id_mod, id_game_workshop):
|
||
mod_steam_workshop = f"{dir_workshop_ark}/content/{id_game_workshop}/{id_mod}/WindowsNoEditor/"
|
||
mod_ark_mods = f"{dir_mods_ark}{id_mod}"
|
||
modextractdir = f"{dir_workshop_ark}tmp"
|
||
|
||
if id_mod == "111111111":
|
||
return
|
||
|
||
for dirpath, dirnames, filenames in os.walk(mod_steam_workshop):
|
||
for dname in dirnames:
|
||
os.makedirs(os.path.join(modextractdir, os.path.relpath(os.path.join(dirpath, dname), mod_steam_workshop)), exist_ok=True)
|
||
|
||
for fname in filenames:
|
||
if not os.path.isfile(os.path.join(mod_steam_workshop, fname)) and not os.path.isfile(os.path.join(mod_steam_workshop, fname + ".z")):
|
||
os.unlink(os.path.join(modextractdir, fname))
|
||
|
||
for dname in dirnames:
|
||
if not os.path.isdir(os.path.join(mod_steam_workshop, dname)):
|
||
shutil.rmtree(os.path.join(modextractdir, os.path.relpath(os.path.join(dirpath, dname), mod_steam_workshop)))
|
||
|
||
for root, dirs, files in os.walk(mod_steam_workshop):
|
||
for name in files:
|
||
if not (name.endswith(".z") or name.endswith(".z.uncompressed_size")):
|
||
srcfile = os.path.join(root, name)
|
||
dstfile = os.path.join(modextractdir, os.path.relpath(srcfile, mod_steam_workshop))
|
||
if not os.path.isfile(dstfile) or os.path.getmtime(srcfile) > os.path.getmtime(dstfile):
|
||
shutil.copy2(srcfile, dstfile)
|
||
|
||
modname = subprocess.check_output(['curl', '-s', 'https://steamcommunity.com/sharedfiles/filedetails/?id={}'.format(id_mod)]).decode('utf-8')
|
||
modname = re.search(r'<div class="workshopItemTitle">(.+)</div>', modname)
|
||
modname = modname and modname.group(1)
|
||
|
||
if os.path.isfile("{}/.mod".format(modextractdir)):
|
||
os.remove("{}/.mod".format(modextractdir))
|
||
|
||
modfile_bytes = b''
|
||
with open(os.path.join(modextractdir, 'mod.info'), 'rb') as f:
|
||
data = f.read()
|
||
mapnamelen = struct.unpack_from('<L', data, offset=0)
|
||
mapnamelen = mapnamelen[0]
|
||
mapname = str(data[4:mapnamelen + 3], 'utf-8')
|
||
nummaps = struct.unpack_from('<L', data, offset=mapnamelen + 4)
|
||
nummaps = nummaps[0]
|
||
pos = mapnamelen + 8
|
||
modname = (modname + mapname + "\x00").encode('utf-8')
|
||
modnamelen = len(modname)
|
||
modpath = ("../../../" + "ShooterGame" + "/Content/Mods/" + id_mod + "\x00").encode('utf-8')
|
||
modpathlen = len(modpath)
|
||
print(id_mod, 0, modnamelen, modname, modpathlen, modpath)
|
||
type(id_mod)
|
||
modfile_bytes += struct.pack('<LLL{}sL{}sL'.format(modnamelen, modpathlen),
|
||
int(id_mod), 0, modnamelen, modname, modpathlen, modpath, nummaps)
|
||
for _ in range(nummaps):
|
||
mapfilelen = struct.unpack_from('<L', data, offset=pos)
|
||
mapfilelen = mapfilelen[0]
|
||
mapfile = data[mapnamelen + 12:mapnamelen + 12 + mapfilelen]
|
||
modfile_bytes += struct.pack('<L{}s'.format(mapfilelen), mapfilelen, mapfile)
|
||
pos = pos + 4 + mapfilelen
|
||
modfile_bytes += b'\x33\xFF\x22\xFF\x02\x00\x00\x00\x01'
|
||
|
||
with open("{}/modmeta.info".format(modextractdir), 'ab') as f:
|
||
if os.path.isfile("{}/modmeta.info".format(modextractdir)):
|
||
f.write(open("{}/modmeta.info".format(modextractdir), 'rb').read())
|
||
else:
|
||
f.write(b'\x01\x00\x00\x00\x08\x00\x00\x00ModType\x00\x02\x00\x00\x001\x00')
|
||
|
||
with open(modextractdir + '.mod', 'wb') as f:
|
||
f.write(modfile_bytes)
|
||
|
||
if modextractdir != mod_ark_mods:
|
||
if not os.path.isdir(mod_ark_mods):
|
||
os.makedirs(mod_ark_mods)
|
||
|
||
|
||
@ hlna.command()
|
||
@ click.option("-m", required=True, help="Название Сервера")
|
||
@ click.option("-e/-d", default=True, help="-e активировать карты, -d деактивировать")
|
||
def enablemap(m, e):
|
||
"""Включение/выключение карт"""
|
||
m = m.split(",")
|
||
if not os.path.isdir(dir_deactivated):
|
||
create_dir(dir_deactivated)
|
||
if e == True:
|
||
port_s = []
|
||
query_p = []
|
||
for k in list_config:
|
||
data = read_yaml(k)
|
||
port_s.append(data['Port'])
|
||
query_p.append(data['QueryPort'])
|
||
for i in m:
|
||
try:
|
||
if i in list_config:
|
||
print(f"Карта {i} уже есть в активных")
|
||
continue
|
||
data = read_yaml(i, False)
|
||
if data['Port'] in port_s:
|
||
print("Предлагаем заменить")
|
||
continue
|
||
if data['QueryPort'] in query_p:
|
||
print("Заменить query port?")
|
||
continue
|
||
x = os.system(
|
||
f"mv {dir_deactivated}{i} {dir_maps_ark} >> {dir_logs}{date} 2>&1") # Добавить текущее время
|
||
with open(f"{dir_logs}{date}.log", "a") as f:
|
||
f.write(f"[{time}] File {i} has been moved to {dir_maps_ark}\n")
|
||
if x == 0:
|
||
print(f"Карта активирована - {i}")
|
||
else:
|
||
print(f"{i} либо уже активирована, либо такой карты нет")
|
||
finally:
|
||
pass
|
||
# except:
|
||
# print("ошибка при активации карты")
|
||
# pass
|
||
else:
|
||
for i in m:
|
||
try:
|
||
if i in delist_config:
|
||
print(f"Карта {i} уже есть в деактивированных")
|
||
continue
|
||
x = os.system(
|
||
f"mv {dir_maps_ark}{i} {dir_deactivated} >> {dir_logs}{date} 2>&1") # Добавить текущее время
|
||
with open(f"{dir_logs}{date}.log", "a") as f:
|
||
f.write(f"[{time}] File {i} has been moved to {dir_deactivated}\n")
|
||
if x == 0:
|
||
print(f"Карта деактивирована - {i}")
|
||
else:
|
||
print(f"{i} либо деактивирована, либо такой карты нет")
|
||
except:
|
||
pass
|
||
|
||
|
||
@hlna.command()
|
||
def status(list_config=list_config):
|
||
# Добавить сортивку по кластерам и вывод несколько столбиков
|
||
if list_config == [] and delist_config == []:
|
||
print("Сервера не сконфигурированы")
|
||
else:
|
||
for i in list_config:
|
||
data = read_yaml(i, game="ARK")
|
||
x = os.system(f"lsof -w -i :{data['Port']}")
|
||
if x == 0:
|
||
print(colorama.Fore.GREEN + "Сервер запущен" + colorama.Style.RESET_ALL)
|
||
else:
|
||
print(colorama.Fore.RED + "Сервер не запущен" + colorama.Style.RESET_ALL)
|
||
print(f"""
|
||
Имя сервера: {i}
|
||
Карта: {data['map']}
|
||
Моды: {data['ModsId']}
|
||
Пароль: {data['ServerPassword']}
|
||
Кластер: {data['Cluster']}
|
||
Кластер id: {data['clusterid']}
|
||
Query порт: {data['QueryPort']}
|
||
Порт сервера: {data['Port']}
|
||
Rcon включен: {data['RCONEnabled']}
|
||
Rcon порт : {data['RCONPort']}
|
||
Максимальное кол-во игроков: {data['MaxPlayers']}""")
|
||
print("-" * 40)
|
||
|
||
if delist_config != []:
|
||
x = input("Есть неактивные сервера, показать Y/n: ")
|
||
if x != "n":
|
||
for i in delist_config:
|
||
data = read_yaml(i, False)
|
||
print(f"""
|
||
Имя сервера: {i}
|
||
Карта: {data['map']}
|
||
Моды: {data['ModsId']}
|
||
Пароль: {data['ServerPassword']}
|
||
Кластер: {data['Cluster']}
|
||
Кластер id: {data['clusterid']}
|
||
Query порт: {data['QueryPort']}
|
||
Порт сервера: {data['Port']}
|
||
Rcon включен: {data['RCONEnabled']}
|
||
Rcon порт : {data['RCONPort']}
|
||
Максимальное кол-во игроков: {data['MaxPlayers']}""")
|
||
print("-" * 40)
|
||
|
||
|
||
@hlna.command(help='Для запуска, сконфигурированного сервера или кластера')
|
||
@click.option('-g', help="Название игры для запуска. (ark, 7days")
|
||
@click.option('-m', default='all', help="Название карты для запуска или all для запуска все карт")
|
||
def start(g, m):
|
||
start_stop("start", g, m)
|
||
|
||
|
||
@hlna.command(help='Для остановки, сконфигурированного сервера или кластера')
|
||
@click.option('-g', help="Название игры для запуска. (ark, 7days")
|
||
@click.option('-m', default='all', help="Название карты для запуска или all для запуска все карт")
|
||
def stop(g, m):
|
||
start_stop("stop", g, m)
|
||
|
||
|
||
@hlna.command(help='Для перезапуска, сконфигурированного сервера или кластера')
|
||
@click.option('-g', help="Название игры для запуска. (ark, 7days")
|
||
@click.option('-m', default='all', help="Название карты для запуска или all для запуска все карт")
|
||
def restart(g, m):
|
||
start_stop("restart", g, m)
|
||
|
||
|
||
def start_stop(action, g, m, list_config=list_config):
|
||
if g == "ark":
|
||
dict_mapname = {}
|
||
dict_allmapname = []
|
||
for i in list_config:
|
||
data = read_yaml(i, game="ARK")
|
||
dict_mapname[data['SessionName']] = data['map']
|
||
dict_allmapname.append(data['SessionName'])
|
||
names_serverstart = []
|
||
for ns, v in dict_mapname.items():
|
||
if v in m:
|
||
names_serverstart.append(ns)
|
||
if list_config != []: #Перенести выше для проверки наличия конфигов
|
||
if m == "all":
|
||
names_serverstart = dict_allmapname
|
||
print(f"Выполняется для карт(-ы) {names_serverstart}")
|
||
else:
|
||
names_serverstart = choose_map(names_serverstart)
|
||
for i in names_serverstart:
|
||
data = read_yaml(i, game="ARK")
|
||
y = os.system(f"~/git/hln-a/hlna.py rcon SaveWorld -m {i}") if action == "restart" or action == "stop" else ""
|
||
x = os.system(f"systemctl --user {action} ark_{data['SessionName'].lower()}.service")
|
||
print_line(y)
|
||
if x == 0:
|
||
print_line("Готово")
|
||
else:
|
||
print("Ни одной карты не установлено")
|
||
elif g == "7days":
|
||
x = os.system(f"systemctl --user {action} 7days.service")
|
||
if x == 0:
|
||
print_line("Готово")
|
||
|
||
|
||
def read_yaml(list_config=list_config, flag=True, game=""):
|
||
# Читаем конфиги активных или неактивных карт в зависимости от флага
|
||
if game == "ARK":
|
||
path_yaml = f"{dir_maps_ark}{list_config}" if flag else f"{dir_deactivated}{list_config}"
|
||
elif game == "path_server":
|
||
path_yaml = dir_config + "config"
|
||
with open(path_yaml, "r") as yamlfile:
|
||
data = yaml.load(yamlfile, Loader=yaml.FullLoader)
|
||
return data[0] # возвращаем словарь со всеми значениями
|
||
|
||
|
||
def choose_map(arr):
|
||
new_arr = []
|
||
arr = sorted(arr)
|
||
print('Найдены сервера с этой картой')
|
||
for i, map in enumerate(arr):
|
||
print(f"{i + 1}) {map}")
|
||
while True:
|
||
try:
|
||
x = input("Выберите сервер из списка, либо несколько через запятую: ").split(',')
|
||
x = [int(i) for i in x]
|
||
break
|
||
except:
|
||
print("Неправильный ввод")
|
||
|
||
for i in x:
|
||
new_arr.append(arr[i - 1])
|
||
print('Выбранные сервера:', new_arr)
|
||
|
||
return new_arr
|
||
|
||
|
||
@hlna.command()
|
||
@click.argument('c', nargs=1)
|
||
@click.option('-m', required=True, help="Название карты для применения rcon команды")
|
||
def rcon(m, c):
|
||
print_line(f"Команда: , {c}")
|
||
print_line(f"Карты: , {m}")
|
||
dict_mapname = {}
|
||
dict_adminpwd = {}
|
||
if list_config:
|
||
rcon_ports = []
|
||
for i in list_config:
|
||
data = read_yaml(i, game="ARK")
|
||
dict_mapname[data['RCONPort']] = data['map']
|
||
dict_adminpwd[data['RCONPort']] = data['ServerAdminPassword']
|
||
if m == "all":
|
||
for rcon_p in dict_mapname:
|
||
rcon_ports.append(rcon_p)
|
||
else:
|
||
for rcon_p, name_map in dict_mapname.items():
|
||
print_line(f"переменные name_map и m {name_map} & {m}") # обьединить с таким же блоком в start()
|
||
if name_map in m:
|
||
rcon_ports.append(rcon_p)
|
||
print_line(f"Карта которая запускается {name_map}")
|
||
for port in rcon_ports:
|
||
print(f"Rcon выполнен для {port}")
|
||
passwd = dict_adminpwd[port]
|
||
with Client('127.0.0.1', port, passwd=str(passwd)) as client:
|
||
response = client.run(c)
|
||
print(response)
|
||
else:
|
||
pass
|
||
|
||
|
||
def zero(x=""):
|
||
return ""
|
||
|
||
|
||
if not os.path.exists(dir_config + "config"):
|
||
dir_server = path_server()
|
||
else:
|
||
print_line("else")
|
||
data = read_yaml(game="path_server")
|
||
if data['path_server'] == "":
|
||
path_server()
|
||
else:
|
||
print_line(data['path_server'])
|
||
dir_server = data['path_server']
|
||
|
||
|
||
dir_unit = f"{home_dir}/.config/systemd/user/"
|
||
dir_logs = f"{dir_config}logs/"
|
||
|
||
dir_server_ark = f"{dir_server}ARK/"
|
||
dir_server_exec = f"{dir_server_ark}ShooterGame/Binaries/Linux/"
|
||
dir_workshop_ark = f"{home_dir}/.local/share/Steam/steamapps/workshop/"
|
||
dir_mods_ark = f"{dir_server_ark}ShooterGame/Content/Mods/"
|
||
|
||
dir_server_7days = f"{dir_server}/7Days/"
|
||
|
||
now = datetime.datetime.now()
|
||
date = now.strftime("%Y-%m-%d")
|
||
time = now.strftime("%H:%M:%S")
|
||
create_dir(dir_server)
|
||
create_dir(dir_unit)
|
||
create_dir(dir_config)
|
||
create_dir(dir_logs)
|
||
|
||
|
||
|
||
if __name__ == '__main__':
|
||
hlna()
|
||
|
||
|