a2qlinux 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. a2qlinux-0.2.0/.gitignore +32 -0
  2. a2qlinux-0.2.0/CHANGELOG.md +72 -0
  3. a2qlinux-0.2.0/LICENSE +21 -0
  4. a2qlinux-0.2.0/PKG-INFO +142 -0
  5. a2qlinux-0.2.0/README.md +100 -0
  6. a2qlinux-0.2.0/a2qlinux/__init__.py +6 -0
  7. a2qlinux-0.2.0/a2qlinux/_version.py +24 -0
  8. a2qlinux-0.2.0/a2qlinux/bin/questlog_ctl.exe +0 -0
  9. a2qlinux-0.2.0/a2qlinux/bin/wpcap.dll +0 -0
  10. a2qlinux-0.2.0/a2qlinux/config.py +148 -0
  11. a2qlinux-0.2.0/a2qlinux/desktop.py +138 -0
  12. a2qlinux-0.2.0/a2qlinux/launcher.py +1089 -0
  13. a2qlinux-0.2.0/a2qlinux/pcap_bridge.py +205 -0
  14. a2qlinux-0.2.0/a2qlinux/setup_desktop.py +403 -0
  15. a2qlinux-0.2.0/a2qlinux/steam.py +101 -0
  16. a2qlinux-0.2.0/a2qlinux/tray.py +66 -0
  17. a2qlinux-0.2.0/a2qlinux/update.py +411 -0
  18. a2qlinux-0.2.0/bridge/build.sh +26 -0
  19. a2qlinux-0.2.0/bridge/questlog_ctl.c +188 -0
  20. a2qlinux-0.2.0/bridge/tests/bridge_client_test.c +70 -0
  21. a2qlinux-0.2.0/bridge/tests/zorder_guard_test.c +161 -0
  22. a2qlinux-0.2.0/bridge/wpcap_bridge.c +516 -0
  23. a2qlinux-0.2.0/docs/ARCHITECTURE.md +985 -0
  24. a2qlinux-0.2.0/docs/INSTALL.md +298 -0
  25. a2qlinux-0.2.0/docs/README.md +12 -0
  26. a2qlinux-0.2.0/docs/RELEASE.md +155 -0
  27. a2qlinux-0.2.0/docs/TROUBLESHOOTING.md +73 -0
  28. a2qlinux-0.2.0/docs/UPDATING.md +116 -0
  29. a2qlinux-0.2.0/docs/USING.md +126 -0
  30. a2qlinux-0.2.0/pyproject.toml +69 -0
  31. a2qlinux-0.2.0/tests/__init__.py +0 -0
  32. a2qlinux-0.2.0/tests/test_config.py +82 -0
  33. a2qlinux-0.2.0/tests/test_desktop.py +89 -0
  34. a2qlinux-0.2.0/tests/test_launcher.py +325 -0
  35. a2qlinux-0.2.0/tests/test_pcap_bridge.py +120 -0
  36. a2qlinux-0.2.0/tests/test_replay_stream.py +163 -0
  37. a2qlinux-0.2.0/tests/test_setup_desktop.py +164 -0
  38. a2qlinux-0.2.0/tests/test_steam.py +49 -0
  39. a2qlinux-0.2.0/tests/test_update.py +265 -0
  40. a2qlinux-0.2.0/tools/__init__.py +0 -0
  41. a2qlinux-0.2.0/tools/pcap2questlog.py +32 -0
  42. a2qlinux-0.2.0/tools/replay_stream.py +249 -0
  43. a2qlinux-0.2.0/tools/tcp_owner_probe.c +56 -0
@@ -0,0 +1,32 @@
1
+ # Built by bridge/build.sh (Windows parts, test programs, tools)
2
+ *.exe
3
+ *.dll
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.pyc
8
+
9
+ # IDE
10
+ .idea/
11
+ .vscode/
12
+
13
+ # Claude Code local config (skills, local settings) — kept per-machine, not committed
14
+ .claude/
15
+
16
+ # Private notes (Polish): other meters, game rules, network diagnostics of this
17
+ # machine. Kept locally, never committed.
18
+ notes/
19
+
20
+ # Editor / OS
21
+ *.bak
22
+ *.orig
23
+ .DS_Store
24
+
25
+ # Runtime
26
+ *.log
27
+
28
+ # Packaging
29
+ a2qlinux/_version.py
30
+ dist/
31
+ build/
32
+ *.egg-info/
@@ -0,0 +1,72 @@
1
+ # Changelog
2
+
3
+ What changed for players, release by release. Technical details are in
4
+ `docs/ARCHITECTURE.md`.
5
+
6
+ ## [0.2.0] — 2026-11-05
7
+
8
+ ### Changed
9
+ - A2Qlinux is now installed and updated from PyPI: `pipx install a2qlinux`,
10
+ then `pipx upgrade a2qlinux` for new versions. After updating from 0.1.0,
11
+ which was installed from a downloaded file, switch over once: quit
12
+ Questlog, then run `pipx uninstall a2qlinux && pipx install a2qlinux`. The
13
+ menu entry, the Steam launch option and the settings stay as they are.
14
+ - Play in Steam (with the launch option) starts Questlog first and the game
15
+ a few seconds later, once Questlog runs, instead of the other way round.
16
+ That is what lets the game end without disturbing Questlog.
17
+ - Quit Questlog ends it at once when no game data is waiting to be saved
18
+ (without the game, or a while after closing it); while playing, it still
19
+ waits until the last data is saved, at most about 10 seconds.
20
+ - The status window opens in the terminal the desktop has (GNOME Terminal,
21
+ Ptyxis, the Xfce or MATE terminal, Debian's default terminal or xterm),
22
+ not only in Konsole. Without any, a notification says which to install.
23
+
24
+ ### Added
25
+ - `a2qlinux-setup` installs Questlog when it is not there yet: it downloads
26
+ the newest version from Questlog's authors, checks it and puts it in
27
+ place. Installing Questlog by hand is no longer needed.
28
+ - `a2qlinux-setup` checks everything A2Qlinux needs, including that
29
+ capturing the game's traffic is allowed and that the tray icon can run on
30
+ the desktop, and for anything missing prints the exact command for the
31
+ distribution in use.
32
+ - A settings file, `~/.config/a2qlinux/config.toml`, created by
33
+ `a2qlinux-setup`: Questlog's folder, what happens after the game (Questlog
34
+ stays or closes, and after how long it closes), and automatic updates.
35
+ Mistakes in it are reported with their line, and the default is used
36
+ meanwhile.
37
+ - The install guide covers Debian, Ubuntu, Fedora and openSUSE besides
38
+ Arch, in numbered steps with one package command per distribution, and
39
+ says what A2Qlinux needs from the desktop and from Steam.
40
+
41
+ ### Fixed
42
+ - Steam no longer shows AION 2 as running after the game is closed while
43
+ Questlog stays open: a moment after the game ends, Steam shows Play again,
44
+ and Questlog keeps running untouched. Only when the game was started
45
+ before Questlog does Questlog restart, about 10 seconds after the game, as
46
+ it was (window open or only in the tray).
47
+ - AION 2's Proton environment is found wherever Steam is installed, not
48
+ only in its default folder. A Steam from Flatpak, which A2Qlinux cannot
49
+ work with, is named as the reason.
50
+
51
+ ## [0.1.0] — 2026-10-18
52
+
53
+ First release.
54
+
55
+ ### Added
56
+ - Questlog Desktop runs next to AION 2 on Linux, inside the game's Proton
57
+ environment, with live game traffic: the damage meter, boss HP and alerts
58
+ work as on Windows.
59
+ - Questlog can be started before, after or together with the game; with the
60
+ Steam launch option it starts with the game, and pressing Play while
61
+ Questlog is open lets the game join it.
62
+ - Clicks in the game stay in the game while Questlog's window is open behind
63
+ it.
64
+ - A tray icon with Open and Quit that works every time, in place of
65
+ Questlog's own, whose menu opens only once under Proton.
66
+ - Quitting Questlog waits until it has saved its data, without touching the
67
+ game; opening it again within those seconds keeps it running.
68
+ - Questlog is kept up to date: new versions are downloaded in the background
69
+ (never while the game runs), checked, installed at the next start, and
70
+ rolled back if they do not start.
71
+ - Installation with pipx; `a2qlinux-setup` creates the "Questlog (AION 2)"
72
+ menu entry, which keeps itself pointing at the installed program.
a2qlinux-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 raman78
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,142 @@
1
+ Metadata-Version: 2.5
2
+ Name: a2qlinux
3
+ Version: 0.2.0
4
+ Summary: Questlog Desktop (AION 2 damage meter) on Linux under Proton, with live game traffic.
5
+ Project-URL: homepage, https://github.com/raman78/A2Qlinux
6
+ Project-URL: repository, https://github.com/raman78/A2Qlinux
7
+ Project-URL: issues, https://github.com/raman78/A2Qlinux/issues
8
+ Author: raman78
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 raman78
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: aion2,dps-meter,linux,proton,questlog,wine
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Environment :: X11 Applications :: Qt
34
+ Classifier: Natural Language :: English
35
+ Classifier: Operating System :: POSIX :: Linux
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Topic :: Games/Entertainment
38
+ Requires-Python: >=3.11
39
+ Requires-Dist: pyqt6>=6.5
40
+ Requires-Dist: python-xlib>=0.33
41
+ Description-Content-Type: text/markdown
42
+
43
+ # A2Qlinux
44
+
45
+ Run [Questlog Desktop](https://questlog.gg/aion-2/en/app), the Windows-only
46
+ damage meter and overlay app for AION 2, on Linux next to the game under
47
+ Steam's Proton, with live game traffic.
48
+
49
+ Questlog reads the game's traffic through Npcap, a Windows driver that cannot
50
+ work under Wine/Proton. A2Qlinux captures the traffic on the Linux side with
51
+ `dumpcap` and hands it to Questlog through its own stand-in for Npcap's
52
+ `wpcap.dll`. Questlog runs inside the game's Proton prefix, in its normal
53
+ live-capture mode, with its overlays over the game. Its program files stay
54
+ as shipped; the only change A2Qlinux makes to Questlog's folder is removing
55
+ the configuration of Questlog's own updater, which cannot install under
56
+ Proton (A2Qlinux updates it instead).
57
+
58
+ It also handles what comes with sharing a Wine session with a fullscreen
59
+ game:
60
+
61
+ - starting Questlog before, after or together with the game (Steam launch
62
+ option), without blocking the game's launch;
63
+ - keeping clicks in the game while Questlog's window is open behind it;
64
+ - its own tray icon (Open / Quit) in place of Questlog's, whose menu opens
65
+ only once under Proton;
66
+ - quitting Questlog without losing its last data and without touching the
67
+ game or other programs in the prefix;
68
+ - updating Questlog: its own updater cannot install under Proton, so A2Qlinux
69
+ downloads new versions in the background (not while the game runs), checks
70
+ them against what it relies on, installs them at the next start and rolls
71
+ back if they do not start.
72
+
73
+ Status: in daily use on CachyOS, KDE Plasma 6 (Wayland), Proton 11
74
+ (`proton-cachyos-slr`), Questlog 0.1.37. Other distributions and desktops
75
+ are untested; what they need (Steam from the distribution or Valve, not
76
+ Flatpak; a system tray; Python 3.11 or newer; the packages per distribution)
77
+ is in [docs/INSTALL.md](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#what-you-need-before-you-start).
78
+
79
+ ## Quick start
80
+
81
+ The [installation guide](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md) walks through each step, with the commands
82
+ for Arch, Debian, Ubuntu, Fedora and openSUSE. In short:
83
+
84
+ 1. Install the packages A2Qlinux uses — see
85
+ [Installing the packages](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#installing-the-packages).
86
+ 2. Join the `wireshark` group and log in again — see
87
+ [Allowing capture](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#allowing-capture).
88
+ 3. `pipx install a2qlinux`, `pipx ensurepath`, open a new terminal, then
89
+ `a2qlinux-setup --desktop-shortcut`. It installs Questlog, checks
90
+ everything else and prints the command for anything still missing — see
91
+ [Installing A2Qlinux and Questlog](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#installing-a2qlinux-and-questlog).
92
+ 4. Start **Questlog (AION 2)** from the menu, or set the Steam launch option
93
+ that `a2qlinux-setup` prints.
94
+
95
+ ## Documentation
96
+
97
+ - [docs/INSTALL.md](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md) — requirements, installing, removal.
98
+ - [docs/USING.md](https://github.com/raman78/A2Qlinux/blob/main/docs/USING.md) — starting, tray icon, playing.
99
+ - [docs/UPDATING.md](https://github.com/raman78/A2Qlinux/blob/main/docs/UPDATING.md) — Questlog updates, installing Questlog
100
+ by hand, and updating A2Qlinux itself (`pipx upgrade a2qlinux`).
101
+ - [docs/TROUBLESHOOTING.md](https://github.com/raman78/A2Qlinux/blob/main/docs/TROUBLESHOOTING.md) — problems, FAQ.
102
+ - [docs/ARCHITECTURE.md](https://github.com/raman78/A2Qlinux/blob/main/docs/ARCHITECTURE.md) — how it works and why, failure
103
+ modes, tests, what a Questlog update can break.
104
+
105
+ ## Repository layout
106
+
107
+ | Path | What |
108
+ |---|---|
109
+ | `a2qlinux/launcher.py` | launcher (`a2qlinux-run`): capture, bridge, starting/quitting Questlog, tray |
110
+ | `a2qlinux/pcap_bridge.py` | TCP server that feeds captured packets to the DLL |
111
+ | `a2qlinux/desktop.py` | `a2qlinux`: menu-entry entry point; one launcher at a time |
112
+ | `a2qlinux/tray.py` | tray icon (PyQt6) |
113
+ | `a2qlinux/config.py` | settings from `~/.config/a2qlinux/config.toml` |
114
+ | `a2qlinux/update.py` | installing Questlog, and background Questlog updates: download, verify, check, install, roll back |
115
+ | `a2qlinux/steam.py` | `a2qlinux-steam`: Steam launch-option wrapper |
116
+ | `a2qlinux/setup_desktop.py` | `a2qlinux-setup`: dependency and capture checks with install commands, Questlog installation, menu entry, icon |
117
+ | `a2qlinux/bin/` | the built Windows parts (shipped in the package, not in git) |
118
+ | `bridge/` | Windows parts in C: `wpcap.dll` stand-in, `questlog_ctl.exe`, their tests; `build.sh` |
119
+ | `tests/` | Python tests: `python3 -m unittest` |
120
+ | `tools/` | diagnostics: replay-file tools, TCP-owner probe |
121
+
122
+ The Windows parts are built with `clang` against the installed Wine's headers
123
+ (`bridge/build.sh`) — by the release workflow for the packages, by hand in a
124
+ source checkout; built files are not kept in the repository. Releasing:
125
+ [docs/RELEASE.md](https://github.com/raman78/A2Qlinux/blob/main/docs/RELEASE.md).
126
+
127
+ ## Not affiliated
128
+
129
+ A2Qlinux is an independent project, not made or endorsed by Questlog's
130
+ authors or by AION 2's publisher. It contains no Questlog code or assets:
131
+ Questlog is downloaded from its authors, and its icon is taken from your own
132
+ installation. Questlog and its name belong to its authors (questlog.gg).
133
+
134
+ Whether third-party meters are allowed is for the game's publisher, NCSOFT,
135
+ to decide. It has not said so either way, and its rules forbid
136
+ "unauthorized programs" in general terms. Using any third-party meter,
137
+ under Windows or through A2Qlinux, is at your own risk; check the
138
+ publisher's current rules.
139
+
140
+ ## License
141
+
142
+ MIT — see [LICENSE](https://github.com/raman78/A2Qlinux/blob/main/LICENSE).
@@ -0,0 +1,100 @@
1
+ # A2Qlinux
2
+
3
+ Run [Questlog Desktop](https://questlog.gg/aion-2/en/app), the Windows-only
4
+ damage meter and overlay app for AION 2, on Linux next to the game under
5
+ Steam's Proton, with live game traffic.
6
+
7
+ Questlog reads the game's traffic through Npcap, a Windows driver that cannot
8
+ work under Wine/Proton. A2Qlinux captures the traffic on the Linux side with
9
+ `dumpcap` and hands it to Questlog through its own stand-in for Npcap's
10
+ `wpcap.dll`. Questlog runs inside the game's Proton prefix, in its normal
11
+ live-capture mode, with its overlays over the game. Its program files stay
12
+ as shipped; the only change A2Qlinux makes to Questlog's folder is removing
13
+ the configuration of Questlog's own updater, which cannot install under
14
+ Proton (A2Qlinux updates it instead).
15
+
16
+ It also handles what comes with sharing a Wine session with a fullscreen
17
+ game:
18
+
19
+ - starting Questlog before, after or together with the game (Steam launch
20
+ option), without blocking the game's launch;
21
+ - keeping clicks in the game while Questlog's window is open behind it;
22
+ - its own tray icon (Open / Quit) in place of Questlog's, whose menu opens
23
+ only once under Proton;
24
+ - quitting Questlog without losing its last data and without touching the
25
+ game or other programs in the prefix;
26
+ - updating Questlog: its own updater cannot install under Proton, so A2Qlinux
27
+ downloads new versions in the background (not while the game runs), checks
28
+ them against what it relies on, installs them at the next start and rolls
29
+ back if they do not start.
30
+
31
+ Status: in daily use on CachyOS, KDE Plasma 6 (Wayland), Proton 11
32
+ (`proton-cachyos-slr`), Questlog 0.1.37. Other distributions and desktops
33
+ are untested; what they need (Steam from the distribution or Valve, not
34
+ Flatpak; a system tray; Python 3.11 or newer; the packages per distribution)
35
+ is in [docs/INSTALL.md](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#what-you-need-before-you-start).
36
+
37
+ ## Quick start
38
+
39
+ The [installation guide](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md) walks through each step, with the commands
40
+ for Arch, Debian, Ubuntu, Fedora and openSUSE. In short:
41
+
42
+ 1. Install the packages A2Qlinux uses — see
43
+ [Installing the packages](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#installing-the-packages).
44
+ 2. Join the `wireshark` group and log in again — see
45
+ [Allowing capture](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#allowing-capture).
46
+ 3. `pipx install a2qlinux`, `pipx ensurepath`, open a new terminal, then
47
+ `a2qlinux-setup --desktop-shortcut`. It installs Questlog, checks
48
+ everything else and prints the command for anything still missing — see
49
+ [Installing A2Qlinux and Questlog](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md#installing-a2qlinux-and-questlog).
50
+ 4. Start **Questlog (AION 2)** from the menu, or set the Steam launch option
51
+ that `a2qlinux-setup` prints.
52
+
53
+ ## Documentation
54
+
55
+ - [docs/INSTALL.md](https://github.com/raman78/A2Qlinux/blob/main/docs/INSTALL.md) — requirements, installing, removal.
56
+ - [docs/USING.md](https://github.com/raman78/A2Qlinux/blob/main/docs/USING.md) — starting, tray icon, playing.
57
+ - [docs/UPDATING.md](https://github.com/raman78/A2Qlinux/blob/main/docs/UPDATING.md) — Questlog updates, installing Questlog
58
+ by hand, and updating A2Qlinux itself (`pipx upgrade a2qlinux`).
59
+ - [docs/TROUBLESHOOTING.md](https://github.com/raman78/A2Qlinux/blob/main/docs/TROUBLESHOOTING.md) — problems, FAQ.
60
+ - [docs/ARCHITECTURE.md](https://github.com/raman78/A2Qlinux/blob/main/docs/ARCHITECTURE.md) — how it works and why, failure
61
+ modes, tests, what a Questlog update can break.
62
+
63
+ ## Repository layout
64
+
65
+ | Path | What |
66
+ |---|---|
67
+ | `a2qlinux/launcher.py` | launcher (`a2qlinux-run`): capture, bridge, starting/quitting Questlog, tray |
68
+ | `a2qlinux/pcap_bridge.py` | TCP server that feeds captured packets to the DLL |
69
+ | `a2qlinux/desktop.py` | `a2qlinux`: menu-entry entry point; one launcher at a time |
70
+ | `a2qlinux/tray.py` | tray icon (PyQt6) |
71
+ | `a2qlinux/config.py` | settings from `~/.config/a2qlinux/config.toml` |
72
+ | `a2qlinux/update.py` | installing Questlog, and background Questlog updates: download, verify, check, install, roll back |
73
+ | `a2qlinux/steam.py` | `a2qlinux-steam`: Steam launch-option wrapper |
74
+ | `a2qlinux/setup_desktop.py` | `a2qlinux-setup`: dependency and capture checks with install commands, Questlog installation, menu entry, icon |
75
+ | `a2qlinux/bin/` | the built Windows parts (shipped in the package, not in git) |
76
+ | `bridge/` | Windows parts in C: `wpcap.dll` stand-in, `questlog_ctl.exe`, their tests; `build.sh` |
77
+ | `tests/` | Python tests: `python3 -m unittest` |
78
+ | `tools/` | diagnostics: replay-file tools, TCP-owner probe |
79
+
80
+ The Windows parts are built with `clang` against the installed Wine's headers
81
+ (`bridge/build.sh`) — by the release workflow for the packages, by hand in a
82
+ source checkout; built files are not kept in the repository. Releasing:
83
+ [docs/RELEASE.md](https://github.com/raman78/A2Qlinux/blob/main/docs/RELEASE.md).
84
+
85
+ ## Not affiliated
86
+
87
+ A2Qlinux is an independent project, not made or endorsed by Questlog's
88
+ authors or by AION 2's publisher. It contains no Questlog code or assets:
89
+ Questlog is downloaded from its authors, and its icon is taken from your own
90
+ installation. Questlog and its name belong to its authors (questlog.gg).
91
+
92
+ Whether third-party meters are allowed is for the game's publisher, NCSOFT,
93
+ to decide. It has not said so either way, and its rules forbid
94
+ "unauthorized programs" in general terms. Using any third-party meter,
95
+ under Windows or through A2Qlinux, is at your own risk; check the
96
+ publisher's current rules.
97
+
98
+ ## License
99
+
100
+ MIT — see [LICENSE](https://github.com/raman78/A2Qlinux/blob/main/LICENSE).
@@ -0,0 +1,6 @@
1
+ """A2Qlinux: Questlog Desktop for AION 2 on Linux under Proton, with live game traffic."""
2
+
3
+ try:
4
+ from ._version import __version__
5
+ except ImportError: # a source checkout that was never built or installed
6
+ __version__ = "0+unknown"
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.2.0'
22
+ __version_tuple__ = version_tuple = (0, 2, 0)
23
+
24
+ __commit_id__ = commit_id = None
Binary file
@@ -0,0 +1,148 @@
1
+ """User settings: ~/.config/a2qlinux/config.toml.
2
+
3
+ Which value wins, highest first:
4
+ 1. a command-line option (--interface, --close-with-game, --no-auto-update, --exe)
5
+ 2. an environment variable (QUESTLOG_DIR)
6
+ 3. this file
7
+ 4. the default in SETTINGS
8
+
9
+ Only behaviour a user may want to change is here. Values that follow from
10
+ how Questlog or Wine work (how long Questlog needs to save, wait limits) are
11
+ named constants in the code, documented in docs/ARCHITECTURE.md.
12
+
13
+ Nothing wrong in the file is ignored silently: load() returns each problem
14
+ (file, line, what is wrong) next to the settings, using the default for that
15
+ setting; the launcher shows them in its window and as a notification.
16
+ """
17
+
18
+ from dataclasses import dataclass
19
+ import os
20
+ from pathlib import Path
21
+ import re
22
+ import tomllib
23
+
24
+ CONFIG_PATH = Path(os.environ.get("XDG_CONFIG_HOME") or Path.home() / ".config") / "a2qlinux" / "config.toml"
25
+ # Closing Questlog after the game does not wait for it to save, so the delay
26
+ # must cover the time Questlog takes to save game data (see launcher.SAVE_WAIT).
27
+ MIN_AFTER_GAME_DELAY = 10.5
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class Setting:
32
+ default: object
33
+ kind: type
34
+ help: str
35
+ choices: tuple = ()
36
+ minimum: float = None
37
+
38
+
39
+ SETTINGS = {
40
+ "questlog_dir": Setting("~/Games/Questlog", str,
41
+ "Folder with Questlog.exe (the QUESTLOG_DIR environment variable overrides it)."),
42
+ "interface": Setting("", str,
43
+ "Network interface carrying the game's traffic; empty: the only one besides lo."),
44
+ "after_game": Setting("keep", str,
45
+ '"keep": Questlog stays open after the game, and Steam sees the game as closed; '
46
+ '"close": Questlog closes with the game.',
47
+ choices=("keep", "close")),
48
+ "after_game_delay": Setting(15, (int, float),
49
+ 'With after_game = "close": seconds after the game exits before Questlog closes '
50
+ f"(a game restarted sooner keeps it open). At least {MIN_AFTER_GAME_DELAY:g}.",
51
+ minimum=MIN_AFTER_GAME_DELAY),
52
+ "auto_update": Setting(True, bool, "Download new Questlog versions in the background and install them "
53
+ "at the next start."),
54
+ "update_check_hours": Setting(6, (int, float), "Hours between checks for a new Questlog.", minimum=0.25),
55
+ }
56
+
57
+
58
+ @dataclass(frozen=True)
59
+ class Settings:
60
+ questlog_dir: Path
61
+ interface: str
62
+ after_game: str
63
+ after_game_delay: float
64
+ auto_update: bool
65
+ update_check_hours: float
66
+
67
+
68
+ def _line_of(text, key):
69
+ for number, line in enumerate(text.splitlines(), 1):
70
+ if re.match(rf"\s*{re.escape(key)}\s*=", line):
71
+ return number
72
+ return None
73
+
74
+
75
+ def load(path=CONFIG_PATH):
76
+ """(Settings, problems). A missing file is no problem: all defaults."""
77
+ values = {name: spec.default for name, spec in SETTINGS.items()}
78
+ problems = []
79
+ path = Path(path)
80
+ try:
81
+ text = path.read_text()
82
+ data = tomllib.loads(text)
83
+ except FileNotFoundError:
84
+ text, data = "", {}
85
+ except (OSError, UnicodeDecodeError) as error:
86
+ text, data = "", {}
87
+ problems.append(f"{path}: cannot be read ({error}); using the defaults.")
88
+ except tomllib.TOMLDecodeError as error:
89
+ text, data = "", {}
90
+ problems.append(f"{path}: not valid TOML ({error}); using the defaults.")
91
+ for name, value in data.items():
92
+ where = f"{path}, line {_line_of(text, name) or '?'}"
93
+ spec = SETTINGS.get(name)
94
+ if spec is None:
95
+ problems.append(f"{where}: unknown setting '{name}' (known: {', '.join(SETTINGS)}); ignored.")
96
+ continue
97
+ wrong_type = not isinstance(value, spec.kind) or (spec.kind is not bool and isinstance(value, bool))
98
+ if wrong_type:
99
+ problems.append(f"{where}: '{name}' must be {_kind_name(spec.kind)}, not {value!r}; "
100
+ f"using {spec.default!r}.")
101
+ continue
102
+ if spec.choices and value not in spec.choices:
103
+ problems.append(f"{where}: '{name}' must be one of {', '.join(map(repr, spec.choices))}, "
104
+ f"not {value!r}; using {spec.default!r}.")
105
+ continue
106
+ if spec.minimum is not None and value < spec.minimum:
107
+ problems.append(f"{where}: '{name}' must be at least {spec.minimum:g}, not {value!r}; "
108
+ f"using {spec.default!r}.")
109
+ continue
110
+ values[name] = value
111
+ env_dir = os.environ.get("QUESTLOG_DIR")
112
+ values["questlog_dir"] = Path(env_dir or values["questlog_dir"]).expanduser()
113
+ values["after_game_delay"] = float(values["after_game_delay"])
114
+ values["update_check_hours"] = float(values["update_check_hours"])
115
+ return Settings(**values), problems
116
+
117
+
118
+ def _kind_name(kind):
119
+ if kind is bool:
120
+ return "true or false"
121
+ if kind is str:
122
+ return "a quoted text"
123
+ return "a number"
124
+
125
+
126
+ def questlog_dir():
127
+ """Where Questlog is, for the parts that need only that (the menu entry, the Steam wrapper)."""
128
+ return load()[0].questlog_dir
129
+
130
+
131
+ def template(questlog_dir=None):
132
+ """The file a2qlinux-setup writes when there is none: every setting, at its default, explained."""
133
+ lines = ["# A2Qlinux settings. Delete a line to get its default back.",
134
+ "# A command-line option or the QUESTLOG_DIR variable overrides the value here.", ""]
135
+ for name, spec in SETTINGS.items():
136
+ value = str(questlog_dir) if name == "questlog_dir" and questlog_dir else spec.default
137
+ lines.append(f"# {spec.help}")
138
+ lines.append(f"{name} = {_toml(value)}")
139
+ lines.append("")
140
+ return "\n".join(lines)
141
+
142
+
143
+ def _toml(value):
144
+ if isinstance(value, bool):
145
+ return "true" if value else "false"
146
+ if isinstance(value, str):
147
+ return '"' + value.replace("\\", "\\\\").replace('"', '\\"') + '"'
148
+ return repr(value)