Files
servermods/sync_modpack.sh.backup
2026-04-04 23:14:07 +08:00

217 lines
6.6 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
REPO_DIR="/tmp/mod_repo"
SERVER_MODS_FILE="/tmp/server_mods.txt"
MINECRAFT_MODS_DIR="/home/minecraft/mods"
STATE_DIR="$REPO_DIR/state"
MODPACK_DIR="$REPO_DIR/modpack"
VERSION_FILE="$REPO_DIR/VERSION"
GIT_REPO="ssh://git@jianfgit.xyz:220/jianf/servermods.git"
MODRINTH_INDEX="$MODPACK_DIR/modrinth.index.json"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
get_current_version() {
if [[ -f "$VERSION_FILE" ]]; then
cat "$VERSION_FILE"
else
echo "0.0.0"
fi
}
increment_version() {
local version="$1"
IFS='.' read -r major minor patch <<< "$version"
patch=$((patch + 1))
echo "$major.$minor.$patch"
}
get_file_hash() {
local file_path="$1"
if [[ -f "$file_path" ]]; then
sha1sum "$file_path" | awk '{print $1}'
else
echo "0000000000000000000000000000000000000000"
fi
}
find_mod_file() {
local base_name="$1"
# Find the actual mod file that starts with the base name
local mod_file
mod_file=$(find "$MINECRAFT_MODS_DIR" -name "${base_name}-*.jar" | head -1 || echo "")
if [[ -z "$mod_file" ]]; then
# Try exact match as fallback
mod_file="$MINECRAFT_MODS_DIR/${base_name}.jar"
if [[ ! -f "$mod_file" ]]; then
echo ""
else
echo "$mod_file"
fi
else
echo "$mod_file"
fi
}
create_modrinth_index() {
local version="$1"
local mods_json="$2"
local gunpacks_json="$3"
# Start building the JSON
{
echo '{'
echo ' "formatVersion": 1,'
echo ' "game": {'
echo ' "type": "forge",'
echo ' "version": "1.20.1"'
echo ' },'
echo " \"versionId\": \"$version\","
echo ' "name": "minimal-client-modpack",'
echo ' "summary": "Minimal client modpack for connecting to the server",'
echo ' "files": ['
} > "$MODRINTH_INDEX"
local first=true
# Process mods
while IFS= read -r mod; do
if [[ -n "$mod" ]]; then
local mod_path
mod_path=$(find_mod_file "$mod")
if [[ -n "$mod_path" && -f "$mod_path" ]]; then
local mod_filename
mod_filename=$(basename "$mod_path")
local hash
hash=$(get_file_hash "$mod_path")
if [[ "$first" == true ]]; then
first=false
else
echo ',' >> "$MODRINTH_INDEX"
fi
{
echo ' {'
echo ' "path": "mods/'"$mod_filename"'",'
echo ' "hashes": {'
echo " \"sha1\": \"$hash\""
echo ' },'
echo ' "env": {'
echo ' "client": ["required"],'
echo ' "server": ["unsupported"]'
echo ' },'
echo ' "downloads": []'
echo ' }'
} >> "$MODRINTH_INDEX"
fi
fi
done < "$mods_json"
# Process gunpacks
while IFS= read -r gunpack; do
if [[ -n "$gunpack" ]]; then
gunpack=$(echo "$gunpack" | sed 's/^"//' | sed 's/"$//')
local gunpack_path
gunpack_path=$(find "$REPO_DIR/tacz" -name "$gunpack" -type f | head -1 || echo "")
if [[ -n "$gunpack_path" && -f "$gunpack_path" ]]; then
local hash
hash=$(get_file_hash "$gunpack_path")
echo ',' >> "$MODRINTH_INDEX"
{
echo ' {'
echo ' "path": "tacz/'"$gunpack"'",'
echo ' "hashes": {'
echo " \"sha1\": \"$hash\""
echo ' },'
echo ' "env": {'
echo ' "client": ["required"],'
echo ' "server": ["unsupported"]'
echo ' },'
echo ' "downloads": []'
echo ' }'
} >> "$MODRINTH_INDEX"
fi
fi
done < "$gunpacks_json"
# Close the JSON array and object
{
echo ' ]'
echo '}'
} >> "$MODRINTH_INDEX"
}
main() {
log "Starting modpack synchronization"
mkdir -p "$STATE_DIR"
mkdir -p "$MODPACK_DIR"
mkdir -p "$REPO_DIR/tacz" # Ensure tacz directory exists
if [[ ! -f "$SERVER_MODS_FILE" ]]; then
log "ERROR: Server mods file not found: $SERVER_MODS_FILE"
exit 1
fi
if [[ ! -d "$MINECRAFT_MODS_DIR" ]]; then
log "ERROR: Minecraft mods directory not found: $MINECRAFT_MODS_DIR"
exit 1
fi
grep -v "^disabled$" "$SERVER_MODS_FILE" | sed 's/-[0-9].*$//' | sort > "$STATE_DIR/current_mods_sorted.txt"
local has_changes=false
if [[ -f "$STATE_DIR/mods.json" && -f "$STATE_DIR/gunpacks.json" ]]; then
if ! cmp -s "$STATE_DIR/current_mods_sorted.txt" "$STATE_DIR/mods.json"; then
log "Mod list has changed"
has_changes=true
else
log "Mod list unchanged"
fi
log "Checking gunpacks for changes"
has_changes=true
else
log "No previous state found, treating as initial run"
has_changes=true
fi
if [[ "$has_changes" == true ]]; then
log "Changes detected, updating modpack"
cp "$STATE_DIR/current_mods_sorted.txt" "$STATE_DIR/mods.json" 2>/dev/null || true
ls -1 "$REPO_DIR/tacz"/*.zip 2>/dev/null | xargs -I{} basename {} > "$STATE_DIR/gunpacks.json" || echo "" > "$STATE_DIR/gunpacks.json"
local current_version
current_version=$(get_current_version)
local new_version
new_version=$(increment_version "$current_version")
log "Version update: $current_version -> $new_version"
create_modrinth_index "$new_version" "$STATE_DIR/mods.json" "$STATE_DIR/gunpacks.json"
echo "$new_version" > "$VERSION_FILE"
log "Updating git repository"
git add "$MODRINTH_INDEX" "$VERSION_FILE" "$STATE_DIR/mods.json" "$STATE_DIR/gunpacks.json"
if ! git diff --cached --quiet; then
git commit -m "Update modpack to version $new_version"
log "Pushing to remote repository"
git push origin main
log "Successfully pushed version $new_version"
else
log "No changes to commit"
fi
else
log "No changes detected, skipping update"
fi
log "Modpack synchronization completed"
}
main "$@"