sigma12 / app.py
yobberbyte's picture
Update app.py
6f99a6a verified
print("STARTED")
import gradio as gr
import spaces, requests, os, time, threading, subprocess, shutil, tarfile, urllib.request
from huggingface_hub import hf_hub_download, upload_file
# ========================
# PATHS
# ========================
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
BASE_DIR = os.path.join(ROOT_DIR, "minecraft_server")
WORLD_PATH = os.path.join(BASE_DIR, "world")
NETHER_PATH = os.path.join(BASE_DIR, "world_nether")
END_PATH = os.path.join(BASE_DIR, "world_the_end")
# ========================
# ENV
# ========================
ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "")
HF_TOKEN = os.environ.get("HF_TOKEN", "")
PLAYIT_AUTH_KEY = os.environ.get("PLAYIT_AUTH_KEY", "")
HF_REPO_ID = "Dalleon/McSaves"
# ========================
# GLOBALS
# ========================
SERVER_PROCESS = None
TCP_PROCESS = None
PUBLIC_TCP = None
SERVER_ONLINE = False
# ========================
# KEEP ALIVE (ANTI-PAUSE)
# ========================
def keep_alive():
while True:
try:
requests.get("http://127.0.0.1:7860")
print("[KEEPALIVE]")
except:
pass
time.sleep(240)
# ========================
# JAVA INSTALL
# ========================
def install_java():
print("[JAVA] Installing...")
url = "https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz"
path = os.path.join(BASE_DIR, "java.tar.gz")
urllib.request.urlretrieve(url, path)
extract = os.path.join(BASE_DIR, "java")
os.makedirs(extract, exist_ok=True)
with tarfile.open(path, "r:gz") as tar:
tar.extractall(extract)
for f in os.listdir(extract):
if f.startswith("jdk"):
java_home = os.path.join(extract, f)
os.environ["JAVA_HOME"] = java_home
os.environ["PATH"] = os.path.join(java_home, "bin") + ":" + os.environ["PATH"]
print("[JAVA] Ready")
# ========================
# SERVER OUTPUT
# ========================
def read_output():
global SERVER_PROCESS
while True:
if SERVER_PROCESS and SERVER_PROCESS.stdout:
line = SERVER_PROCESS.stdout.readline()
if line:
print("[MC]", line.strip())
time.sleep(0.1)
# ========================
# SAVE WORLD
# ========================
def save_world():
global SERVER_PROCESS
print("[SAVE] Saving...")
if SERVER_PROCESS:
SERVER_PROCESS.stdin.write("save-all\n")
SERVER_PROCESS.stdin.flush()
time.sleep(10)
tar_path = os.path.join(BASE_DIR, "world.tar.gz")
with tarfile.open(tar_path, "w:gz") as tar:
if os.path.exists(WORLD_PATH):
tar.add(WORLD_PATH, arcname="world")
if os.path.exists(NETHER_PATH):
tar.add(NETHER_PATH, arcname="world_nether")
if os.path.exists(END_PATH):
tar.add(END_PATH, arcname="world_the_end")
try:
upload_file(
path_or_fileobj=tar_path,
path_in_repo="world.tar.gz",
repo_id=HF_REPO_ID,
token=HF_TOKEN,
repo_type="model"
)
print("[SAVE] Uploaded")
except Exception as e:
print("[SAVE ERROR]", e)
# ========================
# LOAD WORLD
# ========================
def load_world():
print("[LOAD] Loading...")
try:
file_path = hf_hub_download(
repo_id=HF_REPO_ID,
filename="world.tar.gz",
token=HF_TOKEN
)
except:
print("[LOAD] No backup")
return
if os.path.exists(WORLD_PATH):
shutil.rmtree(WORLD_PATH)
with tarfile.open(file_path, "r:gz") as tar:
tar.extractall(BASE_DIR)
# ========================
# PLAYIT
# ========================
def start_tcp():
global PUBLIC_TCP, SERVER_ONLINE, TCP_PROCESS
path = os.path.join(BASE_DIR, "playit")
if not os.path.exists(path):
print("[PLAYIT] Downloading...")
urllib.request.urlretrieve(
"https://github.com/playit-cloud/playit-agent/releases/latest/download/playit-linux-amd64",
path
)
os.chmod(path, 0o755)
TCP_PROCESS = subprocess.Popen(
[path, "--secret", PLAYIT_AUTH_KEY],
cwd=BASE_DIR,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
timeout = time.time() + 20
while time.time() < timeout:
line = TCP_PROCESS.stdout.readline()
if line:
print("[PLAYIT]", line.strip())
if "playit.gg" in line:
for part in line.split():
if "playit.gg" in part:
PUBLIC_TCP = part
break
if PUBLIC_TCP:
break
SERVER_ONLINE = True
print("[PLAYIT] Address:", PUBLIC_TCP)
# ========================
# START SERVER
# ========================
def start_server():
global SERVER_PROCESS
print("[SERVER] Booting...")
time.sleep(5) # ⚠️ critical delay
load_world()
if shutil.which("java") is None:
install_java()
if shutil.which("java") is None:
print("[ERROR] Java missing")
return
with open(os.path.join(BASE_DIR, "eula.txt"), "w") as f:
f.write("eula=true")
SERVER_PROCESS = subprocess.Popen(
[
shutil.which("java"),
"-Xms512M",
"-Xmx1G",
"-jar",
"server.jar",
"--nogui"
],
cwd=BASE_DIR,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
threading.Thread(target=read_output, daemon=True).start()
time.sleep(5)
start_tcp()
# ========================
# WATCHDOG
# ========================
def watchdog():
global SERVER_PROCESS
while True:
if SERVER_PROCESS and SERVER_PROCESS.poll() is not None:
print("[WATCHDOG] Restarting...")
start_server()
time.sleep(10)
# ========================
# BACKGROUND START
# ========================
def start_background():
threading.Thread(target=start_server, daemon=True).start()
threading.Thread(target=keep_alive, daemon=True).start()
threading.Thread(target=watchdog, daemon=True).start()
# ========================
# GET ADDRESS
# ========================
def get_address():
if not SERVER_ONLINE:
return "Starting..."
return PUBLIC_TCP or "No address yet"
# ========================
# UI
# ========================
with gr.Blocks() as app:
gr.Markdown("## ⛏️ Minecraft Server")
address = gr.Textbox(label="Server Address")
btn = gr.Button("Get Address")
start_btn = gr.Button("Start Server (if not running)")
btn.click(fn=get_address, outputs=address)
start_btn.click(fn=start_background)
# 🔥 CRITICAL FIX (prevents pause)
# app.load(start_background)
app.launch()