217 lines
6.6 KiB
Bash
Executable File
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 "$@" |