feat(minecraft): port whitelist import + VT share links + pause from standalone
Three improvements ported from the standalone setupminecraft.sh: - Whitelist: detect existing whitelist.json on re-run, offer to import players by number (0=all, comma list, Enter=skip), no UUID re-lookup for already-resolved entries; new gamertags still looked up via Mojang API - Vanilla Tweaks: add vanillatweaks.net pre-configured share links at the top of the download instructions section (datapacks + crafting tweaks) - Vanilla Tweaks: pause with "Press Enter when datapacks are in datapacks-download/" so user can SCP the ZIP before the build starts https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
This commit is contained in:
+126
-34
@@ -145,11 +145,68 @@ print(snaps[0] if snaps else '')
|
|||||||
[[ $WHITELIST =~ ^[Yy]$ ]] && WHITELIST_ENABLED=true || WHITELIST_ENABLED=false
|
[[ $WHITELIST =~ ^[Yy]$ ]] && WHITELIST_ENABLED=true || WHITELIST_ENABLED=false
|
||||||
|
|
||||||
local WHITELIST_PLAYERS=()
|
local WHITELIST_PLAYERS=()
|
||||||
|
declare -A WHITELIST_PRELOADED # name → uuid, already resolved from existing file
|
||||||
if [ "$WHITELIST_ENABLED" = true ] && [ "$UNATTENDED" != true ]; then
|
if [ "$WHITELIST_ENABLED" = true ] && [ "$UNATTENDED" != true ]; then
|
||||||
echo ""
|
echo ""
|
||||||
log_info "Whitelist Players"
|
log_info "Whitelist Players"
|
||||||
echo " Enter player gamertags to pre-populate the whitelist."
|
|
||||||
echo " UUIDs are looked up automatically. Press Enter alone when done."
|
# Import from existing whitelist.json when re-running against an existing instance
|
||||||
|
local _EXISTING_WL="$MC_DIR/data/whitelist.json"
|
||||||
|
if [ -f "$_EXISTING_WL" ]; then
|
||||||
|
local -a _EX_NAMES _EX_UUIDS
|
||||||
|
mapfile -t _EX_NAMES < <(python3 -c "
|
||||||
|
import json, sys
|
||||||
|
try:
|
||||||
|
data = json.load(open(sys.argv[1]))
|
||||||
|
for p in data:
|
||||||
|
if p.get('name'): print(p['name'])
|
||||||
|
except: pass
|
||||||
|
" "$_EXISTING_WL" 2>/dev/null)
|
||||||
|
mapfile -t _EX_UUIDS < <(python3 -c "
|
||||||
|
import json, sys
|
||||||
|
try:
|
||||||
|
data = json.load(open(sys.argv[1]))
|
||||||
|
for p in data:
|
||||||
|
if p.get('uuid'): print(p['uuid'])
|
||||||
|
except: pass
|
||||||
|
" "$_EXISTING_WL" 2>/dev/null)
|
||||||
|
if [ ${#_EX_NAMES[@]} -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo " Existing whitelist found (${#_EX_NAMES[@]} player(s)):"
|
||||||
|
local _i
|
||||||
|
for _i in "${!_EX_NAMES[@]}"; do
|
||||||
|
printf " %d) %s\n" "$((_i+1))" "${_EX_NAMES[$_i]}"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo " Import from existing? Enter numbers (e.g. 1,3,4), 0=all, Enter=skip:"
|
||||||
|
local _WL_IMPORT=""
|
||||||
|
read -p " Selection: " _WL_IMPORT
|
||||||
|
if [ -n "$_WL_IMPORT" ]; then
|
||||||
|
if [ "$_WL_IMPORT" = "0" ]; then
|
||||||
|
for _i in "${!_EX_NAMES[@]}"; do
|
||||||
|
WHITELIST_PRELOADED["${_EX_NAMES[$_i]}"]="${_EX_UUIDS[$_i]}"
|
||||||
|
done
|
||||||
|
log_success " Imported all ${#_EX_NAMES[@]} existing player(s)"
|
||||||
|
else
|
||||||
|
local -a _SEL_NUMS
|
||||||
|
IFS=',' read -ra _SEL_NUMS <<< "$_WL_IMPORT"
|
||||||
|
local _n
|
||||||
|
for _n in "${_SEL_NUMS[@]}"; do
|
||||||
|
_n="${_n// /}"
|
||||||
|
if [[ "$_n" =~ ^[0-9]+$ ]] && [ "$_n" -ge 1 ] && \
|
||||||
|
[ "$_n" -le "${#_EX_NAMES[@]}" ]; then
|
||||||
|
WHITELIST_PRELOADED["${_EX_NAMES[$((_n-1))]}"]="${_EX_UUIDS[$((_n-1))]}"
|
||||||
|
log_info " Imported: ${_EX_NAMES[$((_n-1))]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " Enter additional gamertags to add. UUIDs looked up automatically."
|
||||||
|
echo " Press Enter alone when done."
|
||||||
echo ""
|
echo ""
|
||||||
while true; do
|
while true; do
|
||||||
local _GT=""
|
local _GT=""
|
||||||
@@ -158,8 +215,9 @@ print(snaps[0] if snaps else '')
|
|||||||
WHITELIST_PLAYERS+=("$_GT")
|
WHITELIST_PLAYERS+=("$_GT")
|
||||||
log_info " Added: $_GT"
|
log_info " Added: $_GT"
|
||||||
done
|
done
|
||||||
if [ ${#WHITELIST_PLAYERS[@]} -gt 0 ]; then
|
local _WL_TOTAL=$(( ${#WHITELIST_PLAYERS[@]} + ${#WHITELIST_PRELOADED[@]} ))
|
||||||
log_success " ${#WHITELIST_PLAYERS[@]} player(s) queued for whitelist"
|
if [ "$_WL_TOTAL" -gt 0 ]; then
|
||||||
|
log_success " $_WL_TOTAL player(s) queued for whitelist"
|
||||||
else
|
else
|
||||||
log_info " No players entered — whitelist will be empty until you add players manually"
|
log_info " No players entered — whitelist will be empty until you add players manually"
|
||||||
fi
|
fi
|
||||||
@@ -918,38 +976,61 @@ print(snaps[0] if snaps else '')
|
|||||||
cd "$MC_DIR" || return 1
|
cd "$MC_DIR" || return 1
|
||||||
|
|
||||||
# ── Whitelist pre-population ────────────────────────────────────────────────
|
# ── Whitelist pre-population ────────────────────────────────────────────────
|
||||||
if [ "$WHITELIST_ENABLED" = true ] && [ ${#WHITELIST_PLAYERS[@]} -gt 0 ]; then
|
local _WL_NEED_WRITE=false
|
||||||
log_info "Looking up UUIDs for whitelist players..."
|
[ "$WHITELIST_ENABLED" = true ] && \
|
||||||
|
[ $(( ${#WHITELIST_PLAYERS[@]} + ${#WHITELIST_PRELOADED[@]} )) -gt 0 ] && \
|
||||||
|
_WL_NEED_WRITE=true
|
||||||
|
|
||||||
|
if [ "$_WL_NEED_WRITE" = true ]; then
|
||||||
|
log_info "Building whitelist.json..."
|
||||||
local _WL_JSON="["
|
local _WL_JSON="["
|
||||||
local _WL_FIRST=true
|
local _WL_FIRST=true
|
||||||
local _WL_COUNT=0
|
local _WL_COUNT=0
|
||||||
local _player _resp _uuid _name
|
|
||||||
for _player in "${WHITELIST_PLAYERS[@]}"; do
|
# Preloaded entries — UUIDs already known, no API call needed
|
||||||
_resp=$(curl -sf --max-time 10 \
|
local _wl_name _uuid
|
||||||
"https://api.mojang.com/users/profiles/minecraft/${_player}" 2>/dev/null || echo "")
|
for _wl_name in "${!WHITELIST_PRELOADED[@]}"; do
|
||||||
if [ -z "$_resp" ]; then
|
_uuid="${WHITELIST_PRELOADED[$_wl_name]}"
|
||||||
log_warning " '$_player' not found — skipping (account may not exist)"
|
log_success " $_wl_name → $_uuid (from existing whitelist)"
|
||||||
continue
|
[ "$_WL_FIRST" = true ] || _WL_JSON+=","
|
||||||
fi
|
_WL_FIRST=false
|
||||||
_uuid=$(echo "$_resp" | python3 -c "
|
_WL_COUNT=$((_WL_COUNT + 1))
|
||||||
|
_WL_JSON+="
|
||||||
|
{\"uuid\": \"$_uuid\", \"name\": \"$_wl_name\"}"
|
||||||
|
done
|
||||||
|
|
||||||
|
# New gamertags — look up via Mojang API
|
||||||
|
if [ ${#WHITELIST_PLAYERS[@]} -gt 0 ]; then
|
||||||
|
log_info " Looking up UUIDs via Mojang API..."
|
||||||
|
local _player _resp _name
|
||||||
|
for _player in "${WHITELIST_PLAYERS[@]}"; do
|
||||||
|
_resp=$(curl -sf --max-time 10 \
|
||||||
|
"https://api.mojang.com/users/profiles/minecraft/${_player}" 2>/dev/null || echo "")
|
||||||
|
if [ -z "$_resp" ]; then
|
||||||
|
log_warning " '$_player' not found — skipping (account may not exist)"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
_uuid=$(echo "$_resp" | python3 -c "
|
||||||
import sys, json
|
import sys, json
|
||||||
d = json.load(sys.stdin)
|
d = json.load(sys.stdin)
|
||||||
uid = d['id']
|
uid = d['id']
|
||||||
print(f'{uid[:8]}-{uid[8:12]}-{uid[12:16]}-{uid[16:20]}-{uid[20:]}')
|
print(f'{uid[:8]}-{uid[8:12]}-{uid[12:16]}-{uid[16:20]}-{uid[20:]}')
|
||||||
" 2>/dev/null || echo "")
|
" 2>/dev/null || echo "")
|
||||||
_name=$(echo "$_resp" | python3 -c "
|
_name=$(echo "$_resp" | python3 -c "
|
||||||
import sys, json; d=json.load(sys.stdin); print(d.get('name',''))" 2>/dev/null || echo "$_player")
|
import sys, json; d=json.load(sys.stdin); print(d.get('name',''))" 2>/dev/null || echo "$_player")
|
||||||
if [ -z "$_uuid" ]; then
|
if [ -z "$_uuid" ]; then
|
||||||
log_warning " Could not parse UUID for '$_player' — skipping"
|
log_warning " Could not parse UUID for '$_player' — skipping"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
log_success " $_name → $_uuid"
|
log_success " $_name → $_uuid"
|
||||||
[ "$_WL_FIRST" = true ] || _WL_JSON+=","
|
[ "$_WL_FIRST" = true ] || _WL_JSON+=","
|
||||||
_WL_FIRST=false
|
_WL_FIRST=false
|
||||||
_WL_COUNT=$((_WL_COUNT + 1))
|
_WL_COUNT=$((_WL_COUNT + 1))
|
||||||
_WL_JSON+="
|
_WL_JSON+="
|
||||||
{\"uuid\": \"$_uuid\", \"name\": \"$_name\"}"
|
{\"uuid\": \"$_uuid\", \"name\": \"$_name\"}"
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
_WL_JSON+="
|
_WL_JSON+="
|
||||||
]"
|
]"
|
||||||
echo "$_WL_JSON" > "$MC_DIR/data/whitelist.json"
|
echo "$_WL_JSON" > "$MC_DIR/data/whitelist.json"
|
||||||
@@ -1012,9 +1093,13 @@ for v in versions:
|
|||||||
echo ""
|
echo ""
|
||||||
log_info "Vanilla Tweaks — download your selected packs manually:"
|
log_info "Vanilla Tweaks — download your selected packs manually:"
|
||||||
echo ""
|
echo ""
|
||||||
echo " 1. Go to: https://vanillatweaks.net/picker/datapacks/"
|
echo " ┌─ Quick start: pre-configured share links (opens VT pre-selected) ─┐"
|
||||||
echo " 2. Select Minecraft version ${VT_VERSION} in the version dropdown"
|
echo " │ Datapacks: https://vanillatweaks.net/share#B3QqSd │"
|
||||||
echo " 3. Enable these packs (your selections from the toggle menu):"
|
echo " │ Crafting tweaks: https://vanillatweaks.net/share#SqzGkO │"
|
||||||
|
echo " └───────────────────────────────────────────────────────────────────-┘"
|
||||||
|
echo ""
|
||||||
|
echo " Or pick manually — go to https://vanillatweaks.net/picker/datapacks/"
|
||||||
|
echo " and select version ${VT_VERSION}, then enable your chosen packs:"
|
||||||
echo ""
|
echo ""
|
||||||
local _LAST_CAT="" _cat dp
|
local _LAST_CAT="" _cat dp
|
||||||
for dp in "${DPACK_ORDER[@]}"; do
|
for dp in "${DPACK_ORDER[@]}"; do
|
||||||
@@ -1027,13 +1112,20 @@ for v in versions:
|
|||||||
echo " • ${DPACKS[$dp]}"
|
echo " • ${DPACKS[$dp]}"
|
||||||
done
|
done
|
||||||
echo ""
|
echo ""
|
||||||
echo " 4. Click Download and save the .zip file"
|
echo " ── How to install ────────────────────────────────────────────────────"
|
||||||
echo " 5. Place the .zip in: ${MC_DIR}/datapacks-download/"
|
echo " 1. Download the ZIP from vanillatweaks.net (use share link or pick)"
|
||||||
echo " 6. Rebuild: cd ${MC_DIR} && docker compose build"
|
echo " 2. SCP it to this server (run on your local machine):"
|
||||||
echo " 7. Restart: cd ${MC_DIR} && docker compose up -d"
|
echo " scp ~/Downloads/VanillaTweaks*.zip $(whoami)@$(hostname -I | awk '{print $1}'):${MC_DIR}/datapacks-download/"
|
||||||
echo ""
|
echo " 3. On this server:"
|
||||||
|
echo " cd ${MC_DIR}/datapacks-download"
|
||||||
|
echo " unzip 'VanillaTweaks*.zip' && rm VanillaTweaks*.zip"
|
||||||
|
echo " 4. Rebuild: cd ${MC_DIR} && docker compose build"
|
||||||
|
echo " 5. Restart: cd ${MC_DIR} && docker compose up -d"
|
||||||
|
echo " ──────────────────────────────────────────────────────────────────────"
|
||||||
echo " The itzg image extracts .zip files from /datapacks/ on startup."
|
echo " The itzg image extracts .zip files from /datapacks/ on startup."
|
||||||
echo " Datapacks land in ${MC_NAME}/data/datapacks/ and persist across restarts."
|
echo " Datapacks land in ${MC_NAME}/data/datapacks/ and persist across restarts."
|
||||||
|
echo ""
|
||||||
|
read -p " Press Enter when datapacks are in datapacks-download/ (or Enter to skip): "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── LuckPerms bootstrap script ──────────────────────────────────────────────
|
# ── LuckPerms bootstrap script ──────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user