* [Windows] Close running instances and purge stale runtime DLLs during update
* [Windows] Scope running-instance handling to install dir and fix NSIS build
- Drop !include nsExec.nsh: nsExec is a plugin DLL, not a header, so
makensis aborts before NSIS can build the installer.
- Match processes by image name and executable path under $INSTDIR via
PowerShell, then close (WM_CLOSE) and force-stop only those PIDs, so an
unrelated oracle.exe (Oracle DB) is never killed on a silent /R update.
- Gate the stale-runtime-DLL purge on $INSTDIR\cockatrice.exe existing, so
a first-time install can't recursively delete an unrelated Plugins
directory.
* [Windows] Make process detection rely on an explicit PowerShell exit code
* [Windows] Fix exit-code detection in the uninstaller process check
* [Windows] Pass the install dir to PowerShell without quoting pitfalls
* [Windows] Fail closed when a process path is unreadable
* [Windows] Only pre-check running instances for /R updates
* [Windows] Wait on a wall-clock 60 s deadline instead of a loop counter
* [Windows] Verify the force close and abort if the process survived
* [Windows] Defer silent updates instead of force-killing the client
* [Windows] Purge OpenSSL 3 DLLs on portable upgrades and broaden the stale-DLL guard
* [Windows] Replace the GetTickCount macro with a direct System::Call
* [Windows] Only close running instances whose path is readable
CloseMatchingApps reused the fail-closed detection filter, which counts a
process whose Path cannot be read (Access denied) as a match. The installer
runs elevated, so CloseMainWindow() would then be delivered to an unrelated
oracle.exe / servatrice.exe belonging to some other program, silently closing
a third party application during a Cockatrice update.
The set of processes we act on now has to be the strict one: a readable path
under $INSTDIR. Unreadable paths are simply not ours.
* [Windows] Match running instances by a readable path under the install dir
The Path read in the Where-Object filter raises "Access is denied" for
processes the installer cannot open, and both branches of the try/catch
turned that into a match. Together with mapping every non-zero nsExec result
to "running" this made the guard a hard stop rather than a fail-closed one: a
machine with an Oracle database service (or a servatrice service) running as
SYSTEM always has a process named oracle / servatrice whose path cannot be
read, so every silent update aborted after 60 s and every interactive install
re-asked for Retry indefinitely.
A process whose path cannot be read is not one of ours - the updater is
launched by the application it updates and therefore runs in the same user
session, and an interactive install is elevated and can read the paths of the
user's own processes. Both the detection and the close path now require a
readable path under $INSTDIR, which is what the comment above the helpers
already claimed.
* [Windows] Distinguish "could not determine" from "definitely running"
Mapping every non-zero nsExec result to "running" folds nsExec's "error"
return (powershell.exe could not be started at all - removed, blocked by
policy, refused by antivirus) into "Cockatrice is running". That state can
never clear: closing applications does not help, so silent installs aborted
after the full 60 s wait and interactive installs could not get past the
Retry/Cancel prompt.
IsAppRunning now reports three states (0 not running, 1 running, 2 could not
determine) and a new IsProcessLookupAvailable preflight checks that
powershell.exe can run at all. A broken PowerShell is reported to the user
once - with a message box, since a silent install would otherwise show
nothing - and the install continues instead of being blocked forever. Only a
definite "running" is now waited for.
* [Windows] Force-stop the console applications after the grace period
Servatrice and Oracle are console applications, so CloseMainWindow()
returns false and does nothing for them. Every silent update therefore
waited the full 60 s and then aborted, and every interactive install looped
on the Retry prompt, for any user running Servatrice out of the install
directory.
They now get a second shutdown path: once the grace period is over they are
force-stopped by PID with the same strict install-dir filter, since they hold
no unsaved user data. Cockatrice keeps the graceful-only treatment - a
force-kill there could destroy an unsaved deck - and still aborts instead.
* [Windows] Tell the user when a silent install or uninstall is aborted
On the /R path the installer runs with SetSilent and SetAutoClose, so the
DetailPrint before Abort went nowhere: the user clicks Help -> Check for
Client Updates, the download finishes, Cockatrice closes its window, and
nothing else happens - no update and no error, because the client launches the
installer detached and never looks at its exit code.
Every silent abort path now shows a message box telling the user which
application is still open and that they should close it and run the
installer again. The same applies to the silent uninstall, where the only
output is a log file nobody reads.
* [Windows] Treat leftover runtime files as an install marker for the purge
The guard on the stale-DLL purge only looked for the three executables and
uninstall.exe, so it skipped precisely the case the purge exists for: a
previous failed update whose uninstaller removed what it could and silently
skipped the Qt DLLs that a running instance had locked. None of the four
markers is left in that directory, and the stale DLLs then survive into the
new install.
A leftover Qt6Core.dll (what we ship today) or the qt.conf written by a
portable install now count as an install marker as well.
* [Windows] Run the section instance check before any file is deleted
Call EnsureAppsNotRunning sat after the portable-upgrade block, which had
already deleted the old cockatrice.exe, Qt*.dll and plugins directory. An
interactive install ("Portable mode" pointing at an existing portable folder)
has $ReinstallMode = 0, so the .onInit guard is skipped and locked files were
silently skipped - exactly the mixed-Qt-DLL state this change is about.
The check now runs right after SetOutPath, before the first Delete/RMDir in
the section.
* [Windows] Guard the old install before the old uninstaller deletes files
The interactive upgrade path removes the previous installation long before the
install section: componentsPagePre runs the old UninstallString on the
components page, i.e. before the directory page and before any call of ours
can check anything. Every uninstaller shipped before this change has no
un.EnsureAppsNotRunning, so for exactly the versions affected by #1576 the old
files were deleted while cockatrice.exe was still running and the new
installer had no say in it.
componentsPagePre now runs the same check before both ExecWait calls. At that
point $INSTDIR is still only the default, not the directory the old install
lives in, so the new EnsureOldInstallNotRunning guards the location recorded
in the registry instead. The helpers now work on a $GuardDir the caller
picks; the normal entry points keep seeding it with $INSTDIR.
* [Windows] Do not abort the section check past the point of no return
"nothing has been replaced yet, so aborting just defers the update" only holds
for the guard in .onInit. On the /R path AutoUninstallIfNeeded has already run
the old uninstaller, which RMDir /r's the whole install directory, and the
purge below it deletes the runtime files - so an Abort from the section would
leave the user with the old version uninstalled and the new one not installed
at all, which is strictly worse than the bug this change fixes.
The ordering now guarantees the check already passed: .onInit guards the /R
path before the uninstall, so the section only repeats it where that is not
already true, i.e. for interactive installs, where nothing of this installer
has been deleted yet and an Abort is the correct outcome.
As a safety net for whatever the purge could not remove (a still locked file,
or a check that could not run at all), HasStaleRuntimeFiles reports surviving
runtime files with a message box - also on a silent update, where there is no
other way to let the user know the install came out incomplete.
* [Windows] Only block the in-app updater with a message box
The message box on the silent abort would also fire for a plain /S install,
which is exactly the unattended case: a package manager (or a CI job) running
the installer with a leftover Cockatrice process would now hang forever on a
dialog nobody can see instead of aborting.
The box is therefore limited to /R, the path the in-app updater takes, where
the user just clicked Help -> Check for Client Updates, the client launches
the installer detached and never inspects its exit code, and the window is
about to disappear - without a message, the update would silently not happen.
Every silent abort also sets an error level now, so an unattended caller can
see that the run failed instead of having to read the log.
The silent uninstaller reports through log and exit code for the same reason:
it is run unattended by the /R updater itself (QuietUninstallString) and by
package managers. The installer that invoked it tells the user about the
incomplete result itself.
* [Windows] Treat an unset guard directory as undeterminable
$GuardDir is set by the three entry points into the check, but it is now what
decides whether a process counts as one of ours, and an empty string would
match every process that merely shares an image name - the same false positive
the strict path filter exists to avoid. Report it as "could not determine"
instead of running the check, so a future caller that forgets to set it warns
the user rather than closing or killing a third party process.
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Build] Keep Windows installs free of build-tree artifacts
Several Windows packaging gaps could leak Visual Studio CMake build
output into the installed application or the NSIS installer:
- The per-app DLL sweep used
${CMAKE_BINARY_DIR}/${PROJECT_NAME}/${CMAKE_BUILD_TYPE}, which is
empty on multi-config generators, collapsing the recursive
DIRECTORY install into the whole build tree (containing *.dir,
*_autogen, .qt, .qsb, x64, ...). Point it at the real per-config
output with $<TARGET_FILE_DIR:...> and exclude build artifacts.
- install(FILES ${OPENSSL_INCLUDE_DIRS} ...) tried to install OpenSSL
include directories as files. CMake refuses this
("install FILES given directory"); it only slipped through CI
because the vcpkg OpenSSL config leaves the variable empty. Remove it;
fixup_bundle already ships the OpenSSL runtime DLLs.
- The NSIS uninstaller only deleted *.exe/*.dll and a few known files,
so build-tree leftovers survived an uninstall/reinstall cycle. Wipe
the whole directory tree instead.
- Add a Windows CI gate that lists the packaged installer with 7-Zip
and fails the build if any build-tree artifact path is found.
* Update .ci/compile.sh
Co-authored-by: tooomm <tooomm@users.noreply.github.com>
* [Build] Rework Windows installer artifact exclusions per review
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: tooomm <tooomm@users.noreply.github.com>
* Add scheme-variant theme asset resolution (#7209-1)
ThemeManager::assetPath() and schemeVariantPath() resolve a theme asset to its scheme-variant file (prefix-light/dark.png) with fallback to the plain asset, and themePixmap()/loadBrush()/loadExtraBrush() use them. CSS files load style-dark.css or style-light.css when present. Home widget re-resolves its background on theme change.
Link pixel_map_generator.cpp into the oracle target, which needs Qt6::Xml for QDomDocument.
* Fix clang-format wrap of theme format probe lists
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Build] Add precompiled headers for Qt-backed executables
Reparsing QtCore/QtGui/QtWidgets/QtNetwork in ~460 client translation
units is the dominant compilation cost. Precompile the two common layers:
- qtcore_pch.h (Qt Core only; safe even for headless Servatrice)
- qtwidgets_pch.h (adds Gui/Widgets/Network; used by Cockatrice and Oracle)
target_precompile_headers() requires CMake 3.16, now the project minimum.
Estimated 30-50% faster client rebuilds.
* [Build] Format qtwidgets precompiled header
clang-format include regrouping and a missing trailing newline.
* [Build] Add PCH-aware ccache sloppiness config; format cmake/pch headers
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [App] Add onboarding wizard
Took 10 minutes
Took 3 minutes
Took 7 minutes
Took 9 minutes
Took 2 minutes
Took 1 minute
Took 7 minutes
* Adjust CI
Took 14 minutes
Took 56 seconds
Took 2 seconds
Took 3 seconds
* Adjust CI again
Took 14 minutes
Took 2 seconds
* Comments and fixes
Took 9 seconds
Took 1 minute
* Rebase.
Took 5 minutes
Took 50 seconds
Took 15 seconds
* Comments.
Took 7 minutes
* CI lol
Took 3 minutes
* CI again lol
Took 4 minutes
* Drop some settings, add some new ones.
Took 19 minutes
* Resize when expanding section
Took 4 minutes
Took 3 minutes
Took 7 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [CI] Remove Qt5
Took 10 minutes
Took 9 minutes
* Revert CI failure and fix up comments
Took 4 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Application] Add single instance guard and mime types.
Took 2 hours 39 minutes
Took 18 minutes
Took 5 minutes
Took 12 seconds
Took 11 seconds
* Rework
Took 30 minutes
Took 50 seconds
* Only enforce single instance if launched with arguments.
Took 5 minutes
* Prototype intents
Took 53 minutes
Took 6 seconds
* Connect/disconnect and join game/room intents.
Took 3 hours 14 minutes
Took 2 seconds
Took 15 seconds
* Fix include.
Took 1 minute
Took 23 seconds
Took 2 seconds
* Mac handling.
Took 10 minutes
Took 12 seconds
Took 3 minutes
* Lint.
Took 3 minutes
* Rebase.
Took 3 minutes
Took 17 seconds
* Implement UrlSchemeEventFilter
Took 10 minutes
Took 7 seconds
* Qt Moc
Took 3 minutes
* Modern PList.
Took 21 minutes
Took 1 minute
* Debug output.
Took 6 minutes
Took 19 minutes
* Watch file:// prefix.
Took 15 minutes
Took 7 seconds
* Better handler.
Took 6 minutes
* Don't store reference in member
Took 5 minutes
* Move impl to cpp, fix lifetime issues.
Took 11 minutes
Took 2 minutes
* Better single-instance handoff, url intent harded
copy game link context-menu
Polish for installers
Took 35 minutes
Took 8 seconds
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* Bump minimum_required to 3.5 and GoogleTest to 1.12
GoogleTest 1.12 is the oldest version that sets cmake_minimum_required() to 3.5 in the CMakeLists files it provides
* code style changes
* Use 1.17.0
* Set minimum to 3.10 to make top-level CMakeLists
* New hash
Co-authored-by: tooomm <tooomm@users.noreply.github.com>
* Update cmake/gtest-CMakeLists.txt.in
Co-authored-by: tooomm <tooomm@users.noreply.github.com>
---------
Co-authored-by: tooomm <tooomm@users.noreply.github.com>
Co-authored-by: ebbit1q <ebbit1q@gmail.com>
* Add -R option in Windows NSIS script
Took 23 minutes
* Small fix.
Took 3 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* fix(cmake): guard filter_string_test behind WITH_ORACLE or WITH_CLIENT. filter_string_test links against libcockatrice_filters, which is only built when WITH_ORACLE or WITH_CLIENT is enabled. Without this guard, test-only builds fail at configure time because the target doesn't exist. The guard condition mirrors the one in the root CMakeLists.txt that controls whether libcockatrice_filters is built.
* fix(cmake): centralize TEST_QT_MODULES in FindQtRuntime.cmake Each test CMakeLists.txt was independently defining TEST_QT_MODULES with its own subset of Qt modules. This duplicated knowledge that already lives in FindQtRuntime.cmake (which handles module discovery for all other targets: SERVATRICE, COCKATRICE, ORACLE). Consolidate into a single definition using the union of all test requirements (Concurrent Network Svg Widgets), matching the existing pattern for application-target modules. This ensures test-only builds (-DTEST=ON without application targets) discover all necessary Qt components.
* fix(cmake): guard libcockatrice_network behind application targets. libcockatrice_network is only needed by the client, server, and oracle targets. Other application-specific libraries (settings, models, filters) already have similar guards. This was an oversight that caused test-only builds to fail when network dependencies weren't available.
* Move logger and key signals from libcockatrice_utility to Cockatrice.
Took 9 minutes
* Only link Qt::Core instead of COCKATRICE_QT_MODULES to libraries, if possible.
Took 2 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* Set some CPack variables
WIP for DMG background image
* Use a .tif for background
* Add Background image and DS_Store script
Script is from https://www.kitware.com//creating-mac-os-x-packages-with-cmake/ with cmake.app changed to cockatrice.app
* Add position for all icons
* Adjust background size and icon position
This draws dbconverter off the screen as a hack to hide it, so hopefully it doesn't break.
* Add files via upload
* Change Icon Position
Icon position is probably relative to the window edge, not the edge of the screen so the numbers should be lower.
* Adjust Icon Position and Window Boundaries
Applescript seems to use the center of the icon rather than the left corner so the coordinates need to be adjusted by 64 px.
The finder window counts the 22 px of the title bar in the window size so 22 must be added to the fourth coord of position to fit the entire image.
* Fix spelling of Servatrice
* Satifsfy Code Style
* Use vector format (eps)
* Delete background.tif
* Use vector format (eps)
* Use the right file extention in the script
* Point to svg
* Use svg
* Add svg for background image
* Delete background.eps
* Use plain SVG, adjust text
* Move applescript to /cmake
* Move background to /cmake
* Point CPack to /cmake
background and applescript now reside there
* Revert to .tif
* Use compressed .tif
* Use more specific file name
* Script expects .background:background.tif
* remove dependency on deprecated qt5 libraries for qt6
removes the use of qt6-5compat for builds
replaces use of QRegExp with QRegularExpression
fixes incorrect usage of QRegExp
removes use of QTextCodec
fixes incorrect usage of QTextCodec
sets qtlinguist as a required component for qt6
* fix anchoredPattern not existing in qt 5.11
* merge clangify and cmakify into format.sh
update desktop lint workflow to 22.04
print cmake-format version as well
um, rename things?
add extra examples to format.sh --help
add option to not run clang-format
fix version display in .ci/lint_cpp.sh
fix relative paths in format.sh
fix formatting dirs
* run ./format.sh --cmake --branch ""
* revert formatting of cmake comments
Add lock around deleting arrows for commanding cards
Add support for Qt6 w/ Backwards Qt5
Handle Qt5/6 cross compilation better
Last cleanups
caps matter
Fix serv
Prevent crash on 6.3.0 Linux & bump to 5.8 min
Prevent out of bounds indexing
Delete shutdown timer if it exists
Fixup ticket comments, remove unneeded guards
Try to add support for missing OSes
Update .ci/release_template.md
Update PR based on comments
Update XML name after done and remove Hirsute
Address local game crash
Address comments from PR (again)
Tests don't work on mac, will see if a problem on other OSes
make soundengine more consistent across qt versions
disable tests on distros that are covered by others
Fix Oracle Crash due to bad memory access
Update Oracle to use new Qt6 way of adding translations
Add support for Qt5/Qt6 compiling of Cockatrice
Remove unneeded calls to QtMath/cmath/math.h
Update how we handle bitwise comparisons for enums with Tray Icon
Change header guards to not duplicate function
Leave comment & Fix Path for GHA Qt
Update common/server.h
Update cockatrice/src/window_main.cpp
Rollback change on cmake module path for NSIS
check docker image requirements
add size limit to ccache
put variables in quotes
properly set build type on mac
avoid names used in cmake
fix up cmake module path
cmake 3.10 does not recognize prepend
Support Tests in FindQtRuntime
set ccache size on non debug builds as well
immediately return when removing non existing client
handle incTxBytes with a signal instead
don't set common link libraries in cockatrice/CMakeLists.txt
add comments
set macos qt version to 6
Try upgrading XCode versions to latest they can be supported on
Ensure Qt gets linked
add tmate so i can see what's going on
Qt6 points two directories further down than Qt5 with regard to the top lib path, so we need to account for this
Establish Plugins directory for Qt6
Establish TLS plugins for Qt6 services
Minor change for release channel network manager
Let windows build in parallel cores
Wrong symbols
Qt6 patch up for signal
add missing qt6 package on deb builds
boolean expressions are hard
negative indexes should go to the end
Intentionally fail cache
move size checks to individual zone types
Hardcode libs needed for building on Windows, as the regex was annoying
Update wording
use the --parallel option in all builds
clean up the .ci scripts some more
tweak fedora build
add os parameter to compile.sh
I don't really like this but it seems the easiest way
I'd prefer if these types of quirks would live in the main configuration
file, the yml
fixup yml
readd appended cache key to vcpkg step
fix windows 32 quirk
the json hash is already added to the key as well
remove os parameter and clean up ci files
set name_build.sh to output relative paths
set backwards compatible version of xcode and qt on mac
set QTDIR for mac builds on qt5
has no effect for qt6
export BUILD_DIR to name_build.sh
merge mac build steps
merge homebrew steps, set package suffix
link qt5
remove brew link
set qtdir to qt5 only
compile.sh vars need to be empty not 0
fix sets manager search bar on qt 5.12/15
fix oracle subprocess errors being ignored on qt 5
clean up translation loading
move en@source translation file so it will not get included in packages
NOTE: this needs to be done at transifex as well!
Use generator platform over osname
Short circuit if not Win defined
* add ubuntu 21.10 to ci
remove ubuntu 20.10
* forgot to update dockerfile
* add googletest from repos
* update downloaded gtest
ideally this should just grab the master version
* fix hash
* fix cmake issue
* Basic mtgjsonv4 support
* Fix set type
* [WIP] Oracle: use zx instead of zip
* clanfigy fixes
* Fix reading last block of xz
* Added back zip support
* [WIP] adding xz on ci + fixes
* typo
* resolve conflict
* Make gcc an happy puppy
* test appveyor build
* appveyor maybe
* Appveyor: add xz bindir
* Update ssl version (the old one is not available anymore)
* Windows is a really shitty platform to code on.
* test vcpkg
* again
* gosh
* nowarn
* warning 2
* static
* Maybe
* cmake fix
* fsck this pain
* FindWin32SslRuntime: add vcpkg path
* Appveyor: cache support, force usable of openssl from vcpkg
* updated as suggested
* ouch
* Import card uuids and expose this property as !uuid! for card image download
* Minor style fixes
* address changed URL