Second part of the audit of every screen for a Docker server. What it found, and
what now happens:
- Play with friends. "Servers open" read the BindIP of the configuration files, which
the containers force to 0.0.0.0, so it was green on a fresh server while who can
connect is decided by the address the ports are published on (bindAddress in
docker.json). Opening and closing now edit bindAddress (and set
CoA.AllowRemoteClients), the open state is read from it, and enabling a mode no
longer fails on netsh / PowerShell after it already rewrote the files. There is no
firewall row on Linux (Docker publishes the ports itself); the Windows reply is
unchanged.
- The "private services" check (Friends and Diagnostics) could never fail on Linux: it
reads the Windows listener table. For a Docker server it is computed from how the
ports are published: the database never, the console only on 127.0.0.1, the game
servers on bindAddress.
- Console, Database tab: read a mysql log file that does not exist; it shows
`docker logs` of the database container.
- The Overview showed a service that had stopped by itself as "Stopped"; it now says
"Stopped unexpectedly".
- Settings: a Docker server that was added but never started had no
worldserver.conf and the page failed; it is created from its template. A talent
file path outside the Core folder is refused (the container cannot see it).
- Backups of configuration now include docker.json; verifying the files of an
imported Docker server looked for worldserver.exe and reported it missing.
- Linux locations: the friend package and the diagnostics go to the desktop folder
(from the user directories file) instead of /tmp, the problem report names the
distribution, and the size advice for companions reads /proc/meminfo instead of
assuming 8 GB.
Every Windows branch is the code that was there; the dispatch is the early return on
docker::is_docker (or the host flavor for the firewall).
Found by auditing every screen for a Docker server.
- Server settings: Ra.Enable, Ra.IP and Updates.EnableDatabases were on the page and
written to worldserver.conf, but the containers get AC_RA_ENABLE, AC_RA_IP and
AC_UPDATES_ENABLE_DATABASES, and the core reads those before the file: the change
was accepted and had no effect, and the page showed the file's value while the
container ran another. A Docker server no longer offers them (nor "restore
recommended defaults" for them), and a change forced through is refused with the
reason. The list is docker::FORCED_KEYS, and a test compares it to the variables
the containers really get, so adding one without the other fails.
- `server restart` (and idlerestart) make the core exit with code 2 and expect a
supervisor to start it again; the Docker world had none and showed "crashed". It now
gets `--restart on-failure:3`, applied once the server is up (so a start that fails
stays failed instead of looping); a stop or `server shutdown` (code 0) is never
restarted.
On SteamOS and Bazzite /home is a link to /var/home; Wine keeps the path it was
given, so the resolved one alone can miss the command line. The start order is
unchanged (database up and healthy before the realm list is updated): a comment
says so.
client::launch started Ascension.exe directly, which cannot work on Linux, and
client::is_running found nothing (it reads the Windows process list). wine.rs is
the Linux counterpart, and both hand over to it on a Linux host.
It runs the command of the project's own launcher script: umu-run with a Proton
build (GAMEID=0, PROTONPATH, WINEPREFIX, started from the client folder), else
plain Wine, with WINEDLLOVERRIDES=divxtac=d (DivxTac.dll deadlocks the world
loading screen under wine-mono). The newest GE-Proton found for Steam is used, or
umu's own choice; COA_PROTONPATH, COA_WINEPREFIX and client-launch.json override
the detection; the prefix defaults to ~/Games/umu/coa-client. The game runs in its
own process group, so closing the Manager does not close it, and prints to
client.log. Whether it runs is read from /proc, where the command line holds the
Windows form of the client path. A clear message says what to install when neither
umu nor Wine is found.
Tests: detection (newest build, no build, Wine only, nothing, overrides), the
command, the /proc match, and a real spawn with a stand-in umu-run that records its
environment. Not run: the real client.
The Realm card showed "io: No such file or directory (os error 2)" on a Docker
server: the Wildcard check read Core/worldserver.exe. The card lets the owner
switch realm, so it is made to work rather than hidden.
What the repack's patched launcher did at each start is done by the Docker
backend: finish an interrupted switch (realms::before_start), name the realms in
the realm list, and give the containers the databases of the selected realm
(acore_world_wildcard, acore_characters_wildcard). The switch itself is the shared
code. prepare_launcher has nothing to patch on a Docker server, and Wildcard
support is read from Core/worldserver as it is from Core/worldserver.exe (the .exe
wins when both exist, so a repack is read as before).
Tests: the support check on both binary names, no launcher to adapt, and the
databases passed to the containers for each realm. Creating the Wildcard realm
itself needs a build and a database with the Wildcard migrations and was not run.
Found by installing a server through the new screen: the update check of a Docker
server read the Windows "stable" channel and offered "0.261003.17 (you have
0.261003.1)". Applying it would have put the repack's executables, MySQL and
launcher into a Linux server folder.
Refused in the core (update::preview, apply and rollback), so no caller can do it.
The Settings tab says that updates are not available for Docker servers yet; the
background check stays quiet, as for any failed check.
A test applies the same update package to the same folder with and without
Settings/docker.json: refused and untouched with it, committed without it.
The install commands ask coa_core::platform::flavor() once and hand a Docker
install to src-tauri/src/docker_install.rs; the repack arm of each command is
untouched (an early return and an extra optional parameter are all that changed
in lib.rs). New command install_environment tells the screen the kind of server,
the suggested folder (~/CoaServer) and why Docker cannot be used, if it cannot.
On Linux the install screen shows the game data folder (used in place, read-only)
and the server package (a folder or an address; there is no default address until
a signed Linux package is published), and disables Install until both are given
and Docker works. It shows Docker's own message with a "Check again" button when
Docker is missing, stopped or not allowed for the user. The Windows screen is
unchanged (checked side by side in the browser mock).
A debug build (tauri dev) accepts another package key named in
COA_DEV_TRUSTED_KEY, to try the installer on a package signed with a throwaway
key; a release build always uses the embedded key.
New text is English only for now (other languages fall back to it).
- Add UnsavedChangesGuard modal (Save/Discard/Cancel) when navigating between tabs
- Wire guard into ModulesPage and SettingsPage with floating action bar
- Implement crash parser and explanation engine in coa-core
- Expose list_crashes Tauri command and CrashItem API
- Add auto-restart on unexpected server crash with crash loop protection
- Add crash counter badge and CrashHistoryModal with human-readable explanations and full crashlogs
- Support all 6 locales (en, ru, de, fr, es, zh)
Only the client's own connection errors (ERROR 2003 and 2002, "Can't connect") count as a stopped
database. The SQLSTATE 22003 of an out-of-range value contains "2003" and hid the real error of a
failing release migration. The message now also carries the client's last line.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>