This commit is contained in:
2025-10-02 00:51:42 +02:00
commit 070b02ea62
16 changed files with 298 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
data/*
backups/*.tar.gz

17
README.md Normal file
View File

@@ -0,0 +1,17 @@
**Struktura**
mc-server/
├── data/ # Svět a soubory serveru (svázané přes Docker volume)
├── backups/ # Automatické zálohy
├── docker-compose.yml # Minecraft server v Dockeru
├── backup.sh # 🔁 Pravidelné zálohy světa
├── restore.sh # ♻️ Obnova zálohy podle výběru
├── start.sh # ▶️ Spuštění serveru
├── stop.sh # ⛔ Zastavení serveru (volitelné)
└── restart.sh # 🔄 Restart serveru (volitelné)
**cron job:**
*/15 * * * * /cesta/mc-server/backup.sh >> /cesta/mc-server/backup.log 2>&1

39
backup.sh Normal file
View File

@@ -0,0 +1,39 @@
#!/bin/bash
# Absolutní cesta ke skriptu
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONTAINER="mc-vanilla"
BACKUP_DIR="/mnt/backups/minecraft_backups/frankstein"
WORLD_DIR="$DIR/data/world"
DATE_FULL=$(date +%F_%H-%M)
DATE_HOUR=$(date +%F_%H)
DATE_DAY=$(date +%F)
ARCHIVE_NAME="$BACKUP_DIR/world_$DATE_FULL.tar.gz"
mkdir -p "$BACKUP_DIR"
# Zakázání ukládání ve hře
docker exec -i $CONTAINER rcon-cli save-off
docker exec -i $CONTAINER rcon-cli save-all
sleep 3
# Vytvoření zálohy
tar -czf "$ARCHIVE_NAME" "$WORLD_DIR"
# Znovupovolení ukládání
docker exec -i $CONTAINER rcon-cli save-on
# Smazání všech záloh ze stejné hodiny, kromě nejnovější
find "$BACKUP_DIR" -name "world_${DATE_HOUR}_*.tar.gz" ! -newer "$ARCHIVE_NAME" -delete
# Zachování pouze nejnovější zálohy z každého předchozího dne
find "$BACKUP_DIR" -name "world_*.tar.gz" | while read file; do
file_day=$(basename "$file" | cut -d'_' -f2)
newest=$(find "$BACKUP_DIR" -name "world_${file_day}_*.tar.gz" | sort | tail -n 1)
if [ "$file" != "$newest" ]; then
rm "$file"
fi
done

1
backups/poznamka.md Normal file
View File

@@ -0,0 +1 @@
tady se budou nacházet zálohy serveru až se spustí!

5
discord-bot/.env-bot Normal file
View File

@@ -0,0 +1,5 @@
TOKEN='MTI1ODE0NDgxODk3OTE0Nzg5Ng.GKTl0Q.4vzvSFiPs8tl93B42R7PcqpM70C2Ov0YXHQdVU'
GUILD_ID=938745671870185482
CHANNEL_ID=1382456524009640057
MC_HOST='147.185.221.29'
MC_PORT=7272

11
discord-bot/Dockerfile Normal file
View File

@@ -0,0 +1,11 @@
# discord-bot/Dockerfile
FROM python:3.11-slim
WORKDIR /discord-bot
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "frankstein-bot.py"]

View File

@@ -0,0 +1,52 @@
import discord
from discord.ext import tasks, commands
from mcstatus import JavaServer
import os
TOKEN = os.environ['TOKEN']
MC_HOST = os.environ.get('MC_HOST', 'localhost')
MC_PORT = int(os.environ.get('MC_PORT', 7272))
CHANNEL_ID = int(os.environ['CHANNEL_ID'])
intents = discord.Intents.default()
bot = commands.Bot(command_prefix='!', intents=intents)
@bot.event
async def on_ready():
print(f'Přihlášen jako {bot.user}')
update_status.start()
@tasks.loop(seconds=5)
async def update_status():
channel = bot.get_channel(CHANNEL_ID)
if channel is None:
print("Kanál nenalezen.")
return
try:
server = JavaServer(MC_HOST, MC_PORT)
status = server.status()
player_count = status.players.online
name = f'🟢|online|👤:{player_count}'
except Exception as e:
print("Server offline nebo nelze připojit:", e)
name = '🔴|server down!!!'
try:
if name != channel.name:
await channel.edit(name=name)
except discord.Forbidden:
print("Bot nemá oprávnění měnit název kanálu.")
except discord.HTTPException as e:
print("HTTP chyba:", e)
bot.run(TOKEN)

View File

@@ -0,0 +1,3 @@
discord.py
mcstatus
python-dotenv

37
docker-compose.yml Normal file
View File

@@ -0,0 +1,37 @@
services:
mc-vanilla:
image: itzg/minecraft-server
container_name: mc-vanilla
ports:
- "25565:25565"
environment:
TZ: "Europe/Prague"
#TYPE: "PAPER"
VERSION: "1.21.6"
EULA: "TRUE"
ENABLE_RCON: "true"
RCON_PASSWORD: "Revoluce@1989"
RCON_PORT: 25575
MAX_PLAYERS: 6
VIEW_DISTANCE: 20
SIMULATION_DISTANCE: 10
OVERRIDE_ICON: true
ICON: /icon.png
DIFFICULTY: hard
MEMORY: 10G
INIT_MEMORY: 10G
volumes:
- ./data:/data
- ./icon.png:/icon.png
restart: unless-stopped
frankstein-discord-bot:
image: python:3.11-slim
build:
context: ./discord-bot
dockerfile: Dockerfile
volumes:
- ./discord-bot:/discord-bot
env_file:
- discord-bot/.env-bot

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

70
minecraft_env_vars.md Normal file
View File

@@ -0,0 +1,70 @@
Minecraft Server Docker Environment Variables (itzg/minecraft-server)
=====================================================================
🧩 Server Configuration
-----------------------
EULA: Must be set to "TRUE" to accept the Minecraft EULA.
VERSION: Specify the Minecraft server version, e.g., "1.20.4".
TYPE: Server type, such as "VANILLA", "FORGE", "FABRIC", "PAPER", etc.
MOTD: Message of the day displayed in the server list.
DIFFICULTY: Game difficulty; options: "peaceful", "easy", "normal", "hard".
MAX_PLAYERS: Max number of players allowed.
VIEW_DISTANCE: Number of chunks sent to players around them.
ALLOW_NETHER: Enable or disable the Nether.
ENABLE_COMMAND_BLOCK: Enable or disable command blocks.
FORCE_GAMEMODE: Force players to join in the default game mode.
GENERATE_STRUCTURES: Enable or disable structure generation.
HARDCORE: Enable or disable hardcore mode.
MAX_BUILD_HEIGHT: Max build height.
SPAWN_ANIMALS: Enable or disable animal spawning.
SPAWN_MONSTERS: Enable or disable monster spawning.
SPAWN_NPCS: Enable or disable NPC spawning.
SPAWN_PROTECTION: Radius of spawn protection for non-ops.
LEVEL_NAME: Name of the world folder.
LEVEL_TYPE: "DEFAULT", "FLAT", "LARGEBIOMES", "AMPLIFIED", "CUSTOMIZED".
LEVEL_SEED: World seed.
PVP: Enable or disable player combat.
ONLINE_MODE: Enable/disable Mojang authentication.
ALLOW_FLIGHT: Allow/disallow flight.
🛡️ Access Control
-----------------
WHITELIST: Comma-separated list of usernames.
OPS: Comma-separated list of operators.
ENABLE_WHITELIST: Enable/disable whitelist.
ENFORCE_WHITELIST: Always enforce whitelist.
⚙️ Advanced Settings
--------------------
ICON: URL or file path to server icon.
OVERRIDE_ICON: TRUE to override existing icon.
ENABLE_RCON: Enable/disable RCON.
RCON_PASSWORD: RCON password.
RCON_PORT: Default is 25575.
ENABLE_QUERY: Enable/disable GameSpy4 query.
QUERY_PORT: Default is 25565.
ENABLE_JMX: Enable/disable JMX.
JMX_PORT: Default is 7091.
USE_AIKAR_FLAGS: Use Aikar's JVM flags.
JVM_OPTS, JVM_XX_OPTS, JVM_DD_OPTS: JVM tuning.
EXTRA_ARGS: Extra server args.
LOG_TIMESTAMP: Include timestamps in logs.
ENABLE_ROLLING_LOGS: Enable rolling logs.
🧪 Experimental/Modding
------------------------
MODPACK, MODPACK_VERSION: Modpack configs.
MODRINTH_PROJECT, MODRINTH_VERSION: Modrinth config.
CURSEFORGE_PROJECT, CURSEFORGE_FILE_ID: CurseForge config.
AUTODOWNLOAD: Automatically download mods.
🕒 Time and Locale
------------------
TZ: Timezone, e.g., "Europe/Prague".
🧰 Custom Properties
--------------------
CUSTOM_SERVER_PROPERTIES: Newline-separated key=value for custom settings.
See: https://github.com/itzg/docker-minecraft-server

8
restart.sh Normal file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
SERVICE_NAME="mc-vanilla"
echo "🔄 Restartuji server..."
docker compose up -d --force-recreate --build "$SERVICE_NAME"

34
restore.sh Normal file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
#relative path
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONTAINER="mc-vanilla"
BACKUP_DIR="/mnt/backups/minecraft_backups/frankstein"
WORLD_DIR="$DIR/data/world"
mapfile -t BACKUPS < <(ls -1t "$BACKUP_DIR"/world_*.tar.gz)
if [ ${#BACKUPS[@]} -eq 0 ]; then
echo "❌ Žádné zálohy nenalezeny!"
exit 1
fi
echo "📦 Dostupné zálohy:"
for i in "${!BACKUPS[@]}"; do
echo "[$i] ${BACKUPS[$i]}"
done
read -p "🔁 Zadej číslo zálohy: " INDEX
SELECTED="${BACKUPS[$INDEX]}"
[ -z "$SELECTED" ] && echo "❌ Neplatný výběr." && exit 1
read -p "⚠️ Přepsat svět? (y/N): " CONFIRM
[[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]] && exit 0
docker compose stop "$CONTAINER"
rm -rf "$WORLD_DIR"
tar -xzf "$SELECTED" -C .
read -p "▶️ Spustit server? (y/N): " AUTOSTART
[[ "$AUTOSTART" == "y" || "$AUTOSTART" == "Y" ]] && docker compose up -d --force-recreate "$CONTAINER"

10
start.sh Normal file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
SERVICE_NAME="mc-vanilla"
if docker ps --format '{{.Names}}' | grep -q "$SERVICE_NAME"; then
echo "✅ Server už běží."
else
echo "▶️ Spouštím server..."
docker compose up -d --force-recreate "$SERVICE_NAME"
fi

7
stop.sh Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
SERVICE_NAME="mc-vanilla"
echo "⛔ Zastavuji server..."
docker compose stop "$SERVICE_NAME"