mirror of
https://github.com/aclist/dztui.git
synced 2025-01-15 05:28:06 +01:00
Compare commits
No commits in common. "99d964bf449bbee524d67cbe719350b6929b8a2a" and "e6b5e40bb2bc5e30288f01e6922488de5001290d" have entirely different histories.
99d964bf44
...
e6b5e40bb2
4 changed files with 19 additions and 125 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,16 +1,5 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [5.6.0-beta.18] 2024-12-14
|
|
||||||
### Added
|
|
||||||
- Open Steam workshop subscriptions dialog
|
|
||||||
- Additional logging
|
|
||||||
### Fixed
|
|
||||||
- Empty dialog popups if user manually deletes local mods while application is running
|
|
||||||
- Abort DayZ path discovery if VDF if Steam files are not synched
|
|
||||||
- Avoid sudo escalation if system map count is sufficient (jiriks74)
|
|
||||||
### Changed
|
|
||||||
- Admonish user to restart Steam in error dialog if DayZ path could not be found
|
|
||||||
|
|
||||||
## [5.6.0-beta.17] 2024-12-14
|
## [5.6.0-beta.17] 2024-12-14
|
||||||
### Added
|
### Added
|
||||||
- Additional logging
|
- Additional logging
|
||||||
|
|
35
dzgui.sh
35
dzgui.sh
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
version=5.6.0-beta.18
|
version=5.6.0-beta.17
|
||||||
|
|
||||||
#CONSTANTS
|
#CONSTANTS
|
||||||
aid=221100
|
aid=221100
|
||||||
|
@ -406,20 +406,13 @@ check_architecture(){
|
||||||
}
|
}
|
||||||
check_map_count(){
|
check_map_count(){
|
||||||
[[ $is_steam_deck -gt 0 ]] && return 0
|
[[ $is_steam_deck -gt 0 ]] && return 0
|
||||||
local map_count_file="/proc/sys/vm/max_map_count"
|
local count=1048576
|
||||||
local min_count=1048576
|
|
||||||
local conf_file="/etc/sysctl.d/dayz.conf"
|
local conf_file="/etc/sysctl.d/dayz.conf"
|
||||||
local current_count
|
if [[ -f $conf_file ]]; then
|
||||||
if [[ ! -f ${map_count_file} ]]; then
|
logger DEBUG "System map count is already $count or higher"
|
||||||
logger WARN "File '${map_count_file}' doesn't exist!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
current_count=$(cat ${map_count_file})
|
|
||||||
if [[ $current_count -ge $min_count ]]; then
|
|
||||||
logger DEBUG "System map count is set to ${current_count}"
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
qdialog "sudo password required to set system vm map count." "OK" "Cancel"
|
qdialog "sudo password required to check system vm map count." "OK" "Cancel"
|
||||||
if [[ $? -eq 0 ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
local pass
|
local pass
|
||||||
logger INFO "Prompting user for sudo escalation"
|
logger INFO "Prompting user for sudo escalation"
|
||||||
|
@ -428,11 +421,13 @@ check_map_count(){
|
||||||
logger WARN "User aborted password prompt"
|
logger WARN "User aborted password prompt"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
logger DEBUG "Old map count is $current_count"
|
local ct=$(sudo -S <<< "$pass" sh -c "sysctl -q vm.max_map_count | awk -F'= ' '{print \$2}'")
|
||||||
[[ $current_count -lt $min_count ]] && current_count=$min_count
|
logger DEBUG "Old map count is $ct"
|
||||||
sudo -S <<< "$pass" sh -c "echo 'vm.max_map_count=${current_count}' > $conf_file"
|
local new_ct
|
||||||
|
[[ $ct -lt $count ]] && ct=$count
|
||||||
|
sudo -S <<< "$pass" sh -c "echo 'vm.max_map_count=$ct' > $conf_file"
|
||||||
sudo sysctl -p "$conf_file"
|
sudo sysctl -p "$conf_file"
|
||||||
logger DEBUG "Updated map count to $min_count"
|
logger DEBUG "Updated map count to $count"
|
||||||
else
|
else
|
||||||
logger WARN "User aborted map count prompt"
|
logger WARN "User aborted map count prompt"
|
||||||
return 1
|
return 1
|
||||||
|
@ -583,10 +578,10 @@ fetch_helpers_by_sum(){
|
||||||
[[ -f "$config_file" ]] && source "$config_file"
|
[[ -f "$config_file" ]] && source "$config_file"
|
||||||
declare -A sums
|
declare -A sums
|
||||||
sums=(
|
sums=(
|
||||||
["ui.py"]="99544ccef6060125509c4b689a808a15"
|
["ui.py"]="be3da1e542d14105f4358dd38901e25a"
|
||||||
["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
|
["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
|
||||||
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
|
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
|
||||||
["funcs"]="98261fdba4323f77c6dd610c1efc4d11"
|
["funcs"]="37897aa36bc2fb6286cee02c8bb07258"
|
||||||
["lan"]="c62e84ddd1457b71a85ad21da662b9af"
|
["lan"]="c62e84ddd1457b71a85ad21da662b9af"
|
||||||
)
|
)
|
||||||
local author="aclist"
|
local author="aclist"
|
||||||
|
@ -752,7 +747,7 @@ find_library_folder(){
|
||||||
local search_path="$1"
|
local search_path="$1"
|
||||||
steam_path="$(python3 "$helpers_path/vdf2json.py" -i "$1/steamapps/libraryfolders.vdf" \
|
steam_path="$(python3 "$helpers_path/vdf2json.py" -i "$1/steamapps/libraryfolders.vdf" \
|
||||||
| jq -r '.libraryfolders[]|select(.apps|has("221100")).path')"
|
| jq -r '.libraryfolders[]|select(.apps|has("221100")).path')"
|
||||||
if [[ ! $? -eq 0 ]] || [[ -z $steam_path ]]; then
|
if [[ ! $? -eq 0 ]]; then
|
||||||
logger WARN "Failed to parse Steam path using '$search_path'"
|
logger WARN "Failed to parse Steam path using '$search_path'"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
@ -805,7 +800,7 @@ create_config(){
|
||||||
find_library_folder "$default_steam_path"
|
find_library_folder "$default_steam_path"
|
||||||
if [[ -z $steam_path ]]; then
|
if [[ -z $steam_path ]]; then
|
||||||
logger raise_error "Steam path was empty"
|
logger raise_error "Steam path was empty"
|
||||||
zenity --question --text="DayZ not found or not installed at the Steam library given. NOTE: if you recently installed DayZ or moved its location, you MUST restart Steam first for these changes to synch." --ok-label="Choose path manually" --cancel-label="Exit"
|
zenity --question --text="DayZ not found or not installed at the Steam library given." --ok-label="Choose path manually" --cancel-label="Exit"
|
||||||
if [[ $? -eq 0 ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
logger INFO "User selected file picker"
|
logger INFO "User selected file picker"
|
||||||
file_picker
|
file_picker
|
||||||
|
|
|
@ -104,7 +104,6 @@ declare -A funcs=(
|
||||||
["Connect by IP"]="validate_and_connect"
|
["Connect by IP"]="validate_and_connect"
|
||||||
["Connect by ID"]="validate_and_connect"
|
["Connect by ID"]="validate_and_connect"
|
||||||
["Connect from table"]="connect_from_table"
|
["Connect from table"]="connect_from_table"
|
||||||
["find_id"]="find_id"
|
|
||||||
["toggle"]="toggle"
|
["toggle"]="toggle"
|
||||||
["Open link"]="open_link"
|
["Open link"]="open_link"
|
||||||
["filter"]="dump_servers"
|
["filter"]="dump_servers"
|
||||||
|
@ -122,7 +121,6 @@ declare -A funcs=(
|
||||||
["is_in_favs"]="is_in_favs"
|
["is_in_favs"]="is_in_favs"
|
||||||
["show_log"]="show_log"
|
["show_log"]="show_log"
|
||||||
["Output system info to log file"]="generate_log"
|
["Output system info to log file"]="generate_log"
|
||||||
["open_user_workshop"]="open_user_workshop"
|
|
||||||
["open_workshop_page"]="open_workshop_page"
|
["open_workshop_page"]="open_workshop_page"
|
||||||
["Add to my servers"]="update_favs_from_table"
|
["Add to my servers"]="update_favs_from_table"
|
||||||
["Remove from my servers"]="update_favs_from_table"
|
["Remove from my servers"]="update_favs_from_table"
|
||||||
|
@ -334,32 +332,18 @@ is_in_favs(){
|
||||||
done
|
done
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
find_id(){
|
|
||||||
local file="$default_steam_path/config/loginusers.vdf"
|
|
||||||
[[ ! -f $file ]] && return 1
|
|
||||||
local res=$(python3 $HOME/.local/share/dzgui/helpers/vdf2json.py \
|
|
||||||
-i "$file" | jq -r '.users
|
|
||||||
|to_entries[]
|
|
||||||
|select(.value.MostRecent=="1")
|
|
||||||
|.key'
|
|
||||||
)
|
|
||||||
[[ -z $res ]] && return 1
|
|
||||||
printf "%s" "$res"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
list_mods(){
|
list_mods(){
|
||||||
local symlink
|
local symlink
|
||||||
local sep
|
local sep
|
||||||
local name
|
local name
|
||||||
local base_dir
|
local base_dir
|
||||||
local size
|
local size
|
||||||
local mods
|
|
||||||
if [[ -z $(installed_mods) ]] || [[ -z $(find $workshop_dir -maxdepth 2 -name "*.cpp" | grep .cpp) ]]; then
|
if [[ -z $(installed_mods) ]] || [[ -z $(find $workshop_dir -maxdepth 2 -name "*.cpp" | grep .cpp) ]]; then
|
||||||
printf "No mods currently installed or incorrect path set."
|
printf "No mods currently installed or incorrect path set."
|
||||||
logger WARN "Found no locally installed mods"
|
logger WARN "Found no locally installed mods"
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
mods=$(for dir in $(find $game_dir/* -maxdepth 1 -type l); do
|
for dir in $(find $game_dir/* -maxdepth 1 -type l); do
|
||||||
symlink=$(basename $dir)
|
symlink=$(basename $dir)
|
||||||
sep="␞"
|
sep="␞"
|
||||||
name=$(awk -F\" '/name/ {print $2}' "${dir}/meta.cpp")
|
name=$(awk -F\" '/name/ {print $2}' "${dir}/meta.cpp")
|
||||||
|
@ -367,14 +351,7 @@ list_mods(){
|
||||||
size=$(du -s "$(readlink -f "$game_dir/$symlink")" | awk '{print $1}')
|
size=$(du -s "$(readlink -f "$game_dir/$symlink")" | awk '{print $1}')
|
||||||
size=$(python3 -c "n=($size/1024) +.005; print(round(n,4))")
|
size=$(python3 -c "n=($size/1024) +.005; print(round(n,4))")
|
||||||
LC_NUMERIC=C printf "%s$sep%s$sep%s$sep%3.3f\n" "$name" "$symlink" "$base_dir" "$size"
|
LC_NUMERIC=C printf "%s$sep%s$sep%s$sep%3.3f\n" "$name" "$symlink" "$base_dir" "$size"
|
||||||
done | sort -k1)
|
done | sort -k1
|
||||||
# user may have manually pruned mods out-of-band
|
|
||||||
# handle directory detritus but no actual mods
|
|
||||||
if [[ -z $mods ]]; then
|
|
||||||
printf "No mods currently installed or incorrect path set."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
echo "$mods"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
installed_mods(){
|
installed_mods(){
|
||||||
|
@ -1074,12 +1051,6 @@ update_config_val(){
|
||||||
show_log(){
|
show_log(){
|
||||||
< "$debug_log" sed 's/Keyword␞/Keyword/'
|
< "$debug_log" sed 's/Keyword␞/Keyword/'
|
||||||
}
|
}
|
||||||
open_user_workshop(){
|
|
||||||
shift
|
|
||||||
local id="$1"
|
|
||||||
url="https://steamcommunity.com/profiles/$id/myworkshopfiles/?appid=$aid&browsefilter=mysubscriptions"
|
|
||||||
$steam_cmd steam://openurl/$url &
|
|
||||||
}
|
|
||||||
open_workshop_page(){
|
open_workshop_page(){
|
||||||
shift
|
shift
|
||||||
local id="$1"
|
local id="$1"
|
||||||
|
@ -1202,7 +1173,7 @@ legacy_symlinks(){
|
||||||
logger INFO "Removing legacy symlinks"
|
logger INFO "Removing legacy symlinks"
|
||||||
for d in "$game_dir"/*; do
|
for d in "$game_dir"/*; do
|
||||||
if [[ $d =~ @[0-9]+-.+ ]]; then
|
if [[ $d =~ @[0-9]+-.+ ]]; then
|
||||||
logger INFO "Unlinking '$d'"
|
logger INFO "Unlinking $d"
|
||||||
unlink "$d"
|
unlink "$d"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -1212,14 +1183,11 @@ legacy_symlinks(){
|
||||||
logger INFO "Removing legacy encoding format"
|
logger INFO "Removing legacy encoding format"
|
||||||
for d in "${mod_dirs[@]}"; do
|
for d in "${mod_dirs[@]}"; do
|
||||||
# suppress errors if mods are downloading at boot
|
# suppress errors if mods are downloading at boot
|
||||||
logger INFO "Testing directory '$d'"
|
|
||||||
[[ ! -f "$d/meta.cpp" ]] && continue
|
[[ ! -f "$d/meta.cpp" ]] && continue
|
||||||
local id=$(awk -F"= " '/publishedid/ {print $2}' "$d"/meta.cpp | awk -F\; '{print $1}')
|
local id=$(awk -F"= " '/publishedid/ {print $2}' "$d"/meta.cpp | awk -F\; '{print $1}')
|
||||||
logger INFO "Given id is '$id'"
|
|
||||||
local encoded_id=$(echo "$id" | awk '{printf("%c",$1)}' | base64 | sed 's/\//_/g; s/=//g; s/+/]/g')
|
local encoded_id=$(echo "$id" | awk '{printf("%c",$1)}' | base64 | sed 's/\//_/g; s/=//g; s/+/]/g')
|
||||||
logger INFO "Resolved id is '$encoded_id'"
|
|
||||||
if [[ -h "$game_dir/@$encoded_id" ]]; then
|
if [[ -h "$game_dir/@$encoded_id" ]]; then
|
||||||
logger INFO "Unlinking '$game_dir/@$encoded_id'"
|
logger INFO "Unlinking $game_dir/@$encoded_id"
|
||||||
unlink "$game_dir/@$encoded_id"
|
unlink "$game_dir/@$encoded_id"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
@ -215,7 +215,6 @@ class RowType(EnumWithAttrs):
|
||||||
"label": "Toggle mod install mode",
|
"label": "Toggle mod install mode",
|
||||||
"tooltip": "Switch between manual and auto mod installation",
|
"tooltip": "Switch between manual and auto mod installation",
|
||||||
"default": "manual",
|
"default": "manual",
|
||||||
"link_label": "Open Steam Workshop",
|
|
||||||
"alt": "auto",
|
"alt": "auto",
|
||||||
"val": "auto_install"
|
"val": "auto_install"
|
||||||
}
|
}
|
||||||
|
@ -757,29 +756,6 @@ def process_tree_option(input, treeview):
|
||||||
case RowType.TGL_BRANCH:
|
case RowType.TGL_BRANCH:
|
||||||
wait_msg = "Updating DZGUI branch"
|
wait_msg = "Updating DZGUI branch"
|
||||||
call_on_thread(False, "toggle", wait_msg, cmd_string)
|
call_on_thread(False, "toggle", wait_msg, cmd_string)
|
||||||
case RowType.TGL_INSTALL:
|
|
||||||
if query_config(None, "auto_install")[0] == "1":
|
|
||||||
proc = call_out(transient_parent, "toggle", cmd_string)
|
|
||||||
grid.update_right_statusbar()
|
|
||||||
tooltip = format_metadata(command.dict["label"])
|
|
||||||
transient_parent.grid.update_statusbar(tooltip)
|
|
||||||
return
|
|
||||||
# manual -> auto mode
|
|
||||||
proc = call_out(transient_parent, "find_id", "")
|
|
||||||
if proc.returncode == 1:
|
|
||||||
link=None
|
|
||||||
uid=None
|
|
||||||
else:
|
|
||||||
link=command.dict["link_label"]
|
|
||||||
uid=proc.stdout
|
|
||||||
manual_sub_msg = """\
|
|
||||||
When switching from MANUAL to AUTO mod install mode,
|
|
||||||
DZGUI will manage mod installation and deletion for you.
|
|
||||||
To prevent conflicts with Steam Workshop subscriptions and old mods from being downloaded
|
|
||||||
when Steam updates, you should unsubscribe from any existing Workshop mods you manually subscribed to.
|
|
||||||
Open your Profile > Workshop Items and select 'Unsubscribe from all'
|
|
||||||
on the right-hand side, then click OK below to enable AUTO mod install mode."""
|
|
||||||
LinkDialog(transient_parent, textwrap.dedent(manual_sub_msg), Popup.NOTIFY, link, command, uid)
|
|
||||||
case _:
|
case _:
|
||||||
proc = call_out(transient_parent, "toggle", cmd_string)
|
proc = call_out(transient_parent, "toggle", cmd_string)
|
||||||
grid.update_right_statusbar()
|
grid.update_right_statusbar()
|
||||||
|
@ -2229,40 +2205,6 @@ class ModDialog(GenericDialog):
|
||||||
subprocess.Popen(['/usr/bin/env', 'bash', funcs, "open_workshop_page", mod_id])
|
subprocess.Popen(['/usr/bin/env', 'bash', funcs, "open_workshop_page", mod_id])
|
||||||
|
|
||||||
|
|
||||||
class LinkDialog(GenericDialog):
|
|
||||||
def __init__(self, parent, text, mode, link, command, uid=None):
|
|
||||||
super().__init__(parent, text, mode)
|
|
||||||
|
|
||||||
self.dialog = GenericDialog(parent, text, mode)
|
|
||||||
self.dialogBox = self.dialog.get_content_area()
|
|
||||||
self.dialog.set_default_response(Gtk.ResponseType.OK)
|
|
||||||
self.dialog.set_size_request(500, 0)
|
|
||||||
|
|
||||||
if link is not None:
|
|
||||||
button = Gtk.Button(label=link)
|
|
||||||
button.set_margin_start(60)
|
|
||||||
button.set_margin_end(60)
|
|
||||||
button.connect("clicked", self._on_button_clicked, uid)
|
|
||||||
self.dialogBox.pack_end(button, False, False, 0)
|
|
||||||
|
|
||||||
self.dialog.show_all()
|
|
||||||
self.dialog.connect("response", self._on_dialog_response, parent, command)
|
|
||||||
|
|
||||||
def _on_button_clicked(self, button, uid):
|
|
||||||
subprocess.Popen(['/usr/bin/env', 'bash', funcs, "open_user_workshop", uid])
|
|
||||||
|
|
||||||
def _on_dialog_response(self, dialog, resp, parent, command):
|
|
||||||
match resp:
|
|
||||||
case Gtk.ResponseType.DELETE_EVENT:
|
|
||||||
return
|
|
||||||
case Gtk.ResponseType.OK:
|
|
||||||
self.dialog.destroy()
|
|
||||||
proc = call_out(parent, "toggle", command.dict["label"])
|
|
||||||
parent.grid.update_right_statusbar()
|
|
||||||
tooltip = format_metadata(command.dict["label"])
|
|
||||||
parent.grid.update_statusbar(tooltip)
|
|
||||||
|
|
||||||
|
|
||||||
class EntryDialog(GenericDialog):
|
class EntryDialog(GenericDialog):
|
||||||
def __init__(self, parent, text, mode, link):
|
def __init__(self, parent, text, mode, link):
|
||||||
super().__init__(parent, text, mode)
|
super().__init__(parent, text, mode)
|
||||||
|
|
Loading…
Reference in a new issue