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) | |