250 lines
7.6 KiB
Bash
250 lines
7.6 KiB
Bash
|
#!/bin/bash
|
||
|
|
||
|
# Set variables
|
||
|
INFO_MAP_FILENAME="Info_Map.imp"
|
||
|
VERBOSE=0
|
||
|
GENERATEXML=0
|
||
|
MAP_FOLDER=""
|
||
|
ARCHIVE_FILE=""
|
||
|
DIRECT_FILE=""
|
||
|
LOG_FILE="./script.log"
|
||
|
DEFAULT=""
|
||
|
DEPENDENCIES=("7z" "hexdump" "awk")
|
||
|
|
||
|
# Functions declaration
|
||
|
|
||
|
# Check if all required commands are available
|
||
|
check_dependencies() {
|
||
|
for cmd in "${DEPENDENCIES[@]}"; do
|
||
|
if ! command -v "$cmd" &> /dev/null; then
|
||
|
echo "ERROR: Required command '$cmd' is not installed. Please install it and try again."
|
||
|
exit 1
|
||
|
fi
|
||
|
done
|
||
|
}
|
||
|
|
||
|
# Log message to console and file
|
||
|
log_message() {
|
||
|
if [[ $VERBOSE -eq 1 ]]; then
|
||
|
echo "$1" | tee -a "$LOG_FILE"
|
||
|
else
|
||
|
echo "$1" >> "$LOG_FILE"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# Clean up temporary files when script exits
|
||
|
cleanup() {
|
||
|
if [[ -f "/tmp/$INFO_MAP_FILENAME" ]]; then
|
||
|
rm "/tmp/$INFO_MAP_FILENAME"
|
||
|
fi
|
||
|
log_message "Cleaned up temporary files."
|
||
|
}
|
||
|
trap cleanup EXIT
|
||
|
|
||
|
# Progress bar for long operations
|
||
|
show_progress() {
|
||
|
for i in {1..4}; do
|
||
|
sleep 1
|
||
|
case $i in
|
||
|
1) echo -ne 'Processing: [# ] (0%)\r' ;;
|
||
|
2) echo -ne 'Processing: [##### ] (25%)\r' ;;
|
||
|
3) echo -ne 'Processing: [########## ] (50%)\r' ;;
|
||
|
4) echo -ne 'Processing: [############### ] (75%)\r' ;;
|
||
|
esac
|
||
|
done
|
||
|
echo -ne 'Processing: [####################### ] (100%)\r\n'
|
||
|
}
|
||
|
|
||
|
# Parse Info_Map.imp file
|
||
|
parseInfoMapFile() {
|
||
|
log_message "Parsing file..."
|
||
|
|
||
|
MAP_NAME=$(hexdump -C "$INFOMAP_FILE" | awk -F"|" '{ print $2 }' | tr -d "\n" | cut -c 21-200)
|
||
|
MAP_SWID_FscShort=$(hexdump -C "$INFOMAP_FILE" | awk 'NR==1 {print toupper($10$11$12$13)}')
|
||
|
MAP_REGION=$(hexdump -C "$INFOMAP_FILE" | awk 'NR==1 {print "0x" toupper($11)}')
|
||
|
MAP_YEAR=$(hexdump -C "$INFOMAP_FILE" | awk 'NR==1 {print "0x" toupper($13)}')
|
||
|
log_message "Parsing completed [OK]"
|
||
|
}
|
||
|
|
||
|
# Display map information
|
||
|
showMapInfos() {
|
||
|
echo -e "\n===================== Map Information ========================="
|
||
|
echo -e "Map Name : \"$MAP_NAME\""
|
||
|
echo -e "SWID_FscShort : \"$MAP_SWID_FscShort\""
|
||
|
echo -e "Map Region : \"$MAP_REGION\""
|
||
|
echo -e "Map Year : \"$MAP_YEAR\""
|
||
|
echo -e "===============================================================\n"
|
||
|
}
|
||
|
|
||
|
# Show the XML entry to add
|
||
|
showLookupXMLEntry() {
|
||
|
LONG_MAP_NAME="$MAP_NAME (SWID_FscShort=$MAP_SWID_FscShort, MapRegion=$MAP_REGION, MapYear=$MAP_YEAR)"
|
||
|
echo -e "\n===================== XML Generation ==========================="
|
||
|
echo -e "Add this entry at the end of the maps list in your Lookup.xml file:\n"
|
||
|
echo -e "<SgbmId id=\"NAVD_000024A8_255_007_034\" SWID_FscShort=\"$MAP_SWID_FscShort\" name=\"$LONG_MAP_NAME\" supplier=\"NTQ\" sop=\"01.05.2021\" version=\"10_09\" MapOrderNumberBMW=\"\" MapOrderNumberMINI=\"\" MapOrderNumberRR=\"\" successorMapOrderNumberBMW=\"\" successorMapOrderNumberMINI=\"\" successorMapOrderNumberRR=\"\" NextNo=\"01826\">\n\t<EcuVariant CompatibilityIdentifier=\"NBTevo-HB\" Format=\"CIC\" />\n\t<SwUpdate SwUpdateEntry=\"\"/>\n</SgbmId>"
|
||
|
echo -e "\n===============================================================\n"
|
||
|
}
|
||
|
|
||
|
# Validate input file permissions
|
||
|
validate_file() {
|
||
|
if [[ ! -r "$1" ]]; then
|
||
|
echo "ERROR: Cannot read file $1. Check permissions."
|
||
|
exit 2
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# Process an archive file
|
||
|
processArchiveFile() {
|
||
|
if [[ ! -f "$ARCHIVE_FILE" ]]; then
|
||
|
log_message "ERROR: Archive file \"$ARCHIVE_FILE\" does not exist"
|
||
|
exit 2
|
||
|
fi
|
||
|
|
||
|
log_message "File archive exists"
|
||
|
|
||
|
PATH_TO_INFOMAP_FILE=$(7z l "$ARCHIVE_FILE" | grep "$INFO_MAP_FILENAME" | grep -v "LIGHT" | awk '{print $NF}')
|
||
|
|
||
|
log_message "Looking for \"$INFO_MAP_FILENAME\" in the archive... [OK] - $PATH_TO_INFOMAP_FILE"
|
||
|
|
||
|
filename=$(basename -- "$ARCHIVE_FILE")
|
||
|
extension="${filename##*.}"
|
||
|
|
||
|
case "$extension" in
|
||
|
"7z"|"7Z")
|
||
|
log_message "Extracting \"$INFO_MAP_FILENAME\" from 7zip archive..."
|
||
|
show_progress
|
||
|
7z -y e "$ARCHIVE_FILE" -o"/tmp" "$PATH_TO_INFOMAP_FILE"
|
||
|
;;
|
||
|
"zip"|"ZIP"|"tar")
|
||
|
show_progress
|
||
|
7z -y e "$ARCHIVE_FILE" -o"/tmp" "$PATH_TO_INFOMAP_FILE" > /dev/null
|
||
|
;;
|
||
|
*)
|
||
|
log_message "Unsupported archive format: $extension"
|
||
|
exit 2
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
if [[ -f "/tmp/$INFO_MAP_FILENAME" ]]; then
|
||
|
INFOMAP_FILE="/tmp/$INFO_MAP_FILENAME"
|
||
|
else
|
||
|
log_message "ERROR: \"$INFO_MAP_FILENAME\" not found in /tmp"
|
||
|
exit 2
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# Process map folder
|
||
|
processFolder() {
|
||
|
log_message "Processing folder \"$MAP_FOLDER\"..."
|
||
|
|
||
|
if [[ -d "$MAP_FOLDER/1" ]]; then
|
||
|
INFOMAP_FILE=$(find "$MAP_FOLDER/1" -name "$INFO_MAP_FILENAME" | grep -v "LIGHT" | head -n 1)
|
||
|
if [[ -z "$INFOMAP_FILE" ]]; then
|
||
|
log_message "ERROR: \"$INFO_MAP_FILENAME\" not found in folder(s) 1/INFO*"
|
||
|
exit 2
|
||
|
fi
|
||
|
else
|
||
|
log_message "ERROR: Folder \"$MAP_FOLDER\" does not contain expected map files"
|
||
|
exit 2
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# Batch process for multiple maps
|
||
|
process_batch() {
|
||
|
for file in "$1"/*; do
|
||
|
if [[ -d "$file" ]]; then
|
||
|
log_message "Processing folder: $file"
|
||
|
processFolder "$file"
|
||
|
elif [[ -f "$file" ]]; then
|
||
|
log_message "Processing archive: $file"
|
||
|
processArchiveFile "$file"
|
||
|
fi
|
||
|
done
|
||
|
}
|
||
|
|
||
|
# Set working directory
|
||
|
setWorkDir() {
|
||
|
if [[ -d "$MAP_FOLDER" ]]; then
|
||
|
cd "$MAP_FOLDER" || exit 1
|
||
|
log_message "Using map folder \"$MAP_FOLDER\"... [OK]"
|
||
|
else
|
||
|
log_message "ERROR: Given folder \"$MAP_FOLDER\" does not exist"
|
||
|
exit 2
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# Prompt for confirmation before overwriting
|
||
|
prompt_for_confirmation() {
|
||
|
read -p "File $1 exists. Overwrite? (y/n): " choice
|
||
|
case "$choice" in
|
||
|
y|Y ) log_message "Overwriting...";;
|
||
|
n|N ) log_message "Skipping..."; exit 0;;
|
||
|
* ) log_message "Invalid choice"; exit 1;;
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
# Show usage/help message
|
||
|
show_help() {
|
||
|
echo "Usage: InfoMap.sh [OPTIONS]"
|
||
|
echo "Extract hex information from downloaded BMW / Mini / RR Maps"
|
||
|
echo "Options:"
|
||
|
echo " -d <dir> Specify the map folder to process."
|
||
|
echo " -z <file> Specify the archive file to process (zip, 7z, etc.)."
|
||
|
echo " -f <file> Specify the Info_Map.imp file directly."
|
||
|
echo " -v Enable verbose mode."
|
||
|
echo " -x Generate XML entry."
|
||
|
echo " -b <dir> Batch process multiple folders or archives in the directory."
|
||
|
echo " -h Show this help message."
|
||
|
}
|
||
|
|
||
|
############# Main Program Starts #############
|
||
|
|
||
|
# Show help if no arguments are provided
|
||
|
if [[ $# -eq 0 ]]; then
|
||
|
show_help
|
||
|
exit 0
|
||
|
fi
|
||
|
|
||
|
POSITIONAL_ARGS=()
|
||
|
|
||
|
while getopts ":d:z:f:xb:vh" option; do
|
||
|
case $option in
|
||
|
d) MAP_FOLDER="$OPTARG" ;;
|
||
|
z) ARCHIVE_FILE="$OPTARG" ;;
|
||
|
f) DIRECT_FILE="$OPTARG" ;;
|
||
|
v) VERBOSE=1 ;;
|
||
|
x) GENERATEXML=1 ;;
|
||
|
b) process_batch "$OPTARG"; exit 0 ;;
|
||
|
h) show_help; exit 0 ;;
|
||
|
*) echo "Invalid option: -$OPTARG"; show_help; exit 1 ;;
|
||
|
esac
|
||
|
done
|
||
|
shift $((OPTIND-1))
|
||
|
|
||
|
# Check dependencies
|
||
|
check_dependencies
|
||
|
|
||
|
# Processing logic based on provided arguments
|
||
|
if [[ -n "$DIRECT_FILE" ]]; then
|
||
|
validate_file "$DIRECT_FILE"
|
||
|
INFOMAP_FILE="$DIRECT_FILE"
|
||
|
elif [[ -n "$MAP_FOLDER" ]]; then
|
||
|
setWorkDir
|
||
|
processFolder
|
||
|
elif [[ -n "$ARCHIVE_FILE" ]]; then
|
||
|
processArchiveFile
|
||
|
else
|
||
|
log_message "No valid input provided"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
# Parsing Info_Map.imp file
|
||
|
parseInfoMapFile
|
||
|
|
||
|
# Display map information
|
||
|
showMapInfos
|
||
|
|
||
|
# Generate XML entry if required
|
||
|
if [[ $GENERATEXML -eq 1 ]]; then
|
||
|
showLookupXMLEntry
|
||
|
fi
|