123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #!/usr/bin/env bash
- # Utility script to check the game sanity
- # As of now, this script does not repair files.
- #
- # Usage: ./check_integrity.sh FILENAME quick
- # FILENAME : Checksum file e.g. "pkg_version" of the game or voiceover pack
- # "quick" : Skips md5 checks for more speed but is less reliable
- set -e
- # ======== Functions
- fatal() {
- echo
- for arg in "$@"; do
- echo " * $arg" >&2
- done
- echo
- exit 1
- }
- on_file_mismatch() {
- # 1 = Error Msg, 2 = Filepath
- >&2 echo "$2"
- >&2 echo " * $1"
- }
- if [[ $(uname) == "Darwin" || $(uname) == *"BSD" ]]; then
- STATFLAGS="-f %z"
- md5sum() {
- md5 -q $@
- }
- else
- STATFLAGS="-c %s"
- fi
- check_single() {
- # 1 = filepath
- filepath="$1"
- checksum="$2"
- filesize="$3"
- #echo "Testing: $filepath $checksum $filesize"
- if [ ! -e "$filepath" ]; then
- on_file_mismatch "Missing" "$filepath"
- return
- fi
- local size=$(stat $STATFLAGS "$filepath")
- if [ "$size" -ne "$filesize" ]; then
- on_file_mismatch "Size mismatch: $size != $filesize" "$filepath"
- return
- fi
- if [ "$CHECK_MD5" -eq 1 ]; then
- sum=($(md5sum "$filepath"))
- if [ "$sum" != "$checksum" ]; then
- on_file_mismatch "Checksum error: $sum != $checksum" "$filepath"
- return
- fi
- fi
- }
- # ======== Evaluated variables
- MASTER_FILE="$1"
- CHECK_MD5=1
- JOBS=4
- [ ! -e "$MASTER_FILE" ] && fatal \
- "Checksum file $MASTER_FILE not found."
- if [ "$2" == "quick" ]; then
- CHECK_MD5=0
- echo "--- Mode: Quick file size checking (fast, less reliable)"
- else
- echo "--- Mode: Detailed md5 checking (slow, most reliable)"
- fi
- echo ""
- # This is faster than running "jq" on each line
- # outputs a string in form of "Direcotry/File.ext|abc123|10001"
- per_line_data=$(jq -r "[.remoteName, .md5, .fileSize] | join(\"|\")" "$MASTER_FILE")
- i=0
- total=$(echo "$per_line_data" | wc -l)
- while IFS='|' read -r filepath checksum filesize; do
- i=$((i + 1))
- while [ $(jobs | wc -l) -gt $JOBS ]; do
- sleep 0.1
- done
- check_single "$filepath" "$checksum" "$filesize" &
- # Log file names every now and then
- if [ $((i % 500)) == 0 ]; then
- percent=$((i * 100 / total))
- echo "--- Progress: ${percent}% (${i} / ${total})"
- fi
- done <<< "$per_line_data"
- while [ $(jobs | wc -l) -gt 1 ]; do
- sleep 0.1
- done
- echo ""
- echo "==> DONE"
- exit 0
|