Merge pull request #230 from aclist/prerelease/6.0.0-beta.8

Prerelease/6.0.0-beta.8
This commit is contained in:
aclist 2025-11-04 15:59:48 +09:00 committed by GitHub
commit 385b1a5af2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 306 additions and 77 deletions

View File

@ -1,5 +1,23 @@
# Changelog
## [6.0.0-beta.8] XXXX-XX-XX
## Added
- Internal flag to allow distribution packaged releases to disable in-app updates
- Pre-boot check to test whether script was invoked directly
- Commandline usage help text
## Fixed
- ESC key destroying wait dialogs while a thread is pending
- Tooltip signals being erroneously drawn on main menu
- Leaky variable name in dialog titles
- Prevent extraneous signals from propagating when column width is adjusted
- Script failing to start when remote endpoints are unavailable (GaryBlackbourne)
## Changed
- Optimize time complexity of pre-boot checks (GaryBlackbourne)
- Moved location of notes file
- Rewrote distance calculation module (GaryBlackbourne)
## [6.0.0-beta.7] 2025-09-20
## Added
- Users can save text notes to describe servers

71
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,71 @@
# Introduction
Thank you for your interest in DZGUI!
This guide goes over development conventions and best practices for contributors.
If you are a developer, you can skip to the end.
# Requesting help
If you encounter a problem with DZGUI, you can submit tickets on the GitHub
(issue tracker)[https://github.com/aclist/dzgui-devel/issues] under the
`troubleshooting` tag.
# How can I help the project?
There are several ways to help this project.
1. Report bugs that you find
2. Request features that you would like
3. Contribute features and fixes to the codebase
4. Contribute documentation to the project
Before making any contribution, please read the `CODE_OF_CONDUCT.md` and act
accordingly.
## 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:
- What version are you using?
- What distribution are you using?
- What is the issue that you found?
- How can we reproduce the issue?
You can also attach screenshots, logs, or other data that can help us.
## Requesting a feature
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.
Please note that this is a community project, so it takes time for us to develop
features. Putting in a feature request does not mean that it will be implemented,
but we will do our best to support as many cool ideas as possible.
## Contributing code or documentation
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>`.
If there is no pending prerelease PR, you can base your changes off of
the `testing` branch. You may later be asked to retarget your PR to the prerelease
branch once a new one is made. This is because out-of-band PRs are consolidated into
the next release before merging.
The following naming conventions apply for PRs:
- fix/<your-fix> - patch/hotfix branches
- feat/<your-feature> - feature branches
- doc/<your-doc-branch> - documentation branches
- infra/<your-infra-branch> - infrastructure branches
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
will be merged to `prerelease/<latest-version>`, then `testing`, and after a live
testing phase, to `stable` as well.
It is recommended to follow
(Conventional Commits)[https://www.conventionalcommits.org/en/v1.0.0/], as this
integrates well with tooling and helps the project review your code.

110
dzgui.sh
View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -o pipefail
version=6.0.0.beta-7
version=6.0.0.beta-8
#CONSTANTS
aid=221100
@ -63,17 +63,14 @@ testing_url="$url_prefix/testing"
releases_url="https://github.com/$author/$repo/releases/download/browser"
km_helper_url="$releases_url/latlon"
set_im_module(){
#TODO: drop pending SteamOS changes
pgrep -a gamescope | grep -q "generate-drm-mode"
if [[ $? -eq 0 ]]; then
GTK_IM_MODULE=""
if pgrep -a gamescope | grep -q "generate-drm-mode"; then
unset GTK_IM_MODULE
logger INFO "Detected Steam Deck (Game Mode), unsetting GTK_IM_MODULE"
else
return
fi
}
redact(){
sed 's@\(/home/\)[^/]*@\1REDACTED@g'
}
@ -87,13 +84,21 @@ logger(){
printf "%s␞%s␞%s::%s()::%s␞%s\n" "$date" "$tag" "$self" "$caller" "$line" "$string" \
| redact >> "$debug_log"
}
setup_dirs(){
for dir in "$state_path" "$cache_path" "$share_path" "$helpers_path" "$freedesktop_path" "$config_path" "$log_path"; do
if [[ ! -d $dir ]]; then
mkdir -p "$dir"
fi
directories=()
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"
done
}
setup_state_files(){
if [[ -f "$debug_log" ]]; then
rm "$debug_log" && touch $debug_log
@ -104,9 +109,8 @@ setup_state_files(){
logger INFO "Migrating legacy version file"
fi
# wipe cache files
local path="$cache_path"
if find "$path" -mindepth 1 -maxdepth 1 | read; then
for file in $path/*; do
if [[ $(ls -A "$cache_path") ]]; then
for file in "$cache_path"/*; do
rm "$file"
done
logger INFO "Wiped cache files"
@ -221,8 +225,7 @@ END
}
depcheck(){
for dep in "${!deps[@]}"; do
command -v "$dep" 2>&1>/dev/null
if [[ $? -eq 1 ]]; then
if ! command -v "$dep" &> /dev/null; then
local msg="Requires $dep >= ${deps[$dep]}"
raise_error_and_quit "$msg"
fi
@ -612,10 +615,10 @@ fetch_helpers_by_sum(){
[[ -f "$config_file" ]] && source "$config_file"
declare -A sums
sums=(
["funcs"]="c27a81577c818b4f4d786ada52ad5042"
["funcs"]="6ae3ead7034dc8e7543472bddee75c63"
["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
["servers.py"]="7f83d5c1ca54acb12f1bd6657feb2ecf"
["ui.py"]="8d6e52b3e9032acbb84ba6cf137f455a"
["servers.py"]="ed442c3aecf33f777d59dcf53650d263"
["ui.py"]="8d05bbd7b8e15a97fae568e9a3dbf4d6"
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
["pefile.py"]="21531f2c0d9dfa5f110cf6779f9d22c0"
)
@ -1117,13 +1120,61 @@ uninstall(){
rm "$self"
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(){
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; }
if [[ $1 == "--uninstall" ]] || [[ $1 == "-u" ]]; then
uninstall &&
exit 0
fi
# parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
"--uninstall" | "-u")
uninstall
exit 0
# shift
;;
"--version" | "-v")
echo $version
exit 0
# shift
;;
"--help" | "-h")
usage
exit 0
# shift
;;
*)
echo "Unrecognized command!"
return 1
esac
done
set_im_module
@ -1132,7 +1183,12 @@ main(){
printf "All OK. Kicking off UI...\n"
python3 "$ui_helper" "--init-ui" "$version" "$is_steam_deck"
}
main "$@"
#TODO: tech debt: cruddy handling for steam forking
[[ $? -eq 1 ]] && pkill -f dzgui.sh
if [[ $(basename "$0") == "dzgui.sh" ]]; then
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
set -o pipefail
version="6.0.0-beta.7"
version="6.0.0-beta.8"
#CONSTANTS
aid=221100

View File

@ -1,36 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define R 6371
#define TO_RAD (3.1415926536 / 180)
double dist(double th1, double ph1, double th2, double ph2)
{
double dx, dy, dz;
ph1 -= ph2;
ph1 *= TO_RAD, th1 *= TO_RAD, th2 *= TO_RAD;
dz = sin(th1) - sin(th2);
dx = cos(ph1) * cos(th1) - cos(th2);
dy = sin(ph1) * cos(th1);
return asin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * R;
}
int main(int argc, const char * argv[])
{
if(argc < 5 || argc > 5){
return 1;
}
float coords[4];
for(int i=1;i<5;i++){
if(atof(argv[i]) == 0){
return 1;
}
coords[i] = atof(argv[i]);
}
double d = dist(coords[1], coords[2], coords[3], coords[4]);
printf("%.1f\n", d);
return 0;
}

View File

@ -87,6 +87,7 @@ def parse_json(json: list) -> list:
except KeyError:
continue
malformed = False
for key in [
"map",
"gametype",
@ -98,7 +99,11 @@ def parse_json(json: list) -> list:
try:
row[key]
except KeyError:
continue
malformed = True
break
if malformed is True:
continue
try:
r = row["gametype"].split(",")
@ -167,7 +172,7 @@ def parse_json(json: list) -> list:
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:
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")
def validate_ip(addr: str):
def validate_ip(addr: str) -> Record:
fields = addr.split(":")
if len(fields) != 2:
raise InvalidIpError("Address must be formatted as IP:Queryport")

1
helpers/tools/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
latlon

24
helpers/tools/Makefile Normal file
View File

@ -0,0 +1,24 @@
bin := latlon
CC = gcc
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -Wpedantic
CFLAGS += -std=c23
CFLAGS += -O3
LDFLAGS += -lm
PREFIX ?= $(HOME)/.local/share/dzgui
all: $(bin)
install: $(bin)
install -Dm 755 $(bin) $(PREFIX)
$(bin): latlon.c
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
clean:
rm -f $(bin)

77
helpers/tools/latlon.c Normal file
View File

@ -0,0 +1,77 @@
// This small program computes the distance between two points on the Earths
// surface. The algorithm used for computing is called haversine formula.
// Source for the algorithm can be found here:
// https://en.wikipedia.org/wiki/Haversine_formula
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
// Earth's radius in meters.
#define RADIUS ((12756L / 2.0L) * 1000L)
// PI natural constant
#define PI 3.1415926536L
// coordinates struct for storing points
struct Coordinate {
double latitude;
double longitude;
};
/**
* @brief Calculates a radian value from an angle
*/
double radian_from(const double angle) {
return (angle * PI) / 180;
}
/**
* @brief Calculate the haversine function from an angle in radian
*/
double haversine(const double angle) { return ((1.0L - cos(angle)) / 2); }
/**
* @brief Calculate the distance between two coordinates
*/
double great_circle_distance(const struct Coordinate a,
const struct Coordinate b) {
// calculate longitude and latitude differences
struct Coordinate diff_coord = {
.longitude = a.longitude - b.longitude,
.latitude = a.latitude - b.latitude,
};
// calculate haversine(theta) value, where theta is the angle between the
// two coordinates
double hav_theta = haversine(diff_coord.latitude)
+ cos(a.latitude) * cos(b.latitude) * haversine(diff_coord.longitude);
// calculate distance from radius, and haversine(theta) values
double distance = 2 * RADIUS * asin(sqrt(hav_theta));
return distance;
}
int main(int argc, const char* argv[]) {
if (argc < 5 || argc > 5) {
return 1;
}
const struct Coordinate a = {
.latitude = radian_from(atof(argv[1])),
.longitude = radian_from(atof(argv[2])),
};
const struct Coordinate b = {
.latitude = radian_from(atof(argv[3])),
.longitude = radian_from(atof(argv[4])),
};
// Returns the distance in meters.
// To pretty-print the result in a consumer of this module, it is
// recommended to divide the result by 1,000 and round it.
printf("%.1f\n", great_circle_distance(a, b));
return 0;
}

View File

@ -78,7 +78,7 @@ servers_path = f"{cache_path}/{app_name_abbr}.servers"
config_path = f"{user_path}/.config/dztui"
config_file = f"{config_path}/dztuirc"
history_file = f"{state_path}/{app_name_abbr}.history"
notes_file = f"{state_path}/{app_name_abbr}.notes.json"
notes_file = f"{config_path}/{app_name_abbr}.notes.json"
logger = logging.getLogger(__name__)
log_file = f"{log_path}/{app_name}_DEBUG.log"
@ -1872,6 +1872,9 @@ class TreeView(Gtk.TreeView):
) -> bool:
if self.is_server_context(self.view) is False:
return
if self.subpage is None:
return
coords = widget.convert_widget_to_bin_window_coords(x, y)
path = self.get_path_at_pos(coords.bx, coords.by)
if path is None:
@ -2573,7 +2576,7 @@ class TreeView(Gtk.TreeView):
App.right_panel.filters_vbox.set_active_combo(0)
App.grid.right_panel.filters_vbox.set_visible(True)
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()
@ -3207,8 +3210,11 @@ class GenericDialog(Gtk.MessageDialog):
self.outer.set_margin_end(30)
def _on_dialog_delete(
self, response_id: Gtk.ResponseType
self, response_id: Gtk.ResponseType, event: Gdk.Event
) -> Literal[True]:
"""
Prevent manual dialog destruction
"""
return True
def _return_to_main_menu(self, widget: Gtk.Widget) -> None:
@ -3232,7 +3238,7 @@ class LanDialog(Gtk.MessageDialog):
buttons=Gtk.ButtonsType.OK_CANCEL,
text="Scan LAN servers",
secondary_text="Select the query port",
title="{appname}",
title=f"{app_name} - Dialog",
modal=True,
)
@ -3758,7 +3764,7 @@ class LeftLabel(Gtk.Label):
class Options(Gtk.Box):
def __init__(self):
def __init__(self, self_update=True):
super().__init__(
orientation=Gtk.Orientation.VERTICAL,
margin_start=10,
@ -3835,11 +3841,18 @@ class Options(Gtk.Box):
self.branch_combo.append_text("Testing")
self.branch_combo.set_active(0)
self.branch_combo.connect("changed", self._on_branch_changed)
self.branch_combo.set_sensitive(self_update)
msg = (
"Stable: only contains stable features. "
"Testing: pre-release beta, contains new features."
)
if self_update is True:
msg = (
"Stable: only contains stable 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)
version_rows = [
@ -4355,7 +4368,7 @@ class Notebook(Gtk.Notebook):
self.keys.show_all()
self.append_page(self.keys)
self.settings = Options()
self.settings = Options(self_update=True)
self.settings.type = RowType.OPTIONS
self.settings.show_all()
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