From 5486b29d737226c2186d296481d2e5fff8ceccee Mon Sep 17 00:00:00 2001 From: Ewan Croft Date: Mon, 15 Jun 2026 21:08:10 +0100 Subject: [PATCH] replace TCP Shield with playit.gg tunnel; overhaul docs and scripts --- .env.example | 110 ++++++ .gitignore | 1 + README.md | 136 +++++-- compose.yml | 30 +- docs/duckdns.md | 36 -- docs/features.md | 14 +- docs/getting-started.md | 64 ++- docs/maintenance.md | 42 +- docs/playit.md | 57 +++ docs/system-requirements.md | 53 ++- docs/troubleshooting.md | 59 ++- docs/usage.md | 38 +- scripts/auto_configure.sh | 5 +- scripts/setup_master.sh | 752 +++++++++++++++++------------------- 14 files changed, 845 insertions(+), 552 deletions(-) create mode 100644 .env.example delete mode 100644 docs/duckdns.md create mode 100644 docs/playit.md diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..8e0dd6f --- /dev/null +++ b/.env.example @@ -0,0 +1,110 @@ +# ============================================================================= +# Ewan's Minecraft Server — environment configuration +# Copy this file to .env and fill in the required values. +# Lines prefixed with # are comments and have no effect. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Required +# ----------------------------------------------------------------------------- + +# Minecraft version to run. Must be set before starting the server. +# Run: MC_VERSION=1.21.1 ./scripts/auto_configure.sh +MC_VERSION= + +# Secret key for the playit.gg tunnel agent. +# Leave blank on first run — the agent will print a claim URL. +# After claiming, paste the secret from the playit dashboard here. +PLAYIT_SECRET= + +# ----------------------------------------------------------------------------- +# Server identity +# ----------------------------------------------------------------------------- + +MC_SERVER_NAME=Ewan's Minecraft Server +MC_MOTD=A Minecraft Server + +# ----------------------------------------------------------------------------- +# Gameplay +# ----------------------------------------------------------------------------- + +# peaceful, easy, normal, hard +MC_DIFFICULTY=easy +MC_DIFFICULTY_LOCK=false + +# survival, creative, adventure, spectator +MC_GAMEMODE=survival +MC_FORCE_GAMEMODE=false + +MC_HARDCORE=false +MC_PVP=false + +# Set to false for a cracked/offline server (not recommended) +MC_ONLINE_MODE=true + +# ----------------------------------------------------------------------------- +# Players +# ----------------------------------------------------------------------------- + +MC_MAX_PLAYERS=6 +MC_IDLE_TIMEOUT=5 + +MC_ENABLE_WHITELIST=true + +# Comma-separated UUIDs (use https://mcuuid.net to look them up) +MC_WHITELIST= +MC_OPS= + +# ----------------------------------------------------------------------------- +# World +# ----------------------------------------------------------------------------- + +MC_LEVEL_NAME=world +# Leave blank for a random seed +MC_LEVEL_SEED= +# minecraft:normal, minecraft:flat, minecraft:large_biomes, minecraft:amplified +MC_LEVEL_TYPE=minecraft:normal +MC_ALLOW_NETHER=true +MC_GENERATE_STRUCTURES=true + +# ----------------------------------------------------------------------------- +# Performance +# ----------------------------------------------------------------------------- + +MC_VIEW_DISTANCE=4 +MC_SIMULATION_DISTANCE=3 + +# ----------------------------------------------------------------------------- +# Data paths +# ----------------------------------------------------------------------------- + +MC_DATA_DIR=/Volumes/Storage/Server/MC/data +MC_BACKUP_DIR=/Volumes/Storage/Server/MC/backups + +# ----------------------------------------------------------------------------- +# Docker image +# ----------------------------------------------------------------------------- + +# arm64 (Apple Silicon / Raspberry Pi) — default +MC_IMAGE=itzg/minecraft-server:java21-arm64 + +# Uncomment for x86_64: +# MC_IMAGE=itzg/minecraft-server:java21 + +# Server type: PAPER, VANILLA, FABRIC, FORGE +MC_TYPE=PAPER + +# ----------------------------------------------------------------------------- +# RCON (disabled by default) +# ----------------------------------------------------------------------------- + +MC_ENABLE_RCON=false +MC_RCON_PASSWORD= +MC_RCON_PORT=25575 + +# ----------------------------------------------------------------------------- +# Misc +# ----------------------------------------------------------------------------- + +MC_TIMEZONE=Europe/London +MC_ENABLE_ROLLING_LOGS=true diff --git a/.gitignore b/.gitignore index 2202d48..ac93680 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ data/ temp/ +playit/ .env \ No newline at end of file diff --git a/README.md b/README.md index a43842d..2579cfa 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,129 @@ # Ewan's Minecraft Server -This repository contains the necessary files to set up and run Ewan's Minecraft Server using Docker Compose. The server is configured with PaperMC, several Spigot resources, and a RealIP plugin. It also includes a companion script to set up dynamic DNS using DuckDNS. - -This setup is primarily intended for personal use or small groups of friends. +A Dockerised PaperMC server configured for small groups, with tunnelled public access via [playit.gg](https://playit.gg) — no port forwarding required. ## Table of Contents * [License](./LICENSE) * [Features](./docs/features.md) * [System Requirements](./docs/system-requirements.md) -* [Getting Started](./docs/getting-started.md) -* [DuckDNS Setup (Optional)](./docs/duckdns.md) +* [Getting Started](#getting-started) +* [playit.gg Tunnel Setup](./docs/duckdns.md) * [Usage](./docs/usage.md) * [Maintenance](./docs/maintenance.md) * [Troubleshooting](./docs/troubleshooting.md) * [Contributing](./docs/contributing.md) * [Contact](./docs/contact.md) -* [Rules of my server](./docs/rules.md) +* [Rules](./docs/rules.md) + +## Getting Started + +### Prerequisites + +* Docker Desktop (or OrbStack on macOS) +* A [playit.gg](https://playit.gg) account + +### 1. Clone the repository + +```bash +git clone https://github.com/ewanc26/mc-server.git +cd mc-server +``` + +### 2. Configure the environment + +```bash +cp .env.example .env +``` + +Open `.env` and set at minimum: + +* `MC_VERSION` — Minecraft version to run (e.g. `1.21.1`) +* `PLAYIT_SECRET` — leave blank for now; see step 4 + +Then run the auto-configuration script to select the correct Java image and plugins: + +```bash +MC_VERSION=1.21.1 ./scripts/auto_configure.sh +``` + +### 3. Start the server + +```bash +docker compose up -d +``` + +### 4. Claim the playit.gg tunnel + +On first run without a `PLAYIT_SECRET`, the playit agent prints a claim URL: + +```bash +docker compose logs playit +``` + +Open the URL, sign into playit.gg, and add a **Minecraft** tunnel pointed at `mc:25565`. Copy the secret key from the dashboard into `.env`: + +``` +PLAYIT_SECRET=your_secret_here +``` + +Then restart the agent: -### How to Use the Scripts +```bash +docker compose restart playit +``` -This project includes several utility scripts located in the `scripts/` directory. These scripts are designed to help you manage your Minecraft server. +Your server is now reachable at the address shown in the playit dashboard — no port forwarding or DNS configuration needed. -1. **`setup_master.sh`**: This is the main setup script. Run it first to ensure all prerequisites are met and to configure your server. This script will also offer to set up a convenient alias for the server status script. +### 5. Whitelist players - ```bash - ./scripts/setup_master.sh - ``` +Add player UUIDs (comma-separated) to `MC_WHITELIST` and `MC_OPS` in `.env`, then restart: -2. **`server_status_mac.sh` / `server_status_linux.sh`**: These scripts are OS-specific and allow you to start, stop, and check the status of your Minecraft server. If you allowed `setup_master.sh` to create the alias, you can use `mcserver` followed by the command. +```bash +docker compose restart mc +``` - * **Using the `mcserver` alias (recommended after running `setup_master.sh`): +Or manage in-game via RCON: - * **Start the server:** +```bash +docker compose exec mc rcon-cli +``` - ```bash - mcserver start - ``` +## Scripts - * **Stop the server:** +Utility scripts live in `scripts/`. - ```bash - mcserver stop - ``` +**`setup_master.sh`** — main setup script; run this first. - * **Check server status:** +```bash +./scripts/setup_master.sh +``` - ```bash - mcserver status - ``` +**`auto_configure.sh`** — selects the correct Java image and plugin set for a given Minecraft version. - * **Directly running the scripts (if alias is not set up or preferred): +```bash +MC_VERSION=1.21.1 ./scripts/auto_configure.sh +``` - * **Start the server:** +**`server_status_mac.sh` / `server_status_linux.sh`** — start, stop, and check server status. `setup_master.sh` can configure an `mcserver` alias for these. - ```bash - ./scripts/server_status_mac.sh start # For macOS - ./scripts/server_status_linux.sh start # For Linux - ``` +```bash +mcserver start +mcserver stop +mcserver status +``` - * **Stop the server:** +## Data - ```bash - ./scripts/server_status_mac.sh stop # For macOS - ./scripts/server_status_linux.sh stop # For Linux - ``` +Server world data and backups are stored at: - * **Check server status:** +``` +/Volumes/Storage/Server/MC/ +├── data/ # world, plugins, configs +└── backups/ # automated backups via Backuper plugin +``` - ```bash - ./scripts/server_status_mac.sh status # For macOS - ./scripts/server_status_linux.sh status # For Linux - ``` +These paths can be overridden in `.env` via `MC_DATA_DIR` and `MC_BACKUP_DIR`. ## ☕ Support diff --git a/compose.yml b/compose.yml index d39c3bc..76cc88a 100644 --- a/compose.yml +++ b/compose.yml @@ -17,9 +17,10 @@ services: stdin_open: true restart: ${MC_RESTART_POLICY:-unless-stopped} + # Local-only — playit.gg handles external ingress ports: - - "${MC_SERVER_PORT:-25565}:25565" - - "${MC_RCON_PORT:-25575}:25575" + - "127.0.0.1:${MC_SERVER_PORT:-25565}:25565" + - "127.0.0.1:${MC_RCON_PORT:-25575}:25575" # Optimized memory limits (6GB) deploy: @@ -261,8 +262,8 @@ services: aliases: now-in-commands.yml volumes: - - "${MC_DATA_DIR:-./data}:/data" - - "${MC_BACKUP_DIR:-../backups}:/backups" + - "${MC_DATA_DIR:-/Volumes/Storage/Server/MC/data}:/data" + - "${MC_BACKUP_DIR:-/Volumes/Storage/Server/MC/backups}:/backups" # Health check healthcheck: @@ -279,16 +280,13 @@ services: - "com.minecraft.version=${MC_VERSION:-1.21.1}" - "com.minecraft.optimization=${MC_OPTIMIZATION_TIER:-auto}" - tcpshield-agent: - image: tcpshield/sentry-node:latest - container_name: tcpshield-agent - restart: always + playit: + image: ghcr.io/playit-cloud/playit-agent:0.15 + container_name: playit-agent environment: - - SENTRY_TOKEN=${SENTRY_TOKEN} - - BACKEND_ADDR=mc-server:25565 - networks: - - tcpshield-net - -networks: - tcpshield-net: - driver: bridge + PLAYIT_SECRET: "${PLAYIT_SECRET}" + volumes: + - ./playit:/etc/playit + restart: unless-stopped + depends_on: + - mc diff --git a/docs/duckdns.md b/docs/duckdns.md deleted file mode 100644 index 3965f87..0000000 --- a/docs/duckdns.md +++ /dev/null @@ -1,36 +0,0 @@ -# DuckDNS Setup (Optional) - -## What is DuckDNS? - -DuckDNS is a free dynamic DNS service. The script `scripts/setup_duckdns.sh` automates updating your IP every hour. - -### Prerequisites - -* account and token. -* `curl`, `cron` installed - -#### Ubuntu - -```bash -sudo apt update && sudo apt install curl cron -y -``` - -#### macOS - -* `curl` is pre-installed. -* `cron` available, but `launchd` is preferred. - -### Running the Script - -```bash -cd mc-server -chmod +x scripts/setup_duckdns.sh -./scripts/setup_duckdns.sh -``` - -Follow prompts for domain and token. - -### macOS Notes - -* May require Full Disk Access for Terminal. -* Consider using `launchd` instead of `cron`. diff --git a/docs/features.md b/docs/features.md index 52c4091..7f7881e 100644 --- a/docs/features.md +++ b/docs/features.md @@ -1,8 +1,10 @@ # Features -* **Personal Use Optimised:** This setup is primarily configured for personal use or small groups of friends, balancing performance and ease of management for private gameplay. -* **PaperMC Server:** Optimised for performance and stability. -* **Dockerised:** Easy setup and consistent environment across different systems. -* **Configurable:** Easily modify server settings via `compose.yml`. -* Persistent Data: Server worlds and configurations are stored persistently in the `./data/minecraft` directory. -* **Dynamic DNS Integration (DuckDNS):** Companion script for automatic IP address updates, allowing players to connect via a consistent domain name. +- **Personal use optimised:** Configured for small groups of friends, balancing performance and ease of management. +- **PaperMC:** Performance-optimised server with plugin support. +- **Dockerised:** Consistent environment across macOS and Linux via Docker Compose. +- **Environment-driven config:** All settings controlled through `.env` — no need to edit `compose.yml` directly. +- **Persistent data:** World data, plugins, and configs stored at `/Volumes/Storage/Server/MC/data`. Backups at `/Volumes/Storage/Server/MC/backups`. +- **Public access via playit.gg:** Tunnelled connection with no port forwarding or router configuration required. +- **Automatic backups:** Managed by the Backuper plugin. +- **Performance plugins:** Spark for profiling, Minefetch for in-game system stats. diff --git a/docs/getting-started.md b/docs/getting-started.md index 9a4f896..3613e71 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,18 +2,72 @@ ## Prerequisites -* Ensure [System Requirements](system-requirements.md) are met. -* Active internet connection. +- [System requirements](system-requirements.md) met. +- A [playit.gg](https://playit.gg) account. ## Setup -### Clone the Repository +### 1. Clone the repository ```bash git clone https://github.com/ewanc26/mc-server.git cd mc-server ``` -### Configure +### 2. Configure the environment -* Edit `compose.yml` to set server version, plugins, and other settings. +```bash +cp .env.example .env +``` + +Open `.env` and set at minimum: + +- `MC_VERSION` — Minecraft version to run (e.g. `1.21.1`) +- `MC_WHITELIST` — comma-separated player UUIDs +- `MC_OPS` — comma-separated operator UUIDs + +Leave `PLAYIT_SECRET` blank for now. + +### 3. Run auto-configuration + +Selects the correct Java image and plugin set for your chosen version: + +```bash +MC_VERSION=1.21.1 ./scripts/auto_configure.sh +``` + +### 4. Start the server + +```bash +docker compose up -d +``` + +### 5. Claim the playit.gg tunnel + +On first run the playit agent prints a claim URL. Retrieve it: + +```bash +docker compose logs playit +``` + +Open the URL, sign in, and add a **Minecraft** tunnel pointed at `mc:25565`. Copy the secret key from the dashboard and add it to `.env`: + +``` +PLAYIT_SECRET=your_secret_here +``` + +Then restart the agent: + +```bash +docker compose restart playit +``` + +Your server address is shown in the playit dashboard. Share it with whitelisted players. + +### 6. (Optional) Run the setup script + +For a guided setup including optimisation prompts, neofetch installation, and alias configuration: + +```bash +./scripts/setup_master.sh +``` diff --git a/docs/maintenance.md b/docs/maintenance.md index 3dad99b..d422f9a 100644 --- a/docs/maintenance.md +++ b/docs/maintenance.md @@ -1,18 +1,50 @@ # Maintenance -## Updating the Server +## Updating the Minecraft Version + +Update `MC_VERSION` in `.env`, then re-run auto-configuration and restart: ```bash +MC_VERSION=1.21.4 ./scripts/auto_configure.sh docker compose down -# Edit VERSION in compose.yml docker compose up -d -```` +``` + +## Updating the Server Image + +```bash +docker compose pull +docker compose down +docker compose up -d +``` ## Plugin Management -* Update `SPIGET_RESOURCES` (for SpigotMC resource IDs like ProtocolLib (ID 1997)) or `PLUGINS` (for direct URLs like TCPShield RealIP, Backuper, Headstones) in `compose.yml` -* Or place `.jar` files into `./data/minecraft/plugins` and: +Plugins are configured in `.env` via two variables: + +- `MC_SPIGET_RESOURCES` — SpigotMC resource IDs (e.g. `1997` for ProtocolLib) +- `MC_PLUGINS` — direct download URLs for plugin JARs + +The auto-configuration script (`scripts/auto_configure.sh`) sets these for the selected Minecraft version. To add a plugin manually, append its URL to `MC_PLUGINS` in `.env` and restart: ```bash docker compose restart mc ``` + +Or drop a `.jar` directly into `/Volumes/Storage/Server/MC/data/plugins` and restart. + +## Backups + +Backups are written to `/Volumes/Storage/Server/MC/backups` by the Backuper plugin automatically. + +For a manual snapshot before making changes, the setup script can create one: + +```bash +./scripts/setup_master.sh +``` + +Or copy the data directory yourself: + +```bash +cp -r /Volumes/Storage/Server/MC/data /Volumes/Storage/Server/MC/backups/manual_$(date +%Y%m%d) +``` diff --git a/docs/playit.md b/docs/playit.md new file mode 100644 index 0000000..9438dbf --- /dev/null +++ b/docs/playit.md @@ -0,0 +1,57 @@ +# playit.gg Tunnel Setup + +[playit.gg](https://playit.gg) provides a free persistent tunnel to your Minecraft server with no port forwarding or router configuration required. + +## First-time setup + +### 1. Start the playit agent + +If `PLAYIT_SECRET` is not yet set in `.env`, start just the agent: + +```bash +docker compose up -d playit +``` + +### 2. Retrieve the claim URL + +```bash +docker compose logs playit +``` + +Look for a line containing `https://playit.gg/claim/...` and open it in your browser. + +### 3. Configure the tunnel + +Sign into playit.gg and add a tunnel with these settings: + +- **Type:** Minecraft Java +- **Local address:** `mc:25565` + +### 4. Add the secret to `.env` + +Copy the secret key from the playit dashboard and add it: + +``` +PLAYIT_SECRET=your_secret_here +``` + +### 5. Restart the agent + +```bash +docker compose restart playit +``` + +The tunnel address is shown in the playit dashboard — share it with whitelisted players. + +## Reclaiming a lost or expired secret + +If the agent can't connect, re-run the first-time setup flow: + +1. Remove `PLAYIT_SECRET` from `.env` (or leave it blank) +2. `docker compose restart playit` +3. Check `docker compose logs playit` for a new claim URL +4. Update `PLAYIT_SECRET` in `.env` and restart again + +## Custom domain + +playit.gg supports custom domains on paid plans. Configure these in the playit dashboard — no changes needed in `.env` or `compose.yml`. diff --git a/docs/system-requirements.md b/docs/system-requirements.md index 11b4a91..892bc27 100644 --- a/docs/system-requirements.md +++ b/docs/system-requirements.md @@ -2,53 +2,44 @@ ## General -* **Docker Engine:** Version 20.10 or higher. -* **Docker Compose V2:** Included with Docker Desktop and recommended for all installations. -* **Minimum 4GB RAM:** Dedicated to the Minecraft server (configured in `compose.yml`). More is recommended for larger player counts or complex worlds. -* **Sufficient Disk Space:** For world data and backups. +- **Docker Engine:** Version 20.10 or higher (Docker Compose V2 required). +- **RAM:** 512MB minimum available to Docker; 1-2GB recommended for comfortable headroom. +- **Disk space:** Sufficient for world data and backups at `/Volumes/Storage/Server/MC`. -## Ubuntu Server 22.04.5 LTS +## macOS -Ensure your Ubuntu server is up-to-date: +Install **OrbStack** (recommended) or **Docker Desktop**: -```bash -sudo apt update -sudo apt upgrade -y -```` +- [OrbStack](https://orbstack.dev) — lighter, faster, native on Apple Silicon +- [Docker Desktop](https://docs.docker.com/desktop/install/mac-install/) -**Install Docker Engine and Docker Compose V2:** +Verify: -Follow the official Docker documentation: +```bash +docker --version +docker compose version +``` -* [https://docs.docker.com/engine/install/ubuntu/](https://docs.docker.com/engine/install/ubuntu/) -* [https://docs.docker.com/compose/install/](https://docs.docker.com/compose/install/) +## Linux (Ubuntu 22.04+) -Or, using `apt`: +Keep your system up to date: ```bash -sudo apt install docker.io -y -sudo systemctl enable --now docker -sudo usermod -aG docker "$USER" -newgrp docker -sudo apt install docker-compose-plugin -y +sudo apt update && sudo apt upgrade -y ``` -Verify installation: +Install Docker Engine and Compose V2: ```bash -docker --version -docker compose version +sudo apt install docker.io docker-compose-plugin -y +sudo systemctl enable --now docker +sudo usermod -aG docker "$USER" +newgrp docker ``` -## macOS 15.5 - -**Install Docker Desktop for Mac:** - -Download from: - -* [https://docs.docker.com/desktop/install/mac-install/](https://docs.docker.com/desktop/install/mac-install/) +Or follow the [official Docker docs](https://docs.docker.com/engine/install/ubuntu/). -Verify installation: +Verify: ```bash docker --version diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 73807c6..78299bd 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -1,10 +1,57 @@ # Troubleshooting -* **Server not starting:** -Check `docker compose logs mc`, ensure Docker is running, and that the EULA is accepted. +## Server not starting -* **Connection issues:** -Confirm port `25565` is open, the server is online, the Minecraft client version matches, and DuckDNS is updating correctly. +Check the logs: -* **Plugins failing:** -Inspect the server logs for compatibility errors or syntax issues in `compose.yml`. +```bash +docker compose logs mc +``` + +Common causes: + +- `MC_VERSION` not set in `.env` — the server will refuse to start without it +- EULA not accepted — ensure `MC_EULA=TRUE` in `.env` +- Docker not running — start Docker Desktop or OrbStack first +- Port conflict on `127.0.0.1:25565` — check if something else is using that port locally + +## Players can't connect + +- Check the playit dashboard at — confirm the tunnel is active and the address is correct +- Confirm the playit agent is running: `docker compose logs playit` +- If `PLAYIT_SECRET` is missing from `.env`, the agent won't start a tunnel — see [getting-started.md](getting-started.md) step 5 +- Confirm the player's UUID is in `MC_WHITELIST` in `.env` +- Ensure the Minecraft client version matches `MC_VERSION` (or that ViaVersion is active for cross-version support) + +## Tunnel not working + +```bash +docker compose restart playit +docker compose logs playit +``` + +If the agent prints a claim URL, your secret has expired or was never set. Re-claim: + +1. Open the URL in the logs +2. Reconfigure the tunnel in the playit dashboard +3. Update `PLAYIT_SECRET` in `.env` +4. `docker compose restart playit` + +## Plugins failing + +Check server logs for compatibility errors: + +```bash +docker compose logs mc | grep -i "error\|warn\|plugin" +``` + +- Ensure the plugin version supports your `MC_VERSION` +- Re-run `auto_configure.sh` to reset to known-compatible versions + +## Performance issues + +```bash +docker stats mc +``` + +In-game, run `/spark profiler start` and check the report for bottlenecks. Lower `MC_VIEW_DISTANCE` or `MC_SIMULATION_DISTANCE` in `.env` if TPS is consistently below 20. diff --git a/docs/usage.md b/docs/usage.md index 629ac1e..4eea402 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -6,10 +6,16 @@ docker compose up -d ``` +This starts both the Minecraft server (`mc`) and the playit tunnel agent (`playit`). + ## Viewing Logs ```bash +# Minecraft server docker compose logs -f mc + +# playit agent +docker compose logs -f playit ``` ## Stopping the Server @@ -24,14 +30,36 @@ docker compose down docker compose exec mc rcon-cli ``` -Type `exit` to leave the console. +Type `exit` to leave. + +## Whitelisting and Operator Permissions + +Set `MC_WHITELIST` and `MC_OPS` in `.env` (comma-separated UUIDs), then restart: + +```bash +docker compose restart mc +``` + +Or manage live via the console: -## Whitelisting / Operator Permissions +```bash +docker compose exec mc rcon-cli +# then: +whitelist add +op +``` -Set `OPS` in `compose.yml`, or use: +## Checking Server Performance ```bash -docker compose exec mc rcon-cli op +docker stats mc ``` -Use `whitelist add ` if the whitelist is enabled. +In-game: + +``` +/tps — current TPS +/spark profiler start — profile for 60s then generate report +/minefetch — system info +/loadfetch — CPU/RAM graphs +``` diff --git a/scripts/auto_configure.sh b/scripts/auto_configure.sh index 1ade086..f49f234 100644 --- a/scripts/auto_configure.sh +++ b/scripts/auto_configure.sh @@ -60,10 +60,9 @@ BACKUPER_URL="https://github.com/DVDishka/Backuper/releases/download/4.0.6/Backu MINEFETCH_URL="https://github.com/mlijekome/minefetch/releases/download/Release/Minefetch-1.0-SNAPSHOT.jar" LUCKPERMS_URL="https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.151.jar" SPARK_URL="https://spark.lucko.me/download/bukkit/spark-1.10.117.jar" -TCPSHIELD_URL="https://github.com/TCPShield/RealIP/releases/download/2.8.1/TCPShield-2.8.1.jar" # Combine plugin URLs -PLUGINS="${TCPSHIELD_URL},${BACKUPER_URL},${VIAVERSION_URL},${MINEFETCH_URL},${LUCKPERMS_URL},${SPARK_URL}" +PLUGINS="${BACKUPER_URL},${VIAVERSION_URL},${MINEFETCH_URL},${LUCKPERMS_URL},${SPARK_URL}" # Generate/update .env file ENV_FILE="$(dirname "$0")/../.env" @@ -117,7 +116,7 @@ echo "" echo -e "Configuration summary:" echo -e " Minecraft Version: ${YELLOW}${MC_VERSION}${NC}" echo -e " Java Version: ${YELLOW}${JAVA_VERSION}${NC}" -echo -e " Plugins: ViaVersion, Backuper, TCPShield, Minefetch, LuckPerms, Spark" +echo -e " Plugins: ViaVersion, Backuper, Minefetch, LuckPerms, Spark" echo "" echo -e "To use a different Minecraft version, run:" echo -e " ${YELLOW}MC_VERSION=1.20.4 $0${NC}" diff --git a/scripts/setup_master.sh b/scripts/setup_master.sh index 2ac4df9..9c2a0b1 100644 --- a/scripts/setup_master.sh +++ b/scripts/setup_master.sh @@ -1,7 +1,6 @@ #!/bin/bash # Master Setup Script for Ewan's Minecraft Server -# Enhanced with Maximum Efficiency Optimizations and Minefetch Integration # Colors for output RED='\033[0;31m' @@ -19,7 +18,10 @@ COMPOSE_FILE="$SERVER_DIR/compose.yml" BACKUP_DIR="$SERVER_DIR/data_backups" CONFIG_APPLIED=false -# Function to print colored output +# --------------------------------------------------------------------------- +# Output helpers +# --------------------------------------------------------------------------- + print_info() { echo -e "${BLUE}[INFO]${NC} $1" } @@ -44,21 +46,22 @@ print_tip() { echo -e "${MAGENTA}[TIP]${NC} $1" } -# Function to print banner print_banner() { echo -e "${CYAN}" cat << "EOF" ╔═══════════════════════════════════════════════════════════╗ ║ ║ -║ Ewan's Minecraft Server - Master Setup Script ║ -║ Maximum Efficiency Edition with Minefetch ║ +║ Ewan's Minecraft Server — Setup Script ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝ EOF echo -e "${NC}" } -# Function to detect operating system +# --------------------------------------------------------------------------- +# Environment +# --------------------------------------------------------------------------- + detect_os() { if [[ "$OSTYPE" == "darwin"* ]]; then OS="macOS" @@ -69,7 +72,6 @@ detect_os() { fi } -# Function to detect Linux distribution detect_linux_distro() { if [ -f /etc/os-release ]; then . /etc/os-release @@ -83,7 +85,6 @@ detect_linux_distro() { fi } -# Function to check if Docker is installed and running check_docker() { print_info "Checking Docker installation..." if ! command -v docker &> /dev/null; then @@ -91,7 +92,7 @@ check_docker() { print_info "Please install Docker Desktop from https://www.docker.com/products/docker-desktop/" exit 1 fi - + if ! docker info &> /dev/null; then print_error "Docker is installed but not running." print_info "Please start Docker Desktop and try again." @@ -100,584 +101,543 @@ check_docker() { print_success "Docker is installed and running." } -# Function to check if Docker Compose is installed check_docker_compose() { print_info "Checking Docker Compose installation..." - if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then - print_error "Docker Compose is not installed." - print_info "It's usually included with Docker Desktop. Please ensure Docker Desktop is up to date." + if ! docker compose version &> /dev/null; then + print_error "Docker Compose V2 is not available." + print_info "Ensure Docker Desktop is up to date." exit 1 fi print_success "Docker Compose is available." } -# Function to create backup +# --------------------------------------------------------------------------- +# .env setup +# --------------------------------------------------------------------------- + +setup_env() { + print_header "Environment Configuration" + + local env_file="$SERVER_DIR/.env" + local env_example="$SERVER_DIR/.env.example" + + if [ ! -f "$env_file" ]; then + if [ -f "$env_example" ]; then + print_info "No .env file found. Copying from .env.example..." + cp "$env_example" "$env_file" + print_success ".env created — open it and fill in MC_VERSION at minimum." + read -p "Press Enter when ready, or Ctrl+C to exit and edit first: " + else + print_warning ".env.example not found. Create .env manually before continuing." + read -p "Press Enter when ready, or Ctrl+C to exit: " + fi + else + print_success ".env file found." + fi + + # Source .env so variables are available for the rest of the script + if [ -f "$env_file" ]; then + set -a + # shellcheck disable=SC1090 + source "$env_file" + set +a + fi + + if [ -z "$MC_VERSION" ]; then + read -p "Minecraft version to use [1.21.1]: " input_version + export MC_VERSION="${input_version:-1.21.1}" + else + print_info "MC_VERSION: $MC_VERSION" + fi +} + +# --------------------------------------------------------------------------- +# Backup +# --------------------------------------------------------------------------- + create_backup() { print_header "Creating Backup" - - if [ ! -d "$SERVER_DIR/data" ]; then - print_warning "No data directory found. Skipping backup." + + local data_dir="${MC_DATA_DIR:-/Volumes/Storage/Server/MC/data}" + + if [ ! -d "$data_dir" ]; then + print_warning "No data directory found at $data_dir. Skipping backup." return 0 fi - - # Create backup directory if it doesn't exist + mkdir -p "$BACKUP_DIR" - + local backup_name="data_backup_$(date +%Y%m%d_%H%M%S)" local backup_path="$BACKUP_DIR/$backup_name" - + print_info "Creating backup: $backup_name" print_info "This may take a few minutes..." - - if cp -r "$SERVER_DIR/data" "$backup_path"; then - print_success "Backup created successfully at: $backup_path" - - # Also backup compose.yml + + if cp -r "$data_dir" "$backup_path"; then + print_success "Backup created at: $backup_path" if [ -f "$COMPOSE_FILE" ]; then cp "$COMPOSE_FILE" "$backup_path/compose.yml.backup" - print_success "compose.yml backed up as well" + print_success "compose.yml backed up as well." fi - return 0 else - print_error "Failed to create backup" + print_error "Failed to create backup." return 1 fi } -# Function to show optimization levels +# --------------------------------------------------------------------------- +# Optimisation +# --------------------------------------------------------------------------- + show_optimization_levels() { echo "" - print_header "Available Optimization Levels" + print_header "Available Optimisation Levels" echo "" - + echo -e "${GREEN}1) Maximum Efficiency (RECOMMENDED)${NC}" - echo " ├─ Memory: 256MB-1.28GB (93% reduction)" + echo " ├─ Memory: 256MB-1.28GB" echo " ├─ Players: 6 max" echo " ├─ View Distance: 4 chunks" - echo " ├─ Plugins: 5 essential" - echo " ├─ Cost Savings: ~$60/month" - echo " └─ Best for: 2-6 players, budget hosting" + echo " └─ Best for: 2-6 players" echo "" - - echo -e "${YELLOW}2) Ultra-Optimized (BALANCED)${NC}" - echo " ├─ Memory: 384MB-1.5GB (75% reduction)" + + echo -e "${YELLOW}2) Ultra-Optimised (BALANCED)${NC}" + echo " ├─ Memory: 384MB-1.5GB" echo " ├─ Players: 8 max" echo " ├─ View Distance: 5 chunks" - echo " ├─ Plugins: 6 essential" - echo " ├─ Cost Savings: ~$45/month" - echo " └─ Best for: 4-8 players, moderate hosting" + echo " └─ Best for: 4-8 players" echo "" - - echo -e "${CYAN}3) Light Optimization${NC}" - echo " ├─ Memory: 512MB-2GB (50% reduction)" + + echo -e "${CYAN}3) Light Optimisation${NC}" + echo " ├─ Memory: 512MB-2GB" echo " ├─ Players: 10 max" echo " ├─ View Distance: 6 chunks" - echo " ├─ Plugins: 6 essential" - echo " ├─ Cost Savings: ~$30/month" - echo " └─ Best for: 6-10 players, standard hosting" + echo " └─ Best for: 6-10 players" echo "" - + echo -e "${RED}4) Original Configuration${NC}" echo " ├─ Memory: 4GB fixed" echo " ├─ Players: 10 max" echo " ├─ View Distance: 10 chunks" - echo " ├─ Plugins: 11 total" - echo " ├─ Cost: Full price" - echo " └─ Best for: High-end hosting, many players" + echo " └─ Best for: high-end hosting" echo "" - - echo -e "${BLUE}5) Skip Optimization${NC}" + + echo -e "${BLUE}5) Skip${NC}" echo " └─ Keep current configuration" echo "" } -# Function to apply Maximum Efficiency configuration apply_max_efficiency() { print_header "Applying Maximum Efficiency Configuration" - - # The compose.yml is already updated with max efficiency settings - # Just verify it exists + if [ ! -f "$COMPOSE_FILE" ]; then print_error "compose.yml not found at $COMPOSE_FILE" return 1 fi - - print_success "Maximum Efficiency configuration already applied to compose.yml" - print_info "Configuration includes:" + + print_success "Maximum Efficiency settings applied in compose.yml." + print_info "Configuration:" echo " - Memory: 256MB-1.28GB" echo " - View Distance: 4 chunks" echo " - Simulation Distance: 3 chunks" echo " - Max Players: 6" - echo " - Plugins: 5 essential (includes Minefetch)" - echo " - Advanced JVM tuning (16 custom flags)" - echo " - Aggressive Paper/Spigot/Bukkit optimizations" - + echo " - Plugins: 5 (Backuper, ViaVersion, Minefetch, LuckPerms, Spark)" + echo " - Aikar's JVM flags" + CONFIG_APPLIED=true return 0 } -# Function to install neofetch (cross-platform) +# --------------------------------------------------------------------------- +# Neofetch (for Minefetch plugin) +# --------------------------------------------------------------------------- + install_neofetch() { print_header "Installing Neofetch for Minefetch Plugin" - - # Check if server is running - if ! docker ps | grep -q "mc"; then - print_warning "Server container 'mc' is not running." - print_info "Please start the server first, then run: docker exec mc apt-get update && docker exec mc apt-get install -y neofetch" + + if ! docker ps | grep -q "^.*mc$"; then + print_warning "Server container 'mc' is not running. Start the server first." return 1 fi - - print_info "Detected OS: $OS" - - if [ "$OS" == "Linux" ] || docker ps | grep -q "mc"; then - # Install in Docker container - print_info "Installing neofetch in server container..." - - # Detect container OS - docker exec mc bash -c "cat /etc/os-release" &> /dev/null - if [ $? -eq 0 ]; then - local container_os=$(docker exec mc bash -c "grep '^ID=' /etc/os-release | cut -d'=' -f2 | tr -d '\"'") - print_info "Container OS: $container_os" - - case "$container_os" in - ubuntu|debian) - print_info "Installing via apt-get..." - docker exec mc bash -c "apt-get update -qq && apt-get install -y neofetch" > /dev/null 2>&1 - ;; - fedora|rhel|centos|rocky|almalinux) - print_info "Installing via dnf/yum..." - if docker exec mc bash -c "command -v dnf" &> /dev/null; then - docker exec mc bash -c "dnf install -y neofetch" > /dev/null 2>&1 - else - docker exec mc bash -c "yum install -y neofetch" > /dev/null 2>&1 - fi - ;; - *) - print_warning "Unknown container OS. Attempting apt-get..." - docker exec mc bash -c "apt-get update -qq && apt-get install -y neofetch" > /dev/null 2>&1 - ;; - esac - fi - - # Verify installation - if docker exec mc bash -c "command -v neofetch" &> /dev/null; then - local version=$(docker exec mc neofetch --version 2>&1 | head -1) - print_success "Neofetch installed in container: $version" - - # Test it - print_info "Testing neofetch output:" - echo "----------------------------------------" - docker exec mc neofetch --off --stdout | head -10 - echo "----------------------------------------" - - return 0 - else - print_error "Failed to install neofetch in container" - return 1 - fi - elif [ "$OS" == "macOS" ]; then - # Install on macOS host (for reference) - print_info "Detected macOS. Installing neofetch via Homebrew..." - - if ! command -v brew &> /dev/null; then - print_warning "Homebrew not found. Installing Homebrew first..." - print_info "This may take several minutes. Please be patient..." - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - - # Add Homebrew to PATH - if [[ -f "/opt/homebrew/bin/brew" ]]; then - eval "$(/opt/homebrew/bin/brew shellenv)" - elif [[ -f "/usr/local/bin/brew" ]]; then - eval "$(/usr/local/bin/brew shellenv)" + + print_info "Installing neofetch in server container..." + + local container_os + container_os=$(docker exec mc bash -c "grep '^ID=' /etc/os-release | cut -d'=' -f2 | tr -d '\"'" 2>/dev/null) + + case "$container_os" in + ubuntu|debian) + docker exec mc bash -c "apt-get update -qq && apt-get install -y neofetch" > /dev/null 2>&1 + ;; + fedora|rhel|centos|rocky|almalinux) + if docker exec mc bash -c "command -v dnf" &> /dev/null; then + docker exec mc bash -c "dnf install -y neofetch" > /dev/null 2>&1 + else + docker exec mc bash -c "yum install -y neofetch" > /dev/null 2>&1 fi - fi - - print_info "Installing neofetch..." - brew install neofetch - - if command -v neofetch &> /dev/null; then - print_success "Neofetch installed on macOS host" - print_info "Note: For Minefetch to work in Minecraft, neofetch must also be in the container" - return 0 - else - print_error "Failed to install neofetch on macOS" - return 1 - fi - fi -} + ;; + *) + print_warning "Unknown container OS ($container_os). Attempting apt-get..." + docker exec mc bash -c "apt-get update -qq && apt-get install -y neofetch" > /dev/null 2>&1 + ;; + esac -# Function to setup DuckDNS -setup_duckdns_service() { - print_header "Setting up DuckDNS" - - local duckdns_script="$SCRIPT_DIR/setup_duckdns.sh" - - if [ -f "$duckdns_script" ]; then - chmod +x "$duckdns_script" - "$duckdns_script" - if [ $? -eq 0 ]; then - print_success "DuckDNS setup completed" - else - print_error "DuckDNS setup failed. Check output above." - return 1 - fi + if docker exec mc bash -c "command -v neofetch" &> /dev/null; then + local version + version=$(docker exec mc neofetch --version 2>&1 | head -1) + print_success "Neofetch installed: $version" + echo "----------------------------------------" + docker exec mc neofetch --off --stdout | head -10 + echo "----------------------------------------" + return 0 else - print_error "setup_duckdns.sh not found in scripts directory" + print_error "Failed to install neofetch in container." return 1 fi } -# Function to start the Minecraft server +# --------------------------------------------------------------------------- +# Server start +# --------------------------------------------------------------------------- + start_minecraft_server() { print_header "Starting Minecraft Server" - - cd "$SERVER_DIR" - - print_info "Starting server with docker-compose..." - - if docker-compose up -d 2>/dev/null || docker compose up -d 2>/dev/null; then - print_success "Server started successfully" - - print_info "Waiting for server to initialize (this may take 30-60 seconds)..." + + cd "$SERVER_DIR" || exit 1 + + if docker compose up -d; then + print_success "Containers started." + + print_info "Waiting for server to initialise (this may take 30-60 seconds)..." sleep 5 - - # Show logs + print_info "Showing server logs (Ctrl+C to stop watching):" echo "----------------------------------------" - docker-compose logs -f --tail=20 mc 2>/dev/null || docker compose logs -f --tail=20 mc 2>/dev/null & + docker compose logs -f --tail=20 mc & local logs_pid=$! - - # Wait a bit then stop showing logs sleep 15 kill $logs_pid 2>/dev/null - echo "" - print_tip "To view full logs, run: docker-compose logs -f mc" - print_tip "To check server status, run: docker ps" - + + print_tip "Full logs: docker compose logs -f mc" + print_tip "Status: docker ps" return 0 else - print_error "Failed to start server" + print_error "Failed to start containers." return 1 fi } -# Function to show server status -show_server_status() { - print_header "Server Status" - - if docker ps | grep -q "mc"; then - print_success "Server is RUNNING" - - # Get resource usage - print_info "Resource Usage:" - docker stats mc --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" - - echo "" - print_tip "In-game commands to check performance:" - echo " /tps - Check server TPS" - echo " /minefetch - Display system information" - echo " /loadfetch - Display CPU/RAM usage with graphs" - else - print_warning "Server is NOT running" - print_info "To start: docker-compose up -d" +# --------------------------------------------------------------------------- +# playit.gg tunnel +# --------------------------------------------------------------------------- + +setup_playit() { + print_header "playit.gg Tunnel" + + local env_file="$SERVER_DIR/.env" + + # Check if PLAYIT_SECRET is already configured + if [ -f "$env_file" ] && grep -qE "^PLAYIT_SECRET=.+" "$env_file"; then + print_success "PLAYIT_SECRET is set — tunnel will start automatically." + return 0 + fi + + print_warning "PLAYIT_SECRET is not set in .env." + print_info "Starting the playit agent to generate a claim URL..." + + cd "$SERVER_DIR" || exit 1 + docker compose up -d playit 2>/dev/null + + print_info "Waiting for claim URL..." + sleep 4 + + echo "" + docker compose logs --tail=30 playit 2>/dev/null + echo "" + + print_tip "1. Open the claim URL above in your browser and sign into playit.gg" + print_tip "2. Add a Minecraft tunnel pointed at mc:25565" + print_tip "3. Copy the secret key from the playit dashboard" + print_tip "4. Add it to .env: PLAYIT_SECRET=your_secret_here" + print_tip "5. Run: docker compose restart playit" + echo "" +} + +# --------------------------------------------------------------------------- +# Shell aliases +# --------------------------------------------------------------------------- + +setup_aliases() { + print_header "Setting up Command Aliases" + + local shell_profile="" + local alias_script="" + + if [ "$OS" == "macOS" ]; then + shell_profile="${HOME}/.zshrc" + [ ! -f "$shell_profile" ] && shell_profile="${HOME}/.bash_profile" + alias_script="server_status_mac.sh" + elif [ "$OS" == "Linux" ]; then + shell_profile="${HOME}/.bashrc" + [ ! -f "$shell_profile" ] && shell_profile="${HOME}/.zshrc" + alias_script="server_status_linux.sh" + fi + + if [ -z "$shell_profile" ]; then + print_warning "Could not find shell profile. Add aliases manually." + return 1 + fi + + if grep -q "alias mcserver=" "$shell_profile" 2>/dev/null; then + print_info "Aliases already exist in $shell_profile." + return 0 fi + + { + echo "" + echo "# Minecraft Server Aliases" + echo "alias mcserver='$SCRIPT_DIR/$alias_script'" + echo "alias mclog='docker compose -f $COMPOSE_FILE logs -f mc'" + echo "alias mcstats='docker stats mc'" + echo "alias mcstart='docker compose -f $COMPOSE_FILE up -d'" + echo "alias mcstop='docker compose -f $COMPOSE_FILE down'" + echo "alias mcrestart='docker compose -f $COMPOSE_FILE restart'" + } >> "$shell_profile" + + print_success "Aliases added to $shell_profile." + print_info "Available aliases: mcserver, mclog, mcstats, mcstart, mcstop, mcrestart" + print_tip "Run: source $shell_profile (or restart your terminal)" } -# Function to run post-installation tests +# --------------------------------------------------------------------------- +# Post-install tests +# --------------------------------------------------------------------------- + run_post_install_tests() { print_header "Running Post-Installation Tests" - + local tests_passed=0 local tests_total=5 - - # Test 1: Docker running - print_info "Test 1/5: Docker status" - if docker ps | grep -q "mc"; then - print_success "✓ Server container is running" + + # Test 1: mc container running + print_info "Test 1/5: mc container" + if docker ps --format '{{.Names}}' | grep -q "^mc$"; then + print_success "✓ mc container is running" ((tests_passed++)) else - print_error "✗ Server container is not running" + print_error "✗ mc container is not running" fi - + # Test 2: Memory usage print_info "Test 2/5: Memory usage" - local mem_usage=$(docker stats mc --no-stream --format "{{.MemUsage}}" | awk '{print $1}') - if [[ ! -z "$mem_usage" ]]; then + local mem_usage + mem_usage=$(docker stats mc --no-stream --format "{{.MemUsage}}" 2>/dev/null | awk '{print $1}') + if [ -n "$mem_usage" ]; then print_success "✓ Memory usage: $mem_usage" ((tests_passed++)) else - print_error "✗ Could not get memory usage" + print_error "✗ Could not read memory usage" fi - - # Test 3: Neofetch installed - print_info "Test 3/5: Neofetch installation" + + # Test 3: Neofetch + print_info "Test 3/5: Neofetch" if docker exec mc bash -c "command -v neofetch" &> /dev/null; then print_success "✓ Neofetch is installed" ((tests_passed++)) else - print_warning "✗ Neofetch is not installed (Minefetch won't work)" + print_warning "✗ Neofetch not installed — Minefetch won't work" fi - - # Test 4: TCP Shield plugin - print_info "Test 4/5: TCP Shield plugin" + + # Test 4: playit agent + print_info "Test 4/5: playit agent" sleep 2 - if docker-compose logs mc 2>/dev/null | grep -q "TCPShield" || docker compose logs mc 2>/dev/null | grep -q "TCPShield"; then - print_success "✓ TCP Shield plugin detected" + if docker ps --format '{{.Names}}' | grep -q "^playit-agent$"; then + print_success "✓ playit agent is running" ((tests_passed++)) else - print_warning "✗ TCP Shield plugin not detected (may still be loading)" + print_warning "✗ playit agent not running — check PLAYIT_SECRET in .env" fi - - # Test 5: Server responsiveness - print_info "Test 5/5: Server responsiveness" - if docker-compose logs mc 2>/dev/null | grep -q "Done" || docker compose logs mc 2>/dev/null | grep -q "Done"; then - print_success "✓ Server is ready (Done loading)" + + # Test 5: Server done loading + print_info "Test 5/5: Server ready" + if docker compose logs mc 2>/dev/null | grep -q "Done"; then + print_success "✓ Server is ready" ((tests_passed++)) else - print_warning "✗ Server still initializing (this is normal, wait 1-2 minutes)" + print_warning "✗ Server still initialising — wait 1-2 minutes and recheck" fi - + echo "" - print_info "Tests Passed: $tests_passed/$tests_total" - + print_info "Tests passed: $tests_passed/$tests_total" + if [ $tests_passed -ge 3 ]; then - print_success "Server setup looks good! ✓" + print_success "Setup looks good! ✓" else - print_warning "Some tests failed. Please check the output above." + print_warning "Some tests failed. Check the output above." fi } -# Function to setup aliases -setup_aliases() { - print_header "Setting up Command Aliases" - - local shell_profile="" +# --------------------------------------------------------------------------- +# Summary +# --------------------------------------------------------------------------- - if [ "$OS" == "macOS" ]; then - if [ -f "$HOME/.zshrc" ]; then - shell_profile="$HOME/.zshrc" - elif [ -f "$HOME/.bash_profile" ]; then - shell_profile="$HOME/.bash_profile" - fi - ALIAS_SCRIPT="server_status_mac.sh" - elif [ "$OS" == "Linux" ]; then - if [ -f "$HOME/.bashrc" ]; then - shell_profile="$HOME/.bashrc" - elif [ -f "$HOME/.zshrc" ]; then - shell_profile="$HOME/.zshrc" - fi - ALIAS_SCRIPT="server_status_linux.sh" - fi - - if [ -n "$shell_profile" ]; then - local alias_command="alias mcserver='$SCRIPT_DIR/$ALIAS_SCRIPT'" - - if ! grep -q "alias mcserver=" "$shell_profile"; then - echo "" >> "$shell_profile" - echo "# Minecraft Server Aliases" >> "$shell_profile" - echo "$alias_command" >> "$shell_profile" - echo "alias mclog='docker-compose -f $SERVER_DIR/compose.yml logs -f mc'" >> "$shell_profile" - echo "alias mcstats='docker stats mc'" >> "$shell_profile" - echo "alias mcstop='docker-compose -f $SERVER_DIR/compose.yml down'" >> "$shell_profile" - echo "alias mcstart='docker-compose -f $SERVER_DIR/compose.yml up -d'" >> "$shell_profile" - echo "alias mcrestart='docker-compose -f $SERVER_DIR/compose.yml restart'" >> "$shell_profile" - - print_success "Aliases added to $shell_profile" - print_info "Available aliases:" - echo " mcserver - Server status script" - echo " mclog - View server logs" - echo " mcstats - View resource usage" - echo " mcstart - Start server" - echo " mcstop - Stop server" - echo " mcrestart - Restart server" - echo "" - print_tip "Run: source $shell_profile (or restart terminal)" - else - print_info "Aliases already exist in $shell_profile" - fi - else - print_warning "Could not find shell profile. Please add aliases manually." - fi -} - -# Function to display final summary display_summary() { echo "" print_header "Setup Complete! 🎉" echo "" - - print_success "Your Minecraft server is configured and ready!" + + print_success "Your Minecraft server is configured and ready." echo "" - + if [ "$CONFIG_APPLIED" = true ]; then - echo -e "${GREEN}Applied Configuration: Maximum Efficiency${NC}" + echo -e "${GREEN}Applied: Maximum Efficiency${NC}" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo " Memory Usage: 256MB-1.28GB (93% reduction)" - echo " Max Players: 6" - echo " View Distance: 4 chunks" - echo " Simulation Distance: 3 chunks" - echo " Plugins: 5 essential (includes Minefetch)" - echo " Estimated Savings: ~$60/month" + echo " Memory: 256MB-1.28GB" + echo " Max players: 6" + echo " View distance: 4 chunks" + echo " Simulation distance: 3 chunks" + echo " Plugins: 5 (Backuper, ViaVersion, Minefetch, LuckPerms, Spark)" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" fi - + print_info "Quick Commands:" - echo " View logs: docker-compose logs -f mc" - echo " Check status: docker stats mc" - echo " Stop server: docker-compose down" - echo " Restart: docker-compose restart" + echo " View logs: docker compose logs -f mc" + echo " Status: docker stats mc" + echo " Stop: docker compose down" + echo " Restart: docker compose restart" echo "" - - print_info "In-Game Commands (once connected):" - echo " /minefetch - Display system information" - echo " /loadfetch - Display CPU/RAM usage graphs" - echo " /tps - Check server performance" + + print_info "In-Game Commands:" + echo " /tps - Server performance" + echo " /minefetch - System information" + echo " /loadfetch - CPU/RAM graphs" echo "" - + print_info "Next Steps:" - echo " 1. Wait 1-2 minutes for full server startup" - echo " 2. Connect via your TCP Shield domain" - echo " 3. Run /minefetch to test system monitoring" - echo " 4. Monitor performance with: docker stats mc" + echo " 1. Wait 1-2 minutes for full startup" + echo " 2. Complete playit.gg tunnel setup if not done — https://playit.gg/account/tunnels" + echo " 3. Connect via your playit.gg address" + echo " 4. Run /minefetch to verify system monitoring" echo "" - + print_info "Documentation:" - echo " - MAX_EFFICIENCY_GUIDE.md - Complete optimization details" - echo " - docs/ folder - Additional guides and troubleshooting" + echo " - docs/ — guides and troubleshooting" + echo " - .env — all configurable options" echo "" - - if [ -d "$BACKUP_DIR" ]; then - print_tip "Backups are stored in: $BACKUP_DIR" - fi - + echo "" print_success "Happy crafting! ⛏️" echo "" } -# Main function +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- + main() { clear print_banner - - # Detect OS + detect_os - print_info "Detected Operating System: $OS" - + print_info "Operating System: $OS" + if [ "$OS" == "Linux" ]; then detect_linux_distro - print_info "Linux Distribution: $DISTRO" + print_info "Distribution: $DISTRO" fi - + if [ "$OS" == "Unknown" ]; then print_error "Unsupported operating system: $OSTYPE" - print_info "This script supports macOS and Linux only" + print_info "This script supports macOS and Linux only." exit 1 fi echo "" - - # Check prerequisites + + # Prerequisites check_docker check_docker_compose echo "" - - # Auto-configure Java version and plugins based on Minecraft version - print_header "Auto-Configuring for Minecraft Version" + + # Environment (.env + MC_VERSION) + setup_env + echo "" + + # Auto-configure image and plugins for the given MC version + print_header "Auto-Configuring for Minecraft $MC_VERSION" if [ -f "$SCRIPT_DIR/auto_configure.sh" ]; then - # Make script executable chmod +x "$SCRIPT_DIR/auto_configure.sh" - - # Get MC version if set, otherwise prompt - if [ -z "$MC_VERSION" ]; then - read -p "Minecraft version to use [1.21.1]: " input_version - export MC_VERSION="${input_version:-1.21.1}" - fi - - # Run auto-configuration bash "$SCRIPT_DIR/auto_configure.sh" - print_success "Auto-configuration complete" + print_success "Auto-configuration complete." else - print_warning "Auto-configuration script not found. Using defaults." + print_warning "auto_configure.sh not found. Using existing settings." fi echo "" - - # Create backup - print_info "It's recommended to create a backup before proceeding." + + # Optional backup + print_info "It's recommended to back up your data before proceeding." read -p "Create backup now? (Y/n): " backup_choice if [[ ! "$backup_choice" =~ ^[Nn]$ ]]; then create_backup || print_warning "Continuing without backup..." fi echo "" - - # Show optimization levels and apply + + # Optimisation level show_optimization_levels - read -p "Select optimization level (1-5) [1]: " opt_level + read -p "Select optimisation level (1-5) [1]: " opt_level opt_level=${opt_level:-1} - + case "$opt_level" in - 1) - apply_max_efficiency - ;; + 1) apply_max_efficiency ;; 2|3|4) - print_info "Selected configuration level $opt_level" - print_warning "Note: The current compose.yml has Maximum Efficiency applied" - print_warning "To use other levels, you'll need to manually modify compose.yml" - print_tip "See documentation for configuration examples" - ;; - 5) - print_info "Skipping optimization. Using current configuration." - ;; - *) - print_warning "Invalid selection. Using current configuration." + print_info "Levels 2-4 require manual edits to compose.yml." + print_tip "See docs/ for configuration examples." ;; + 5) print_info "Keeping current configuration." ;; + *) print_warning "Invalid selection. Keeping current configuration." ;; esac echo "" - - # Setup DuckDNS - read -p "Do you want to set up or reconfigure DuckDNS? (y/N): " setup_duckdns_choice - if [[ "$setup_duckdns_choice" =~ ^[Yy]$ ]]; then - setup_duckdns_service - else - print_info "Skipping DuckDNS setup" - fi - echo "" - - # Start Minecraft Server - read -p "Do you want to start the Minecraft server now? (Y/n): " start_server_choice + + # Start server + read -p "Start the server now? (Y/n): " start_server_choice if [[ ! "$start_server_choice" =~ ^[Nn]$ ]]; then start_minecraft_server + echo "" + setup_playit else - print_info "Skipping server start" - print_tip "Start manually with: docker-compose up -d" + print_info "Skipping server start." + print_tip "Start manually with: docker compose up -d" + echo "" + print_info "To set up the playit tunnel later, run:" + print_tip "docker compose up -d playit && docker compose logs playit" fi echo "" - - # Install Minefetch - if docker ps | grep -q "mc"; then - read -p "Install neofetch for Minefetch plugin? (Y/n): " install_neo_choice + + # Neofetch for Minefetch plugin + if docker ps --format '{{.Names}}' | grep -q "^mc$"; then + read -p "Install neofetch for the Minefetch plugin? (Y/n): " install_neo_choice if [[ ! "$install_neo_choice" =~ ^[Nn]$ ]]; then install_neofetch else - print_info "Skipping neofetch installation" - print_warning "Minefetch plugin won't work without neofetch" + print_info "Skipping neofetch." + print_warning "Minefetch won't work without it." fi echo "" fi - - # Setup Aliases - read -p "Do you want to set up command aliases? (Y/n): " setup_aliases_choice + + # Aliases + read -p "Set up shell aliases? (Y/n): " setup_aliases_choice if [[ ! "$setup_aliases_choice" =~ ^[Nn]$ ]]; then setup_aliases else - print_info "Skipping alias setup" + print_info "Skipping alias setup." fi echo "" - - # Run tests - if docker ps | grep -q "mc"; then + + # Post-install tests + if docker ps --format '{{.Names}}' | grep -q "^mc$"; then read -p "Run post-installation tests? (Y/n): " run_tests_choice if [[ ! "$run_tests_choice" =~ ^[Nn]$ ]]; then echo "" @@ -685,10 +645,8 @@ main() { echo "" fi fi - - # Show final summary + display_summary } -# Run main function main "$@" -- 2.51.2