dotfiles
My PC Dotfiles & Websitegit clone https://github.com/maydayv7/dotfiles
scripts/mods.sh (3575B)
1#! /usr/bin/env nix
2#! nix shell nixpkgs#bash nixpkgs#cacert nixpkgs#coreutils nixpkgs#curl nixpkgs#jq nixpkgs#nix -c bash
3
4set -euo pipefail
5
6# Script to automatically update Minecraft Server Mods from Modrinth #
7
8API="https://api.modrinth.com/v2"
9COMMIT_PREFIX="chore(mc-server): Update"
10
11# Locate mod metadata file
12SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13DATA="${MODS_FILE:-${SCRIPT_DIR}/../modules/games/mc-server/_mods.nix}"
14
15if [[ ! -f "${DATA}" ]]
16then
17 echo "Mod metadata file not found: '${DATA}'"
18 exit 1
19fi
20
21export CURL_CA_BUNDLE="${CURL_CA_BUNDLE:-$(nix eval --raw nixpkgs#cacert)/etc/ssl/certs/ca-bundle.crt}"
22
23# Tracking
24declare -a UNAVAILABLE=()
25updated=0
26uptodate=0
27
28# Fetch latest version metadata for a project, target loader and game version
29latest() {
30 local id="${1}" loader="${2}" version="${3}"
31 curl -s -G "${API}/project/${id}/version" \
32 --data-urlencode "loaders=[\"${loader}\"]" \
33 --data-urlencode "game_versions=[\"${version}\"]" \
34 | jq -r '
35 (sort_by(.date_published) | reverse | .[0]) as $v
36 | if $v == null then empty
37 else (($v.files | map(select(.primary)) + .)[0]) as $f
38 | if $f == null then empty else "\($f.url)\t\($f.hashes.sha512)" end
39 end
40 ' 2>/dev/null || true
41}
42
43# Update every mod of a loader
44process_loader() {
45 local loader="${1}" json version count
46 json="$(nix eval --json -f "${DATA}" "${loader}" 2>/dev/null || true)"
47
48 if [[ -z "${json}" || "${json}" == "null" ]]
49 then
50 return 0
51 fi
52
53 version="$(echo "${json}" | jq -r '.version')"
54 count="$(echo "${json}" | jq -r '.mods | length')"
55
56 echo "==> Loader '${loader}' (Minecraft ${version}): ${count} mods"
57
58 local i name id oldurl oldhash result newurl sha512 newhash
59 for ((i = 0; i < count; i++))
60 do
61 name="$(echo "${json}" | jq -r ".mods[${i}].name")"
62 id="$(echo "${json}" | jq -r ".mods[${i}].id")"
63 oldurl="$(echo "${json}" | jq -r ".mods[${i}].url")"
64 oldhash="$(echo "${json}" | jq -r ".mods[${i}].hash")"
65
66 result="$(latest "${id}" "${loader}" "${version}")"
67 newurl="$(echo "${result}" | cut -f1)"
68 sha512="$(echo "${result}" | cut -f2)"
69
70 if [[ -z "${result}" || "${newurl}" == "null" || -z "${newurl}" || "${sha512}" == "null" ]]
71 then
72 echo " ✗ ${name}: no build for Minecraft ${version}"
73 UNAVAILABLE+=("${name} (${loader} ${version})")
74 continue
75 fi
76
77 if [[ "${newurl}" == "${oldurl}" ]]
78 then
79 echo " = ${name}: up to date"
80 ((uptodate += 1)) || true
81 continue
82 fi
83
84 newhash="$(nix hash convert --hash-algo sha512 --to sri "${sha512}")"
85
86 sed -i "s|${oldurl}|${newurl}|" "${DATA}"
87 sed -i "s|${oldhash}|${newhash}|" "${DATA}"
88
89 echo " ↑ ${name}: updated"
90 ((updated += 1)) || true
91 done
92
93 # Commit per loader
94 if [[ "${COMMIT:-true}" == "true" ]]
95 then
96 git -C "$(dirname "${DATA}")" diff-index --quiet HEAD "${DATA}" 2>/dev/null || \
97 git -C "$(dirname "${DATA}")" commit -q -n "${DATA}" \
98 -m "${COMMIT_PREFIX} \`${loader}\` mods" || true
99 fi
100}
101
102# Execution
103echo "Checking for Mod Updates..."
104
105# Iterate over every defined loader
106mapfile -t LOADERS < <(nix eval --json -f "${DATA}" 2>/dev/null | jq -r 'keys[]')
107for loader in "${LOADERS[@]}"
108do
109 process_loader "${loader}"
110done
111
112# Summary
113echo
114echo "Summary: ${updated} updated, ${uptodate} up to date, ${#UNAVAILABLE[@]} unavailable"
115if (( ${#UNAVAILABLE[@]} > 0 ))
116then
117 echo "Could not update to the target Minecraft version:"
118 for m in "${UNAVAILABLE[@]}"
119 do
120 echo " - ${m}"
121 done
122fi