Compare commits

...

26 Commits

Author SHA1 Message Date
Koloszár Gergely
f46cea0ab8
Merge 506c82e86a into 7e45cb0fa2 2025-10-25 02:52:17 +00:00
aclist
506c82e86a chore: reword CONTRIBUTING.md
Corrected some typos and reworded passive voice/some sections for
brevity.
2025-10-25 11:51:19 +09:00
aclist
7e45cb0fa2 chore: backport funcs file changes from testing
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2025-10-25 11:37:48 +09:00
aclist
3729d3c656 chore: update changelog 2025-10-25 11:35:22 +09:00
aclist
773d24a00c chore: backport patch from testing 2025-10-25 11:33:42 +09:00
aclist
08f1f9f4d1
Merge pull request #235 from GaryBlackbourne/dzgui-sh-cleanup
dzgui.sh argument handling and cleanup
2025-10-25 11:28:43 +09:00
aclist
ec7daf7f6b fix: store filepaths in array
I opted to encapsulate these in an array because I was paranoid about
needing to separate each directory with a whitespace when storing them
on a stringwise basis. This should be safer and ensure the paths don't
get concatenated together if the whitespace is omitted.
2025-10-23 13:57:19 +09:00
aclist
d0de2974d8 fix: emit heredoc directly 2025-10-23 13:44:50 +09:00
aclist
5a54d43601 fix: encapsulate usage command 2025-10-23 13:38:56 +09:00
Gergely Koloszar
1dfe9cd9df Fix not checking dotfiles in cache path 2025-10-21 19:04:38 +00:00
Gergely Koloszar
f2124218e4 Add handling for multiple argument, version getting option and help 2025-10-18 23:12:59 +02:00
Gergely Koloszar
cf087d96c7 Add check for script sourcing 2025-10-18 23:12:31 +02:00
Gergely Koloszar
6bb59f4060 Clean up depcheck 2025-10-18 22:53:14 +02:00
Gergely Koloszar
d53476399d Clean up setup_state_files 2025-10-18 22:52:49 +02:00
Gergely Koloszar
d34293e2c8 Clean up setup_dirs 2025-10-18 22:52:13 +02:00
Gergely Koloszar
f82df9eacf Clean up set_im_module 2025-10-18 22:51:52 +02:00
aclist
23fb10f48e fix: malformed servers
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2025-10-16 22:38:52 +09:00
aclist
eeca71fc25 drop: tutorial images
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2025-10-03 20:20:10 +09:00
aclist
89f37ab70d fix: use fixed-width property 2025-10-03 19:52:55 +09:00
aclist
9d1ee7e130 chore: update checksums
Some checks are pending
Mirror to Codeberg / mirror-to-codeberg (push) Waiting to run
2025-10-03 01:22:02 +09:00
aclist
9a37cebe47 fix: f-string in dialog title 2025-10-03 01:20:40 +09:00
aclist
239f806f7e chore: update changelog
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2025-09-30 19:09:39 +09:00
aclist
54e2d2feaa fix: block tooltips on main menu 2025-09-30 19:08:04 +09:00
aclist
796dcd5588 fix: missing param 2025-09-30 19:07:42 +09:00
aclist
35f1f180d2 chore: bump version 2025-09-23 20:56:00 +09:00
aclist
fe40a5e54f feat: self_update flag 2025-09-23 20:46:12 +09:00
15 changed files with 199 additions and 75 deletions

View File

@ -1,5 +1,21 @@
# Changelog # Changelog
## [6.0.0-beta.8] XXXX-XX-XX
## Added
- Flag to disable branch toggle for distro-packaged releases
- Test whether script was sourced inline
- Commandline usage help text
## Fixed
- ESC key destroying wait dialogs while thread is pending
- Tooltip signals being processed on main menu
- Leaky variable name in dialog title
- Prevent extraneous signals from propagating when column width is adjusted
- Script failing to start when remote endpoints are unavailable
## Changed
- Optimize time cost of setup checks
## [6.0.0-beta.7] 2025-09-20 ## [6.0.0-beta.7] 2025-09-20
## Added ## Added
- Users can save text notes to describe servers - Users can save text notes to describe servers

View File

@ -1,16 +1,15 @@
# Introduction # Introduction
Thank you for considering contributing to DZGUI! Thank you for your interest in DZGUI!
This is a guide for contributors containing conventions best practices and rules This guide goes over development conventions and best practices for contributors.
of development and aims to ease the beginning of a contribution. If you are a developer, you can skip to the end.
# How can I request help? # Requesting help
There is an issue tracker on github If you encounter a problem with DZGUI, you can submit tickets on the GitHub
(link)[https://github.com/aclist/dzgui-devel/issues] where you can submit (issue tracker)[https://github.com/aclist/dzgui-devel/issues] under the
tickets. If you need help troubleshooting a problem, submit a ticket. There is a `troubleshooting` tag.
category called `troubleshooting` which is exactly what you need.
# How can I help the project? # How can I help the project?
@ -23,44 +22,48 @@ There are several ways to help this project.
Before making any contribution, please read the `CODE_OF_CONDUCT.md` and act Before making any contribution, please read the `CODE_OF_CONDUCT.md` and act
accordingly. accordingly.
## How to report ## Submitting a ticket
Navigate to the GitHub (issue tracker)[https://github.com/aclist/dzgui-devel/issues].
From there, follow the onscreen prompts. You will be asked questions such as:
Reproduce the bug that you found. Navigate to the issue tracker on github:
(link)[https://github.com/aclist/dzgui-devel/issues]
Create a ticket where you give us the following:
- What version are you using? - What version are you using?
- What distribution are you using? - What distribution are you using?
- What is the issue that you found? - What is the issue that you found?
- How can we reproduce the issue? - How can we reproduce the issue?
- Possible screenshots, logs, other data that can help us
## How to request a feature You can also attach screenshots, logs, or other data that can help us.
Navigate to the projects issue tracker ## Requesting a feature
(link)[https://github.com/aclist/dzgui-devel/issues]. Search for your idea to
see if anyone had posted a simmilar idea. If not, open a ticket where you
describe your feature and its possible benefits. Please note, that this is a
community project, it takes time for us to develop features, having a feature
request doesn't mean that it will be implemented, but we do our best to support
as many cool ideas as possible.
## How to contribute code or documentation You can also request features via the same issue tracker. It is good practice to
first search for your idea to see if a similar one has already been posted.
If not, open a ticket where you describe your feature and its possible benefits.
If you have an issue of interest in the issue tracker or any other change that Please note that this is a community project, so it takes time for us to develop
you would like to have implemented you can contribute code to this project. For features. Putting in a feature request does not mean that it will be implemented,
this, you may fork this repository and checkout to but we will do our best to support as many cool ideas as possible.
`prerelease/<latest-version>`. All new features and fixes will be merged to this
branch, so open your branch from here. Name it according to our convention: ## Contributing code or documentation
- fix/<your-fix> - fix branches
If you would like to take ownership or assist with an issue on the issue tracker, or
contribute a new change, please follow the guidelines below.
Fork this repository and check out the code up to `prerelease/<latest-version>`.
All new features and fixes will be merged to this branch, so open your branch
from here.
The following naming conventions apply for PRs:
- fix/<your-fix> - patch/hotfix branches
- feat/<your-feature> - feature branches - feat/<your-feature> - feature branches
- doc/<your-doc-branch> - documentation branches - doc/<your-doc-branch> - documentation branches
- infra/<your-infra-branch> - infrastructure branches - infra/<your-infra-branch> - infrastructure branches
Now you can implement your changes and test it locally. If they work you may Implement your changes and test them locally. If they work you may
open a merge request, and then we review your changes. If everything is OK, it open a merge request, and then we review your changes. If everything is OK, it
will be merged to `prerelease/<latest-version>`, then `testing` and after a live will be merged to `prerelease/<latest-version>`, then `testing` and after a live
testing phase, to `stable` as well. testing phase, to `stable` as well.
During development, it is recommended to follow (conventional It is recommended to follow
commits)[https://www.conventionalcommits.org/en/v1.0.0/], it helps the project (Conventional Commits)[https://www.conventionalcommits.org/en/v1.0.0/], as this
maintainers when they review your code. integrates well with tooling and helps the project review your code.

139
dzgui.sh
View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -o pipefail set -o pipefail
version=6.0.0.beta-7 version=6.0.0.beta-8
#CONSTANTS #CONSTANTS
aid=221100 aid=221100
@ -63,17 +63,14 @@ testing_url="$url_prefix/testing"
releases_url="https://github.com/$author/$repo/releases/download/browser" releases_url="https://github.com/$author/$repo/releases/download/browser"
km_helper_url="$releases_url/latlon" km_helper_url="$releases_url/latlon"
set_im_module(){ set_im_module(){
#TODO: drop pending SteamOS changes #TODO: drop pending SteamOS changes
pgrep -a gamescope | grep -q "generate-drm-mode" if pgrep -a gamescope | grep -q "generate-drm-mode"; then
if [[ $? -eq 0 ]]; then unset GTK_IM_MODULE
GTK_IM_MODULE=""
logger INFO "Detected Steam Deck (Game Mode), unsetting GTK_IM_MODULE" logger INFO "Detected Steam Deck (Game Mode), unsetting GTK_IM_MODULE"
else
return
fi fi
} }
redact(){ redact(){
sed 's@\(/home/\)[^/]*@\1REDACTED@g' sed 's@\(/home/\)[^/]*@\1REDACTED@g'
} }
@ -87,13 +84,21 @@ logger(){
printf "%s␞%s␞%s::%s()::%s␞%s\n" "$date" "$tag" "$self" "$caller" "$line" "$string" \ printf "%s␞%s␞%s::%s()::%s␞%s\n" "$date" "$tag" "$self" "$caller" "$line" "$string" \
| redact >> "$debug_log" | redact >> "$debug_log"
} }
setup_dirs(){ setup_dirs(){
for dir in "$state_path" "$cache_path" "$share_path" "$helpers_path" "$freedesktop_path" "$config_path" "$log_path"; do directories=()
if [[ ! -d $dir ]]; then directories+=("$state_path")
directories+=("$cache_path")
directories+=("$share_path")
directories+=("$helpers_path")
directories+=("$freedesktop_path")
directories+=("$config_path")
directories+=("$log_path")
for dir in "${directories[@]}"; do
mkdir -p "$dir" mkdir -p "$dir"
fi
done done
} }
setup_state_files(){ setup_state_files(){
if [[ -f "$debug_log" ]]; then if [[ -f "$debug_log" ]]; then
rm "$debug_log" && touch $debug_log rm "$debug_log" && touch $debug_log
@ -104,9 +109,8 @@ setup_state_files(){
logger INFO "Migrating legacy version file" logger INFO "Migrating legacy version file"
fi fi
# wipe cache files # wipe cache files
local path="$cache_path" if [[ $(ls -A "$cache_path") ]]; then
if find "$path" -mindepth 1 -maxdepth 1 | read; then for file in "$cache_path"/*; do
for file in $path/*; do
rm "$file" rm "$file"
done done
logger INFO "Wiped cache files" logger INFO "Wiped cache files"
@ -221,8 +225,7 @@ END
} }
depcheck(){ depcheck(){
for dep in "${!deps[@]}"; do for dep in "${!deps[@]}"; do
command -v "$dep" 2>&1>/dev/null if ! command -v "$dep" &> /dev/null; then
if [[ $? -eq 1 ]]; then
local msg="Requires $dep >= ${deps[$dep]}" local msg="Requires $dep >= ${deps[$dep]}"
raise_error_and_quit "$msg" raise_error_and_quit "$msg"
fi fi
@ -493,20 +496,47 @@ stale_symlinks(){
unlink "$l" unlink "$l"
done done
} }
check_availability() {
if [[ -z $1 ]]; then
return 1
fi
local url=$1
local timeout_sec="3"
if [[ $2 ]]; then
timeout_sec=$2
fi
if ! ping -w "$timeout_sec" "$url" > /dev/null 2>&1; then
logger WARN "Failed to reach $url, service may be down."
return 1
fi
}
local_latlon(){ local_latlon(){
if [[ -z $(command -v dig) ]]; then if [[ -z $(command -v dig) ]]; then
local local_ip=$(curl -Ls "https://ipecho.net/plain") local url_ipecho="https://ipecho.net/plain"
if ! check_availability "ipecho.net"; then
logger WARN "Failed to get external ip address, ipecho.net service may be down."
return 1
fi
local local_ip=$(curl -Ls "$url_ipecho")
else else
# TODO : implement checking remote
local local_ip=$(dig -4 +short myip.opendns.com @resolver1.opendns.com) local local_ip=$(dig -4 +short myip.opendns.com @resolver1.opendns.com)
fi fi
local url="http://ip-api.com/json/$local_ip" local url_ip_api="http://ip-api.com/json/$local_ip"
local res=$(curl -Ls "$url" | jq -r '"\(.lat)\n\(.lon)"') if ! check_availability "ip-api.com"; then
logger WARN "Failed to get local coordinates, ip-api.com service may be down."
return 1
fi
local res=$(curl -Ls "$url_ip_api" | jq -r '"\(.lat)\n\(.lon)"')
if [[ -z "$res" ]]; then if [[ -z "$res" ]]; then
logger WARN "Failed to get local coordinates" logger WARN "Failed to get local coordinates"
return 1 return 1
fi fi
echo "$res" > "$coords_file" echo "$res" > "$coords_file"
} }
lock(){ lock(){
[[ ! -f $lock_file ]] && touch $lock_file [[ ! -f $lock_file ]] && touch $lock_file
local pid=$(cat $lock_file) local pid=$(cat $lock_file)
@ -585,10 +615,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=(
["funcs"]="c27a81577c818b4f4d786ada52ad5042" ["funcs"]="6ae3ead7034dc8e7543472bddee75c63"
["query_v2.py"]="55d339ba02512ac69de288eb3be41067" ["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
["servers.py"]="7f83d5c1ca54acb12f1bd6657feb2ecf" ["servers.py"]="ed442c3aecf33f777d59dcf53650d263"
["ui.py"]="8d6e52b3e9032acbb84ba6cf137f455a" ["ui.py"]="f03879f088ad074f2ce3c92607c30202"
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397" ["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
["pefile.py"]="21531f2c0d9dfa5f110cf6779f9d22c0" ["pefile.py"]="21531f2c0d9dfa5f110cf6779f9d22c0"
) )
@ -1090,13 +1120,61 @@ uninstall(){
rm "$self" rm "$self"
echo "Uninstall routine complete" echo "Uninstall routine complete"
} }
usage(){
cat <<- EOM
DZGUI - Free and Open Source DayZ launcher
Usage:
dzgui.sh [options]
Description:
When no option is provided, the script launches DZGUI.
Options:
-u, --uninstall:
Uninstalls the software
-v, --version:
Prints the version
-h, --help:
Prints this message
EOM
}
main(){ main(){
local zenv=$(zenity --version 2>/dev/null) # setup zenity environment
local zenv=""
zenv=$(zenity --version 2>/dev/null)
[[ -z $zenv ]] && { echo "Requires zenity >= ${deps[$steamsafe_zenity]}"; exit 1; } [[ -z $zenv ]] && { echo "Requires zenity >= ${deps[$steamsafe_zenity]}"; exit 1; }
if [[ $1 == "--uninstall" ]] || [[ $1 == "-u" ]]; then
uninstall && # parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
"--uninstall" | "-u")
uninstall
exit 0 exit 0
fi # shift
;;
"--version" | "-v")
echo $version
exit 0
# shift
;;
"--help" | "-h")
usage
exit 0
# shift
;;
*)
echo "Unrecognized command!"
return 1
esac
done
set_im_module set_im_module
@ -1105,7 +1183,12 @@ main(){
printf "All OK. Kicking off UI...\n" printf "All OK. Kicking off UI...\n"
python3 "$ui_helper" "--init-ui" "$version" "$is_steam_deck" python3 "$ui_helper" "--init-ui" "$version" "$is_steam_deck"
} }
main "$@"
#TODO: tech debt: cruddy handling for steam forking if [[ $(basename "$0") == "dzgui.sh" ]]; then
[[ $? -eq 1 ]] && pkill -f dzgui.sh main "$@"
#TODO: tech debt: cruddy handling for steam forking
[[ $? -eq 1 ]] && pkill -f dzgui.sh
fi

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -o pipefail set -o pipefail
version="6.0.0-beta.7" version="6.0.0-beta.8"
#CONSTANTS #CONSTANTS
aid=221100 aid=221100
@ -369,6 +369,10 @@ local_latlon(){
get_dist(){ get_dist(){
shift shift
local given_ip="$1" local given_ip="$1"
if [[ ! -f $_cache_coords ]]; then
printf "Unknown"
return
fi
readarray -t coords < "$_cache_coords" readarray -t coords < "$_cache_coords"
readarray -t n < <(<<< "$given_ip" awk 'BEGIN{RS="."}{$1=$1}1') readarray -t n < <(<<< "$given_ip" awk 'BEGIN{RS="."}{$1=$1}1')

View File

@ -87,6 +87,7 @@ def parse_json(json: list) -> list:
except KeyError: except KeyError:
continue continue
malformed = False
for key in [ for key in [
"map", "map",
"gametype", "gametype",
@ -98,6 +99,10 @@ def parse_json(json: list) -> list:
try: try:
row[key] row[key]
except KeyError: except KeyError:
malformed = True
break
if malformed is True:
continue continue
try: try:
@ -167,7 +172,7 @@ def parse_json(json: list) -> list:
return rows return rows
def query_direct(ip: str, qport: int, TIMEOUT=3.0) -> dict | None: def query_direct(ip: str, qport: int, TIMEOUT: float=3.0) -> dict | None:
try: try:
info = a2s.info((ip, qport), TIMEOUT) info = a2s.info((ip, qport), TIMEOUT)
@ -440,7 +445,7 @@ def query_bm_api(api_key: str, bm_id: str) -> Record:
raise BmAPIError("Failed to query Battlemetrics") raise BmAPIError("Failed to query Battlemetrics")
def validate_ip(addr: str): def validate_ip(addr: str) -> Record:
fields = addr.split(":") fields = addr.split(":")
if len(fields) != 2: if len(fields) != 2:
raise InvalidIpError("Address must be formatted as IP:Queryport") raise InvalidIpError("Address must be formatted as IP:Queryport")

View File

@ -1872,6 +1872,9 @@ class TreeView(Gtk.TreeView):
) -> bool: ) -> bool:
if self.is_server_context(self.view) is False: if self.is_server_context(self.view) is False:
return return
if self.subpage is None:
return
coords = widget.convert_widget_to_bin_window_coords(x, y) coords = widget.convert_widget_to_bin_window_coords(x, y)
path = self.get_path_at_pos(coords.bx, coords.by) path = self.get_path_at_pos(coords.bx, coords.by)
if path is None: if path is None:
@ -2573,7 +2576,7 @@ class TreeView(Gtk.TreeView):
App.right_panel.filters_vbox.set_active_combo(0) App.right_panel.filters_vbox.set_active_combo(0)
App.grid.right_panel.filters_vbox.set_visible(True) App.grid.right_panel.filters_vbox.set_visible(True)
for column in self.get_columns(): for column in self.get_columns():
column.connect("notify::width", self._on_col_width_changed) column.connect("notify::fixed-width", self._on_col_width_changed)
App.grid.statusbar.update_server_meta() App.grid.statusbar.update_server_meta()
@ -3207,8 +3210,11 @@ class GenericDialog(Gtk.MessageDialog):
self.outer.set_margin_end(30) self.outer.set_margin_end(30)
def _on_dialog_delete( def _on_dialog_delete(
self, response_id: Gtk.ResponseType self, response_id: Gtk.ResponseType, event: Gdk.Event
) -> Literal[True]: ) -> Literal[True]:
"""
Prevent manual dialog destruction
"""
return True return True
def _return_to_main_menu(self, widget: Gtk.Widget) -> None: def _return_to_main_menu(self, widget: Gtk.Widget) -> None:
@ -3232,7 +3238,7 @@ class LanDialog(Gtk.MessageDialog):
buttons=Gtk.ButtonsType.OK_CANCEL, buttons=Gtk.ButtonsType.OK_CANCEL,
text="Scan LAN servers", text="Scan LAN servers",
secondary_text="Select the query port", secondary_text="Select the query port",
title="{appname}", title=f"{app_name} - Dialog",
modal=True, modal=True,
) )
@ -3758,7 +3764,7 @@ class LeftLabel(Gtk.Label):
class Options(Gtk.Box): class Options(Gtk.Box):
def __init__(self): def __init__(self, self_update=True):
super().__init__( super().__init__(
orientation=Gtk.Orientation.VERTICAL, orientation=Gtk.Orientation.VERTICAL,
margin_start=10, margin_start=10,
@ -3835,11 +3841,18 @@ class Options(Gtk.Box):
self.branch_combo.append_text("Testing") self.branch_combo.append_text("Testing")
self.branch_combo.set_active(0) self.branch_combo.set_active(0)
self.branch_combo.connect("changed", self._on_branch_changed) self.branch_combo.connect("changed", self._on_branch_changed)
self.branch_combo.set_sensitive(self_update)
if self_update is True:
msg = ( msg = (
"Stable: only contains stable features. " "Stable: only contains stable features. "
"Testing: pre-release beta, contains new features." "Testing: pre-release beta, contains new features."
) )
else:
msg = (
"In-app updates are disabled when installing "
"DZGUI via the system package manager."
)
eb = InfoEventBox(msg) eb = InfoEventBox(msg)
version_rows = [ version_rows = [
@ -4355,7 +4368,7 @@ class Notebook(Gtk.Notebook):
self.keys.show_all() self.keys.show_all()
self.append_page(self.keys) self.append_page(self.keys)
self.settings = Options() self.settings = Options(self_update=True)
self.settings.type = RowType.OPTIONS self.settings.type = RowType.OPTIONS
self.settings.show_all() self.settings.show_all()
self.append_page(self.settings) self.append_page(self.settings)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB