sigma13 / app.py
yobberbyte's picture
Create app.py
c6cbfcd verified
print("STARTED")
import gradio as gr
import 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")
os.makedirs(BASE_DIR, exist_ok=True)
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
# ========================
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
# ========================
# DOWNLOAD PAPER (1.20.6)
# ========================
def download_paper():
jar_path = os.path.join(BASE_DIR, "server.jar")
if os.path.exists(jar_path):
print("[PAPER] already exists")
return
print("[PAPER] downloading 1.20.6...")
url = "https://api.papermc.io/v2/projects/paper/versions/1.20.6/builds/latest/downloads/paper-1.20.6-latest.jar"
urllib.request.urlretrieve(url, jar_path)
# ========================
# READ 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)
# ========================
# LOAD WORLD
# ========================
def load_world():
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] starting...")
load_world()
download_paper()
# accept eula
with open(os.path.join(BASE_DIR, "eula.txt"), "w") as f:
f.write("eula=true")
SERVER_PROCESS = subprocess.Popen(
[
"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()
# ========================
# START BUTTON HANDLER
# ========================
def start_background():
threading.Thread(target=start_server, daemon=True).start()
return "Starting server..."
# ========================
# 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")
start_btn = gr.Button("Start Server")
status = gr.Textbox(label="Status")
addr_btn = gr.Button("Get Address")
address = gr.Textbox(label="Server Address")
start_btn.click(fn=start_background, outputs=status)
addr_btn.click(fn=get_address, outputs=address)
app.launch()