#!/usr/bin/env python3 import os import re import threading from pathlib import Path from pprint import pprint import yaml import click import colorama import click_completion home_dir = Path.home() dir_server = f"{home_dir}/ARK_Servers/" config_hlna = f"{home_dir}/.config/hlna/" "Убрать" mods_id = "" listen_server = True @click.group() def hlna(): pass 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 list_config = find_file(config_hlna) delist_config = find_file(config_hlna+"deactivated") def print_line(text): """Добавление тире вокруг текста, покраска""" print(colorama.Fore.YELLOW + "-"*30) print(colorama.Fore.GREEN + text) print(colorama.Fore.YELLOW + "-"*30 + colorama.Style.RESET_ALL) print_line(f"list_config=, {list_config}") def create_dir(directory): """Проверка и создание директории""" if not os.path.exists(directory): os.mkdir(directory) def check_int(number=""): """Проверка на ввод числа""" while True: try: x = input(number) if x == "": return 0 x = x.replace(' ', '') x = x.replace(',', '') x = int(x) return x except ValueError: print("Введите число") create_dir(dir_server) create_dir(config_hlna) @hlna.command(help='Для конфигурирования параметров запускаемого сервера или кластера серверов') def config(name_server=list_config): port_s = [] query_p = [] id_srv = {} data = {} cluster_dir_override = "" cluster_id = "" count_cluster = check_int("""Укажите требуется ли кластер? 1. Да 2. Нет : """) if count_cluster == 1: cluster_server = True cluster_id = input("Укажите id для кластера, любое сочетание символов: \n") create_dir(dir_server + cluster_id) cluster_dir_override = (dir_server + cluster_id) else: cluster_server = False if name_server != []: print("Уже установленные карты: ") for i in name_server: data = read_yaml(i) print(f"{i} : {data['map']}") port_s.append(data['Port']) query_p.append(data['QueryPort']) id_srv[data['SessionName']] = data['id_server'] count_maps = check_int("Укажите количество карт: \n") if count_maps == 0: # 0 возвращает check_int когда, ничего не было введено count_maps = 1 for i in range(count_maps): while True: "Проверка на выбор карты из списка" os.system("clear") 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 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' if name_server != []: data = read_yaml(name_server[-1]) h = (input("Укажите название Сервера: \n")) if h == '': if map_s in name_server: name_server.pop(); name_server.append(map_s + str(name_server.count(map_s))) else: name_server.pop(); name_server.append(map_s) # если enter, то ставим последним элементом карту else: name_server.append(h) while True: id_server = input("Укажите метку для запуска или конфигурирования этой карты") if id_server == "": if id_srv == {}: print_line("Значение по умолчанию") else: if id_srv != {}: # Если есть хоть какой-то id if id_server in id_srv[name_server[-1]]: # тут ошибка ! break if id_server in id_srv.values(): # Если введёное уже есть в списке меток print_line("Метка уже занята") else: id_srv[name_server[-1]] = id_server break else: id_srv[name_server[-1]] = id_server break while True: port_server = check_int("Укажите порт Сервера <7777>: \n") if port_server == 0: if port_s == []: port_server = 7777 else: port_server = max(port_s) + 2 if port_server is port_s: # если веденный порт есть в списке портов print("Этот порт уже занят") else: break while True: query_port = check_int("Укажите Query-порт Сервера <27015>: \n") if query_port == 0: if query_p == []: query_port = 27015 else: query_port = max(query_p) + 2 if query_port is query_p: # если веденный порт есть в списке портов print("Этот порт уже занят") else: break password_server = input("Укажите пароль Сервера: \n") max_players = check_int("Укажите максимальное количество игроков: \n") if max_players == 0: max_players = 70 yaml_create(cluster_server, map_s, name_server[-1], port_server, query_port, password_server, max_players, cluster_id, cluster_dir_override, id_srv[name_server[-1]]) def yaml_create(cluster_server, map_s, name_server, port_server, query_port, password_server, max_players, cluster_id, cluster_dir_override, id_srv): settings_hlna = [ { 'map' : map_s, 'id_server' : id_srv, 'Cluster' : cluster_server, 'SessionName' : name_server, 'Port' : port_server, 'QueryPort' : query_port, 'ServerPassword' : password_server, 'MaxPlayers' : max_players, 'ModsId' : mods_id, 'Listen' : listen_server, 'ServerPath' : dir_server, 'clusterid' : cluster_id, 'clusterdir' : cluster_dir_override } ] with open(config_hlna + f"{name_server}", 'w') as yamlfile: yaml.dump(settings_hlna, yamlfile) print(colorama.Fore.GREEN + "Конфиг создан" + colorama.Style.RESET_ALL) @hlna.command() @click.option("-m", required=True, help="Название Сервера") @click.option("-e/-d", default=True, help="-e активировать карты, -d деактивировать") def enablemap(m,e): """Тут переписать надо""" m = m.split(",") m = check_name_map(m, False) create_dir(config_hlna + "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) if data['Port'] in port_s: print("Предлагаем заменить") if data['QueryPort'] in query_p: print("Заменить query port?") x = os.system(f"mv {config_hlna}deactivated/{i} {config_hlna + i} 2>> {config_hlna}logs") #Добавить текущее время if x == 0: print(f"Карта активирована - {i}") else: print(f"{i} либо уже активирована, либо такой карты нет") except: print("ошибка") pass else: for i in m: try: if i in delist_config: print(f"Карта {i} уже есть в деактивированных") continue x = os.system(f"mv {config_hlna + i} {config_hlna}deactivated/{i} 2>> {config_hlna}logs") #Добавить текущее время if x == 0: print(f"Карта деактивирована - {i}") else: print(f"{i} либо деактивирована, либо такой карты нет") except: pass @hlna.command() def servers(map_server=list_config): # Добавить сортивку по кластерам и вывод несколько столбиков if map_server == [] and delist_config == []: print("Сервера не установлены") else: for i in map_server: data = read_yaml(i) 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['ModsId']} Пароль: {data['ServerPassword']} Кластер: {data['Cluster']} Кластер id: {data['clusterid']} Query порт: {data['QueryPort']} Порт сервера: {data['Port']} Максимальное кол-во игроков: {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['ModsId']} Пароль: {data['ServerPassword']} Кластер: {data['Cluster']} Кластер id: {data['clusterid']} Query порт: {data['QueryPort']} Порт сервера: {data['Port']} Максимальное кол-во игроков: {data['MaxPlayers']}""") print("-" * 40) @hlna.command(help='Для запуска, сконфигурированного сервера или кластера') @click.option('-m', default='all', help="Название карты для запуска или all для запуска все карт") def start(m, map_server=list_config): if map_server != []: if m == "all": print("Запускаем все активные карты") else: m = m.split(",") m = check_name_map(m) map_server = m for i in map_server: data = read_yaml(i) create_dir(data['ServerPath'] + i) print_line("Качаем карту: " + i) x = os.system( f"steamcmd +force_install_dir {data['ServerPath'] + i} +login anonymous +app_update 376030 +quit") print_line("Карта скачана: " + i) def start(i): os.chdir(data['ServerPath'] + i + "/ShooterGame/Binaries/Linux/") os.system( f"./ShooterGameServer {i}?SessionName={data['SessionName']}?Port={data['Port']}?QueryPort={data['QueryPort']}?MaxPlayers={data['MaxPlayers']}?GameModIds={data['ModsId']}?listen={data['Listen']} -clusterid={data['clusterid']} -ClusterDirOverride={data['clusterdir']}") if x == 0: threads = threading.Thread(target=start, args=(i,)) threads.start() else: print(f"Карта {i} не установлена") else: print("Ни одной карты не установлено") @hlna.command(help='Для удаления серверов') @click.option('-m', required=True, help="Название карты для удаления") def delete(m, list_config=list_config): for i in list_config: data = read_yaml(i) if data['id_server'] == m: n = input(f"Вы действительно хотите удалить сервер? Это действие отменить невозможно - {i}, y\\N") if n == "y": os.system(f"rm {home_dir}/.config/hlna/{i}") os.system(f"rm -rf {dir_server}{i}") else: continue def read_yaml(map_server, flag=True): # Читаем конфиги активных или неактивных карт в зависимости от флага if flag == True: dirs = f"{home_dir}/.config/hlna/{map_server}" else: dirs = f"{home_dir}/.config/hlna/deactivated/{map_server}" with open(dirs, "r") as yamlfile: data = yaml.load(yamlfile, Loader=yaml.FullLoader) return data[0] # возвращаем словарь со всеми значениями def check_name_map(maps, flag=True): map_choise = [] for i in maps: if flag == True: if map_choise[-1] in list_config: print_line(f"{i} - Подготавливаем карту {map_choise[-1]}") else: map_choise.pop() print("Карта-", i, "не установлена") else: if map_choise[-1] in delist_config or map_choise[-1] in list_config: print_line(f"{i} - Подготавливаем карту {map_choise[-1]}") else: map_choise.pop() print("Карта -", i, "не установлена") return map_choise if __name__ == '__main__': hlna()