import gradio as gr import subprocess import os import requests import shutil versions = requests.get("https://api.purpurmc.org/v2/purpur/", timeout=10).json()['versions'] process = None server_path = "server" os.makedirs(server_path, exist_ok=True) def download_playit(): os.makedirs(f"{server_path}/plugins", exist_ok=True) url = "https://github.com/playit-cloud/playit-minecraft-plugin/releases/latest/download/playit-minecraft-plugin.jar" os.system(f"curl -L -o {server_path}/plugins/playit-minecraft-plugin.jar {url}") def download_server(version_id: str): if not os.path.exists(f"{server_path}/server.jar"): url = f"https://api.purpurmc.org/v2/purpur/{version_id}/latest/download" os.system(f"curl -L -o {server_path}/server.jar {url}") # Принимаем EULA автоматически with open(f"{server_path}/eula.txt", "w") as f: f.write("eula=true") def start_mc(ram, version: str): global process download_server(version) download_playit() process = subprocess.Popen( ["java", f"-Xmx{ram}M", "-jar", f"server.jar", "nogui"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, universal_newlines=True, cwd=server_path ) log_output = "" for line in iter(process.stdout.readline, ""): log_output += line yield log_output def send_command(command): global process if process and process.poll() is None: process.stdin.write(command + "\n") process.stdin.flush() return f"✅ Команда \"{command}\" отправлена" return "Сервер не запущен" def load_properties(): if not os.path.exists(f"{server_path}/server.properties"): return "# Файл еще не создан, запустите сервер один раз или введите настройки вручную." with open(f"{server_path}/server.properties", "r") as f: return f.read() def save_properties(content): with open(f"{server_path}/server.properties", "w") as f: f.write(content) return "✅ Файл server.properties сохранен!" def download_server_folder(): if not os.path.exists(server_path): return None archive_path = shutil.make_archive("server", 'zip', server_path) return archive_path with gr.Blocks() as demo: gr.Markdown("# HFcraft") with gr.Tabs(): with gr.Tab("Консоль"): with gr.Row(): version_dropdown = gr.Dropdown(choices=versions, value=versions[-1], label="Версия Minecraft (Purpur)") ram_slider = gr.Slider(512, 12288, value=4096, step=1, label="ОЗУ (МБ)") start_btn = gr.Button("Запустить", variant="primary") logs = gr.Textbox(label="Логи", lines=15, interactive=False) with gr.Row(): cmd_input = gr.Textbox(label="Команда") send_btn = gr.Button("Отправить", scale=0) status_msg = gr.Markdown("") with gr.Tab("Настройки"): prop_editor = gr.Textbox( label="Редактор server.properties", lines=20, elem_id="prop-text" ) with gr.Row(): refresh_btn = gr.Button("Загрузить server.properties") save_btn = gr.Button("Сохранить server.properties", variant="primary") prop_status = gr.Markdown("") with gr.Row(): export_btn = gr.Button("Скачать сервер", variant="secondary") file_output = gr.File(label="архив") export_btn.click( fn=download_server_folder, outputs=[file_output] ) # Логика Консоли start_btn.click(start_mc, inputs=[ram_slider, version_dropdown], outputs=[logs]) send_btn.click(send_command, inputs=[cmd_input], outputs=[status_msg]) send_btn.click(lambda: "", None, cmd_input) # Логика Редактора refresh_btn.click(load_properties, outputs=[prop_editor]) save_btn.click(save_properties, inputs=[prop_editor], outputs=[prop_status]) demo.launch()