#!/bin/bash set -e # ───────────────────────────────────────────── # 1. Resolve Working Directory # ───────────────────────────────────────────── if [ -d "/data" ]; then echo "[System] Persistent /data bucket found. Taking ownership..." sudo chown -R minecraft:minecraft /data 2>/dev/null || true sudo chmod -R 775 /data 2>/dev/null || true cd /data else echo "[Warning] No /data bucket found. World will reset on restart!" mkdir -p /app/server cd /app/server fi WORKDIR=$(pwd) echo "[System] Working directory: $WORKDIR" # ───────────────────────────────────────────── # 2. Clean Up Old/Corrupted Files # ───────────────────────────────────────────── echo "[System] Cleaning up old jars..." # Only remove specific old plugin jars, NOT the whole plugins dir yet rm -f plugins/Via*.jar rm -f plugins/EaglerX*.jar rm -f server.jar echo "[System] Clearing Paperclip cache..." rm -rf cache mkdir -p logs mkdir -p plugins/EaglercraftXServer # ───────────────────────────────────────────── # 3. Install Node.js Dependencies # ───────────────────────────────────────────── echo "[System] Installing WebSocket proxy dependencies..." npm install http-proxy --save 2>&1 | tail -1 # ───────────────────────────────────────────── # 4. Download Paper 1.12.2 # ───────────────────────────────────────────── echo "[System] Downloading Paper 1.12.2..." curl -fsSL \ -A "Mozilla/5.0" \ -o server.jar \ "https://api.papermc.io/v2/projects/paper/versions/1.12.2/builds/1620/downloads/paper-1.12.2-1620.jar" if [ ! -s server.jar ]; then echo "[Error] server.jar download failed or is empty. Aborting." exit 1 fi echo "[System] server.jar downloaded successfully ($(du -sh server.jar | cut -f1))." # ───────────────────────────────────────────── # 5. Download Plugins # ───────────────────────────────────────────── echo "[System] Downloading EaglerXServer & EaglerXRewind..." curl -fsSL -A "Mozilla/5.0" \ -o plugins/EaglerXServer.jar \ "https://github.com/lax1dude/eaglerxserver/releases/download/v1.0.8/EaglerXServer.jar" curl -fsSL -A "Mozilla/5.0" \ -o plugins/EaglerXRewind.jar \ "https://github.com/lax1dude/eaglerxserver/releases/download/v1.0.8/EaglerXRewind.jar" echo "[System] Downloading ViaVersion suite..." curl -fsSL -A "Mozilla/5.0" \ -o plugins/ViaVersion.jar \ "https://github.com/ViaVersion/ViaVersion/releases/download/5.8.1/ViaVersion-5.8.1.jar" curl -fsSL -A "Mozilla/5.0" \ -o plugins/ViaBackwards.jar \ "https://cdn.modrinth.com/data/NpvuJQoq/versions/8YdMHUIl/ViaBackwards-5.9.0-SNAPSHOT.jar" curl -fsSL -A "Mozilla/5.0" \ -o plugins/ViaRewind.jar \ "https://cdn.modrinth.com/data/TbHIxhx5/versions/r3AZ5yTY/ViaRewind-4.1.0-SNAPSHOT.jar" # Verify all plugins downloaded echo "[System] Verifying plugin downloads..." for jar in \ plugins/EaglerXServer.jar \ plugins/EaglerXRewind.jar \ plugins/ViaVersion.jar \ plugins/ViaBackwards.jar \ plugins/ViaRewind.jar do if [ ! -s "$jar" ]; then echo "[Error] $jar is missing or empty! Aborting." exit 1 fi echo " [OK] $jar ($(du -sh "$jar" | cut -f1))" done # ───────────────────────────────────────────── # 6. Server Configuration # ───────────────────────────────────────────── echo "[System] Writing eula.txt and server.properties..." echo "eula=true" > eula.txt cat > server.properties << 'PROPS' server-port=25565 online-mode=false motd=Eaglercraft Server max-players=60 PROPS # ───────────────────────────────────────────── # 7. EaglerXServer Listener Config # ───────────────────────────────────────────── echo "[System] Writing EaglercraftXServer listener config..." cat > plugins/EaglercraftXServer/listeners.yml << 'LISTENEOF' listeners: - address: 127.0.0.1:25566 motd: "&dEaglercraftX\n&ePowered by EaglerXServer" max_players: 60 online_mode: false forward_ip: true LISTENEOF # ───────��───────────────────────────────────── # 8. Generate Node.js Web Console # ───────────────────────────────────────────── echo "[System] Writing webconsole.js..." cat > webconsole.js << 'NODEEOF' 'use strict'; const http = require('http'); const fs = require('fs'); const path = require('path'); const { spawn, exec } = require('child_process'); const httpProxy = require('http-proxy'); const LOG_FILE = path.join(__dirname, 'logs', 'latest.log'); const MC_PORT = 25566; // EaglerXServer internal WS port const WEB_PORT = 7860; // Exposed port // ── Banner ──────────────────────────────────────────────────────────────────── console.log('========================================='); console.log(' Eaglercraft Server + Web Console '); console.log('========================================='); // ── Start Minecraft ─────────────────────────────────────────────────────────── const mcProcess = spawn('java', [ '-Xms2G', '-Xmx2G', '-XX:+UseG1GC', '-jar', 'server.jar', 'nogui' ], { cwd: __dirname }); const logStream = fs.createWriteStream(LOG_FILE, { flags: 'w' }); mcProcess.stdout.pipe(logStream, { end: false }); mcProcess.stderr.pipe(logStream, { end: false }); mcProcess.stdout.pipe(process.stdout); mcProcess.stderr.pipe(process.stderr); mcProcess.on('exit', (code) => { console.log(`[MC] Server process exited with code ${code}`); logStream.end(); }); // ── WebSocket Proxy ─────────────────────────────────────────────────────────── const proxy = httpProxy.createProxyServer({ target: `ws://127.0.0.1:${MC_PORT}`, ws: true }); proxy.on('error', (err, req, socket) => { console.warn('[Proxy] Routing error (server may still be booting):', err.message); if (socket && socket.writable) socket.destroy(); }); // ── HTML Page ───────────────────────────────────────────────────────────────── const PAGE_HTML = `