Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b25b235fa | |||
| a6d0bcfb5f | |||
| a46776838a | |||
| 6bcad99bec | |||
| 8d6591a19d |
+2
-1
@@ -1,4 +1,5 @@
|
||||
*
|
||||
!h2mm
|
||||
!install.sh
|
||||
!README.md
|
||||
!README.md
|
||||
!version
|
||||
@@ -7,6 +7,7 @@
|
||||
- [Basic usage](#basic-usage)
|
||||
- [Install a mod](#install-a-mod)
|
||||
- [Uninstall a mod](#uninstall-a-mod)
|
||||
- [Enable/disable mods](#enabledisable-mods)
|
||||
- [List installed mods](#list-installed-mods)
|
||||
- [Advanced usage](#advanced-usage)
|
||||
- [Shortcuts](#shortcuts)
|
||||
@@ -57,7 +58,7 @@ h2mm install -n "Example mod" mod.patch_0 mod.patch_0.stream # -n is mandatory w
|
||||
h2mm install -n "Example mod" mod* # using a wildcard to include all files
|
||||
```
|
||||
|
||||
Important: If the mod has more than 1 variant, you need to install the one you want by unarchiving it separately.
|
||||
> Currently, if the mod has more than 1 variant, you need to install the one you want by unarchiving it separately.
|
||||
|
||||
#### Uninstall a mod
|
||||
|
||||
@@ -66,6 +67,16 @@ h2mm uninstall "Example mod"
|
||||
h2mm uninstall -i 1 # uninstall mod with index 1
|
||||
```
|
||||
|
||||
|
||||
#### Enable/disable mods
|
||||
|
||||
```bash
|
||||
h2mm enable "Example mod"
|
||||
h2mm enable -i 1 # enable mod with index 1
|
||||
h2mm disable "Example mod"
|
||||
h2mm disable -i 1 # disable mod with index 1
|
||||
```
|
||||
|
||||
#### List installed mods
|
||||
|
||||
```bash
|
||||
@@ -76,10 +87,12 @@ h2mm list
|
||||
|
||||
### Shortcuts
|
||||
|
||||
You can use the short form of the commands to save some time. The shortcuts are:
|
||||
You can use the short form of commands to save some time. The shortcuts are:
|
||||
|
||||
- `i` for `install`
|
||||
- `u` for `uninstall`
|
||||
- `e` for `enable`
|
||||
- `d` for `disable`
|
||||
- `l` for `list`
|
||||
- `ex` for `export`
|
||||
- `im` for `import`
|
||||
@@ -89,8 +102,6 @@ You can use the short form of the commands to save some time. The shortcuts are:
|
||||
|
||||
You can export all installed mods to a zip file and import mods from the same file. This can be useful for sharing mods with others or for backing up your mods. The zip file will be saved in the current directory.
|
||||
|
||||
This will serve as either a backup or a way to have multiple mod setups.
|
||||
|
||||
```bash
|
||||
h2mm export modpack1.zip
|
||||
h2mm import modpack2.zip
|
||||
@@ -114,7 +125,11 @@ Feel free to contribute to this project by creating a pull request or opening an
|
||||
|
||||
## Planned features
|
||||
|
||||
- [ ] ! Enable/disable mods
|
||||
- [ ] !! Easier way to change mod presets
|
||||
- [ ] !! Change to `.tar.xz` for exporting and importing
|
||||
- [ ] !!! Find a way to make use of `manifest.json` and simplify installing variants
|
||||
- [x] Check for mod updates
|
||||
- [x] Enable/disable mods
|
||||
- [ ] Easier way to change mod presets
|
||||
- [ ] Find a way to make use of `manifest.json` and simplify installing variants
|
||||
- [x] [DEV] Change to `.tar.gz` for exporting and importing
|
||||
- [x] [DEV] Provide fixes for breaking updates
|
||||
- [ ] [DEV] Optimize code - throw errors in 1 line
|
||||
- [ ] [DEV] Rewrite some code to be more readable
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="0.2.0"
|
||||
|
||||
# --- Globals ---
|
||||
|
||||
RED='\033[0;31m'
|
||||
@@ -11,6 +13,10 @@ H2PATH="${HOME}/.config/h2mm/h2path"
|
||||
MODS_DIR=""
|
||||
DB_FILE=""
|
||||
|
||||
LAST_CHECKED_UPDATE_FILE="${HOME}/.config/h2mm/last_update"
|
||||
VERSION_URL="https://raw.githubusercontent.com/v4n00/h2mm-cli/refs/heads/master/version"
|
||||
REPO_URL="https://github.com/v4n00/h2mm-cli"
|
||||
|
||||
# --- Utility Functions ---
|
||||
|
||||
function get_filename_without_path() {
|
||||
@@ -21,6 +27,31 @@ function get_basename() {
|
||||
echo $(get_filename_without_path "$1" | sed -E 's/\.+.*//')
|
||||
}
|
||||
|
||||
function get_extension() {
|
||||
echo $(get_filename_without_path "$1" | sed -E 's/.*patch_[0-9]+//')
|
||||
}
|
||||
|
||||
function get_files_by_entry_from_db() {
|
||||
echo $(echo "$1" | cut -d',' -f4- | tr ',' ' ' | head -1)
|
||||
}
|
||||
|
||||
function get_mod_name_and_index() {
|
||||
if [[ -n "$mod_index" ]]; then # if mod index exists
|
||||
entry=$(grep "^${mod_index}," "$DB_FILE")
|
||||
mod_name=$(echo "$entry" | awk -F, '{print $3}')
|
||||
elif [[ -n "$mod_name" ]]; then # if mod name exists
|
||||
entry=$(grep -i ",$mod_name," "$DB_FILE")
|
||||
mod_index=$(echo "$entry" | awk -F, '{print $1}' | head -1)
|
||||
fi
|
||||
|
||||
if [[ -z "$entry" || -z "$mod_index" || -z "$mod_name" ]]; then
|
||||
echo -e "${RED}Error${NC}: Mod not found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
status=$(echo "$entry" | awk -F, '{print $2}')
|
||||
}
|
||||
|
||||
function find_game_directory() {
|
||||
local search_dir="${HOME}"
|
||||
local target_dir="Steam/steamapps/common/Helldivers\ 2/data"
|
||||
@@ -29,7 +60,6 @@ function find_game_directory() {
|
||||
if [[ -f "$H2PATH" ]]; then
|
||||
saved_dir=$(cat "$H2PATH")
|
||||
if [[ -d "$saved_dir" ]]; then
|
||||
echo "Using saved game directory \$MODS_DIR: $saved_dir" >&2
|
||||
echo "$saved_dir"
|
||||
return
|
||||
else
|
||||
@@ -71,7 +101,7 @@ function initialize_directories() {
|
||||
if [[ ! -f "$DB_FILE" ]]; then
|
||||
touch "$DB_FILE"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "Database file created at: $DB_FILE"
|
||||
echo -e "Database file ${GREEN}created${NC}: $DB_FILE"
|
||||
else
|
||||
echo -e "${RED}Error${NC}: Could not create database file." >&2
|
||||
exit 1
|
||||
@@ -82,7 +112,7 @@ function initialize_directories() {
|
||||
# --- Help Functions ---
|
||||
|
||||
function display_help() {
|
||||
echo "Helldivers 2 Mod Manager v0.1.6"
|
||||
echo "Helldivers 2 Mod Manager v${VERSION}"
|
||||
echo "Usage: h2mm [command] [options]"
|
||||
echo "Commands:"
|
||||
echo " install Install a mod with files (short form: h2mm i)."
|
||||
@@ -125,6 +155,26 @@ function display_uninstall_help() {
|
||||
echo " h2mm uninstall -i 1 # uninstall mod with index 1"
|
||||
}
|
||||
|
||||
function display_enable_help() {
|
||||
echo "Usage: h2mm enable [options] \"<mod_name>\""
|
||||
echo "Short form: h2mm e"
|
||||
echo "Options:"
|
||||
echo " -i <index> Index of the mod to enable."
|
||||
echo "Usage:"
|
||||
echo " h2mm enable \"Example mod\""
|
||||
echo " h2mm enable -i 1 # enable mod with index 1"
|
||||
}
|
||||
|
||||
function display_disable_help() {
|
||||
echo "Usage: h2mm disable [options] \"<mod_name>\""
|
||||
echo "Short form: h2mm d"
|
||||
echo "Options:"
|
||||
echo " -i <index> Index of the mod to disable."
|
||||
echo "Usage:"
|
||||
echo " h2mm disable \"Example mod\""
|
||||
echo " h2mm disable -i 1 # disable mod with index 1"
|
||||
}
|
||||
|
||||
function display_list_help() {
|
||||
echo "Usage: h2mm list"
|
||||
echo "Short form: h2mm l"
|
||||
@@ -155,6 +205,148 @@ function display_import_help() {
|
||||
|
||||
# --- Main Functions ---
|
||||
|
||||
# Check for updates
|
||||
|
||||
function check_for_updates() {
|
||||
if [[ -f "$LAST_CHECKED_UPDATE_FILE" ]]; then
|
||||
last_update=$(cat "$LAST_CHECKED_UPDATE_FILE")
|
||||
if [[ $(date +%Y-%m-%d) -gt $(date +%Y-%m-%d -d "$last_update + 7 days") ]]; then
|
||||
return
|
||||
fi
|
||||
else
|
||||
echo $(date +%Y-%m-%d) > "$LAST_CHECKED_UPDATE_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
latest_version=$(curl -sS "$VERSION_URL")
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "${RED}Error:${NC} Could not check for updates." >&2
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$latest_version" != "$VERSION" ]]; then
|
||||
echo -e "${RED}!${NC} A new version of h2mm is available: ${ORANGE}$VERSION${NC} -> ${GREEN}$latest_version${NC}" >&2
|
||||
echo -e "${RED}!${NC} You can download it from: $REPO_URL" >&2
|
||||
fi
|
||||
|
||||
echo $(date +%Y-%m-%d) > "$LAST_CHECKED_UPDATE_FILE"
|
||||
}
|
||||
|
||||
# Mod management
|
||||
|
||||
function mod_disable() {
|
||||
local mod_name=""
|
||||
local mod_index=""
|
||||
|
||||
[[ $# -eq 0 ]] && { display_disable_help; exit 0; }
|
||||
|
||||
# parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-i)
|
||||
mod_index="$2"; shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
display_disable_help; exit 0
|
||||
;;
|
||||
*)
|
||||
mod_name="$1"; shift 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$mod_name" && -z "$mod_index" ]]; then
|
||||
echo -e "${RED}Error${NC}: Mod name or index is required to disable." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# find mod files
|
||||
get_mod_name_and_index "$mod_name" "$mod_index"
|
||||
|
||||
if [[ "$status" == "DISABLED" ]]; then
|
||||
echo -e "${RED}Error${NC}: Mod $mod_name is already disabled." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# disable each mod file by adding disabled_ to the start of the filename
|
||||
files=$(get_files_by_entry_from_db "$entry")
|
||||
for file in $files; do
|
||||
if [[ ! -f "$MODS_DIR/$file" ]]; then
|
||||
echo -e "${RED}Error${NC}: Mod file $file does not exist." >&2
|
||||
exit 1
|
||||
else
|
||||
disabled_file="disabled_$file"
|
||||
mv "$MODS_DIR/$file" "$MODS_DIR/$disabled_file"
|
||||
echo -e "Disabled ${ORANGE}$file${NC} (changed to ${GREEN}\$MODS_DIR/$disabled_file${NC})." >&2
|
||||
fi
|
||||
done
|
||||
|
||||
# update the database
|
||||
sed -i "/^$mod_index,/s/ENABLED/DISABLED/" "$DB_FILE"
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "Mod $mod_name ${ORANGE}disabled${NC} successfully." >&2
|
||||
else
|
||||
echo -e "${RED}Error${NC}: Failed to disable mod." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function mod_enable() {
|
||||
local mod_name=""
|
||||
local mod_index=""
|
||||
|
||||
[[ $# -eq 0 ]] && { display_enable_help; exit 0; }
|
||||
|
||||
# parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-i)
|
||||
mod_index="$2"; shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
display_enable_help; exit 0
|
||||
;;
|
||||
*)
|
||||
mod_name="$1"; shift 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -z "$mod_name" && -z "$mod_index" ]] && { echo -e "${RED}Error${NC}: Mod name or index is required to enable." >&2; exit 1; }
|
||||
|
||||
# find mod files
|
||||
get_mod_name_and_index "$mod_name" "$mod_index"
|
||||
|
||||
[[ "$status" == "ENABLED" ]] && { echo -e "${RED}Error${NC}: Mod $mod_name is already enabled." >&2; exit 1; }
|
||||
|
||||
files=$(get_files_by_entry_from_db "$entry")
|
||||
|
||||
# enable each mod file by removing disabled_ from the start of the filename
|
||||
for file in $files; do
|
||||
disabled_file="disabled_$file"
|
||||
|
||||
# check if the files exists
|
||||
[[ -f "$MODS_DIR/$disabled_file" ]] || { echo -e "${RED}Error${NC}: Mod file $file does not exist." >&2; exit 1; }
|
||||
|
||||
mv "$MODS_DIR/$disabled_file" "$MODS_DIR/$file"
|
||||
|
||||
# check if the file was moved successfully
|
||||
[[ $? -ne 0 ]] && { echo -e "${RED}Error${NC}: Could not enable mod file $disabled_file." >&2; exit 1; }
|
||||
echo -e "Enabled ${ORANGE}$disabled_file${NC} (changed to ${GREEN}\$MODS_DIR/$file${NC})." >&2
|
||||
done
|
||||
|
||||
# update the database
|
||||
sed -i "/^$mod_index,/s/DISABLED/ENABLED/" "$DB_FILE"
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "Mod $mod_name ${GREEN}enabled${NC} successfully." >&2
|
||||
else
|
||||
echo -e "${RED}Error${NC}: Failed to enable mod." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function mod_reset() {
|
||||
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
|
||||
display_reset_help
|
||||
@@ -175,24 +367,19 @@ function mod_reset() {
|
||||
|
||||
function mod_install() {
|
||||
local mod_name=""
|
||||
local mod_files=()
|
||||
local mod_dir=""
|
||||
local mod_files=()
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
display_install_help
|
||||
exit 0
|
||||
fi
|
||||
[[ $# -eq 0 ]] && { display_install_help; exit 0; }
|
||||
|
||||
# parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-n)
|
||||
mod_name="$2"
|
||||
shift 2
|
||||
mod_name="$2"; shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
display_install_help
|
||||
exit 0
|
||||
display_install_help; exit 0
|
||||
;;
|
||||
*)
|
||||
if [[ -f "$1" && "$1" == *.zip ]]; then
|
||||
@@ -204,20 +391,14 @@ function mod_install() {
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
done
|
||||
|
||||
# zip file containing mod files
|
||||
if [[ -n "$mod_zip" ]]; then
|
||||
if ! command -v unzip &> /dev/null; then
|
||||
echo -e "${RED}Error${NC}: unzip is not installed, please install the package and try again." >&2
|
||||
exit 1
|
||||
fi
|
||||
command -v unzip &> /dev/null || { echo -e "${RED}Error${NC}: unzip package is not installed." >&2; exit 1; }
|
||||
|
||||
if [[ ! -f "$mod_zip" ]]; then
|
||||
echo -e "${RED}Error${NC}: Zip file $mod_zip does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ ! -f "$mod_zip" ]] && { echo -e "${RED}Error${NC}: Zip file $mod_zip does not exist." >&2; exit 1; }
|
||||
|
||||
# check if mod name was provided, otherwise use the zip file name, get rid of .zip and version numbers
|
||||
if [[ -z "$mod_name" ]]; then
|
||||
@@ -230,10 +411,8 @@ function mod_install() {
|
||||
|
||||
# directory containing mod files
|
||||
if [[ -n "$mod_dir" ]]; then
|
||||
if [[ ! -d "$mod_dir" ]]; then
|
||||
echo -e "${RED}Error${NC}: Directory $mod_dir does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
# verify directory exists
|
||||
[[ ! -d "$mod_dir" ]] && { echo -e "${RED}Error${NC}: Directory $mod_dir does not exist." >&2; exit 1; }
|
||||
|
||||
readarray -d '' mod_files < <(find "$mod_dir" -type f -name "*.patch_*" -print0)
|
||||
if [[ -z "$mod_name" ]]; then
|
||||
@@ -242,20 +421,15 @@ function mod_install() {
|
||||
fi
|
||||
|
||||
# verify minimum information required
|
||||
if [[ -z "$mod_name" || ${#mod_files[@]} -eq 0 ]]; then
|
||||
echo -e "${RED}Error${NC}: Mod name and files are required." >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ -z "$mod_name" || ${#mod_files[@]} -eq 0 ]] && { echo -e "${RED}Error${NC}: Mod name and files are required." >&2; exit 1; }
|
||||
|
||||
# verify mod files exist and is not directory
|
||||
for file in "${mod_files[@]}"; do
|
||||
if [[ ! -f "$file" ]]; then
|
||||
if [[ ! -d "$file" ]]; then
|
||||
echo -e "${RED}Error${NC}: File $file does not exist." >&2
|
||||
exit 1
|
||||
else
|
||||
mod_files=(${mod_files[@]/$file})
|
||||
fi
|
||||
# if it isn't a file, check if it's a directory
|
||||
[[ ! -d "$file" ]] && { echo -e "${RED}Error${NC}: File $file does not exist." >&2; exit 1; }
|
||||
|
||||
mod_files=(${mod_files[@]/$file})
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -278,7 +452,7 @@ function mod_install() {
|
||||
patch_count["$base_name"]=$count
|
||||
|
||||
# if the file has an extension, look for the last patch number and use that
|
||||
extension=$(echo "$file" | sed -E 's/.*patch_[0-9]+//')
|
||||
extension=$(get_extension "$file")
|
||||
if [[ -n "$extension" ]]; then
|
||||
target_file="${base_name}.patch_$((patch_count[$base_name] - 1))${extension}"
|
||||
else
|
||||
@@ -286,60 +460,36 @@ function mod_install() {
|
||||
fi
|
||||
|
||||
target_files+=($target_file)
|
||||
|
||||
cp "$file" "$MODS_DIR/$target_file"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "Mod file ${ORANGE}$file${NC} installed at ${GREEN}\$MODS_DIR/$target_file${NC}." >&2
|
||||
else
|
||||
echo -e "${RED}Error${NC}: Could not install mod file $file." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# verify installation worked
|
||||
[[ $? -ne 0 ]] && { echo -e "${RED}Error${NC}: Could not install mod file $file." >&2; exit 1; }
|
||||
echo -e "Mod file ${ORANGE}$file${NC} installed at ${GREEN}\$MODS_DIR/$target_file${NC}." >&2
|
||||
done
|
||||
|
||||
# add entry to database
|
||||
next_id=$(awk -F, 'END {print $1 + 1}' "$DB_FILE")
|
||||
echo "$next_id,$mod_name,${target_files[*]}" >> "$DB_FILE"
|
||||
echo -e "Mod $mod_name ($base_name) ${GREEN}installed successfully${NC}." >&2
|
||||
}
|
||||
|
||||
function mod_list() {
|
||||
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
|
||||
display_list_help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! -s "$DB_FILE" ]]; then
|
||||
echo "No mods installed."
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Installed mods:" >&2
|
||||
awk -F, '{ if (length($3) > 150) $3 = substr($3, 1, 147) "..."; printf "%2s. %s (%s)\n", $1, $2, $3 }' "$DB_FILE"
|
||||
echo "$next_id,ENABLED,$mod_name,${target_files[*]}" >> "$DB_FILE"
|
||||
echo -e "Mod $mod_name ($base_name) ${GREEN}installed${NC} successfully." >&2
|
||||
}
|
||||
|
||||
function mod_uninstall() {
|
||||
local mod_name=""
|
||||
local mod_index=""
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
display_uninstall_help
|
||||
exit 0
|
||||
fi
|
||||
[[ $# -eq 0 ]] && { display_uninstall_help; exit 0; }
|
||||
|
||||
# parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-i)
|
||||
mod_index="$2"
|
||||
shift 2
|
||||
mod_index="$2"; shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
display_uninstall_help
|
||||
exit 0
|
||||
display_uninstall_help; exit 0
|
||||
;;
|
||||
*)
|
||||
mod_name="$1"
|
||||
shift 1
|
||||
mod_name="$1"; shift 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -350,21 +500,11 @@ function mod_uninstall() {
|
||||
fi
|
||||
|
||||
# find mod files
|
||||
if [[ -n "$mod_index" ]]; then
|
||||
entry=$(grep "^${mod_index}," "$DB_FILE")
|
||||
mod_name=$(echo "$entry" | awk -F, '{print $2}')
|
||||
elif [[ -n "$mod_name" ]]; then
|
||||
entry=$(grep -i ",$mod_name," "$DB_FILE")
|
||||
mod_index=$(echo "$entry" | awk -F, '{print $1}' | head -1)
|
||||
fi
|
||||
|
||||
if [[ -z "$entry" ]]; then
|
||||
echo -e "${RED}Error${NC}: Mod not found." >&2
|
||||
exit 1
|
||||
fi
|
||||
get_mod_name_and_index "$mod_name" "$mod_index"
|
||||
|
||||
# delete mod files
|
||||
files=$(echo "$entry" | cut -d',' -f3- | tr ',' ' ' | head -1)
|
||||
files=$(get_files_by_entry_from_db "$entry")
|
||||
echo "$files"
|
||||
declare -A downgrades
|
||||
for file in $files; do
|
||||
if [[ ! -f "$MODS_DIR/$file" ]]; then
|
||||
@@ -372,7 +512,12 @@ function mod_uninstall() {
|
||||
exit 1
|
||||
else
|
||||
echo -e "Removing ${ORANGE}\$MODS_DIR/$file${NC}." >&2
|
||||
rm -f "$MODS_DIR/$file"
|
||||
rm "$MODS_DIR/$file"
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}Error${NC}: Could not remove mod file $file." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
base_name=$(get_basename "$file")
|
||||
current_version=$(echo $file | grep -oP '(?<=patch_)\d+')
|
||||
@@ -391,7 +536,7 @@ function mod_uninstall() {
|
||||
patch_version=$(echo $patch | grep -oP '(?<=patch_)\d+')
|
||||
if [[ $patch_version -gt ${downgrades[$file]} ]]; then
|
||||
new_version=$((patch_version - downgrades[$base_name] - 1))
|
||||
extension=$(echo "$patch" | sed -E 's/.*patch_[0-9]+//')
|
||||
extension=$(get_extension "$path")
|
||||
|
||||
new_patch="${base_name}.patch_${new_version}${extension}"
|
||||
mv "$MODS_DIR/$patch" "$MODS_DIR/$new_patch"
|
||||
@@ -406,7 +551,25 @@ function mod_uninstall() {
|
||||
# remove entry from database
|
||||
sed -i "/^$mod_index/d" "$DB_FILE"
|
||||
|
||||
echo -e "Mod ${GREEN}uninstalled successfully${NC}." >&2
|
||||
echo -e "Mod $mod_name ${ORANGE}uninstalled${NC} successfully." >&2
|
||||
}
|
||||
|
||||
function mod_list() {
|
||||
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
|
||||
display_list_help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! -s "$DB_FILE" ]]; then
|
||||
echo "No mods installed."
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Installed mods:" >&2
|
||||
awk -v GREEN="$GREEN" -v RED="$RED" -v NC="$NC" -F, '{
|
||||
color = ($2 == "DISABLED") ? RED : GREEN;
|
||||
if (length($3) > 150) $3 = substr($3, 1, 147) "...";
|
||||
printf "%2s. [%s%s%s] %s (%s)\n", $1, color, $2, NC, $3, $4}' "$DB_FILE"
|
||||
}
|
||||
|
||||
function mod_export() {
|
||||
@@ -415,12 +578,7 @@ function mod_export() {
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v zip &> /dev/null; then
|
||||
echo -e "${RED}Error${NC}: zip is not installed, please install the package and try again." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -ne "Zip file will be saved in the current directory ($(pwd)). Continue? (Y/n): "
|
||||
echo -ne "Archive file will be saved in the current directory ($(pwd)). Continue? (Y/n): "
|
||||
read -r confirm
|
||||
if [[ "$confirm" == "y" || "$confirm" == "Y" || "$confirm" = "" ]]; then
|
||||
OUT_DIR=$(mktemp -d)
|
||||
@@ -438,13 +596,11 @@ function mod_export() {
|
||||
fi
|
||||
|
||||
current_path=$(pwd)
|
||||
zip_name="Helldivers_2_Mods_$(date +%Y-%m-%d_%H-%M-%S).zip"
|
||||
cd "$OUT_DIR"
|
||||
zip -r "$zip_name" "Helldivers 2 Mods"
|
||||
mv "$zip_name" "$current_path"
|
||||
archive_name="Helldivers_2_Mods_$(date +%Y-%m-%d_%H-%M-%S).tar.gz"
|
||||
tar -czf "$current_path/$archive_name" -C "$OUT_DIR" "Helldivers 2 Mods"
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "Mods exported to ${GREEN}$current_path/$zip_name${NC}." >&2
|
||||
echo -e "Mods exported to ${GREEN}$current_path/$archive_name${NC}." >&2
|
||||
else
|
||||
echo -e "${RED}Error${NC}: Failed to export mods." >&2
|
||||
fi
|
||||
@@ -462,11 +618,6 @@ function mod_import() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v unzip &> /dev/null; then
|
||||
echo -e "${RED}Error${NC}: unzip is not installed, please install the package and try again." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "Importing mods will ${RED}reset${NC} your mods." >&2
|
||||
mod_reset
|
||||
if [[ $? -eq 1 ]]; then
|
||||
@@ -474,7 +625,7 @@ function mod_import() {
|
||||
fi
|
||||
|
||||
OUT_DIR=$(mktemp -d)
|
||||
unzip -qq "$1" -d "$OUT_DIR"
|
||||
tar -xzf "$1" -C "$OUT_DIR"
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}Error${NC}: Could not import mods. Possibly because the zip file is invalid." >&2
|
||||
@@ -507,6 +658,7 @@ function main() {
|
||||
command="$1"
|
||||
shift
|
||||
initialize_directories
|
||||
check_for_updates
|
||||
|
||||
case "$command" in
|
||||
install|i)
|
||||
@@ -518,6 +670,12 @@ function main() {
|
||||
uninstall|u)
|
||||
mod_uninstall "$@"
|
||||
;;
|
||||
enable|e)
|
||||
mod_enable "$@"
|
||||
;;
|
||||
disable|d)
|
||||
mod_disable "$@"
|
||||
;;
|
||||
export|ex)
|
||||
mod_export "$@"
|
||||
;;
|
||||
@@ -527,6 +685,9 @@ function main() {
|
||||
reset|r)
|
||||
mod_reset "$@"
|
||||
;;
|
||||
version|v|-v|--version)
|
||||
echo "${VERSION}"
|
||||
;;
|
||||
help|--help|-h|h)
|
||||
display_help
|
||||
;;
|
||||
|
||||
+76
@@ -2,6 +2,8 @@
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
ORANGE='\033[0;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
DESTINATION_PATH="/usr/local/bin"
|
||||
@@ -12,13 +14,87 @@ if [ "$(id -u)" -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Main ---
|
||||
|
||||
# Warning
|
||||
|
||||
echo -e "!!! ${RED}WARNING${NC} !!!"
|
||||
echo -e "This script will install Helldivers 2 Mod Manager CLI for Linux to $DESTINATION_PATH/$SCRIPT_NAME."
|
||||
echo -e "Running this script will require sudo permissions. ${RED}DO NOT TRUST${NC} random scripts from the internet."
|
||||
echo -e "If you want to review the script before running it, check out the mod repository for yourself:"
|
||||
echo -e "https://github.com/v4n00/h2mm-cli"
|
||||
echo -e "!!! ${RED}WARNING${NC} !!!"
|
||||
echo
|
||||
|
||||
# Check if update
|
||||
|
||||
# Breaking changes hash table
|
||||
|
||||
breaking_changes_patches=(
|
||||
["2"]='sed -i "s/^\([0-9]\+\),/\1,ENABLED,/" "$1/mods.csv"'
|
||||
)
|
||||
|
||||
# Script
|
||||
|
||||
if [[ -x "$(command -v $SCRIPT_NAME)" ]]; then
|
||||
installed_version=$($SCRIPT_NAME --version)
|
||||
# version 1 show the help message, if the first character is not a 0, store installed version as 0.1.6
|
||||
[[ ${installed_version:0:1} != "0" ]] && { installed_version="0.1.6"; }
|
||||
|
||||
latest_version=$(curl -sS https://raw.githubusercontent.com/v4n00/h2mm-cli/refs/heads/master/version)
|
||||
if [[ "$latest_version" == "$installed_version" ]]; then
|
||||
echo -e "You are reinstalling version $installed_version."
|
||||
else
|
||||
echo -e "You are upgrading from ${ORANGE}$installed_version${NC} -> ${GREEN}$latest_version${NC}."
|
||||
fi
|
||||
|
||||
# split version numbers
|
||||
installed_major=""
|
||||
latest_major=""
|
||||
IFS='.' read -r _1 installed_major _2 <<< "$installed_version"
|
||||
IFS='.' read -r _1 latest_major _2 <<< "$latest_version"
|
||||
|
||||
if [[ $latest_major -gt $installed_major ]]; then
|
||||
echo -e "${ORANGE}Warning:${NC} Major version upgrade detected."
|
||||
echo "The script will proceed to upgrade ${SCRIPT_NAME} to avoid breaking changes."
|
||||
|
||||
# find hd2 path
|
||||
search_dir="${HOME}"
|
||||
target_dir="Steam/steamapps/common/Helldivers\ 2/data"
|
||||
echo "Searching for the Helldivers 2 data directory..." >&2
|
||||
game_dir=$(find "$search_dir" -type d -path "*/$target_dir" 2>/dev/null | head -n 1)
|
||||
if [[ -z "$game_dir" ]]; then
|
||||
echo "Could not find the Helldivers 2 data directory automatically." >&2
|
||||
read -p "Please enter the path to the Helldivers 2 data directory: " game_dir
|
||||
game_dir=$(eval echo "$game_dir")
|
||||
|
||||
if [[ ! -d "$game_dir" ]]; then
|
||||
echo -e "${RED}Error${NC}: Provided path is not a valid directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ ! -f "$game_dir/mods.csv" ]] && { echo -e "${RED}Error:${NC} mods.csv not found in $game_dir."; exit 1; }
|
||||
|
||||
# iterate from installed major number to latest major number
|
||||
for ((i = installed_major + 1; i <= latest_major; i++)); do
|
||||
echo -e "${RED}[ ]${NC} Applying breaking changes patch for version $i."
|
||||
|
||||
[[ -n "${breaking_changes_patches[$i]}" ]] && eval $(echo "${breaking_changes_patches[$i]}" | sed "s:\$1:$game_dir:")
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -ne "${RED}Error:${NC} Failed to apply breaking changes patch for version $i. Do you want to continue? (Y/n): "
|
||||
read -r response
|
||||
|
||||
[[ "$response" != "y" && "$response" != "Y" && -n "$response" ]] && { echo "Exiting. Uninstall the script first the retry the install script."; exit 1; }
|
||||
else
|
||||
echo -e "${GREEN}[X]${NC} Breaking changes patch for version $i applied successfully."
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install
|
||||
|
||||
read -p "Install the script to $DESTINATION_PATH or specify another path (must be included in \$PATH)? (Y/path): " response
|
||||
|
||||
if [[ "$response" != "y" && "$response" != "Y" && -n "$response" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user