This commit is contained in:
2026-08-27 17:50:36 +02:00
commit 5a0e6520f4
51 changed files with 14027 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Name=PristonTale EU
Comment=Install, update, and play PristonTale EU in a clean Linux game window
Exec=@PTLINUX_EXECUTABLE@ gui
Icon=@PTLINUX_ICON@
Terminal=false
Categories=Game;RolePlaying;
Keywords=PristonTale;MMORPG;Wine;Proton;
StartupNotify=true

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

411
packaging/install-dependencies.sh Executable file
View File

@@ -0,0 +1,411 @@
#!/usr/bin/env bash
# Host dependency bootstrap shared by install.sh and release validation.
ptlinux_dependency_family()
{
local distribution_id="${1,,}"
local distribution_like=" ${2,,} "
case "$distribution_id" in
ubuntu|debian|linuxmint|pop|elementary|zorin)
printf '%s\n' "debian"
return 0
;;
fedora|nobara)
printf '%s\n' "fedora"
return 0
;;
arch|cachyos|endeavouros|garuda|manjaro)
printf '%s\n' "arch"
return 0
;;
opensuse-tumbleweed|opensuse-leap|opensuse|suse)
printf '%s\n' "suse"
return 0
;;
esac
case "$distribution_like" in
*" debian "*|*" ubuntu "*)
printf '%s\n' "debian"
;;
*" fedora "*)
printf '%s\n' "fedora"
;;
*" arch "*)
printf '%s\n' "arch"
;;
*" suse "*)
printf '%s\n' "suse"
;;
*)
printf '%s\n' "unknown"
;;
esac
}
ptlinux_resolve_dependency_packages()
{
local family="$1"
shift
local dependency
local package
local -a candidates=()
local -a packages=()
for dependency in "$@"
do
candidates=()
case "${family}:${dependency}" in
debian:python)
candidates=(python3)
;;
debian:python-tk)
candidates=(python3-tk)
;;
debian:wine)
candidates=(wine wine64 wine32:i386)
;;
debian:winetricks)
candidates=(winetricks)
;;
debian:gamescope)
candidates=(gamescope)
;;
debian:cabextract)
candidates=(cabextract)
;;
debian:openssl)
candidates=(openssl)
;;
fedora:python)
candidates=(python3)
;;
fedora:python-tk)
candidates=(python3-tkinter)
;;
fedora:wine)
candidates=(wine)
;;
fedora:winetricks)
candidates=(winetricks)
;;
fedora:gamescope)
candidates=(gamescope)
;;
fedora:cabextract)
candidates=(cabextract)
;;
fedora:openssl)
candidates=(openssl)
;;
arch:python)
candidates=(python)
;;
arch:python-tk)
candidates=(tk)
;;
arch:wine)
candidates=(wine)
;;
arch:winetricks)
candidates=(winetricks)
;;
arch:gamescope)
candidates=(gamescope)
;;
arch:cabextract)
candidates=(cabextract)
;;
arch:openssl)
candidates=(openssl)
;;
suse:python)
candidates=(python3)
;;
suse:python-tk)
candidates=(python3-tk)
;;
suse:wine)
candidates=(wine)
;;
suse:winetricks)
candidates=(winetricks)
;;
suse:gamescope)
candidates=(gamescope)
;;
suse:cabextract)
candidates=(cabextract)
;;
suse:openssl)
candidates=(openssl)
;;
*)
printf 'No package mapping for %s on %s systems.\n' "$dependency" "$family" >&2
return 1
;;
esac
for package in "${candidates[@]}"
do
if [[ " ${packages[*]} " != *" ${package} "* ]]
then
packages+=("$package")
fi
done
done
printf '%s\n' "${packages[*]}"
}
ptlinux_read_distribution()
{
local release_file="${PTLINUX_OS_RELEASE:-/etc/os-release}"
local key
local value
PTLINUX_DISTRIBUTION_ID="unknown"
PTLINUX_DISTRIBUTION_LIKE=""
if [[ ! -r "$release_file" ]]
then
return 0
fi
while IFS='=' read -r key value
do
value="${value%\"}"
value="${value#\"}"
value="${value%\'}"
value="${value#\'}"
case "$key" in
ID)
PTLINUX_DISTRIBUTION_ID="$value"
;;
ID_LIKE)
PTLINUX_DISTRIBUTION_LIKE="$value"
;;
esac
done < "$release_file"
}
ptlinux_has_wine_stack()
{
local wine_root
if command -v wine >/dev/null 2>&1 && command -v wineboot >/dev/null 2>&1
then
return 0
fi
for wine_root in /opt/wine-stable/bin /opt/wine-staging/bin /opt/wine-devel/bin
do
if [[ -x "${wine_root}/wine" && -x "${wine_root}/wineboot" ]]
then
return 0
fi
done
return 1
}
ptlinux_detect_missing_dependencies()
{
local python_bin="${PYTHON_BIN:-python3}"
PTLINUX_MISSING_DEPENDENCIES=()
if ! command -v "$python_bin" >/dev/null 2>&1
then
PTLINUX_MISSING_DEPENDENCIES+=(python python-tk)
elif ! "$python_bin" -c 'import _tkinter' >/dev/null 2>&1
then
PTLINUX_MISSING_DEPENDENCIES+=(python-tk)
fi
if ! ptlinux_has_wine_stack
then
PTLINUX_MISSING_DEPENDENCIES+=(wine)
fi
if ! command -v winetricks >/dev/null 2>&1
then
PTLINUX_MISSING_DEPENDENCIES+=(winetricks)
fi
if ! command -v gamescope >/dev/null 2>&1
then
PTLINUX_MISSING_DEPENDENCIES+=(gamescope)
fi
if ! command -v cabextract >/dev/null 2>&1
then
PTLINUX_MISSING_DEPENDENCIES+=(cabextract)
fi
if ! command -v openssl >/dev/null 2>&1
then
PTLINUX_MISSING_DEPENDENCIES+=(openssl)
fi
}
ptlinux_select_privilege_command()
{
PTLINUX_PRIVILEGE_COMMAND=()
if (( EUID == 0 ))
then
return 0
fi
if command -v sudo >/dev/null 2>&1
then
PTLINUX_PRIVILEGE_COMMAND=(sudo)
return 0
fi
if command -v doas >/dev/null 2>&1
then
PTLINUX_PRIVILEGE_COMMAND=(doas)
return 0
fi
if command -v pkexec >/dev/null 2>&1
then
PTLINUX_PRIVILEGE_COMMAND=(pkexec)
return 0
fi
printf '%s\n' "Root access is required, but sudo, doas, and pkexec are unavailable." >&2
return 1
}
ptlinux_print_command()
{
printf '%s' " +"
printf ' %q' "$@"
printf '\n'
}
ptlinux_run_as_root()
{
ptlinux_print_command "${PTLINUX_PRIVILEGE_COMMAND[@]}" "$@"
"${PTLINUX_PRIVILEGE_COMMAND[@]}" "$@"
}
ptlinux_install_resolved_packages()
{
local family="$1"
shift
local -a packages=("$@")
local architecture
local has_i386=0
local package
ptlinux_select_privilege_command
case "$family" in
debian)
for package in "${packages[@]}"
do
if [[ "$package" == "wine32:i386" ]]
then
has_i386=1
fi
done
if (( has_i386 == 1 ))
then
while IFS= read -r architecture
do
if [[ "$architecture" == "i386" ]]
then
has_i386=2
fi
done < <(dpkg --print-foreign-architectures)
if (( has_i386 == 1 ))
then
ptlinux_run_as_root dpkg --add-architecture i386
fi
fi
ptlinux_run_as_root apt-get update
ptlinux_run_as_root apt-get install -y "${packages[@]}"
;;
fedora)
if command -v dnf5 >/dev/null 2>&1
then
ptlinux_run_as_root dnf5 install -y "${packages[@]}"
else
ptlinux_run_as_root dnf install -y "${packages[@]}"
fi
;;
arch)
ptlinux_run_as_root pacman -S --needed --noconfirm "${packages[@]}"
;;
suse)
ptlinux_run_as_root zypper --non-interactive install "${packages[@]}"
;;
*)
printf 'Unsupported dependency family: %s\n' "$family" >&2
return 1
;;
esac
}
ptlinux_install_host_dependencies()
{
local dry_run="$1"
local family
local package_line
local -a packages=()
ptlinux_detect_missing_dependencies
if (( ${#PTLINUX_MISSING_DEPENDENCIES[@]} == 0 ))
then
printf '%s\n' "All required host dependencies are already available."
return 0
fi
ptlinux_read_distribution
family="$(ptlinux_dependency_family "$PTLINUX_DISTRIBUTION_ID" "$PTLINUX_DISTRIBUTION_LIKE")"
if [[ "$family" == "unknown" ]]
then
printf 'Unsupported distribution: %s. Re-run with --skip-deps after installing: %s\n' \
"$PTLINUX_DISTRIBUTION_ID" "${PTLINUX_MISSING_DEPENDENCIES[*]}" >&2
return 1
fi
package_line="$(ptlinux_resolve_dependency_packages \
"$family" "${PTLINUX_MISSING_DEPENDENCIES[@]}")"
read -r -a packages <<< "$package_line"
printf 'Missing host components: %s\n' "${PTLINUX_MISSING_DEPENDENCIES[*]}"
printf 'Distribution packages: %s\n' "${packages[*]}"
if (( dry_run == 1 ))
then
printf '%s\n' "Dry run: system packages were not changed."
return 0
fi
printf '%s\n' "Installing missing host dependencies (authentication may be requested)."
ptlinux_install_resolved_packages "$family" "${packages[@]}"
hash -r
ptlinux_detect_missing_dependencies
if (( ${#PTLINUX_MISSING_DEPENDENCIES[@]} != 0 ))
then
printf 'Dependencies remain unavailable after package installation: %s\n' \
"${PTLINUX_MISSING_DEPENDENCIES[*]}" >&2
return 1
fi
printf '%s\n' "Host dependency installation completed."
}
ptlinux_dependency_main()
{
if [[ "${1:-}" != "--resolve" || $# -lt 3 ]]
then
printf '%s\n' "Usage: install-dependencies.sh --resolve DISTRO DEPENDENCY..." >&2
return 2
fi
shift
local distribution_id="$1"
shift
local family
family="$(ptlinux_dependency_family "$distribution_id" "")"
if [[ "$family" == "unknown" ]]
then
printf 'Unsupported distribution: %s\n' "$distribution_id" >&2
return 1
fi
ptlinux_resolve_dependency_packages "$family" "$@"
}
if [[ "${BASH_SOURCE[0]}" == "$0" ]]
then
set -euo pipefail
ptlinux_dependency_main "$@"
fi

41
packaging/pristontale-eu Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env sh
set -eu
app_home=@PTLINUX_APP_ROOT@
install_directory=@PTLINUX_INSTALL_DIR@
python_bin="${PTLINUX_PYTHON:-python3}"
export PTLINUX_INSTALL_DIR="${install_directory}"
export PTLINUX_APP_HOME="${app_home}"
release_root=""
for candidate in "${app_home}/current" "${app_home}/previous" "${app_home}"
do
if [ ! -d "${candidate}/ptlinux" ]
then
continue
fi
if "$python_bin" -I -c \
'import sys; sys.path.insert(0, sys.argv[1]); import ptlinux, ptlinux.cli' \
"${candidate}" >/dev/null 2>&1
then
release_root="${candidate}"
break
fi
done
if [ -z "${release_root}" ]
then
printf '%s\n' "PristonTale EU Linux application files are missing or invalid: ${app_home}" >&2
exit 1
fi
if [ -n "${PYTHONPATH:-}" ]
then
export PYTHONPATH="${release_root}:${PYTHONPATH}"
else
export PYTHONPATH="${release_root}"
fi
exec "$python_bin" -m ptlinux "$@"