Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9644de3ff5 | |||
| a362b0bb8e |
@@ -1,6 +1,6 @@
|
|||||||
# PristonTale EU for Linux
|
# PristonTale EU for Linux
|
||||||
|
|
||||||
Version 0.9.8 installs, updates, repairs, and launches PristonTale EU through a
|
Version 0.9.11 installs, updates, repairs, and launches PristonTale EU through a
|
||||||
native Linux dashboard. Game files come directly from the publisher and are not
|
native Linux dashboard. Game files come directly from the publisher and are not
|
||||||
included in this archive.
|
included in this archive.
|
||||||
|
|
||||||
@@ -15,11 +15,11 @@ Then run:
|
|||||||
```text
|
```text
|
||||||
openssl pkey -pubin -in launcher-update-public.pem -outform DER | sha256sum
|
openssl pkey -pubin -in launcher-update-public.pem -outform DER | sha256sum
|
||||||
openssl dgst -sha256 -verify launcher-update-public.pem \
|
openssl dgst -sha256 -verify launcher-update-public.pem \
|
||||||
-signature pristontale-eu-linux-installer-v0-9-8.tar.gz.sig \
|
-signature pristontale-eu-linux-installer-v0-9-11.tar.gz.sig \
|
||||||
pristontale-eu-linux-installer-v0-9-8.tar.gz
|
pristontale-eu-linux-installer-v0-9-11.tar.gz
|
||||||
sha256sum -c pristontale-eu-linux-installer-v0-9-8.tar.gz.sha256
|
sha256sum -c pristontale-eu-linux-installer-v0-9-11.tar.gz.sha256
|
||||||
tar -xzf pristontale-eu-linux-installer-v0-9-8.tar.gz
|
tar -xzf pristontale-eu-linux-installer-v0-9-11.tar.gz
|
||||||
cd pristontale-eu-linux-installer-v0-9-8
|
cd pristontale-eu-linux-installer-v0-9-11
|
||||||
./install.sh
|
./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ from .paths import AppPaths
|
|||||||
|
|
||||||
__all__ = ["AppPaths", "__version__"]
|
__all__ = ["AppPaths", "__version__"]
|
||||||
|
|
||||||
__version__ = "0.9.8"
|
__version__ = "0.9.11"
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from typing import Any, Callable
|
|||||||
from ...paths import AppPaths
|
from ...paths import AppPaths
|
||||||
from ...self_update import (
|
from ...self_update import (
|
||||||
LauncherRemoteHistory,
|
LauncherRemoteHistory,
|
||||||
LauncherRemoteRelease,
|
|
||||||
LauncherUpdateCheck,
|
LauncherUpdateCheck,
|
||||||
LauncherUpdateHistory,
|
LauncherUpdateHistory,
|
||||||
inspect_launcher_update_history,
|
inspect_launcher_update_history,
|
||||||
@@ -52,6 +51,46 @@ def release_notes_preview(markdown: str | None) -> str:
|
|||||||
return preview
|
return preview
|
||||||
|
|
||||||
|
|
||||||
|
def update_version_heading(
|
||||||
|
running_version: str,
|
||||||
|
latest_version: str,
|
||||||
|
channel: str,
|
||||||
|
*,
|
||||||
|
update_available: bool,
|
||||||
|
) -> str:
|
||||||
|
"""Describe update versions without confusing an older channel head as current."""
|
||||||
|
|
||||||
|
if update_available:
|
||||||
|
return f"Update: {running_version} → {latest_version}"
|
||||||
|
return (
|
||||||
|
f"Current version: {running_version}\n"
|
||||||
|
f"Latest {channel.title()} release: {latest_version}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def release_history_state(
|
||||||
|
release_status: str,
|
||||||
|
*,
|
||||||
|
is_running: bool,
|
||||||
|
local_active: bool,
|
||||||
|
local_retained: bool,
|
||||||
|
is_older: bool,
|
||||||
|
) -> str:
|
||||||
|
"""Label running and installed releases without treating them as synonymous."""
|
||||||
|
|
||||||
|
if is_running:
|
||||||
|
return "Current"
|
||||||
|
if local_active:
|
||||||
|
return "Installed"
|
||||||
|
if release_status != "active":
|
||||||
|
return release_status.title()
|
||||||
|
if local_retained:
|
||||||
|
return "Retained locally"
|
||||||
|
if is_older:
|
||||||
|
return "Available rollback"
|
||||||
|
return "Published"
|
||||||
|
|
||||||
|
|
||||||
class LauncherUpdateDialog:
|
class LauncherUpdateDialog:
|
||||||
"""Own the update window and expose small refresh/error entry points."""
|
"""Own the update window and expose small refresh/error entry points."""
|
||||||
|
|
||||||
@@ -97,6 +136,8 @@ class LauncherUpdateDialog:
|
|||||||
self._history: Any = None
|
self._history: Any = None
|
||||||
self._history_filter_value: Any = None
|
self._history_filter_value: Any = None
|
||||||
self._history_items: dict[str, tuple[str, str, str | None, bool]] = {}
|
self._history_items: dict[str, tuple[str, str, str | None, bool]] = {}
|
||||||
|
self._release_notes_frame: Any = None
|
||||||
|
self._release_notes_text: Any = None
|
||||||
self._release_notes_button: Any = None
|
self._release_notes_button: Any = None
|
||||||
self._check_button: Any = None
|
self._check_button: Any = None
|
||||||
self._rollback_button: Any = None
|
self._rollback_button: Any = None
|
||||||
@@ -120,7 +161,7 @@ class LauncherUpdateDialog:
|
|||||||
dialog.withdraw()
|
dialog.withdraw()
|
||||||
self._window = dialog
|
self._window = dialog
|
||||||
dialog.title("PristonTale EU — Launcher Updates")
|
dialog.title("PristonTale EU — Launcher Updates")
|
||||||
dialog.resizable(False, False)
|
dialog.resizable(False, True)
|
||||||
dialog.configure(background="#0c0908")
|
dialog.configure(background="#0c0908")
|
||||||
dialog.transient(self._root)
|
dialog.transient(self._root)
|
||||||
self._apply_window_icon(dialog)
|
self._apply_window_icon(dialog)
|
||||||
@@ -201,6 +242,53 @@ class LauncherUpdateDialog:
|
|||||||
sticky="e",
|
sticky="e",
|
||||||
padx=(12, 0),
|
padx=(12, 0),
|
||||||
)
|
)
|
||||||
|
self._release_notes_frame = ttk.Frame(
|
||||||
|
overview,
|
||||||
|
style="SettingsCard.TFrame",
|
||||||
|
)
|
||||||
|
self._release_notes_frame.grid(
|
||||||
|
row=2,
|
||||||
|
column=0,
|
||||||
|
columnspan=2,
|
||||||
|
sticky="ew",
|
||||||
|
pady=(10, 0),
|
||||||
|
)
|
||||||
|
self._release_notes_frame.columnconfigure(0, weight=1)
|
||||||
|
ttk.Label(
|
||||||
|
self._release_notes_frame,
|
||||||
|
text="WHAT'S NEW",
|
||||||
|
style="SettingsText.TLabel",
|
||||||
|
).grid(row=0, column=0, columnspan=2, sticky="w", pady=(0, 4))
|
||||||
|
self._release_notes_text = tk.Text(
|
||||||
|
self._release_notes_frame,
|
||||||
|
name="launcher_update_release_notes",
|
||||||
|
width=1,
|
||||||
|
height=3,
|
||||||
|
wrap="word",
|
||||||
|
background="#100d0c",
|
||||||
|
foreground="#c8b8a8",
|
||||||
|
selectbackground="#6a482d",
|
||||||
|
selectforeground="#ffffff",
|
||||||
|
font=("Sans", 8),
|
||||||
|
borderwidth=0,
|
||||||
|
highlightthickness=0,
|
||||||
|
padx=8,
|
||||||
|
pady=6,
|
||||||
|
state="disabled",
|
||||||
|
takefocus=False,
|
||||||
|
)
|
||||||
|
release_notes_scrollbar = ttk.Scrollbar(
|
||||||
|
self._release_notes_frame,
|
||||||
|
orient="vertical",
|
||||||
|
style="News.Vertical.TScrollbar",
|
||||||
|
command=self._release_notes_text.yview,
|
||||||
|
)
|
||||||
|
self._release_notes_text.configure(
|
||||||
|
yscrollcommand=release_notes_scrollbar.set,
|
||||||
|
)
|
||||||
|
self._release_notes_text.grid(row=1, column=0, sticky="ew")
|
||||||
|
release_notes_scrollbar.grid(row=1, column=1, sticky="ns", padx=(6, 0))
|
||||||
|
self._release_notes_frame.grid_remove()
|
||||||
|
|
||||||
history_card = ttk.LabelFrame(
|
history_card = ttk.LabelFrame(
|
||||||
content,
|
content,
|
||||||
@@ -244,7 +332,7 @@ class LauncherUpdateDialog:
|
|||||||
history_card,
|
history_card,
|
||||||
columns=("version", "channel", "state", "installed"),
|
columns=("version", "channel", "state", "installed"),
|
||||||
show="headings",
|
show="headings",
|
||||||
height=6,
|
height=4,
|
||||||
style="Update.Treeview",
|
style="Update.Treeview",
|
||||||
selectmode="browse",
|
selectmode="browse",
|
||||||
)
|
)
|
||||||
@@ -333,8 +421,8 @@ class LauncherUpdateDialog:
|
|||||||
self._check_again()
|
self._check_again()
|
||||||
dialog.update_idletasks()
|
dialog.update_idletasks()
|
||||||
updates_width, updates_height = fitted_window_size(
|
updates_width, updates_height = fitted_window_size(
|
||||||
760,
|
820,
|
||||||
620,
|
680,
|
||||||
scale=self._ui_scale,
|
scale=self._ui_scale,
|
||||||
screen_width=dialog.winfo_screenwidth(),
|
screen_width=dialog.winfo_screenwidth(),
|
||||||
screen_height=dialog.winfo_screenheight(),
|
screen_height=dialog.winfo_screenheight(),
|
||||||
@@ -365,6 +453,8 @@ class LauncherUpdateDialog:
|
|||||||
assert self._status_value is not None
|
assert self._status_value is not None
|
||||||
assert self._details_value is not None
|
assert self._details_value is not None
|
||||||
assert self._history is not None
|
assert self._history is not None
|
||||||
|
assert self._release_notes_frame is not None
|
||||||
|
assert self._release_notes_text is not None
|
||||||
assert self._release_notes_button is not None
|
assert self._release_notes_button is not None
|
||||||
assert self._check_button is not None
|
assert self._check_button is not None
|
||||||
assert self._rollback_button is not None
|
assert self._rollback_button is not None
|
||||||
@@ -381,10 +471,11 @@ class LauncherUpdateDialog:
|
|||||||
if check is None:
|
if check is None:
|
||||||
self._status_value.set("Checking the signed update channel…")
|
self._status_value.set("Checking the signed update channel…")
|
||||||
self._details_value.set(
|
self._details_value.set(
|
||||||
"Installed launcher "
|
"Running launcher "
|
||||||
+ self._launcher_version
|
+ self._launcher_version
|
||||||
+ " · release information pending"
|
+ " · release information pending"
|
||||||
)
|
)
|
||||||
|
self._set_release_notes_preview("")
|
||||||
self._install_button.configure(state="disabled")
|
self._install_button.configure(state="disabled")
|
||||||
self._refresh_history_actions(busy=busy)
|
self._refresh_history_actions(busy=busy)
|
||||||
return
|
return
|
||||||
@@ -400,13 +491,14 @@ class LauncherUpdateDialog:
|
|||||||
for release in (
|
for release in (
|
||||||
remote_history.releases if remote_history is not None else ()
|
remote_history.releases if remote_history is not None else ()
|
||||||
)
|
)
|
||||||
if release.version == check.current_version and release.status != "active"
|
if release.version == self._launcher_version
|
||||||
|
and release.status != "active"
|
||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
if installed_status is not None:
|
if installed_status is not None:
|
||||||
status_prefix += (
|
status_prefix += (
|
||||||
f"Warning: installed launcher {check.current_version} is "
|
f"Warning: running launcher {self._launcher_version} is "
|
||||||
f"{installed_status}; install the next active eligible release.\n"
|
f"{installed_status}; install the next active eligible release.\n"
|
||||||
)
|
)
|
||||||
self._status_value.set(status_prefix + check.reason)
|
self._status_value.set(status_prefix + check.reason)
|
||||||
@@ -418,18 +510,24 @@ class LauncherUpdateDialog:
|
|||||||
if check.manifest.channel == "prerelease"
|
if check.manifest.channel == "prerelease"
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
|
summary_line = f"{release_summary}\n" if not notes_preview else ""
|
||||||
|
version_line = update_version_heading(
|
||||||
|
self._launcher_version,
|
||||||
|
check.latest_version,
|
||||||
|
check.manifest.channel,
|
||||||
|
update_available=check.available,
|
||||||
|
)
|
||||||
details = (
|
details = (
|
||||||
f"{check.current_version} → {check.latest_version}\n"
|
f"{version_line}\n"
|
||||||
f"{release_title}{prerelease_label}\n"
|
f"{release_title}{prerelease_label}\n"
|
||||||
f"{release_summary}\n"
|
f"{summary_line}"
|
||||||
f"Channel: {check.manifest.channel.title()} · "
|
f"Channel: {check.manifest.channel.title()} · "
|
||||||
f"{format_bytes(check.manifest.archive_size)} · "
|
f"{format_bytes(check.manifest.archive_size)} · "
|
||||||
f"published {check.manifest.published_at} · "
|
f"published {check.manifest.published_at} · "
|
||||||
f"checked {check.checked_at or 'time unavailable'}"
|
f"checked {check.checked_at or 'time unavailable'}"
|
||||||
)
|
)
|
||||||
if notes_preview:
|
|
||||||
details += f"\n\nWhat's new:\n{notes_preview}"
|
|
||||||
self._details_value.set(details)
|
self._details_value.set(details)
|
||||||
|
self._set_release_notes_preview(notes_preview)
|
||||||
self._install_button.configure(
|
self._install_button.configure(
|
||||||
state=(
|
state=(
|
||||||
"normal"
|
"normal"
|
||||||
@@ -442,6 +540,20 @@ class LauncherUpdateDialog:
|
|||||||
)
|
)
|
||||||
self._refresh_history_actions(busy=busy)
|
self._refresh_history_actions(busy=busy)
|
||||||
|
|
||||||
|
def _set_release_notes_preview(self, preview: str) -> None:
|
||||||
|
assert self._release_notes_frame is not None
|
||||||
|
assert self._release_notes_text is not None
|
||||||
|
self._release_notes_text.configure(state="normal")
|
||||||
|
self._release_notes_text.delete("1.0", "end")
|
||||||
|
if preview:
|
||||||
|
self._release_notes_text.insert("1.0", preview)
|
||||||
|
self._release_notes_text.configure(state="disabled")
|
||||||
|
self._release_notes_text.yview_moveto(0.0)
|
||||||
|
if preview:
|
||||||
|
self._release_notes_frame.grid()
|
||||||
|
else:
|
||||||
|
self._release_notes_frame.grid_remove()
|
||||||
|
|
||||||
def _populate_history(self, *, busy: bool) -> None:
|
def _populate_history(self, *, busy: bool) -> None:
|
||||||
assert self._history is not None
|
assert self._history is not None
|
||||||
assert self._history_filter_value is not None
|
assert self._history_filter_value is not None
|
||||||
@@ -461,16 +573,22 @@ class LauncherUpdateDialog:
|
|||||||
else ()
|
else ()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
current_version = (
|
installed_current_version = (
|
||||||
self._installed_history.current_version
|
self._installed_history.current_version
|
||||||
if self._installed_history is not None
|
if self._installed_history is not None
|
||||||
and self._installed_history.current_version is not None
|
and self._installed_history.current_version is not None
|
||||||
else self._launcher_version
|
else self._launcher_version
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
current_semantic = SemanticVersion.parse(current_version)
|
installed_current_semantic = SemanticVersion.parse(
|
||||||
|
installed_current_version
|
||||||
|
)
|
||||||
except ReleaseModelError:
|
except ReleaseModelError:
|
||||||
current_semantic = None
|
installed_current_semantic = None
|
||||||
|
try:
|
||||||
|
running_channel = SemanticVersion.parse(self._launcher_version).channel
|
||||||
|
except ReleaseModelError:
|
||||||
|
running_channel = "unknown"
|
||||||
filter_name = str(self._history_filter_value.get()).casefold()
|
filter_name = str(self._history_filter_value.get()).casefold()
|
||||||
|
|
||||||
def channel_visible(channel: str) -> bool:
|
def channel_visible(channel: str) -> bool:
|
||||||
@@ -478,20 +596,27 @@ class LauncherUpdateDialog:
|
|||||||
|
|
||||||
remote_history = self._get_remote_history()
|
remote_history = self._get_remote_history()
|
||||||
remote_versions: set[str] = set()
|
remote_versions: set[str] = set()
|
||||||
|
displayed_versions: set[str] = set()
|
||||||
if remote_history is not None:
|
if remote_history is not None:
|
||||||
for index, release in enumerate(remote_history.releases):
|
for index, release in enumerate(remote_history.releases):
|
||||||
if not channel_visible(release.channel):
|
if not channel_visible(release.channel):
|
||||||
continue
|
continue
|
||||||
remote_versions.add(release.version)
|
remote_versions.add(release.version)
|
||||||
|
displayed_versions.add(release.version)
|
||||||
local = installed.get(release.version)
|
local = installed.get(release.version)
|
||||||
is_older = (
|
is_older = (
|
||||||
current_semantic is not None
|
installed_current_semantic is not None
|
||||||
and SemanticVersion.parse(release.version) < current_semantic
|
and SemanticVersion.parse(release.version)
|
||||||
|
< installed_current_semantic
|
||||||
)
|
)
|
||||||
can_rollback = release.status == "active" and is_older
|
local_active = bool(local is not None and local.active)
|
||||||
state = self._remote_release_state(
|
can_rollback = (
|
||||||
release,
|
release.status == "active" and is_older and not local_active
|
||||||
local_active=bool(local is not None and local.active),
|
)
|
||||||
|
state = release_history_state(
|
||||||
|
release.status,
|
||||||
|
is_running=release.version == self._launcher_version,
|
||||||
|
local_active=local_active,
|
||||||
local_retained=local is not None,
|
local_retained=local is not None,
|
||||||
is_older=is_older,
|
is_older=is_older,
|
||||||
)
|
)
|
||||||
@@ -517,14 +642,23 @@ class LauncherUpdateDialog:
|
|||||||
for index, release in enumerate(self._installed_history.releases):
|
for index, release in enumerate(self._installed_history.releases):
|
||||||
if release.version in remote_versions or not channel_visible(release.channel):
|
if release.version in remote_versions or not channel_visible(release.channel):
|
||||||
continue
|
continue
|
||||||
|
displayed_versions.add(release.version)
|
||||||
try:
|
try:
|
||||||
is_older = (
|
is_older = (
|
||||||
current_semantic is not None
|
installed_current_semantic is not None
|
||||||
and SemanticVersion.parse(release.version) < current_semantic
|
and SemanticVersion.parse(release.version)
|
||||||
|
< installed_current_semantic
|
||||||
)
|
)
|
||||||
except ReleaseModelError:
|
except ReleaseModelError:
|
||||||
is_older = False
|
is_older = False
|
||||||
state = "Current" if release.active else "Retained locally"
|
state = release_history_state(
|
||||||
|
"active",
|
||||||
|
is_running=release.version == self._launcher_version,
|
||||||
|
local_active=release.active,
|
||||||
|
local_retained=True,
|
||||||
|
is_older=is_older,
|
||||||
|
)
|
||||||
|
can_rollback = is_older and not release.active
|
||||||
iid = f"local:{index}:{release.version}"
|
iid = f"local:{index}:{release.version}"
|
||||||
self._history.insert(
|
self._history.insert(
|
||||||
"",
|
"",
|
||||||
@@ -541,8 +675,30 @@ class LauncherUpdateDialog:
|
|||||||
release.version,
|
release.version,
|
||||||
release.channel,
|
release.channel,
|
||||||
None,
|
None,
|
||||||
is_older,
|
can_rollback,
|
||||||
)
|
)
|
||||||
|
if (
|
||||||
|
self._launcher_version not in displayed_versions
|
||||||
|
and channel_visible(running_channel)
|
||||||
|
):
|
||||||
|
iid = f"running:{self._launcher_version}"
|
||||||
|
self._history.insert(
|
||||||
|
"",
|
||||||
|
0,
|
||||||
|
iid=iid,
|
||||||
|
values=(
|
||||||
|
self._launcher_version,
|
||||||
|
running_channel.title(),
|
||||||
|
"Current",
|
||||||
|
"Running now",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self._history_items[iid] = (
|
||||||
|
self._launcher_version,
|
||||||
|
running_channel,
|
||||||
|
None,
|
||||||
|
False,
|
||||||
|
)
|
||||||
if not self._history.get_children():
|
if not self._history.get_children():
|
||||||
iid = "placeholder"
|
iid = "placeholder"
|
||||||
self._history.insert(
|
self._history.insert(
|
||||||
@@ -567,24 +723,6 @@ class LauncherUpdateDialog:
|
|||||||
self._history.focus(selected_iid)
|
self._history.focus(selected_iid)
|
||||||
self._refresh_history_actions(busy=busy)
|
self._refresh_history_actions(busy=busy)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _remote_release_state(
|
|
||||||
release: LauncherRemoteRelease,
|
|
||||||
*,
|
|
||||||
local_active: bool,
|
|
||||||
local_retained: bool,
|
|
||||||
is_older: bool,
|
|
||||||
) -> str:
|
|
||||||
if local_active:
|
|
||||||
return "Current"
|
|
||||||
if release.status != "active":
|
|
||||||
return release.status.title()
|
|
||||||
if local_retained:
|
|
||||||
return "Retained locally"
|
|
||||||
if is_older:
|
|
||||||
return "Available rollback"
|
|
||||||
return "Published"
|
|
||||||
|
|
||||||
def _history_selected(self, _event: object | None = None) -> None:
|
def _history_selected(self, _event: object | None = None) -> None:
|
||||||
self._refresh_history_actions(busy=self._is_busy())
|
self._refresh_history_actions(busy=self._is_busy())
|
||||||
|
|
||||||
@@ -621,6 +759,7 @@ class LauncherUpdateDialog:
|
|||||||
assert self._check_button is not None
|
assert self._check_button is not None
|
||||||
self._status_value.set("The signed update channel could not be checked.")
|
self._status_value.set("The signed update channel could not be checked.")
|
||||||
self._details_value.set(message)
|
self._details_value.set(message)
|
||||||
|
self._set_release_notes_preview("")
|
||||||
self._check_button.configure(state="normal")
|
self._check_button.configure(state="normal")
|
||||||
|
|
||||||
def _check_again(self) -> None:
|
def _check_again(self) -> None:
|
||||||
@@ -630,6 +769,7 @@ class LauncherUpdateDialog:
|
|||||||
assert self._install_button is not None
|
assert self._install_button is not None
|
||||||
self._status_value.set("Checking the signed update channel…")
|
self._status_value.set("Checking the signed update channel…")
|
||||||
self._details_value.set("Authenticating the selected channel manifests and signatures.")
|
self._details_value.set("Authenticating the selected channel manifests and signatures.")
|
||||||
|
self._set_release_notes_preview("")
|
||||||
self._check_button.configure(state="disabled")
|
self._check_button.configure(state="disabled")
|
||||||
self._install_button.configure(state="disabled")
|
self._install_button.configure(state="disabled")
|
||||||
self._request_check()
|
self._request_check()
|
||||||
@@ -637,8 +777,9 @@ class LauncherUpdateDialog:
|
|||||||
def _view_release_notes(self) -> None:
|
def _view_release_notes(self) -> None:
|
||||||
selected = self._selected_history_item()
|
selected = self._selected_history_item()
|
||||||
if selected is not None:
|
if selected is not None:
|
||||||
if selected[2] is not None:
|
notes_url = selected[2]
|
||||||
self._open_article(selected[2])
|
if notes_url is not None:
|
||||||
|
self._open_article(notes_url)
|
||||||
return
|
return
|
||||||
check = self._get_check()
|
check = self._get_check()
|
||||||
if check is not None and check.manifest.notes_url is not None:
|
if check is not None and check.manifest.notes_url is not None:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "PTEU-Linux-Launcher"
|
name = "PTEU-Linux-Launcher"
|
||||||
version = "0.9.8"
|
version = "0.9.11"
|
||||||
description = "PristonTale EU Linux installer, clean launcher, and diagnostic harness"
|
description = "PristonTale EU Linux installer, clean launcher, and diagnostic harness"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
{
|
{
|
||||||
"application": "PristonTale-EU",
|
"application": "PristonTale-EU",
|
||||||
"archive": {
|
"archive": {
|
||||||
"layout": "flat",
|
"layout": "wrapped",
|
||||||
"name": "PristonTale-EU-0.9.9.tar.gz",
|
"name": "PristonTale-EU-0.9.11.tar.gz",
|
||||||
"sha256": "362fa9ef25b463e58cd5a82e69525bc61f86ea27e12f73105b3789cbf86db317",
|
"sha256": "60b13d6fbc8fe27714c7fe1a65fa73785a13962d96d03decfac1aa62c4e3f6db",
|
||||||
"size": 1473476,
|
"size": 1474010,
|
||||||
"url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/download/v0.9.9/PristonTale-EU-0.9.9.tar.gz"
|
"url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/download/v0.9.11/PristonTale-EU-0.9.11.tar.gz"
|
||||||
},
|
},
|
||||||
"archive_sha256": "362fa9ef25b463e58cd5a82e69525bc61f86ea27e12f73105b3789cbf86db317",
|
"archive_sha256": "60b13d6fbc8fe27714c7fe1a65fa73785a13962d96d03decfac1aa62c4e3f6db",
|
||||||
"archive_size": 1473476,
|
"archive_size": 1474010,
|
||||||
"archive_url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/download/v0.9.9/PristonTale-EU-0.9.9.tar.gz",
|
"archive_url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/download/v0.9.11/PristonTale-EU-0.9.11.tar.gz",
|
||||||
"channel": "stable",
|
"channel": "stable",
|
||||||
"commit": "290d1a5383219aeef0640ec8010d50cb6c1b2a00",
|
"commit": "a362b0bb8e2bf74db9075c5f58db5236b1dc98f6",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"config_schema": 1,
|
"config_schema": 1,
|
||||||
"manifest_schema": 1,
|
"manifest_schema": 1,
|
||||||
"minimum_config_schema": 1,
|
"minimum_config_schema": 1,
|
||||||
"minimum_updater_version": "0.9.9"
|
"minimum_updater_version": "0.5.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "ptlinux/__init__.py",
|
"path": "ptlinux/__init__.py",
|
||||||
"sha256": "f6bc2b93c5098bcc613e4ea47c8c1bbd2386e483aa1368a3807d865d72d9c3d0",
|
"sha256": "b4eaa89165a506ff593083dd32ad30fefe1d8ec7d09af67b45b29a3d13599df0",
|
||||||
"size": 151
|
"size": 152
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "ptlinux/__main__.py",
|
"path": "ptlinux/__main__.py",
|
||||||
@@ -306,8 +306,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "ptlinux/ui/components/update_dialog.py",
|
"path": "ptlinux/ui/components/update_dialog.py",
|
||||||
"sha256": "af5775b07b6872b5e5f465deb8d9f583ddfeeae1df79a126fb2d2fe967bb3d06",
|
"sha256": "1defc85b4cf30f15fa1c30bcfd0cbf961072ba2d2ab8a681ef981e34ef3598d4",
|
||||||
"size": 22005
|
"size": 24138
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "ptlinux/ui/dashboard.py",
|
"path": "ptlinux/ui/dashboard.py",
|
||||||
@@ -371,21 +371,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "release.json",
|
"path": "release.json",
|
||||||
"sha256": "1064833b4387c33b53afcc973577c11faa3c781d7811b039fe8990f789b057b9",
|
"sha256": "afc50744e1d2cd13c3062b6160cd21a0b25870da81270b75b0a35940ca33b23b",
|
||||||
"size": 190
|
"size": 223
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minimum_updater_version": "0.9.9",
|
"minimum_updater_version": "0.5.0",
|
||||||
"notes_url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/tag/v0.9.9",
|
"notes_url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/tag/v0.9.11",
|
||||||
"published_at": "2026-09-09T20:35:13Z",
|
"published_at": "2026-09-09T21:12:47Z",
|
||||||
"release": {
|
"release": {
|
||||||
"notes_markdown": "# PristonTale EU Launcher 0.9.9\n\n## Changes\n\n- Added better support for kubuntu and fixed some issues with telemetry. (`290d1a5`)\n- Updated diagnostic message. (`6e62191`)\n- Updated the update system to support multi channels (stable / pre-release). (`5770969`)\n- Released a new version, 0.9.8. (`2a53a59`)\n- Fixed more issues with Cinnamon window resizing and popups. (`76bef94`)\n- Fixed issues with telemetry. (`1a120bb`)\n- Released new stable version 0.9.7. (`108ea94`)\n- Added a fix for X11 / Cinnamon window popups and maximize button not visible. (`1cfe862`)\n- Added telemetry system to get information about issues. (`f06fc2e`)\n- Upload files to \"updates\" (`a1ff479`)\n- Delete updates/stable.json.sig (`6eea3b2`)\n- Update updates/stable.json (`ee9bb06`)\n- Fixed issues with gamescope not properly launching. (`bea9d6f`)\n\n---\n\nVersion: `0.9.9` \nChannel: `stable` \nTag: `v0.9.9` \nSource commit: `290d1a5383219aeef0640ec8010d50cb6c1b2a00`\n",
|
"notes_markdown": "# PristonTale EU Launcher 0.9.11\n\nFixes the update window layout so release notes no longer cover version history or controls.\n\n---\n\nVersion: `0.9.11` \nChannel: `stable` \nTag: `v0.9.11` \nSource commit: `a362b0bb8e2bf74db9075c5f58db5236b1dc98f6`\n",
|
||||||
"release_notes_url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/tag/v0.9.9",
|
"release_notes_url": "https://git.m4ko.net/m4ko/pristontale-eu-linux/releases/tag/v0.9.11",
|
||||||
"summary": "Added better support for kubuntu and fixed some issues with telemetry. (`290d1a5`)",
|
"summary": "Fixes the update window layout so release notes no longer cover version history or controls.",
|
||||||
"title": "PristonTale EU Launcher 0.9.9"
|
"title": "PristonTale EU Launcher 0.9.11"
|
||||||
},
|
},
|
||||||
"schema": 1,
|
"schema": 1,
|
||||||
"status": "active",
|
"status": "active",
|
||||||
"tag": "v0.9.9",
|
"tag": "v0.9.11",
|
||||||
"version": "0.9.9"
|
"version": "0.9.11"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user