34 Commits

Author SHA1 Message Date
v4n cb71852068 fix: prompts for install script 2025-03-19 20:25:44 +02:00
v4n 26031c0381 version 0.4.0 release 2025-03-19 20:20:12 +02:00
Daedalusspacegames 9c73be1cb7 fix: modify date syntax to enhance compatibility with alternate coreutils implementations, such as [uutils](https://github.com/uutils/coreutils) (#29) 2025-03-19 12:10:17 +02:00
v4n a8e94c19fb feat: command to change load order of mods (#27)
* progress

* progress

* feat: progress

* progress

* done, needs more testing, pr -> change all functions to require -n before specifying name -> v0.4 (reindex db)

* testing done
2025-03-18 16:18:48 +02:00
v4n 6b968172ea fix: updating now works properly 2025-03-10 21:42:55 +02:00
v4n b3bc91522f do not update 2025-03-10 21:14:37 +02:00
v4n a7936c90bd fix: stop latest update 2025-03-10 21:07:03 +02:00
v4n 4d1af7e4a0 feat: modpack-create can select individual mods (#26) 2025-03-10 21:01:06 +02:00
v4n 0eff8afe6b fix: turned code into fn 2025-03-08 00:38:04 +02:00
v4n 3593e32a7b fix: upgrade mods was overwriting files 2025-03-07 23:24:30 +02:00
v4n 797739ea7a fix: uninstall correctly reindexes (fix #21) 2025-03-07 22:57:14 +02:00
v4n df006a7430 fix: infite loop while enabling (#25) 2025-03-07 18:20:34 +02:00
v4n 344e4348d4 fix: non important sed error 2025-03-06 04:09:45 +02:00
v4n 719217d00b bump: version 2025-03-06 01:29:45 +02:00
v4n b1930811f9 fix: segfault from infinite recursion 2025-03-06 01:29:14 +02:00
v4n d1ca18b563 bump: downgrade because of seg fault 2025-03-06 00:59:58 +02:00
v4n 5d91190dbf fix: code cleanup 2025-03-06 00:12:59 +02:00
v4n 28122ee332 feat: list is now compact, added verbose option 2025-03-05 19:09:57 +02:00
v4n 56bb73784e fix: directory checking in wrong place 2025-03-02 15:38:07 +02:00
v4n 0d8f22a2d0 fix: variants fix 2025-02-21 17:15:35 +02:00
v4n 3c6238f8d2 fix: show variants better 2025-02-21 16:16:42 +02:00
v4n a031230117 fix: bash black magic 2025-02-21 16:06:20 +02:00
v4n 77ae53ffa7 fix: weird update bug 2025-02-21 14:03:49 +02:00
v4n c23c57e16c fix: weird update bug 2025-02-21 14:01:36 +02:00
v4n 898400e526 fix: whitespace in help msg 2025-02-21 13:48:50 +02:00
v4n c45f5860d8 bump: version 2025-02-21 13:44:18 +02:00
v4n 838c834cc2 feat: easily install multiple variants (#20)
* feat: easily install multiple variants

* fix: filter only dirs that have patches
2025-02-21 13:16:29 +02:00
v4n 7b8b2fda8f fix: console output, formatting 2025-02-21 12:46:46 +02:00
Catherine Guelque 0485b56df5 There is no need to install in the global path nor to use SUDO if the given path was writtable (#18)
* There's no need for sudo + Added warning if not in PATH

* fix: removed duplicated command call

---------

Co-authored-by: v4n <105587619+v4n00@users.noreply.github.com>
2025-02-17 18:07:54 +02:00
v4n d18a9cdccf fix: formatting 2025-02-06 20:13:45 +02:00
v4n c74f4a8a00 fix: whitespace, version bump for earlier commit 2025-02-06 20:12:27 +02:00
Matt Cavanagh 9f592e7ce2 feat: added .editorconfig to ensure consistency across IDEs and to prevent line ending oopsies (#17) 2025-02-06 19:47:37 +02:00
v4n 21b1822006 fix: uninstall correctly downgrades 2025-02-06 19:43:30 +02:00
v4n dbcc7d1e96 fix: CRLF -> LF 2025-02-06 03:34:33 +02:00
6 changed files with 1839 additions and 1423 deletions
+6
View File
@@ -0,0 +1,6 @@
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
+1
View File
@@ -3,3 +3,4 @@
!install.sh !install.sh
!README.md !README.md
!version !version
!.editorconfig
+23 -22
View File
@@ -34,24 +34,27 @@ h2mm
### Available commands ### Available commands
- `install` - Install a mod by the file provided (directory, zip, patch). - `install` - Install a mod by the file provided (directory, zip, patch).
- `uninstall` - Uninstall a mod by name (or index). - `uninstall` - Uninstall a mod.
- `list` - List all installed mods. - `list` - List all installed mods.
- `enable` - Enable a mod by name (or index). - `enable` - Enable a mod.
- `disable` - Disable a mod by name (or index). - `disable` - Disable a mod.
- `export` - Export installed mods to a zip file. - `export` - Export installed mods to a zip file.
- `import` - Import mods from a zip file. - `import` - Import mods from a zip file.
- `order` - Change load order for a mod.
- `modpack-create` - Create a modpack from the currently installed mods. - `modpack-create` - Create a modpack from the currently installed mods.
- `modpack-switch` - Switch to a modpack by name (or index). - `modpack-switch` - Switch to a modpack.
- `modpack-list` - List all installed modpacks. - `modpack-list` - List all installed modpacks.
- `modpack-delete` - Delete a modpack by name (or index). - `modpack-delete` - Delete a modpack.
- `modpack-overwrite` - Overwrite a modpack by name (or index). - `modpack-overwrite` - Overwrite a modpack.
- `modpack-reset` - Reset all installed modpacks. - `modpack-reset` - Reset all installed modpacks.
- `reset` - Reset all installed mods.
- `update` - Update h2mm to latest version. - `update` - Update h2mm to latest version.
- `reset` - Reset all installed mods.
- `help` - Display this help message. - `help` - Display this help message.
### Basic usage ### Basic usage
To find out how to use a command, you can run `h2mm <COMMAND> --help`.
#### Install mod(s) #### Install mod(s)
```bash ```bash
@@ -62,23 +65,20 @@ 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 h2mm install -n "Example mod" mod* # using a wildcard to include all files
``` ```
> [!NOTE]
> If the mod has more than 1 variant, you need to install the one you want by unarchiving it separately and providing the directory.
#### Uninstall a mod #### Uninstall a mod
```bash ```bash
h2mm uninstall "Example mod" h2mm uninstall -n "Example mod"
h2mm uninstall -i 1 # uninstall mod with index 1 h2mm uninstall -i 3
``` ```
#### Enable/disable mods #### Enable/disable mods
```bash ```bash
h2mm enable "Example mod" h2mm enable -n "Example mod"
h2mm enable -i 1 # enable mod with index 1 h2mm enable -i 3
h2mm disable "Example mod" h2mm disable -n "Example mod"
h2mm disable -i 1 # disable mod with index 1 h2mm disable -i 3
``` ```
#### List installed mods #### List installed mods
@@ -118,24 +118,25 @@ You can use the short form of commands to save some time. The shortcuts are:
- `l` for `list` - `l` for `list`
- `ex` for `export` - `ex` for `export`
- `im` for `import` - `im` for `import`
- `o` for `order`
- `mc` for `modpack-create` - `mc` for `modpack-create`
- `ms` for `modpack-switch` - `ms` for `modpack-switch`
- `ml` for `modpack-list` - `ml` for `modpack-list`
- `md` for `modpack-delete` - `md` for `modpack-delete`
- `mo` for `modpack-overwrite` - `mo` for `modpack-overwrite`
- `mr` for `modpack-reset` - `mr` for `modpack-reset`
- `r` for `reset`
- `up` for `update` - `up` for `update`
- `r` for `reset`
### Modpacks support ### Modpacks support
You can set up modpacks by using the `modpack-*` commands. This allows you to quickly change between a set of mods. For more information, check the help message. You can set up modpacks by using the `modpack-*` commands. This allows you to quickly change between a set of mods. For more information, check the help message.
```bash ```bash
h2mm modpack-create "Modpack 1" h2mm modpack-create -n "Modpack 1"
# install, enable, disable other mods... # install, enable, disable other mods...
h2mm modpack-create "Modpack 2" h2mm modpack-create -n "Modpack 2"
h2mm modpack-switch "Modpack 1" h2mm modpack-switch -n "Modpack 1"
``` ```
### Exporting and importing ### Exporting and importing
@@ -143,8 +144,8 @@ h2mm modpack-switch "Modpack 1"
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 archive file (`.tar.gz`) will be saved in the current directory. 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 archive file (`.tar.gz`) will be saved in the current directory.
```bash ```bash
h2mm export modpack1.zip h2mm export
h2mm import modpack2.zip h2mm import /path/to/mods.tar.gz
``` ```
### Resetting all installed mods ### Resetting all installed mods
+739 -361
View File
File diff suppressed because it is too large Load Diff
+118 -88
View File
@@ -10,102 +10,69 @@ DESTINATION_PATH="/usr/local/bin"
SCRIPT_NAME="h2mm" SCRIPT_NAME="h2mm"
REPO_URL="https://raw.githubusercontent.com/v4n00/h2mm-cli/refs/heads/master" REPO_URL="https://raw.githubusercontent.com/v4n00/h2mm-cli/refs/heads/master"
if [ "$(id -u)" -eq 0 ]; then function log() {
echo "Run me as normal user, not as root." local type="$1"
exit 1 shift
fi case "$type" in
INFO)
echo -e "$*" >&2
;;
ERROR)
echo -e "${RED}[ERROR]${NC} $*" >&2
;;
PROMPT)
echo -ne "$*" >&2
;;
esac
}
# --- Main --- # --- Main ---
# Warning # warning
echo -e "!!! ${RED}WARNING${NC} !!!" cat << EOF
echo -e "This script will install Helldivers 2 Mod Manager CLI for Linux to $DESTINATION_PATH/$SCRIPT_NAME." !!! WARNING !!!
echo -e "Running this script will require sudo permissions. ${RED}DO NOT TRUST${NC} random scripts from the internet." This script will install Helldivers 2 Mod Manager CLI for Linux to $DESTINATION_PATH/$SCRIPT_NAME.
echo -e "If you want to review the script before running it, check out the mod repository for yourself:" Running this script will require sudo permissions. DO NOT TRUST random scripts from the internet.
echo -e "https://github.com/v4n00/h2mm-cli" If you want to review the script before running it, check out the mod repository for yourself:
echo -e "!!! ${RED}WARNING${NC} !!!" https://github.com/v4n00/h2mm-cli
echo !!! WARNING !!!
# Check if update EOF
# Breaking changes hash table
# breaking changes hash table
breaking_changes_patches=( breaking_changes_patches=(
["2"]='sed -i "s/^\([0-9]\+\),/\1,ENABLED,/" "$1/mods.csv"' ["2"]='sed -i "s/^\([0-9]\+\),/\1,ENABLED,/" "$1/mods.csv"'
["3"]='sed -i "1 i\\3" "$1/mods.csv"' ["3"]='sed -i "1 i\\3" "$1/mods.csv"'
["4"]='awk '\''BEGIN {FS=OFS=","} NR==1 {print 4; next} {print NR-1, $2, $3, $4, $5}'\'' "$1/mods.csv" | tee "$1/mods.csv" > /dev/null'
) )
# Handle breaking changes # notify if update is happening
installed_version=""
latest_version=""
if [[ -x "$(command -v $SCRIPT_NAME)" ]]; then if [[ -x "$(command -v $SCRIPT_NAME)" ]]; then
installed_version=$($SCRIPT_NAME --version) 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"; } # if installed version isn't x.x.x crash
if [[ ! "$installed_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
log ERROR "Installed version is not in the correct format."
log ERROR "h2mm is installed here -> $(which h2mm)"
log ERROR "Delete the script file and retry the install script, any mods installed will not be lost."
exit 1
fi
latest_version=$(curl -sS "$REPO_URL"/version) latest_version=$(curl -sS "$REPO_URL"/version)
if [[ "$latest_version" == "$installed_version" ]]; then if [[ "$latest_version" == "$installed_version" ]]; then
echo -e "You are reinstalling version $installed_version." log INFO "You are reinstalling version ${GREEN}$installed_version${NC}."
else else
echo -e "You are upgrading from ${ORANGE}$installed_version${NC} -> ${GREEN}$latest_version${NC}." log INFO "You are upgrading from ${ORANGE}$installed_version${NC} -> ${GREEN}$latest_version${NC}."
fi 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 "${ORANGE}Info${NC}: Check out the changelogs here -> https://github.com/v4n00/h2mm-cli/releases"
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... (20 seconds timeout)" >&2
game_dir=$(timeout 20 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
IFS= read -ep "Please enter the path to the Helldivers 2 data directory: " 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; }
# make backup of mods in case something goes wrong
echo "${ORANGE}V${NC} It is advised to make a backup before proceeding."
h2mm export
# iterate from installed major number to latest major number
for ((i = installed_major + 1; i <= latest_major; i++)); do
if [[ -n "${breaking_changes_patches[$i]}" ]]; then
eval $(echo "${breaking_changes_patches[$i]}" | sed "s:\$1:$game_dir:")
else
echo "No breaking changes for version $i."
fi
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 -er response
[[ "$response" != "y" && "$response" != "Y" && -n "$response" ]] && { echo "Exiting. Uninstall the script first the retry the install script."; exit 1; }
else
echo -e "Breaking changes patch for version ${ORANGE}$i${NC} applied ${GREEN}successfully${NC}."
fi
done
fi
echo
fi fi
# Install
# if steam deck, set destination path to ~/.local/bin # if steam deck, set destination path to ~/.local/bin
IFS= read -ep "Are you installing on a Steam Deck? (y/N): " response_sd log PROMPT "Are you installing on a Steam Deck? (y/N): "
IFS= read -e response_sd
if [[ "$response_sd" == "y" || "$response_sd" == "Y" ]]; then if [[ "$response_sd" == "y" || "$response_sd" == "Y" ]]; then
# steam deck # steam deck
DESTINATION_PATH="$HOME/.local/bin" DESTINATION_PATH="$HOME/.local/bin"
@@ -114,33 +81,96 @@ if [[ "$response_sd" == "y" || "$response_sd" == "Y" ]]; then
# check if ~/.local/bin is in PATH # check if ~/.local/bin is in PATH
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
# add ~/.local/bin to PATH # add ~/.local/bin to PATH
echo -e "${ORANGE}Warning:${NC} Installing the script on a Steam Deck means adding $DESTINATION_PATH to your \$PATH." log INFO "Installing the script on a Steam Deck means adding $DESTINATION_PATH to your \$PATH."
echo -e "${ORANGE}Warning:${NC} If you're using a different shell, you may need to add it manually." log INFO "If you're using a different shell than bash, you may need to add it manually."
IFS= read -ep "Do you want to add $DESTINATION_PATH to your \$PATH in ~/.bashrc? (Y/n): " response log PROMPT "Do you want to add $DESTINATION_PATH to your \$PATH in ~/.bashrc? (Y/n): "
IFS= read -e response
if [[ "$response" == "y" || "$response" = "Y" || -z "$response" ]]; then if [[ "$response" == "y" || "$response" = "Y" || -z "$response" ]]; then
echo "export PATH=\"\$HOME/.local/bin:\$PATH\"" >> "$HOME/.bashrc" echo "export PATH=\"\$HOME/.local/bin:\$PATH\"" >> "$HOME/.bashrc"
echo -e "${GREEN}Success:${NC} Added $DESTINATION_PATH to your \$PATH in ~/.bashrc."
[[ $? -ne 0 ]] && { log ERROR "Failed to add $DESTINATION_PATH to \$PATH in ~/.bashrc." ; exit 1; }
log INFO "Added $DESTINATION_PATH to your \$PATH in ~/.bashrc."
fi fi
fi fi
else else
# not steam deck # not steam deck
# set another path if needed # set another path if needed
IFS= read -ep "Install the script to $DESTINATION_PATH or specify another path (must be included in \$PATH)? (Y/path): " response log PROMPT "Install the script to $DESTINATION_PATH or specify another path (must be included in \$PATH)? (Y/path): "
IFS= read -e response
if [[ "$response" != "y" && "$response" != "Y" && -n "$response" ]]; then if [[ "$response" != "y" && "$response" != "Y" && -n "$response" ]]; then
DESTINATION_PATH="$response" DESTINATION_PATH="$response"
[[ ! -d "$DESTINATION_PATH" ]] && { echo -e "${RED}Error:${NC} Path $DESTINATION_PATH does not exist."; exit 1; } [[ ! -d "$DESTINATION_PATH" ]] && { log ERROR "Path $DESTINATION_PATH does not exist." ; exit 1; }
fi fi
fi fi
echo "Installing $SCRIPT_NAME to $DESTINATION_PATH." # handle breaking changes
sudo curl "$REPO_URL"/h2mm --output "$DESTINATION_PATH/$SCRIPT_NAME" installed_major=$(echo "$installed_version" | awk -F. '{print $2}')
sudo chmod +x "$DESTINATION_PATH/$SCRIPT_NAME" latest_major=$(echo "$latest_version" | awk -F. '{print $2}')
if [[ ! -x "$(command -v $SCRIPT_NAME)" ]]; then if [[ $latest_major -gt $installed_major ]]; then
echo -e "${RED}Error:${NC} Installation failed." log INFO ""
exit 1 log INFO "Major version upgrade detected."
log INFO "Check out the changelogs here -> https://github.com/v4n00/h2mm-cli/releases"
log INFO "The script will proceed to upgrade the database file to avoid breaking changes."
# find hd2 path
search_dir="${HOME}"
target_dir="Steam/steamapps/common/Helldivers\ 2/data"
# check if game directory is in ~/.config/h2mm/h2path
if [[ -f "$HOME/.config/h2mm/h2path" ]]; then
game_dir=$(cat "$HOME/.config/h2mm/h2path")
[[ ! -d "$game_dir" ]] && { log ERROR "Helldivers 2 data directory in ~/.config/h2mm/h2path is not a valid directory." ; exit 1; }
log INFO "Helldivers 2 data directory found: $game_dir."
else
log INFO "Searching for the Helldivers 2 data directory... (20 seconds timeout)"
game_dir=$(timeout 20 find "$search_dir" -type d -path "*/$target_dir" 2>/dev/null | head -n 1)
fi
# if not found, prompt user
if [[ -z "$game_dir" ]]; then
log INFO "Could not find the Helldivers 2 data directory automatically."
log PROMPT "Please enter the path to the Helldivers 2 data directory: "
IFS= read -e game_dir
if [[ ! -d "$game_dir" ]]; then
log ERROR "Provided path is not a valid directory."
exit 1
fi
fi
[[ ! -f "$game_dir/mods.csv" ]] && { log ERROR "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
if [[ -n "${breaking_changes_patches[$i]}" ]]; then
# apply breaking changes patch
eval $(echo "${breaking_changes_patches[$i]}" | sed "s:\$1:$game_dir:g")
else
log INFO "No breaking changes for version $i."
continue
fi
if [[ $? -ne 0 ]]; then
log ERROR "Failed to apply breaking changes patch for version $i. Do you want to continue? (Y/n): "
read -er response
[[ "$response" != "y" && "$response" != "Y" && -n "$response" ]] && { log INFO "Exiting." ; exit 1; }
else
log INFO "Version upgrade fix ${GREEN}successfully${NC} applied for version $i."
fi
done
log INFO ""
fi fi
echo "Helldivers 2 Mod Manager CLI installed successfully to $DESTINATION_PATH/$SCRIPT_NAME. Use it by running '$SCRIPT_NAME'." # install
log INFO "Installing $SCRIPT_NAME to $DESTINATION_PATH."
sudo curl "$REPO_URL"/h2mm --output "$DESTINATION_PATH/$SCRIPT_NAME"
sudo chmod +x "$DESTINATION_PATH/$SCRIPT_NAME"
log INFO ""
[[ ! -x "$(command -v $SCRIPT_NAME)" ]] && { log ERROR "Installation failed. Mod manager was not found in \$PATH." ; exit 1; }
log INFO "Helldivers 2 Mod Manager CLI ${GREEN}successfully${NC} installed: $DESTINATION_PATH/$SCRIPT_NAME."
log INFO "Use it by running '$SCRIPT_NAME'. Made with love <3 by v4n and contributors."
+1 -1
View File
@@ -1 +1 @@
0.3.5 0.4.0