Added City of Division.,
This commit is contained in:
1 parent
62e47a41ae
commit
8244a883b7
4 files changed
+135
No files matched your search
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
recover_city_of_division_window() {
|
||||
local gamePid="$1"
|
||||
local attempt gameWindow geometry key value windowX windowY windowWidth windowHeight
|
||||
local -a gameWindows=()
|
||||
|
||||
# Wait for this launch's off-screen pygame window, not another Wine process.
|
||||
for ((attempt = 0; attempt < 150; attempt++)); do
|
||||
kill -0 "$gamePid" 2>/dev/null || return 0
|
||||
mapfile -t gameWindows < <(
|
||||
xdotool search --all --pid "$gamePid" --name '^City of division,' 2>/dev/null
|
||||
)
|
||||
if [[ ${#gameWindows[@]} -eq 1 ]]; then
|
||||
gameWindow="${gameWindows[0]}"
|
||||
if [[ "$(xdotool getwindowclassname "$gameWindow" 2>/dev/null)" == "cityofdivision.exe" ]] &&
|
||||
geometry="$(xdotool getwindowgeometry --shell "$gameWindow" 2>/dev/null)"; then
|
||||
windowX=""
|
||||
windowY=""
|
||||
windowWidth=""
|
||||
windowHeight=""
|
||||
# Parse xdotool's data without evaluating it as shell commands.
|
||||
while IFS='=' read -r key value; do
|
||||
case "$key" in
|
||||
X) windowX="$value" ;;
|
||||
Y) windowY="$value" ;;
|
||||
WIDTH) windowWidth="$value" ;;
|
||||
HEIGHT) windowHeight="$value" ;;
|
||||
esac
|
||||
done <<< "$geometry"
|
||||
if [[ "$windowX" =~ ^-[0-9]+$ && "$windowY" =~ ^-[0-9]+$ &&
|
||||
"$windowWidth" == 1 && "$windowHeight" == 1 ]]; then
|
||||
if ! xdotool windowmove "$gameWindow" 100 100 \
|
||||
windowsize "$gameWindow" 640 480 windowmap "$gameWindow"; then
|
||||
echo "Could not restore City of Division's off-screen window." >&2
|
||||
return 1
|
||||
fi
|
||||
# If its desktop is elsewhere, normal window selection will
|
||||
# complete focus. Never activate a different workspace here.
|
||||
xdotool windowfocus "$gameWindow" 2>/dev/null || true
|
||||
return 0
|
||||
fi
|
||||
if [[ "$windowX" =~ ^[0-9]+$ && "$windowY" =~ ^[0-9]+$ &&
|
||||
"$windowWidth" =~ ^[0-9]+$ && "$windowHeight" =~ ^[0-9]+$ ]] &&
|
||||
((windowWidth > 1 && windowHeight > 1)); then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
sleep 0.2
|
||||
done
|
||||
echo "Timed out waiting to restore City of Division's window." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
run_city_of_division() {
|
||||
if [[ -z "${DISPLAY:-}" ]] || ! command -v xdotool >/dev/null; then
|
||||
echo "City of Division requires an X11 display and xdotool for its window recovery." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local -a launchCommand=(wine)
|
||||
if command -v gamemoderun >/dev/null; then
|
||||
launchCommand=(gamemoderun wine)
|
||||
fi
|
||||
"${launchCommand[@]}" "$@" &
|
||||
local gamePid=$!
|
||||
recover_city_of_division_window "$gamePid" &
|
||||
local focusPid=$!
|
||||
local gameStatus=0
|
||||
wait "$gamePid" || gameStatus=$?
|
||||
# The worker also stops when this process exits; no persistent focus loop.
|
||||
wait "$focusPid" || true
|
||||
return "$gameStatus"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are shared AGM installer state.
|
||||
export WINEARCH=win64
|
||||
export winVer="win10"
|
||||
|
||||
download "https://blindgames.eu/jeux/city_of_division_setup.exe" || exit 1
|
||||
install_wine_bottle || exit 1
|
||||
|
||||
# Preserve Wine's exit status through the progress wrapper's pipeline.
|
||||
if ! (
|
||||
set -o pipefail
|
||||
install_with_progress wine "Installing City of Division..." \
|
||||
"${cache}/city_of_division_setup.exe" \
|
||||
/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /NOICONS /TASKS= \
|
||||
/NOCLOSEAPPLICATIONS /NORESTARTAPPLICATIONS \
|
||||
'/DIR=C:\Program Files\City of Division'
|
||||
); then
|
||||
alert "City of Division" "Installation failed. No launcher was added."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -s "${WINEPREFIX}/drive_c/Program Files/City of Division/cityofdivision.exe" ]]; then
|
||||
alert "City of Division" "The game executable was not installed. No launcher was added."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
add_launcher 'c:\Program Files\City of Division\cityofdivision.exe'
|
||||
@@ -169,6 +169,36 @@ Run the offline release, installer and updater checks with
|
||||
`python3 tests/tekken3_setup_tests.py`. These use temporary fixtures and do not
|
||||
access the network, start Wine or change installed games.
|
||||
|
||||
## City of Division
|
||||
|
||||
Choose **City of Division** from `./audiogame-manager.sh -i`. The installer
|
||||
downloads the Windows setup from [BlindGames](https://blindgames.eu/jeux/city-of-division.html)
|
||||
and runs it silently in the shared Wine64 bottle. The game installs to
|
||||
`C:\Program Files\City of Division` and uses Windows 10 compatibility.
|
||||
AGM adds its launcher only after setup succeeds and `cityofdivision.exe` exists.
|
||||
The bundled NVDA controller DLLs use AGM's existing launch-time speech handling,
|
||||
including the `-s` option described above.
|
||||
|
||||
On X11, AGM uses `xdotool` to move the game's hidden 1-by-1 window on-screen
|
||||
once per launch. Without this, the language menu can speak but ignore keys,
|
||||
even after selecting Wine in the window manager. Recovery targets only the
|
||||
new game process, stops after restoring its window, and does not switch
|
||||
workspaces. You can then switch away and back using your normal window list.
|
||||
The window recovery requires `xdotool` and does not run in the `-g` debugger mode.
|
||||
|
||||
Before submitting, review the diff and test installation and launch using both
|
||||
console and graphical menus. Check keyboard navigation, screen-reader speech,
|
||||
game audio, connecting to the game service, and quitting/relaunching. Confirm an
|
||||
existing game in the shared Wine64 bottle still launches and speaks. A disposable
|
||||
Wine installation verified setup and the executable path; live gameplay and
|
||||
screen-reader behavior still require testing. Run the isolated failure checks
|
||||
with `bash tests/city_of_division_tests.sh`; these do not start Wine or use the
|
||||
network or installed games. Run `bash tests/city_of_division_focus_tests.sh` for
|
||||
the isolated window-recovery and launch checks. For live acceptance, close and
|
||||
relaunch City of Division twice, check the language menu and main menu keys,
|
||||
then switch away and back using the window list. Confirm the game accepts keys
|
||||
after returning and does not pull focus back while you use another window.
|
||||
|
||||
## AI-assisted contributions
|
||||
|
||||
AI-assisted contributions are welcome. The person submitting the contribution remains responsible for reviewing and testing the changes before submission. Please review the generated diff, run the relevant tests, and describe what changed and how it was tested.
|
||||
@@ -881,6 +881,10 @@ game_launcher() {
|
||||
fi
|
||||
if [[ "$debugGdb" == "1" ]]; then
|
||||
run_with_optional_gamemode winedbg --gdb "${game[1]##*\\}"
|
||||
elif [[ "${wineExec,,}" == "cityofdivision.exe" ]]; then
|
||||
# shellcheck source=.includes/city-of-division.sh
|
||||
source "${scriptDir}/.includes/city-of-division.sh"
|
||||
run_city_of_division "${game[1]##*\\}"
|
||||
else
|
||||
# Use direct wine execution instead of 'wine start' to ensure clipboard works
|
||||
# See: https://bugs.winehq.org/show_bug.cgi?id=50598
|
||||
|
||||
Reference in new issue
Block a user