| import streamlit as st |
| import subprocess |
| import time |
| import os |
| import re |
| import requests |
| import zipfile |
| import stat |
|
|
| |
| DATA_DIR = "/data" |
| SERVER_DIR = os.path.join(DATA_DIR, "bedrock-server") |
| PLAYIT_DIR = os.path.join(DATA_DIR, "playit_gg") |
| PLAYIT_LOG = os.path.join(PLAYIT_DIR, "playit.log") |
| SECRET_KEY = os.environ.get("SECRET_KEY", "") |
|
|
| os.makedirs(SERVER_DIR, exist_ok=True) |
| os.makedirs(PLAYIT_DIR, exist_ok=True) |
|
|
| |
| def download_file(url, dest): |
| if not os.path.exists(dest): |
| r = requests.get(url, allow_redirects=True) |
| with open(dest, 'wb') as f: |
| f.write(r.content) |
| st.sidebar.write(f"Downloaded: {os.path.basename(dest)}") |
|
|
| |
| def setup(): |
| |
| if not os.path.exists(os.path.join(SERVER_DIR, "bedrock_server")): |
| try: |
| r = requests.get("https://www.minecraft.net/en-us/download/server/bedrock") |
| match = re.search(r'https://www.minecraft.net/bedrockserver/[^"]+', r.text) |
| url = match.group(0) if match else "https://www.minecraft.net/bedrockserver/bin-linux/bedrock-server-1.26.14.1.zip" |
| except: |
| url = "https://www.minecraft.net/bedrockserver/bin-linux/bedrock-server-1.26.14.1.zip" |
| zip_path = "/tmp/bedrock-server.zip" |
| download_file(url, zip_path) |
| with zipfile.ZipFile(zip_path, 'r') as zf: |
| zf.extractall(SERVER_DIR) |
| os.chmod(os.path.join(SERVER_DIR, "bedrock_server"), 0o755) |
| os.remove(zip_path) |
| st.sidebar.write("Bedrock server ready.") |
|
|
| |
| playit_bin = "/usr/local/bin/playit" |
| if not os.path.exists(playit_bin): |
| download_file("https://github.com/playit-cloud/playit-agent/releases/latest/download/playit-linux-amd64", playit_bin) |
| os.chmod(playit_bin, 0o755) |
| st.sidebar.write("playit agent ready.") |
|
|
| |
| playit_toml = os.path.join(PLAYIT_DIR, "playit.toml") |
| if not os.path.exists(playit_toml): |
| with open(playit_toml, 'w') as f: |
| f.write("[tunnel.minecraft]\n") |
| f.write("type = \"minecraft-bedrock\"\n") |
| f.write("local_ip = \"0.0.0.0\"\n") |
| f.write("local_port = 19132\n") |
|
|
| |
| playit_proc = None |
| server_proc = None |
|
|
| def start_processes(): |
| global playit_proc, server_proc |
| |
| cmd = ["/usr/local/bin/playit"] |
| if SECRET_KEY: |
| cmd.extend(["--secret", SECRET_KEY]) |
| with open(PLAYIT_LOG, "w") as log: |
| playit_proc = subprocess.Popen(cmd, stdout=log, stderr=subprocess.STDOUT) |
| |
| server_bin = os.path.join(SERVER_DIR, "bedrock_server") |
| server_proc = subprocess.Popen([server_bin], cwd=SERVER_DIR, |
| stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
|
|
| |
| st.set_page_config(page_title="Minecraft Server", page_icon="๐ฎ") |
| st.title("๐ฎ Minecraft Bedrock Server") |
| st.markdown("Alwaysโon server via playit.gg") |
|
|
| with st.sidebar: |
| st.header("Setup") |
| with st.spinner("Downloading..."): |
| setup() |
| if st.button("Restart Server"): |
| if server_proc: |
| server_proc.terminate() |
| if playit_proc: |
| playit_proc.terminate() |
| start_processes() |
| st.success("Restarted!") |
|
|
| |
| if not playit_proc or playit_proc.poll() is not None: |
| start_processes() |
|
|
| |
| st.header("Tunnel Connection") |
| if os.path.exists(PLAYIT_LOG): |
| log = open(PLAYIT_LOG).read() |
| claim = re.search(r'https://playit\.gg/claim/[A-Za-z0-9_=-]+', log) |
| addr = re.search(r'([a-z0-9-]+\.playit\.gg|[a-z0-9-]+\.joinmc\.link)(:[0-9]+)?', log) |
| if addr: |
| st.success(f"โ
LIVE โ Connect to: `{addr.group(0)}`") |
| elif claim: |
| st.warning("๐ Claim needed โ open this link:") |
| st.markdown(f"[{claim.group(0)}]({claim.group(0)})") |
| else: |
| st.info("โณ Waiting for tunnel...") |
| else: |
| st.info("Starting...") |
|
|
| st.caption("Autoโrefreshes every 10 seconds") |
| time.sleep(10) |
| st.rerun() |