#!/usr/bin/env bash
# L4D2 Rebirth custom map sync for Linux (game servers or players).
# Run from your left4dead2/addons folder:   bash l4d2rebirth_maps_sync.sh
# Keeps exactly the maps in https://l4d2rebirth.com/maps/servers/index.csv: downloads missing ones, replaces ones whose MD5 changed,
# and removes other .vpk files in this folder (pass --keep-others to leave them alone).
set -euo pipefail
LIST="https://l4d2rebirth.com/maps/servers/index.csv"
KEEP=0; [[ "${1:-}" == "--keep-others" ]] && KEEP=1
die() { echo "Error: $1" >&2; exit 1; }
[[ "$(pwd)" == */left4dead2/addons ]] || die "run this from your left4dead2/addons folder (now in $(pwd))"
for c in curl md5sum; do command -v "$c" >/dev/null || die "'$c' is not installed"; done
TMP=$(mktemp); trap 'rm -f "$TMP"' EXIT
echo "Downloading map list from $LIST..."
curl --max-time 120 -fsSL -o "$TMP" "$LIST" || die "could not download the map list"
declare -A MD5 LINK
while IFS=';' read -r name size md5 link || [[ -n "$name" ]]; do
  name=$(printf '%s' "$name" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'); [[ -z "$name" ]] && continue
  MD5["$name"]=$(printf '%s' "$md5" | tr -d '[:space:]'); LINK["$name"]=$(printf '%s' "$link" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
done < <(tail -n +2 "$TMP")
echo "Checking installed maps..."
shopt -s nullglob
for f in *.vpk; do
  if [[ -z "${MD5[$f]:-}" ]]; then
    if (( KEEP )); then echo "  not on the list (kept): $f"; else echo "  not on the list, removing: $f"; rm -f -- "$f"; fi
  elif [[ "$(md5sum -- "$f" | awk '{print $1}')" != "${MD5[$f]}" ]]; then echo "  outdated, replacing: $f"; rm -f -- "$f"
  else echo "  up to date: $f"; fi
done
fail=0
for name in "${!MD5[@]}"; do
  [[ -f "$name" ]] && continue
  url="${LINK[$name]// /%20}"; echo "Downloading $name..."
  if [[ "$url" == *.7z ]]; then
    command -v 7z >/dev/null || { echo "  skipped: needs 7z for $url"; fail=1; continue; }
    t=$(mktemp --suffix=.7z); curl -fL -# --retry 3 -o "$t" "$url" && 7z x -y "$t" >/dev/null || { echo "  FAILED $name"; fail=1; }; rm -f "$t"
  else
    curl -fL -# --retry 3 -C - -o "$name.part" "$url" && mv -f -- "$name.part" "$name" || { echo "  FAILED $name (run again to resume)"; fail=1; continue; }
  fi
  if [[ -f "$name" && "$(md5sum -- "$name" | awk '{print $1}')" != "${MD5[$name]}" ]]; then echo "  checksum mismatch, removed $name"; rm -f -- "$name"; fail=1; fi
done
(( fail )) && { echo "Finished with errors - run again to retry."; exit 2; }
echo "Synchronization complete: ${#MD5[@]} maps."
