a243213b47
Covers the Create + Farmer's Delight modpack list, food roadmap pool, cross-platform client bootstrap (offline account + modpack + auto-join), and the venue-box server setup (lazymc idle sleep/wake, Chunky pregen, file distribution).
146 lines
5.6 KiB
Bash
Executable File
146 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# One-time setup for the LAN party's dedicated box: installs a Forge 1.20.1
|
|
# Minecraft server, wraps it in lazymc (auto-sleep when empty / auto-wake on
|
|
# connect), and serves the client install scripts + modpack.zip over HTTP —
|
|
# all as systemd services so the box can run unattended for the 3 days.
|
|
#
|
|
# Target: a Linux machine (Debian/Ubuntu/etc with systemd) at the venue.
|
|
# Run as a normal user with sudo rights: ./setup-server.sh
|
|
set -euo pipefail
|
|
|
|
# ---- EDIT ME ----
|
|
FORGE_MC_VERSION="1.20.1"
|
|
FORGE_BUILD="47.4.28" # current recommended build for 1.20.1 — check files.minecraftforge.net if this is stale
|
|
MC_PUBLIC_PORT=25565 # what players connect to (lazymc listens here)
|
|
MC_INTERNAL_PORT=25566 # real server listens here, lazymc proxies to it
|
|
FILESERVER_PORT=8000 # install.sh / install.ps1 / modpack.zip served from here
|
|
SLEEP_AFTER="5m" # idle time before lazymc stops the real server
|
|
MIN_RAM="2G"
|
|
MAX_RAM="6G" # 5-8 players; see ../HOSTING.md sizing table — bump to 8G (9-12p) or 10-12G (13-15p)
|
|
# ------------------
|
|
|
|
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
SERVER_DIR="$BASE_DIR/mcserver"
|
|
DIST_DIR="$BASE_DIR/dist"
|
|
FORGE_VERSION="${FORGE_MC_VERSION}-${FORGE_BUILD}"
|
|
|
|
command -v java >/dev/null || { echo "Java not found. Install a Java 17+ JDK (e.g. 'sudo apt install -y openjdk-17-jre-headless') then re-run."; exit 1; }
|
|
command -v python3 >/dev/null || { echo "python3 not found. Install it (e.g. 'sudo apt install -y python3') then re-run."; exit 1; }
|
|
|
|
mkdir -p "$SERVER_DIR" "$DIST_DIR"
|
|
|
|
# ---- 1. Install the Forge server ----
|
|
if [[ ! -f "$SERVER_DIR/run.sh" ]]; then
|
|
echo "==> Downloading Forge $FORGE_VERSION installer"
|
|
installer_url="https://maven.minecraftforge.net/net/minecraftforge/forge/${FORGE_VERSION}/forge-${FORGE_VERSION}-installer.jar"
|
|
curl -fsSL -o "$SERVER_DIR/forge-installer.jar" "$installer_url"
|
|
|
|
read -rp "Do you accept the Minecraft EULA (https://aka.ms/MinecraftEULA)? [y/N] " eula_ans
|
|
[[ "$eula_ans" =~ ^[Yy]$ ]] || { echo "EULA not accepted, aborting."; exit 1; }
|
|
|
|
echo "==> Running Forge server installer"
|
|
(cd "$SERVER_DIR" && java -jar forge-installer.jar --installServer)
|
|
echo "eula=true" > "$SERVER_DIR/eula.txt"
|
|
else
|
|
echo "==> Forge server already installed, skipping"
|
|
fi
|
|
|
|
# server.properties: lazymc will rewrite host/port/rcon itself, we just set gameplay-relevant bits
|
|
touch "$SERVER_DIR/server.properties"
|
|
for kv in "online-mode=false" "motd=LAN Party - Create & Delight" "difficulty=normal" "max-players=20"; do
|
|
key="${kv%%=*}"
|
|
if grep -q "^${key}=" "$SERVER_DIR/server.properties" 2>/dev/null; then
|
|
sed -i "s/^${key}=.*/${kv}/" "$SERVER_DIR/server.properties"
|
|
else
|
|
echo "$kv" >> "$SERVER_DIR/server.properties"
|
|
fi
|
|
done
|
|
|
|
mkdir -p "$SERVER_DIR/mods"
|
|
echo "==> NOTE: copy the same mod jars from your client modpack's mods/ folder into $SERVER_DIR/mods/ (Create, Flywheel, Farmer's Delight + addons, JEI, etc.) before first boot."
|
|
|
|
# ---- 2. Install lazymc ----
|
|
if [[ ! -x "$BASE_DIR/lazymc" ]]; then
|
|
echo "==> Downloading latest lazymc"
|
|
api_url="https://api.github.com/repos/timvisee/lazymc/releases/latest"
|
|
release_json="$(curl -fsSL "$api_url")"
|
|
asset_url="$(echo "$release_json" | grep -oE '"browser_download_url": *"[^"]+linux-x64"' | cut -d'"' -f4 | head -n1)"
|
|
[[ -n "$asset_url" ]] || { echo "Could not find linux-x64 lazymc asset" >&2; exit 1; }
|
|
curl -fsSL -o "$BASE_DIR/lazymc" "$asset_url"
|
|
chmod +x "$BASE_DIR/lazymc"
|
|
else
|
|
echo "==> lazymc already present, skipping"
|
|
fi
|
|
|
|
cat > "$BASE_DIR/lazymc.toml" <<EOF
|
|
[server]
|
|
directory = "$SERVER_DIR"
|
|
command = "bash run.sh nogui -Xms${MIN_RAM} -Xmx${MAX_RAM}"
|
|
address = "127.0.0.1:${MC_INTERNAL_PORT}"
|
|
freeze_process = false
|
|
wake_whitelist = false
|
|
|
|
[public]
|
|
address = "0.0.0.0:${MC_PUBLIC_PORT}"
|
|
|
|
[time]
|
|
sleep_after = "${SLEEP_AFTER}"
|
|
minimum_online_time = "1m"
|
|
|
|
[motd]
|
|
sleeping = "☀ Server is asleep, join to wake it up"
|
|
starting = "⏳ Server is starting, hang tight..."
|
|
|
|
[rcon]
|
|
enabled = true
|
|
port = 25575
|
|
EOF
|
|
echo "==> Wrote lazymc.toml (sleeps after ${SLEEP_AFTER} empty, public port ${MC_PUBLIC_PORT} -> internal ${MC_INTERNAL_PORT})"
|
|
|
|
# ---- 3. systemd services ----
|
|
sudo tee /etc/systemd/system/mc-lazymc.service >/dev/null <<EOF
|
|
[Unit]
|
|
Description=LAN party Minecraft server (via lazymc)
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
WorkingDirectory=${BASE_DIR}
|
|
ExecStart=${BASE_DIR}/lazymc
|
|
Restart=on-failure
|
|
User=${USER}
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
sudo tee /etc/systemd/system/mc-fileserver.service >/dev/null <<EOF
|
|
[Unit]
|
|
Description=LAN party modpack/install-script file server
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
WorkingDirectory=${DIST_DIR}
|
|
ExecStart=/usr/bin/python3 -m http.server ${FILESERVER_PORT}
|
|
Restart=on-failure
|
|
User=${USER}
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now mc-lazymc.service mc-fileserver.service
|
|
|
|
echo "==> Done."
|
|
echo " - Minecraft server: public port ${MC_PUBLIC_PORT}, sleeps after ${SLEEP_AFTER} idle, wakes on connect."
|
|
echo " - File server: http://<this-box-lan-ip>:${FILESERVER_PORT}/ serving ${DIST_DIR}/"
|
|
echo " - Put install.sh, install.ps1 and modpack.zip into ${DIST_DIR}/ (see ../HOSTING.md)."
|
|
echo " - Copy your client mod jars into ${SERVER_DIR}/mods/ if you haven't yet, then: sudo systemctl restart mc-lazymc"
|
|
if command -v ufw >/dev/null && sudo ufw status | grep -q "Status: active"; then
|
|
echo "==> ufw is active — opening ${MC_PUBLIC_PORT}/tcp and ${FILESERVER_PORT}/tcp"
|
|
sudo ufw allow "${MC_PUBLIC_PORT}/tcp"
|
|
sudo ufw allow "${FILESERVER_PORT}/tcp"
|
|
fi
|