Spaces:
Running
Running
| import urllib.request | |
| from pathlib import Path | |
| import os | |
| import subprocess | |
| import sys | |
| import shutil | |
| import threading | |
| import time | |
| import signal | |
| import gradio as gr | |
| from mcstatus import JavaServer | |
| # URLs | |
| PAPER_JAR_URL = "https://fill-data.papermc.io/v1/objects/234a9b32098100c6fc116664d64e36ccdb58b5b649af0f80bcccb08b0255eaea/paper-1.20.1-196.jar" | |
| PLAYIT_PLUGIN_URL = "https://github.com/playit-cloud/playit-minecraft-plugin/releases/download/v0.1.4/playit-minecraft-plugin.jar" | |
| # Paths | |
| DATA_DIR = Path("/data") | |
| JAVA_DIR = DATA_DIR / "java" | |
| PLUGINS_DIR = DATA_DIR / "plugins" | |
| JAR_NAME = "paper-1.20.1-196.jar" | |
| JAR_PATH = DATA_DIR / JAR_NAME | |
| # Java download URLs (OpenJDK 17) | |
| JAVA_URLS = { | |
| "linux_x64": "https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_linux-x64_bin.tar.gz", | |
| "linux_aarch64": "https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_linux-aarch64_bin.tar.gz" | |
| } | |
| def get_platform(): | |
| import platform | |
| machine = platform.machine().lower() | |
| if 'x86_64' in machine or 'amd64' in machine: | |
| return "linux_x64" | |
| elif 'aarch64' in machine or 'arm64' in machine: | |
| return "linux_aarch64" | |
| else: | |
| print(f"Unsupported architecture: {machine}") | |
| return "linux_x64" | |
| def check_java(): | |
| java_path = shutil.which("java") | |
| if java_path: | |
| return java_path | |
| custom_java = JAVA_DIR / "bin" / "java" | |
| if custom_java.exists(): | |
| return str(custom_java) | |
| return None | |
| def download_file(url, destination): | |
| print(f"Downloading {url} to {destination}...") | |
| try: | |
| destination.parent.mkdir(parents=True, exist_ok=True) | |
| urllib.request.urlretrieve(url, destination) | |
| print(f"β Downloaded {destination}") | |
| return True | |
| except Exception as e: | |
| print(f"β Failed to download {url}: {e}") | |
| return False | |
| def install_java(): | |
| platform_key = get_platform() | |
| java_url = JAVA_URLS.get(platform_key) | |
| if not java_url: | |
| return False | |
| java_archive = DATA_DIR / "java.tar.gz" | |
| if not download_file(java_url, java_archive): | |
| return False | |
| import tarfile | |
| with tarfile.open(java_archive, 'r:gz') as tar: | |
| temp_dir = DATA_DIR / "java_temp" | |
| temp_dir.mkdir(exist_ok=True) | |
| tar.extractall(temp_dir) | |
| jdk_dir = next(d for d in temp_dir.iterdir() if d.is_dir() and d.name.startswith('jdk')) | |
| if JAVA_DIR.exists(): | |
| shutil.rmtree(JAVA_DIR) | |
| shutil.move(str(jdk_dir), str(JAVA_DIR)) | |
| shutil.rmtree(temp_dir) | |
| java_archive.unlink() | |
| (JAVA_DIR / "bin" / "java").chmod(0o755) | |
| print(f"β Java installed to {JAVA_DIR}") | |
| return True | |
| def setup_minecraft_server(): | |
| DATA_DIR.mkdir(parents=True, exist_ok=True) | |
| java_path = check_java() | |
| if not java_path: | |
| print("Java not found. Installing...") | |
| if not install_java(): | |
| return False | |
| java_path = check_java() | |
| if not java_path: | |
| return False | |
| if not JAR_PATH.exists(): | |
| if not download_file(PAPER_JAR_URL, JAR_PATH): | |
| return False | |
| # Server config | |
| (DATA_DIR / "server.properties").write_text("""server-port=25565 | |
| gamemode=survival | |
| difficulty=easy | |
| spawn-protection=0 | |
| max-players=64 | |
| online-mode=true | |
| motd=Minecraft Server | |
| enable-query=true | |
| query.port=25565 | |
| """) | |
| (DATA_DIR / "eula.txt").write_text("eula=true\n") | |
| # Download Playit plugin | |
| PLUGINS_DIR.mkdir(parents=True, exist_ok=True) | |
| playit_plugin_path = PLUGINS_DIR / "playit-minecraft-plugin.jar" | |
| if download_file(PLAYIT_PLUGIN_URL, playit_plugin_path): | |
| shutil.copy(playit_plugin_path, DATA_DIR / "playit-minecraft-plugin.jar") | |
| print("β Minecraft server setup complete") | |
| return True | |
| def start_server_background(): | |
| global server_process | |
| java_path = check_java() | |
| cmd = [java_path, "-Xmx2G", "-Xms1G", "-jar", str(JAR_PATH), "--nogui"] | |
| server_process = subprocess.Popen(cmd, cwd=DATA_DIR, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) | |
| threading.Thread(target=lambda: [print(f"[SERVER] {line.strip()}") for line in server_process.stdout], daemon=True).start() | |
| time.sleep(5) | |
| print("β Server started in background") | |
| return True | |
| def stop_server(): | |
| global server_process | |
| if server_process: | |
| print("Stopping server...") | |
| server_process.terminate() | |
| server_process.wait(timeout=10) | |
| server_process = None | |
| print("β Server stopped") | |
| def signal_handler(signum, frame): | |
| stop_server() | |
| sys.exit(0) | |
| if __name__ == "__main__": | |
| signal.signal(signal.SIGINT, signal_handler) | |
| signal.signal(signal.SIGTERM, signal_handler) | |
| if setup_minecraft_server(): | |
| start_server_background() | |
| while True: | |
| time.sleep(1) | |