File size: 8,488 Bytes
722781c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#!/bin/bash
# Minecraft Bedrock server startup script for HuggingFace Spaces
# No set -e — we handle errors explicitly

LOG_DIR="/data/logs"
MC_DIR="/data/bedrock-server"
SCRIPTS_DIR="/data/scripts"
PLAYIT_LOG="$PLAYIT_HOME/playit.log"
MC_LOG="$LOG_DIR/minecraft.log"
STATUS_FILE="/tmp/mc_status.json"

mkdir -p "$LOG_DIR"

# ── Write initial status ──────────────────────────────────────────────
write_status() {
    cat > "$STATUS_FILE" <<EOF
{
  "mc_online": ${MC_ONLINE:-false},
  "playit_online": ${PLAYIT_ONLINE:-false},
  "tunnel_address": "${TUNNEL_ADDR:-}",
  "started_at": "${STARTED_AT:-}",
  "uptime": "$(uptime -p 2>/dev/null || echo 'unknown')"
}
EOF
}

MC_ONLINE=false
PLAYIT_ONLINE=false
TUNNEL_ADDR=""
STARTED_AT=$(date -Iseconds)
write_status

# ── Graceful shutdown handler ─────────────────────────────────────────
shutdown_handler() {
    echo ""
    echo "$(date) [SHUTDOWN] Signal received — shutting down gracefully..."

    # Stop Minecraft
    if [ -n "$MC_PID" ] && kill -0 "$MC_PID" 2>/dev/null; then
        echo "$(date) [SHUTDOWN] Stopping Minecraft (PID $MC_PID)..."
        kill -SIGTERM "$MC_PID"
        wait "$MC_PID" 2>/dev/null
        echo "$(date) [SHUTDOWN] Minecraft stopped."
    fi

    # Stop playit
    if [ -n "$PLAYIT_PID" ] && kill -0 "$PLAYIT_PID" 2>/dev/null; then
        echo "$(date) [SHUTDOWN] Stopping playit (PID $PLAYIT_PID)..."
        kill -SIGTERM "$PLAYIT_PID"
        wait "$PLAYIT_PID" 2>/dev/null
    fi

    # Final backup before exit
    echo "$(date) [SHUTDOWN] Running final backup..."
    bash "$SCRIPTS_DIR/backup.sh" || true

    echo "$(date) [SHUTDOWN] Done. Goodbye!"
    exit 0
}
trap 'shutdown_handler' SIGTERM SIGINT SIGHUP

# ── Banner ────────────────────────────────────────────────────────────
echo "======================================================="
echo "    ⛏️  Alpha MC — Minecraft Bedrock Server"
echo "======================================================="
echo "  Started : $(date)"
echo "  CPU     : $(nproc) cores"
echo "  RAM     : $(free -h | awk '/Mem:/{print $3 " used / " $2 " total"}')"
echo "  Disk    : $(df -h /data | awk 'NR==2{print $3 " used / " $2 " total (" $5 " full)"}')"
echo "======================================================="
echo ""

# ── Validate SECRET_KEY ───────────────────────────────────────────────
if [ -z "$SECRET_KEY" ]; then
    echo "╔══════════════════════════════════════════════════════╗"
    echo "║  ⚠️  WARNING: SECRET_KEY is not set!                  ║"
    echo "║  Tunnel will NOT work.                               ║"
    echo "║  Add it in: Space Settings → Repository Secrets     ║"
    echo "╚══════════════════════════════════════════════════════╝"
fi

# ── Status dashboard on port 7860 (keeps HF from pausing) ────────────
echo "[*] Starting status dashboard on port 7860..."
python3 "$MC_DIR/status_server.py" > "$LOG_DIR/status_server.log" 2>&1 &
STATUS_PID=$!
echo "[OK] Status dashboard started (PID $STATUS_PID) → visit the Space URL!"

# ── Cron daemon ───────────────────────────────────────────────────────
service cron start 2>/dev/null && echo "[OK] Cron started" || echo "[!] Cron unavailable (non-fatal)"
crontab /data/crontab.txt 2>/dev/null || true

# ── Setup playit.gg tunnel ────────────────────────────────────────────
mkdir -p "$PLAYIT_HOME"
cat > "$PLAYIT_HOME/playit.toml" << 'EOF'
[tunnel.minecraft-bedrock]
type = "minecraft-bedrock"
local_ip = "127.0.0.1"
local_port = 19132
EOF

> "$PLAYIT_LOG"
echo "[*] Starting playit tunnel agent..."
playit --secret "$SECRET_KEY" >> "$PLAYIT_LOG" 2>&1 &
PLAYIT_PID=$!
echo "[OK] playit started (PID $PLAYIT_PID)"

# ── Wait for tunnel to establish ──────────────────────────────────────
echo ""
echo "══════════════ WAITING FOR PLAYIT TUNNEL ══════════════"
FOUND=0
for i in $(seq 2 2 180); do
    sleep 2

    if ! kill -0 "$PLAYIT_PID" 2>/dev/null; then
        echo "[!] playit crashed. Log:"
        tail -20 "$PLAYIT_LOG"
        echo "[!] Will continue without tunnel — restart Space to retry."
        break
    fi

    CLAIM=$(grep -oE 'https://playit\.gg/claim/[A-Za-z0-9_=+-]+' "$PLAYIT_LOG" 2>/dev/null | head -1)
    if [ -n "$CLAIM" ]; then
        echo ""
        echo "╔══════════════════════════════════════════════════════╗"
        echo "║  🔗 CLAIM YOUR TUNNEL — open this URL:               ║"
        echo "║  $CLAIM"
        echo "║  Tunnel will activate after you visit the link.      ║"
        echo "╚══════════════════════════════════════════════════════╝"
        FOUND=1
        PLAYIT_ONLINE=true
        break
    fi

    ADDR=$(grep -oE '[a-z0-9-]+\.playit\.gg(:[0-9]+)?' "$PLAYIT_LOG" 2>/dev/null | head -1)
    if [ -n "$ADDR" ]; then
        echo ""
        echo "╔══════════════════════════════════════════════════════╗"
        echo "║  ✅ TUNNEL IS LIVE!                                   ║"
        echo "║  Connect in Minecraft: $ADDR"
        echo "╚══════════════════════════════════════════════════════╝"
        TUNNEL_ADDR="$ADDR"
        FOUND=1
        PLAYIT_ONLINE=true
        break
    fi

    echo "  [${i}s] waiting for tunnel..."
done

if [ "$FOUND" -eq 0 ]; then
    echo "[!] No tunnel after 180s. Continuing anyway."
    tail -20 "$PLAYIT_LOG"
fi

# ── Start Minecraft Bedrock server ────────────────────────────────────
echo ""
echo "[*] Starting Minecraft Bedrock server..."
cd "$MC_DIR"
./bedrock_server >> "$MC_LOG" 2>&1 &
MC_PID=$!

# Wait a moment and confirm it's running
sleep 3
if kill -0 "$MC_PID" 2>/dev/null; then
    echo "[OK] Minecraft started (PID $MC_PID)"
    MC_ONLINE=true
else
    echo "[!] Minecraft failed to start. Check logs: $MC_LOG"
    tail -20 "$MC_LOG"
fi

write_status

# ── Background services ───────────────────────────────────────────────
"$SCRIPTS_DIR/monitor.sh" &
echo "[OK] Monitor started (PID $!)"

"$SCRIPTS_DIR/health_check.sh" &
echo "[OK] Health check started (PID $!)"

echo ""
echo "══════════════════════════════════════════════════════"
echo "  🎮 Server is running! Dashboard at the Space URL."
echo "══════════════════════════════════════════════════════"
echo ""

# ── Keep container alive, refresh status every 30s ───────────────────
while true; do
    sleep 30

    # Update online status
    if kill -0 "$MC_PID" 2>/dev/null; then
        MC_ONLINE=true
    else
        MC_ONLINE=false
        echo "$(date) [WARN] Minecraft not running — health_check.sh will restart it."
    fi

    if kill -0 "$PLAYIT_PID" 2>/dev/null; then
        PLAYIT_ONLINE=true
    else
        PLAYIT_ONLINE=false
    fi

    write_status
done