akacross/omp-ingame-browser-wine
open.mp's in-game server browser under Wine/Proton: findings, ompoverlay.asi, and a fix for the crash after reconnecting
README.md
open.mp's in-game server browser on Linux (Wine/Proton)
open.mp's client (omp-client.dll) has a server browser you open inside SA-MP.
It is not drawn by the client itself: it is the
open.mp launcher's own window,
copied into the game every frame. Under Wine that copy is always empty. The
game also tabs out each time the browser opens, and then the browser opens
only once. This repo is the write-up of why, plus the game-side half of the
fix. It also covers a crash the browser's reconnect button exposed, with
its cause and a fix.
Result: the browser works in game under Proton: pictures at ~36 fps, mouse and keyboard, reopening, connecting to a server, with no tab-out. It needs both halves:
| where | what | |
|---|---|---|
| launcher | omp-launcher-wine (or -sampcmd) | parks the browser window off screen, never focused, and publishes its pixels in shared memory |
| game | ompoverlay/ → ompoverlay.asi | hands those pixels to omp-client.dll in place of its empty copy, and repairs its reopen bug |
| game | animwipefix/ → animwipefix.asi | fixes the crash after reconnecting from the browser |
The whole setup (prefix, WebView2, launcher, launch script) is in samp-openmp-linux.
Launcher v1.7.0-wine.1 and later need no
ompoverlay.asi. The game side is built into the launcher (omp-launcher-wine, -sampcmd), which injects it into the game once omp-client connects. It also keeps open.mp 1.7's client from crashing the game as it quits.ompoverlay.asiis only for the 1.6.1 rebuilds; a copy left in the game folder is harmless (the built-in hook stands aside for it).animwipefix.asiis still needed.
Test machine
| OS | CachyOS (Arch), KDE Plasma on Wayland (Xwayland for Wine) |
| GPU | RTX 3070, NVIDIA proprietary driver |
| Proton | proton-cachyos 11.0 (Wine 11.0) through umu-run |
| Game | GTA San Andreas 1.0 US, SA-MP 0.3.7-R5, open.mp client 0.2.2 (omp-client.dll), DXVK d3d9.dll |
| Launcher | open.mp launcher 1.6.1 rebuilt with the Wine pass, WebView2 155.0.4283.45 |
The short version
-
The browser is the launcher.
omp-client.dllasks the launcher over TCP (127.0.0.1:45791) for an overlay window. It copies that window withPrintWindowinto a bitmap each frame and draws it with ImGui. Without the launcher you get a cursor and a strayimgui.ini, nothing else. -
Under Wine the copy is empty. Wine implements
PrintWindowby sendingWM_PRINTwith the caller's DC to the window's owner. The launcher is another process and cannot draw into the game's DC. So the launcher now captures its own page (CapturePreview) into shared memory, andompoverlay.asipoints omp-client'sPrintWindowimport at a copy from it. -
The game tabbed out each time the browser opened:
- the window manager pulled the off-screen window back on screen;
- creating the window took the foreground. Tauri's default
focused(true)makes tao force it, and Wine has no foreground lock; - and the first click into it did too: Chromium focuses its render widget on a button press, which activates the window.
The launcher now makes the window an unmanaged, never-activated, disabled popup, built
focused(false). -
The browser opened only once. omp-client frees its bitmap on close but keeps its size, and only makes a new bitmap when the size changes.
ompoverlay.asiclears that cached size when it sees the empty DC. -
The launcher locked up once: WebView2's browser process crashed and took the launcher's main page with it. The capture loop always has a capture in flight, and closing the window destroyed its WebView under it. Overlays now close only between captures, and a dead WebView2 process is logged and recovered from (the launcher restarts itself).
-
Reconnecting from the browser crashed the game about 30 s later, at
gta_sa.exe+0x41214A. The reconnect deleted the player's car, the player fell, and SA's "remove all animations" freed the fall animation without telling the falling task. That task later wrote through the dead pointer, into memory a car model had taken.animwipefix.asiruns the game's own delete callbacks first, as GTA III and Vice City did.
Details: docs/IN-GAME-BROWSER.md, docs/RECONNECT-CRASH.md, docs/LAUNCHER-LOCKUP.md.
Install
The ASIs go in the GTA folder, next to gta_sa.exe; any ASI loader works
(SA-MP's own, CLEO's or Silent's). With launcher v1.7.0-wine.1 or later only
animwipefix.asi is needed (see the note at the top). Releases have them
prebuilt, or:
./build.sh # needs i686-w64-mingw32-gcc
./build.sh --deploy /path/to/gta
ompoverlay.asidoes nothing unless the launcher publishes frames (the Wine launcher build under Wine). With the stock launcher, or on Windows, every call goes to the realPrintWindow.animwipefix.asipatchesgta_sa.exe1.0 US only. It refuses anything else, and leaves the function alone if another mod has hooked it. It is useful without open.mp too: any skin change on a falling ped can trigger the crash.
Start the game from the launcher (or in the same Wine prefix while the launcher runs): the shared memory frame block exists only inside one wineserver.
Tests
WINEPREFIX=/tmp/testpfx GTA_SA_EXE=/path/to/gta_sa.exe ./build.sh test
ompoverlay: 17 checks against a fakeomp-client.dll, which captures and cleans up the way 0.2.2 does over its real code bytes. Top-down and bottom-up bitmaps, a bigger bitmap, a frame mid-write, an unchanged frame, other windows, and reopening at the same size. The reopen checks fail without the fix.animwipefix: 21 checks. The harness fakesgta_sa.exeat its real addresses, so the plugin patches it fromDllMainas in the game. Whole clumps are then wiped through the patched function, with the game's ownCTaskSimpleInAir::DeleteAnimCBbytes; the real exe's bytes are compared too.
License
MIT. open.mp, its launcher and client are open.mp's; nothing of theirs is in this repository.
This page is built from what GitHub publishes about the repository. samp.directory does not host the code. Report a problem with this listing