a2qlinux 0.2.0__tar.gz → 0.2.1__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.
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/CHANGELOG.md +13 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/PKG-INFO +5 -3
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/README.md +4 -2
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/_version.py +2 -2
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/bin/questlog_ctl.exe +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/bin/wpcap.dll +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/config.py +20 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/setup_desktop.py +18 -12
- a2qlinux-0.2.1/bridge/build.sh +81 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/docs/ARCHITECTURE.md +36 -5
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/docs/INSTALL.md +69 -17
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_config.py +34 -0
- a2qlinux-0.2.0/bridge/build.sh +0 -26
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/.gitignore +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/LICENSE +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/__init__.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/desktop.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/launcher.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/pcap_bridge.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/steam.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/tray.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/a2qlinux/update.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/bridge/questlog_ctl.c +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/bridge/tests/bridge_client_test.c +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/bridge/tests/zorder_guard_test.c +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/bridge/wpcap_bridge.c +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/docs/README.md +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/docs/RELEASE.md +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/docs/TROUBLESHOOTING.md +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/docs/UPDATING.md +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/docs/USING.md +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/pyproject.toml +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/__init__.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_desktop.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_launcher.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_pcap_bridge.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_replay_stream.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_setup_desktop.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_steam.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tests/test_update.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tools/__init__.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tools/pcap2questlog.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tools/replay_stream.py +0 -0
- {a2qlinux-0.2.0 → a2qlinux-0.2.1}/tools/tcp_owner_probe.c +0 -0
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
What changed for players, release by release. Technical details are in
|
|
4
4
|
`docs/ARCHITECTURE.md`.
|
|
5
5
|
|
|
6
|
+
## [0.2.1] — 2026-11-05
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- `a2qlinux-setup --questlog-dir <folder>` now always takes effect: the
|
|
10
|
+
folder is written into the settings file even when that file already
|
|
11
|
+
exists, and the other settings in it stay as they were.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Installing from the source code is one command, `install-from-source.sh`,
|
|
15
|
+
which builds, installs and sets up. The build looks for Wine's files where
|
|
16
|
+
the distributions in the install guide keep them, and names missing build
|
|
17
|
+
tools with the command that installs them.
|
|
18
|
+
|
|
6
19
|
## [0.2.0] — 2026-11-05
|
|
7
20
|
|
|
8
21
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: a2qlinux
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Questlog Desktop (AION 2 damage meter) on Linux under Proton, with live game traffic.
|
|
5
5
|
Project-URL: homepage, https://github.com/raman78/A2Qlinux
|
|
6
6
|
Project-URL: repository, https://github.com/raman78/A2Qlinux
|
|
@@ -116,12 +116,14 @@ for Arch, Debian, Ubuntu, Fedora and openSUSE. In short:
|
|
|
116
116
|
| `a2qlinux/setup_desktop.py` | `a2qlinux-setup`: dependency and capture checks with install commands, Questlog installation, menu entry, icon |
|
|
117
117
|
| `a2qlinux/bin/` | the built Windows parts (shipped in the package, not in git) |
|
|
118
118
|
| `bridge/` | Windows parts in C: `wpcap.dll` stand-in, `questlog_ctl.exe`, their tests; `build.sh` |
|
|
119
|
+
| `install-from-source.sh` | installs this checkout for development: build, editable pipx install, setup |
|
|
119
120
|
| `tests/` | Python tests: `python3 -m unittest` |
|
|
120
121
|
| `tools/` | diagnostics: replay-file tools, TCP-owner probe |
|
|
121
122
|
|
|
122
123
|
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
|
|
124
|
-
source checkout; built files are not kept in
|
|
124
|
+
(`bridge/build.sh`) — by the release workflow for the packages, by
|
|
125
|
+
`install-from-source.sh` in a source checkout; built files are not kept in
|
|
126
|
+
the repository. Releasing:
|
|
125
127
|
[docs/RELEASE.md](https://github.com/raman78/A2Qlinux/blob/main/docs/RELEASE.md).
|
|
126
128
|
|
|
127
129
|
## Not affiliated
|
|
@@ -74,12 +74,14 @@ for Arch, Debian, Ubuntu, Fedora and openSUSE. In short:
|
|
|
74
74
|
| `a2qlinux/setup_desktop.py` | `a2qlinux-setup`: dependency and capture checks with install commands, Questlog installation, menu entry, icon |
|
|
75
75
|
| `a2qlinux/bin/` | the built Windows parts (shipped in the package, not in git) |
|
|
76
76
|
| `bridge/` | Windows parts in C: `wpcap.dll` stand-in, `questlog_ctl.exe`, their tests; `build.sh` |
|
|
77
|
+
| `install-from-source.sh` | installs this checkout for development: build, editable pipx install, setup |
|
|
77
78
|
| `tests/` | Python tests: `python3 -m unittest` |
|
|
78
79
|
| `tools/` | diagnostics: replay-file tools, TCP-owner probe |
|
|
79
80
|
|
|
80
81
|
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
|
|
82
|
-
source checkout; built files are not kept in
|
|
82
|
+
(`bridge/build.sh`) — by the release workflow for the packages, by
|
|
83
|
+
`install-from-source.sh` in a source checkout; built files are not kept in
|
|
84
|
+
the repository. Releasing:
|
|
83
85
|
[docs/RELEASE.md](https://github.com/raman78/A2Qlinux/blob/main/docs/RELEASE.md).
|
|
84
86
|
|
|
85
87
|
## Not affiliated
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.1'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 1)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
Binary file
|
|
Binary file
|
|
@@ -140,6 +140,26 @@ def template(questlog_dir=None):
|
|
|
140
140
|
return "\n".join(lines)
|
|
141
141
|
|
|
142
142
|
|
|
143
|
+
def set_questlog_dir(questlog_dir, path=CONFIG_PATH):
|
|
144
|
+
"""Write `questlog_dir` into the settings file, for a2qlinux-setup --questlog-dir.
|
|
145
|
+
|
|
146
|
+
A missing file is created from template(); in an existing one only the
|
|
147
|
+
questlog_dir line changes (or is added), so the user's other settings and
|
|
148
|
+
comments stay as they are.
|
|
149
|
+
"""
|
|
150
|
+
path = Path(path)
|
|
151
|
+
line = f"questlog_dir = {_toml(str(questlog_dir))}"
|
|
152
|
+
if not path.exists():
|
|
153
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
154
|
+
path.write_text(template(questlog_dir))
|
|
155
|
+
return
|
|
156
|
+
text = path.read_text()
|
|
157
|
+
new, count = re.subn(r"(?m)^[ \t]*questlog_dir[ \t]*=.*$", lambda _: line, text, count=1)
|
|
158
|
+
if not count:
|
|
159
|
+
new = text + ("" if text.endswith("\n") or not text else "\n") + line + "\n"
|
|
160
|
+
path.write_text(new)
|
|
161
|
+
|
|
162
|
+
|
|
143
163
|
def _toml(value):
|
|
144
164
|
if isinstance(value, bool):
|
|
145
165
|
return "true" if value else "false"
|
|
@@ -316,22 +316,28 @@ def main():
|
|
|
316
316
|
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
317
317
|
parser.add_argument("--questlog-dir", type=Path,
|
|
318
318
|
default=None,
|
|
319
|
-
help=f"folder
|
|
320
|
-
"written into
|
|
319
|
+
help=f"Questlog's folder (default: from {config.CONFIG_PATH}, else ~/Games/Questlog); "
|
|
320
|
+
"written into the settings file. Without Questlog.exe in it, the newest Questlog "
|
|
321
|
+
"is installed there")
|
|
321
322
|
parser.add_argument("--desktop-shortcut", action="store_true", help="also put the entry on the desktop")
|
|
322
323
|
args = parser.parse_args()
|
|
324
|
+
created = not config.CONFIG_PATH.exists()
|
|
325
|
+
if args.questlog_dir:
|
|
326
|
+
# Into the settings file, which every A2Qlinux command reads, so the
|
|
327
|
+
# folder used here is the one the launcher uses later.
|
|
328
|
+
config.set_questlog_dir(args.questlog_dir.expanduser().resolve())
|
|
329
|
+
elif created:
|
|
330
|
+
config.CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
331
|
+
config.CONFIG_PATH.write_text(config.template())
|
|
323
332
|
settings, config_problems = config.load()
|
|
324
|
-
questlog_dir =
|
|
333
|
+
questlog_dir = settings.questlog_dir.resolve()
|
|
325
334
|
problems = list(config_problems)
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
f"{config.CONFIG_PATH}; set questlog_dir there, which A2Qlinux reads")
|
|
333
|
-
else:
|
|
334
|
-
print(f"Settings: {config.CONFIG_PATH}")
|
|
335
|
+
print(f"Settings: {config.CONFIG_PATH}"
|
|
336
|
+
+ (" (every setting at its default, with comments)" if created else "")
|
|
337
|
+
+ (f"; questlog_dir = {questlog_dir}" if args.questlog_dir else ""))
|
|
338
|
+
if os.environ.get("QUESTLOG_DIR"):
|
|
339
|
+
print(f"Note: the QUESTLOG_DIR environment variable sets Questlog's folder to {questlog_dir}, over "
|
|
340
|
+
f"{config.CONFIG_PATH}; the menu entry and Steam do not see that variable.")
|
|
335
341
|
|
|
336
342
|
info = os_release()
|
|
337
343
|
missing, wanted = missing_packages()
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Build the Windows parts for x64 with clang and Wine's headers and import
|
|
3
|
+
# libraries; no MinGW toolchain is needed:
|
|
4
|
+
# a2qlinux/bin/wpcap.dll stand-in for Npcap's wpcap.dll, fed by the Linux side
|
|
5
|
+
# a2qlinux/bin/questlog_ctl.exe acts on a running Questlog from inside its Wine session
|
|
6
|
+
# bridge/tests/*.exe test programs for the two above
|
|
7
|
+
# tools/tcp_owner_probe.exe diagnostic: does Wine report TCP connection owners
|
|
8
|
+
# Rebuild after a Wine update.
|
|
9
|
+
#
|
|
10
|
+
# Wine's files are looked for where the distributions put them (their package
|
|
11
|
+
# file lists, docs/ARCHITECTURE.md §14); WINE_INCLUDE and WINE_LIB override that.
|
|
12
|
+
# Anything missing is reported with the command that installs it.
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
cd "$(dirname "$0")"
|
|
15
|
+
|
|
16
|
+
# Package names for building, per distribution family (/etc/os-release).
|
|
17
|
+
family=""
|
|
18
|
+
if [ -r /etc/os-release ]; then
|
|
19
|
+
ids=" $(. /etc/os-release; echo "${ID:-} ${ID_LIKE:-}") "
|
|
20
|
+
case "$ids" in
|
|
21
|
+
*" arch "*) family=arch ;;
|
|
22
|
+
*" ubuntu "*|*" debian "*) family=debian ;;
|
|
23
|
+
*" fedora "*) family=fedora ;;
|
|
24
|
+
*" suse "*|*" opensuse "*) family=suse ;;
|
|
25
|
+
esac
|
|
26
|
+
fi
|
|
27
|
+
case "$family" in
|
|
28
|
+
arch) install="sudo pacman -S --needed clang lld wine" ;;
|
|
29
|
+
debian) install="sudo apt install clang lld libwine-dev" ;;
|
|
30
|
+
fedora) install="sudo dnf install clang lld wine-devel" ;;
|
|
31
|
+
suse) install="sudo zypper install clang lld wine-devel" ;;
|
|
32
|
+
*) install="install clang, lld and Wine's development files (headers and import libraries)" ;;
|
|
33
|
+
esac
|
|
34
|
+
|
|
35
|
+
missing=()
|
|
36
|
+
command -v clang >/dev/null || missing+=("clang")
|
|
37
|
+
command -v ld.lld >/dev/null || missing+=("lld (ld.lld)")
|
|
38
|
+
|
|
39
|
+
# Include root: the folder holding msvcrt/ and windows/ (Arch, Fedora, openSUSE:
|
|
40
|
+
# /usr/include/wine; Debian, Ubuntu: /usr/include/wine/wine).
|
|
41
|
+
W="${WINE_INCLUDE:-}"
|
|
42
|
+
if [ -z "$W" ]; then
|
|
43
|
+
for candidate in /usr/include/wine /usr/include/wine/wine; do
|
|
44
|
+
if [ -f "$candidate/windows/windows.h" ] && [ -d "$candidate/msvcrt" ]; then W="$candidate"; break; fi
|
|
45
|
+
done
|
|
46
|
+
fi
|
|
47
|
+
[ -n "$W" ] && [ -f "$W/windows/windows.h" ] || missing+=("Wine's headers (windows/windows.h)")
|
|
48
|
+
|
|
49
|
+
# Import libraries for x86_64 Windows programs (Arch: /usr/lib/wine; openSUSE:
|
|
50
|
+
# /usr/lib64/wine; Debian, Ubuntu: /usr/lib/x86_64-linux-gnu/wine).
|
|
51
|
+
L="${WINE_LIB:-}"
|
|
52
|
+
if [ -z "$L" ]; then
|
|
53
|
+
for candidate in /usr/lib/wine/x86_64-windows /usr/lib64/wine/x86_64-windows \
|
|
54
|
+
/usr/lib/x86_64-linux-gnu/wine/x86_64-windows; do
|
|
55
|
+
if [ -f "$candidate/libkernel32.a" ]; then L="$candidate"; break; fi
|
|
56
|
+
done
|
|
57
|
+
fi
|
|
58
|
+
[ -n "$L" ] && [ -f "$L/libkernel32.a" ] || missing+=("Wine's x86_64 import libraries (x86_64-windows/libkernel32.a)")
|
|
59
|
+
|
|
60
|
+
if [ ${#missing[@]} -gt 0 ]; then
|
|
61
|
+
echo "bridge/build.sh: cannot build, missing: $(IFS=';'; echo "${missing[*]}" | sed 's/;/; /g')" >&2
|
|
62
|
+
echo " $install" >&2
|
|
63
|
+
echo " (Wine's files in other folders: set WINE_INCLUDE and WINE_LIB.)" >&2
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
echo "Wine's headers: $W; import libraries: $L"
|
|
67
|
+
|
|
68
|
+
mkdir -p ../a2qlinux/bin
|
|
69
|
+
CF=(--target=x86_64-w64-windows-gnu -fuse-ld=lld -nostdinc -isystem "$W/msvcrt" -isystem "$W/windows"
|
|
70
|
+
-isystem "$(clang -print-resource-dir)/include" -O2 -Wall -Wextra)
|
|
71
|
+
clang "${CF[@]}" -shared -o ../a2qlinux/bin/wpcap.dll wpcap_bridge.c -nostdlib -L"$L" -lucrtbase -lkernel32 -luser32 -lws2_32 \
|
|
72
|
+
-Wl,--entry=DllMain
|
|
73
|
+
clang "${CF[@]}" -o ../a2qlinux/bin/questlog_ctl.exe questlog_ctl.c -nostdlib -L"$L" -lucrtbase -lkernel32 -luser32 \
|
|
74
|
+
-lshell32 -Wl,--entry=start
|
|
75
|
+
clang "${CF[@]}" -o tests/bridge_client_test.exe tests/bridge_client_test.c -nostdlib -L"$L" -lucrtbase -lkernel32 \
|
|
76
|
+
-Wl,--entry=main
|
|
77
|
+
clang "${CF[@]}" -o tests/zorder_guard_test.exe tests/zorder_guard_test.c -nostdlib -L"$L" -lucrtbase -lkernel32 \
|
|
78
|
+
-luser32 -lshell32 -Wl,--entry=start
|
|
79
|
+
clang "${CF[@]}" -o ../tools/tcp_owner_probe.exe ../tools/tcp_owner_probe.c -nostdlib -L"$L" -lucrtbase \
|
|
80
|
+
-lkernel32 -liphlpapi -lws2_32 -Wl,--entry=main
|
|
81
|
+
echo "built: a2qlinux/bin/wpcap.dll, a2qlinux/bin/questlog_ctl.exe, bridge/tests/*.exe, tools/tcp_owner_probe.exe"
|
|
@@ -735,7 +735,8 @@ privileges a Wine process should not have. `dumpcap` gets them through the
|
|
|
735
735
|
`wireshark` group and its file capabilities, and runs as the normal user.
|
|
736
736
|
|
|
737
737
|
**The DLL built with clang against Wine's headers**, not MinGW: the build
|
|
738
|
-
needs only `clang`, `lld` and the installed Wine
|
|
738
|
+
needs only `clang`, `lld` and the installed Wine's development files
|
|
739
|
+
(`bridge/build.sh`, §14).
|
|
739
740
|
|
|
740
741
|
**Our tray instead of fixing the Wine one** — §6.2. **The guard instead of a
|
|
741
742
|
patched Proton** — §6.1. **Session end after a delay instead of an immediate
|
|
@@ -856,7 +857,15 @@ release.
|
|
|
856
857
|
`a2qlinux/config.py` reads `~/.config/a2qlinux/config.toml` (or under
|
|
857
858
|
`$XDG_CONFIG_HOME`) with the standard library's `tomllib`. `a2qlinux-setup`
|
|
858
859
|
writes it when missing (`config.template`), with every setting at its
|
|
859
|
-
default and a comment for each
|
|
860
|
+
default and a comment for each. It changes an existing file in one case
|
|
861
|
+
only: `a2qlinux-setup --questlog-dir` (`config.set_questlog_dir`) replaces
|
|
862
|
+
the `questlog_dir` line, or adds it, and leaves every other line and comment
|
|
863
|
+
as it was. The setup then reads the folder back from the file, like every
|
|
864
|
+
other command, so the folder it checks and installs Questlog into is the
|
|
865
|
+
one the launcher uses later. An earlier version only wrote the option into
|
|
866
|
+
a new file; with a file already there, the option was refused, and the
|
|
867
|
+
first-installation code would have installed into a folder the settings did
|
|
868
|
+
not name.
|
|
860
869
|
|
|
861
870
|
| Setting | Default | Replaces | Read by |
|
|
862
871
|
|---|---|---|---|
|
|
@@ -980,6 +989,28 @@ case reads as a missing group membership, not as a missing package.
|
|
|
980
989
|
`pipx install protontricks` provides the command (its wheel's entry
|
|
981
990
|
points). Debian's `wireshark-common` asks whether non-root users may
|
|
982
991
|
capture, with no as the default (its debconf template `install-setuid`);
|
|
983
|
-
`dpkg-reconfigure wireshark-common` changes the answer.
|
|
984
|
-
|
|
985
|
-
from
|
|
992
|
+
`dpkg-reconfigure wireshark-common` changes the answer.
|
|
993
|
+
|
|
994
|
+
**Building from source** (`bridge/build.sh`, `install-from-source.sh`).
|
|
995
|
+
The build needs `clang`, `ld.lld` and Wine's headers and x86_64 import
|
|
996
|
+
libraries. Where the distributions put the latter, from their package file
|
|
997
|
+
lists: headers under `/usr/include/wine` (Arch, Fedora, openSUSE) or
|
|
998
|
+
`/usr/include/wine/wine` (Debian, Ubuntu, package `libwine-dev`); import
|
|
999
|
+
libraries in `x86_64-windows` under `/usr/lib/wine` (Arch),
|
|
1000
|
+
`/usr/lib64/wine` (openSUSE) or `/usr/lib/x86_64-linux-gnu/wine` (Debian,
|
|
1001
|
+
Ubuntu). `build.sh` tries these in turn, takes `WINE_INCLUDE` / `WINE_LIB`
|
|
1002
|
+
over them, and when something is missing prints the family's install line
|
|
1003
|
+
(from `/etc/os-release`, as `a2qlinux-setup` does) and exits 1 before
|
|
1004
|
+
compiling. Fedora 44's `wine-devel` file list (mdapi) showed only
|
|
1005
|
+
`i386-windows` import libraries; whether its x86_64 ones live under
|
|
1006
|
+
`/usr/lib64/wine` is not established, and the build would then say so.
|
|
1007
|
+
Checked here: the detected Arch paths and a Debian-shaped layout given
|
|
1008
|
+
through the variables build code and data sections identical to the
|
|
1009
|
+
previous script's (`llvm-objdump` of `.text`, `.rdata`, `.data`; the files
|
|
1010
|
+
differ only in the PE time stamp, which changes on every build). Only Arch
|
|
1011
|
+
has built it for real. `install-from-source.sh` runs `build.sh`,
|
|
1012
|
+
`pipx install --editable .` (after `pipx uninstall a2qlinux` if one is
|
|
1013
|
+
installed, since pipx refuses a second install), `pipx ensurepath` and
|
|
1014
|
+
`a2qlinux-setup` with `PIPX_BIN_DIR` (default `~/.local/bin`) put first on
|
|
1015
|
+
`PATH`, so the menu entry points at pipx's stable command folder rather
|
|
1016
|
+
than at the environment's own `bin`.
|
|
@@ -180,7 +180,7 @@ What the setup does, in order:
|
|
|
180
180
|
| checks the programs from "Installing the packages", and for missing ones prints one install command for your distribution | `missing: …` and the command |
|
|
181
181
|
| tries a one-second capture, to see that capturing is allowed | `capturing is not allowed yet …` and the commands, if not |
|
|
182
182
|
| starts A2Qlinux's tray icon for a moment, without showing it, to see that it can run on your desktop | a reason, if not; see "The tray icon" in [TROUBLESHOOTING.md](TROUBLESHOOTING.md) |
|
|
183
|
-
| installs Questlog in `~/Games/Questlog` if it is not there yet (about 130 MB) | `Downloading Questlog …`, then `Installed Questlog …` |
|
|
183
|
+
| installs Questlog in its folder (`~/Games/Questlog`, or the one given with `--questlog-dir`) if it is not there yet (about 130 MB) | `Downloading Questlog …`, then `Installed Questlog …` |
|
|
184
184
|
| takes Questlog's icon from it (A2Qlinux does not ship Questlog's logo) | `Icon: …` |
|
|
185
185
|
| creates the "Questlog (AION 2)" entry in your applications menu | `Menu entry: …` |
|
|
186
186
|
| prints the line for Steam's launch options, used in the optional last section | `Steam > AION 2 > …` |
|
|
@@ -188,10 +188,29 @@ What the setup does, in order:
|
|
|
188
188
|
It runs nothing with `sudo` and changes nothing in the game; the commands
|
|
189
189
|
that need administrator rights are printed for you to run.
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
**Questlog in another folder.** A2Qlinux keeps Questlog in `~/Games/Questlog`
|
|
192
|
+
unless you tell it otherwise. To use another folder, run the setup once
|
|
193
|
+
with it:
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
a2qlinux-setup --questlog-dir <folder>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The setup writes that folder into A2Qlinux's settings file (only that line;
|
|
200
|
+
your other settings stay), so the menu entry, the Steam launch option and
|
|
201
|
+
every later run of the setup use it; you do not give it again. Then:
|
|
202
|
+
|
|
203
|
+
| What is in the folder | What the setup does |
|
|
204
|
+
|---|---|
|
|
205
|
+
| a Questlog you unpacked before (`Questlog.exe` is there) | uses it; nothing is downloaded |
|
|
206
|
+
| nothing, or the folder does not exist yet | installs the newest Questlog there |
|
|
207
|
+
| other files, but no `Questlog.exe` | installs nothing, and says so; choose an empty folder |
|
|
208
|
+
|
|
209
|
+
To move back to the default, run it with `--questlog-dir ~/Games/Questlog`,
|
|
210
|
+
or change `questlog_dir` in the settings file.
|
|
211
|
+
|
|
212
|
+
If the automatic installation fails, the message says why; installing
|
|
213
|
+
Questlog by hand is described in
|
|
195
214
|
[UPDATING.md](UPDATING.md#installing-questlog-by-hand).
|
|
196
215
|
|
|
197
216
|
The menu entry keeps itself up to date: each time `a2qlinux` starts, it
|
|
@@ -199,18 +218,51 @@ checks that the entry (and the desktop icon, if you have one) still runs
|
|
|
199
218
|
this installation, and writes it again if not, for example after A2Qlinux
|
|
200
219
|
was reinstalled elsewhere. Options you added to the entry by hand stay.
|
|
201
220
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
221
|
+
### From the source code instead
|
|
222
|
+
|
|
223
|
+
This is for changing A2Qlinux itself; to use it, the PyPI package above is
|
|
224
|
+
all you need. Installing from a copy of the repository differs in two
|
|
225
|
+
ways. The small Windows parts A2Qlinux puts into the game's Proton
|
|
226
|
+
environment are not in the repository, only in the PyPI package, so they
|
|
227
|
+
are built first. And the copy is installed *editable*: pipx runs the files
|
|
228
|
+
in your copy instead of its own copies of them, so a change you make takes
|
|
229
|
+
effect the next time A2Qlinux starts, without installing again.
|
|
230
|
+
|
|
231
|
+
1. Install what the build needs, besides the packages above:
|
|
232
|
+
|
|
233
|
+
| Distribution | Command |
|
|
234
|
+
|---|---|
|
|
235
|
+
| Arch, CachyOS | `sudo pacman -S --needed clang lld wine` |
|
|
236
|
+
| Debian, Ubuntu | `sudo apt install clang lld libwine-dev` |
|
|
237
|
+
| Fedora | `sudo dnf install clang lld wine-devel` |
|
|
238
|
+
| openSUSE | `sudo zypper install clang lld wine-devel` |
|
|
239
|
+
|
|
240
|
+
`clang` and `lld` compile and link the Windows parts; the Wine package
|
|
241
|
+
provides the Windows headers and libraries they are built against.
|
|
242
|
+
2. Get the repository and run its installer from it:
|
|
243
|
+
```
|
|
244
|
+
git clone https://github.com/raman78/A2Qlinux.git && cd A2Qlinux && ./install-from-source.sh --desktop-shortcut
|
|
245
|
+
```
|
|
246
|
+
3. Open a new terminal, so that the A2Qlinux commands are found, and read
|
|
247
|
+
the end of what the installer printed, as in step 4 above.
|
|
248
|
+
|
|
249
|
+
What `install-from-source.sh` does, in order, with a line `== 1/4 …` and so
|
|
250
|
+
on for each step:
|
|
251
|
+
|
|
252
|
+
| Step | Command it runs | Why |
|
|
253
|
+
|---|---|---|
|
|
254
|
+
| 1 | `bash bridge/build.sh` | builds the Windows parts into the copy. It finds Wine's files in the folders Arch, Debian, Ubuntu, Fedora and openSUSE use; if something is missing it prints the install command for your distribution |
|
|
255
|
+
| 2 | `pipx install --editable .` | installs this copy (the `.` is the current folder); an A2Qlinux installed before is removed first, whether from PyPI or another copy |
|
|
256
|
+
| 3 | `pipx ensurepath` | as in step 2 above |
|
|
257
|
+
| 4 | `a2qlinux-setup` | the same checks and setup as above; options given to the installer, such as `--desktop-shortcut`, are passed on |
|
|
258
|
+
|
|
259
|
+
Run it again after `git pull` when the Windows parts changed, or after a
|
|
260
|
+
Wine update (the parts are built against the installed Wine). A change to
|
|
261
|
+
the Python files needs nothing. Building has been tried on Arch and
|
|
262
|
+
CachyOS only so far; the other distributions' folders come from their
|
|
263
|
+
package file lists. If Wine's files are somewhere else, the build says so;
|
|
264
|
+
give the folders as `WINE_INCLUDE=<folder with windows/windows.h>` and
|
|
265
|
+
`WINE_LIB=<folder with libkernel32.a>` in front of the command.
|
|
214
266
|
|
|
215
267
|
## Checking that it works
|
|
216
268
|
|
|
@@ -78,5 +78,39 @@ class LoadTest(unittest.TestCase):
|
|
|
78
78
|
self.assertEqual(settings.after_game, "keep")
|
|
79
79
|
|
|
80
80
|
|
|
81
|
+
class SetQuestlogDirTest(unittest.TestCase):
|
|
82
|
+
"""a2qlinux-setup --questlog-dir writes the folder into the settings file, new or existing."""
|
|
83
|
+
|
|
84
|
+
def setUp(self):
|
|
85
|
+
self.tmp = tempfile.TemporaryDirectory()
|
|
86
|
+
self.path = Path(self.tmp.name) / "a2qlinux" / "config.toml"
|
|
87
|
+
|
|
88
|
+
def tearDown(self):
|
|
89
|
+
self.tmp.cleanup()
|
|
90
|
+
|
|
91
|
+
def test_a_missing_file_is_created_with_the_folder(self):
|
|
92
|
+
config.set_questlog_dir("/games/QL", self.path)
|
|
93
|
+
settings, problems = config.load(self.path)
|
|
94
|
+
self.assertEqual((settings.questlog_dir, problems), (Path("/games/QL"), []))
|
|
95
|
+
self.assertIn("after_game", self.path.read_text()) # the full template
|
|
96
|
+
|
|
97
|
+
def test_an_existing_file_changes_only_that_line(self):
|
|
98
|
+
self.path.parent.mkdir(parents=True)
|
|
99
|
+
self.path.write_text('# mine\nquestlog_dir = "/old"\nauto_update = false # off\n')
|
|
100
|
+
config.set_questlog_dir("/new/QL", self.path)
|
|
101
|
+
self.assertEqual(self.path.read_text(), '# mine\nquestlog_dir = "/new/QL"\nauto_update = false # off\n')
|
|
102
|
+
|
|
103
|
+
def test_a_file_without_the_line_gets_it_added(self):
|
|
104
|
+
self.path.parent.mkdir(parents=True)
|
|
105
|
+
self.path.write_text("auto_update = false")
|
|
106
|
+
config.set_questlog_dir("/new/QL", self.path)
|
|
107
|
+
settings, problems = config.load(self.path)
|
|
108
|
+
self.assertEqual((settings.questlog_dir, settings.auto_update, problems), (Path("/new/QL"), False, []))
|
|
109
|
+
|
|
110
|
+
def test_quotes_and_backslashes_in_the_folder_survive(self):
|
|
111
|
+
config.set_questlog_dir('/games/"odd" \\ name', self.path)
|
|
112
|
+
self.assertEqual(config.load(self.path)[0].questlog_dir, Path('/games/"odd" \\ name'))
|
|
113
|
+
|
|
114
|
+
|
|
81
115
|
if __name__ == "__main__":
|
|
82
116
|
unittest.main()
|
a2qlinux-0.2.0/bridge/build.sh
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Build the Windows parts for x64 with clang and Wine's headers and import
|
|
3
|
-
# libraries; no MinGW toolchain is needed:
|
|
4
|
-
# a2qlinux/bin/wpcap.dll stand-in for Npcap's wpcap.dll, fed by the Linux side
|
|
5
|
-
# a2qlinux/bin/questlog_ctl.exe acts on a running Questlog from inside its Wine session
|
|
6
|
-
# bridge/tests/*.exe test programs for the two above
|
|
7
|
-
# tools/tcp_owner_probe.exe diagnostic: does Wine report TCP connection owners
|
|
8
|
-
# Rebuild after a Wine update.
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
cd "$(dirname "$0")"
|
|
11
|
-
mkdir -p ../a2qlinux/bin
|
|
12
|
-
W=/usr/include/wine
|
|
13
|
-
L=/usr/lib/wine/x86_64-windows
|
|
14
|
-
CF=(--target=x86_64-w64-windows-gnu -fuse-ld=lld -nostdinc -isystem "$W/msvcrt" -isystem "$W/windows"
|
|
15
|
-
-isystem "$(clang -print-resource-dir)/include" -O2 -Wall -Wextra)
|
|
16
|
-
clang "${CF[@]}" -shared -o ../a2qlinux/bin/wpcap.dll wpcap_bridge.c -nostdlib -L"$L" -lucrtbase -lkernel32 -luser32 -lws2_32 \
|
|
17
|
-
-Wl,--entry=DllMain
|
|
18
|
-
clang "${CF[@]}" -o ../a2qlinux/bin/questlog_ctl.exe questlog_ctl.c -nostdlib -L"$L" -lucrtbase -lkernel32 -luser32 \
|
|
19
|
-
-lshell32 -Wl,--entry=start
|
|
20
|
-
clang "${CF[@]}" -o tests/bridge_client_test.exe tests/bridge_client_test.c -nostdlib -L"$L" -lucrtbase -lkernel32 \
|
|
21
|
-
-Wl,--entry=main
|
|
22
|
-
clang "${CF[@]}" -o tests/zorder_guard_test.exe tests/zorder_guard_test.c -nostdlib -L"$L" -lucrtbase -lkernel32 \
|
|
23
|
-
-luser32 -lshell32 -Wl,--entry=start
|
|
24
|
-
clang "${CF[@]}" -o ../tools/tcp_owner_probe.exe ../tools/tcp_owner_probe.c -nostdlib -L"$L" -lucrtbase \
|
|
25
|
-
-lkernel32 -liphlpapi -lws2_32 -Wl,--entry=main
|
|
26
|
-
echo "built: a2qlinux/bin/wpcap.dll, a2qlinux/bin/questlog_ctl.exe, bridge/tests/*.exe, tools/tcp_owner_probe.exe"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|