Commit graph

335 commits

Author SHA1 Message Date
BruebachL
d5d99e4dfb
[Server/Client/Protocol] Add developer staff role (#7211)
* [Server/Client/Protocol] Add developer staff role

Introduce a Developer staff level (proto flag 32, DB admin bit 8) that
sits between admin and moderator: no kick/ban/warn/report/admin powers,
but gets server log access via a new developer command container family
(GET_SERVER_STATS, VIEWLOG_HISTORY) and an idle-timeout exemption.

- Protocol: IsDeveloper flag, developer_commands.proto envelope,
  Command_GetServerStats/Command_GetLogHistory, Response_GetServerStats,
  Command_AdjustMod.should_be_developer
- Servatrice: fail-closed developer dispatcher, uptime snapshot handler,
  shared log history handler reuse, bit-8 DB mapping
- Client: burgundy pawn/badge/labels/sort order, prepareDeveloperCommand,
  minimal Developer stats tab, log tab access, promote/demote actions

Took 24 minutes

Took 18 seconds

* [Server/Client/Protocol] Address developer role review feedback

Address ZeizaZach's review of the developer staff role:

- Nudge the developer log query to exclude private chat and sender IPs
  (the ModeratorCommand path still sees everything).
- Deduplicate Command_GetLogHistory into Command_ViewLogHistory, which now
  extends both ModeratorCommand (ext) and DeveloperCommand (dev_ext); the
  client picks the DeveloperCommand-scoped extension by extendee, and the
  server reads it via the extension number.
- Pull the uptime snapshot SQL into Servatrice_DatabaseInterface as
  getLatestUptimeSnapshot() and widen the reported counters to 64-bit.
- Document the admin bitfield (1 admin, 2 moderator, 4 judge, 8 developer)
  and add a server-side test for the developer command path.

* Add missing trailing newline to user_context_menu.cpp

* Remove stale includes of deleted command_get_log_history proto

The Command_GetLogHistory message was folded into Command_ViewLogHistory,
which deleted command_get_log_history.proto, but serversocketinterface
still #included its generated header. Fresh CI builds fail on the missing
file; local builds masked it by reusing a previously generated header.

* [Server] Exclude chat rows when private-chat filter is bypassable

A developer who omits log_location entirely — or sends only "chat" —
leaves chatType, gameType, roomType all false, so getMessageLogHistory
skips the target_type clause and returns every row, private messages
included. When !allowPrivateChat the server now forces game+room when
no surviving location was requested, guaranteeing the query always
carries a target_type restriction.

[Client] Demote mod+dev to moderator path in log-tab dispatch

The developer command family is strictly weaker than the moderator one
(no private chat, no sender_ip, ip filter ignored), so granting the
developer bit to an existing moderator must not silently strip their
capabilities. useDeveloperCommands is now true only when the user holds
the developer bit and not the moderator bit.

[Client] Hide the IP-address filter for developer log tab users

The developer path ignores the ip_address query field server-side.
Showing the field lets a developer type an IP and get results that are
silently unfiltered by it rather than an empty result set — reads as a
broken filter. Hide labelFindIPAddress/findIPAddress alongside the
privateChat checkbox.

* Developer pawn is silver.

* [Client] Fix indentation of merged Card Art Rules / Developer tabs

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-11 17:18:56 +02:00
BruebachL
7d867b9745
[Oracle/Client] Report card database download progress (#7253)
Some checks failed
CodeQL / Analyze (cpp) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
Build Desktop / Configure (push) Has been cancelled
Build Docker / Servatrice (arm) (push) Has been cancelled
Build Docker / Servatrice (x86) (push) Has been cancelled
Build Desktop / Debian 13 (push) Has been cancelled
Build Desktop / Debian 12 (push) Has been cancelled
Build Desktop / Fedora 44 (push) Has been cancelled
Build Desktop / Fedora 43 (push) Has been cancelled
Build Desktop / Servatrice_Debian 12 (push) Has been cancelled
Build Desktop / Ubuntu 26.04 (push) Has been cancelled
Build Desktop / Ubuntu 24.04 (push) Has been cancelled
Build Desktop / Arch (push) Has been cancelled
Build Desktop / macOS 13 Intel (push) Has been cancelled
Build Desktop / macOS 14 (push) Has been cancelled
Build Desktop / macOS 15 (push) Has been cancelled
Build Desktop / macOS 26 Debug (push) Has been cancelled
Build Desktop / Windows 10 (push) Has been cancelled
Build Docker / Publish multi-platform Servatrice image (push) Has been cancelled
* [Oracle/Client] Report card database download progress

Card database updates ran invisibly: MTGJSON parsing spun an indeterminate
bar on the UI thread and the set import blocked the window, while the
onboarding wizard spawned `oracle -b` with no progress to show at all.

- Add byte-level scan progress to `RawJson::scanSetRanges` via an optional
  callback, throttled to ~100 reports per scan.
- Emit `OracleImporter::dataReadProgress` during the scan and import sets on a
  worker thread, driving the wizard's progress bar per set.
- With `-b`, write machine-readable `PROGRESS <stage> <done> <total>` lines to
  stdout for the download/scan/import stages; stderr keeps the log output.
- Parse the oracle stdout in `MainWindow` and forward it to the onboarding
  wizard, giving the card database step a determinate bar with stage-specific
  status text.
- Guard the async workers against the wizard being closed mid-run.
- Add Google Test coverage for scan progress reporting.

* [Oracle/Client] Harden oracle progress workers and quit prompt

Address review feedback on the download-progress change: decompress and read
sets files off the UI thread, cancel the load/import workers before the
wizard can tear down the importer, and show an 'Extracting file...' status
plus a clean 100% tail so the poll never looks stuck. Quitting Cockatrice
while a card database update runs now asks for confirmation.

* Show 100% for 500ms on complete.

* Disable buttons on set import until done.

* Clean up progress bar.

* Drop wrapper around lambda

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-09 22:27:16 +02:00
RickyRister
6e5c58069b
[Settings] Make chat settings page scrollable (#7271)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
2026-09-07 00:52:06 -07:00
BruebachL
760fe88fa3
[Client] Add setting to ignore all private messages (#7260)
* [Client] Add setting to ignore all private messages (#1250)

* Early return

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-07 08:20:46 +02:00
BruebachL
fff506dbbe
[Client] Show confirmation when adding a user to the ignore list (#1875) (#7261)
Nothing in the UI confirmed that a user had been added to the ignore
list, so the action felt ambiguous and could be repeated by accident.

Show an information dialog when the server acknowledges the
add-to-ignore command.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-07 08:14:39 +02:00
BruebachL
8e0bdafb14
[Client] Prevent contacting users on the ignore list (#7262)
* [Client] Prevent contacting users on the ignore list (#1249)

The ignore list silences incoming messages, but a user on it was still
reachable: the context menu's chat item stayed enabled, private messages
could be sent, and a chat tab could be opened for an ignored user.

Make ignored users uncontactable: disable the chat item for them, refuse
to deliver messages typed in an open PM tab with one, and refuse to open
a new private chat tab with an ignored user (with a hint on how to undo
the ignore).

* Update cockatrice/src/interface/widgets/tabs/tab_message.cpp

Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>
2026-09-07 08:14:15 +02:00
BruebachL
6cdeb0c428
[Client] Explain the buddy and ignore lists in the user tab (#2072) (#7258)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-07 02:29:17 +02:00
BruebachL
745e94f332
[Replay] Skip damage animations when skipping backward in replays (#7249)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-07 02:26:52 +02:00
BruebachL
b01e107908
[Client] Show horizontal art for plane and siege cards in the profile banner (#7118) (#7250)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Use the landscape orientation flag to rotate sideways-layout card art
upright before cropping, so planes/sieges show their horizontal art as
the server profile banner card instead of a rotated full card.

- Curve cropCardArt around the card's landscapeOrientation flag with
  landscape-specific art margins (mirrors CardInfoPictureWidget)
- Add shared CardArtUtils::rotateSidewaysLayoutArt helper and apply it
  to the playmat (game render and settings preview) and card info widget,
  replacing three duplicate 90-degree rotation blocks

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-07 02:20:54 +02:00
BruebachL
8d30ac54f0
[Game] Prevent spectator duplication when replaying joined events (#7248)
* [Game] Prevent spectator duplication when replaying joined events

The spectator branch of eventJoin emitted spectatorJoined unconditionally
even when the spectator was already present (e.g. replayed during a rewind).
Guard it like the player branch and eventGameStateChanged, and make
PlayerListWidget::addPlayer idempotent as defense in depth.

* In resetChatAndPhase() (the rewound() handler), also clear all spectators from both PlayerManager and PlayerListWidget before the replay rebuilds from event 0. The forward replay then re-adds exactly the spectators whose join events fall within the new time range via eventGameStateChanged/eventJoin.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-07 01:57:35 +02:00
BruebachL
b0e566ed54
[Client] Show custom zones in the card display widgets (#7206)
* [Client] Show custom zones in the card display widgets

Card group displays and deck zone displays learn to render custom
zones alongside the standard boards.

- Group display widgets treat custom-zone nodes like other group
  headers, keeping counts and layout consistent.
- Zone display widgets resolve their title through visibleNameFromName
  so custom zones show their user-chosen names localized like the
  standard zones.

* [DeckEditor] Apply sort criteria inside custom zones and align display order with the model

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-05 22:00:21 +02:00
BruebachL
0d09e633e3
[Client] Expose custom zone management in the deck editor (#7205)
* [Client] Expose custom zone management in the deck editor

Wires the state layer into every editor surface that shows deck zones.

- Deck dock: context menu on zones gains New/Rename/Delete/Change
  board actions, with per-zone submenus for adding cards.
- Card database dock and visual database display gain an add-to-zone
  submenu listing custom zones per board plus a create-zone entry.
- All prompt call sites pass validateNewZoneName so duplicates and
  reserved names are rejected inline before Ok unlocks.
- Rename reuses the same dialog in name-only mode, keeping one
  validation contract for every zone-name entry point.
- Change board marks the current board instead of offering a no-op,
  and the state layer refuses moves onto boards holding a same-named
  zone from imported decks.

* [DeckEditor] Address custom-zone menu and export review feedback

* [DeckLoader] Keep the sideboard marker and block ordering when exporting nested zones

- saveToStream_DeckZone threads the owning board zone name down to the card
  writer, so cards in a custom zone under the sideboard keep their SB:
  prefix instead of being re-imported into the maindeck
- nested sub-zones are collected during the loop and written after the
  parent zone's own header and cards, so they no longer read as part of the
  zone printed before them

* [DeckEditor] Fix move-to-zone menu use-after-free and per-zone enabled state

- resolve the card name/provider/collector number before createNewCustomZone
  rebuilds the model tree, then re-find the refreshed index via findCard and
  move it (mirrors the decrementCard re-find pattern)
- the enabled test now compares the card's own zone (nearest custom-zone
  ancestor, else its board), matching moveCardToZone's lookup, so moving a
  card out of a custom zone back to the board root is offered and the card's
  own zone is disabled

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-05 22:00:21 +02:00
BruebachL
9677fad342
[Client] Add zone management to the deck state manager (#7204)
* [Client] Add zone management to the deck state manager

State-layer operations for custom deck zones, plus the shared prompt
dialog that later editor menus will call into.

- moveCardToZone relocates every copy of a card row into any zone,
  refusing non-card rows and tokens so miswired selections can never
  shred a group or turn tokens into deck cards. The current zone is
  found by walking ancestors, which also handles legacy top-level
  zones.
- createCustomZone, renameCustomZone, moveCustomZone and
  removeCustomZone wrap the tree API with memento history, model
  rebuilds and deck hash refreshes via modifyTree.
- Same-board zone moves return success without minting a history
  entry, keeping the undo log honest.
- promptForNewZone asks for a name and the parent zone, keeps Ok
  disabled until the trimmed name passes a caller-supplied validator
  (shown inline as an error), and reports its own translation context.

Took 14 minutes

# Commit time for manual adjustment:
# Took 6 minutes

# Commit time for manual adjustment:
# Took 33 seconds

* [DeckEditor] Address zone-management review feedback

- Expose DecklistNodeTree::hasZoneName and use it in validateNewZoneName
  so the uniqueness scan covers custom zones on every board, not just the
  standard ones.
- Hide the board selector in the rename dialog path where it is not used.
- Emit deckHashChanged after refreshDeckHash so the deck hash label stays
  current after zone create/rename/move/remove.

* [DeckEditor] Notify card set changes after zone edits and drop the board scan

- modifyTree emits cardNodesChanged alongside deckHashChanged so the
  banner-card combo and printing in-deck counts refresh after removing a
  zone that still holds cards
- DecklistNodeTree::findCustomZoneByName is public and moveCustomZone uses
  it, locating zones under non-standard boards (e.g. tokens) instead of
  scanning only main/side/maybeboard

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-05 22:00:21 +02:00
BruebachL
4e9d148163
[TabSupervisor] Initialize all tabs (#7231)
Some checks failed
CodeQL / Analyze (cpp) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
Build Desktop / Configure (push) Has been cancelled
Build Docker / Servatrice (arm) (push) Has been cancelled
Build Docker / Servatrice (x86) (push) Has been cancelled
Build Desktop / Debian 13 (push) Has been cancelled
Build Desktop / Debian 12 (push) Has been cancelled
Build Desktop / Fedora 44 (push) Has been cancelled
Build Desktop / Fedora 43 (push) Has been cancelled
Build Desktop / Servatrice_Debian 12 (push) Has been cancelled
Build Desktop / Ubuntu 26.04 (push) Has been cancelled
Build Desktop / Ubuntu 24.04 (push) Has been cancelled
Build Desktop / Arch (push) Has been cancelled
Build Desktop / macOS 13 Intel (push) Has been cancelled
Build Desktop / macOS 14 (push) Has been cancelled
Build Desktop / macOS 15 (push) Has been cancelled
Build Desktop / macOS 26 Debug (push) Has been cancelled
Build Desktop / Windows 10 (push) Has been cancelled
Build Docker / Publish multi-platform Servatrice image (push) Has been cancelled
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-01 16:11:02 +02:00
BruebachL
45c7ff6f87
[Mods] Properly close card art rules tab on disconnect (#7227)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-09-01 11:31:49 +02:00
RickyRister
03de1af678
[VDS] Fix search filter not being applied on refresh (#7229)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
2026-08-31 10:28:50 +02:00
RickyRister
3dc9dba67a
[SettingsPage] Refactor: Clean up order of variables (#7184)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [SettingsPage] Refactor: Clean up order of variables

* fixes
2026-08-30 14:43:23 -07:00
BruebachL
68e4fa054d
[UserList] Add invite button to hover popup (#7144)
Some checks failed
CodeQL / Analyze (cpp) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
Build Desktop / Configure (push) Has been cancelled
Build Docker / Servatrice (arm) (push) Has been cancelled
Build Docker / Servatrice (x86) (push) Has been cancelled
Build Desktop / Debian 13 (push) Has been cancelled
Build Desktop / Debian 12 (push) Has been cancelled
Build Desktop / Fedora 44 (push) Has been cancelled
Build Desktop / Fedora 43 (push) Has been cancelled
Build Desktop / Servatrice_Debian 12 (push) Has been cancelled
Build Desktop / Ubuntu 26.04 (push) Has been cancelled
Build Desktop / Ubuntu 24.04 (push) Has been cancelled
Build Desktop / Arch (push) Has been cancelled
Build Desktop / macOS 13 Intel (push) Has been cancelled
Build Desktop / macOS 14 (push) Has been cancelled
Build Desktop / macOS 15 (push) Has been cancelled
Build Desktop / macOS 26 Debug (push) Has been cancelled
Build Desktop / Windows 10 (push) Has been cancelled
Build Docker / Publish multi-platform Servatrice image (push) Has been cancelled
* [Client] Send game invites from the user context menu via a private message

The user context menu gains an "Invite to Game" submenu listing the
inviteable games in the room (the inviter's own games, honoring the
buddy-only setting). Picking one opens a private message to the target
user with a cockatrice://joingame link naming the game, so the target
gets a clickable invite instead of a raw URL. Multi-game rooms offer a
picker; a single inviteable game sends directly. Sending a message to
an offline user no longer swallows the draft — it reports that the
user is offline and keeps the typed text.

Took 30 seconds

Took 1 minute

* [Client] Open the invite dialog taller by default without enforcing a minimum size

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-29 21:35:28 +02:00
BruebachL
6f86c45ea8
[Refactor] Extract shared deck conversion prompt helper (#7107)
Move the deck-to-.cod conversion prompt logic (format check, saved
preference handling, overwrite confirmation, dialog) out of
DeckPreviewWidget into dlg_convert_deck_to_cod_format so the deck
editor can reuse it without duplicating it.

Took 4 minutes

Took 4 minutes

Took 1 minute

# Commit time for manual adjustment:
# Took 3 minutes

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-29 21:12:11 +02:00
RickyRister
83833f4684
[UserList] Refactor: split dialog code to separate file (#7189)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
2026-08-28 22:50:06 -07:00
RickyRister
dba7cc73a4
[HomeTab] Introduce button color source setting (#7181)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
2026-08-25 19:27:07 +02:00
BruebachL
b3e126f904
[VDS] Drive folder and preview widgets from the model (#7106)
* [VDS] Drive folder and preview widgets from the model (MVC views)

Took 16 minutes

Took 8 minutes

Took 3 minutes


Took 11 minutes

* Rebase whoopsie

Took 4 minutes

* Hide widgets instead of destroying, go back to signals, rename for consistency.

Took 13 minutes

Took 4 seconds

Took 26 minutes

Took 5 seconds

# Commit time for manual adjustment:
# Took 9 minutes

* Make VDS startup smooth: batch deck loads, guard preview resizes

- Move color identity computation into the background load task and apply
  finished deck loads in bounded batches per event loop turn, so finishing
  hundreds of loads at once cannot stall the UI thread
- Skip redundant resize work in DeckPreviewWidget when the banner width did
  not change, and collect the clamped children once instead of searching the
  widget tree on every layout pass

Took 19 minutes

# Commit time for manual adjustment:
# Took 3 minutes

* [VDS] Expose filter matches as a proxy role instead of dropping rows

The folder display scanned source-model rows and probed acceptance with
mapFromSource(...).isValid(), reaching into both models for one answer.

The proxy now keeps every row and exposes each row's search/tag/color
filter result through FilterMatchRole. The folder display and the tag
filter read everything off proxy indexes, and hidden previews keep their
sorted position in the flow layout instead of being appended at the end.

Took 11 minutes

* [VDS] Bound pending-load drain by time and make row lookups O(1)

The fixed DECK_LOADS_PER_TURN = 24 cap had no measured basis. It was guessed and existed
because every applied load emitted dataChanged into each DeckPreviewWidget,
whose handler resolved its own row with an O(n) linear scan per widget.

The model now maintains a file path -> row hash kept in sync across scans,
renames and deletions, so rowForFilePath is O(1) and the fan-out cost is
gone at its source. The drain applies finished loads until a small time
budget per event loop turn runs out, so throughput self-tunes instead of
relying on an arbitrary count.

* Actual minimal fix for resize squishing

Took 20 minutes

* Fix color widget sizing

Took 16 minutes

* [BannerWidget] Also set a max height

Took 4 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-25 19:23:16 +02:00
BruebachL
e589429bd9
[Client] Pin user list header length to the viewport width (#7158)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Client] Pin user list header length to the viewport width

The header stretch mode kept a resize section property, so after any
column grew past the viewport the list carried an invisible horizontal
pan range that scrolled rows sideways without visual feedback

Drop the leftover property so displayed length always equals viewport
width and horizontal panning is impossible

* Show columns 1 and 2

Took 12 minutes

Took 2 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-25 06:33:57 +02:00
BruebachL
2b7b4e8168
[App] Add onboarding wizard (#7064)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [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>
2026-08-24 23:05:58 +02:00
BruebachL
24d8d8be3b
[VDS] Cache mana symbol renders and skip redundant resizes (#7167)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [VDS] Cache mana symbol renders and skip redundant resizes

- Render each mana symbol once at a bounded master size and derive every
  requested size from the cached master, avoiding repeated full-size SVG
  rasterization on the GUI thread
- Share scaled results through a process-wide cache keyed by symbol and
  size, so repeated widget creation and rescales don't redo the work
- Skip redundant resize work in ColorIdentityWidget and ManaSymbolWidget
  when sizes did not change

Took 8 minutes


Took 50 seconds

* Move to pixmap generator

Took 8 minutes

Took 4 seconds

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-24 19:26:41 +02:00
BruebachL
b13c682a7a
[DeckList] Make deck tree card traversal recursive (#7175)
* [DeckList] Make deck tree card traversal recursive

getCardNodes and forEachCard now descend into nested zones instead of
assuming a flat main/side/token layout. For today's flat trees this is
behavior-preserving; it also removes two latent crashes (unchecked
dynamic_cast dereference, null card nodes passed to forEachCard
callers). Nested zones are introduced by later custom-zones units.

Took 3 minutes


Took 7 seconds

Took 9 seconds

* Fix rebase mistake.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-24 18:44:05 +02:00
BruebachL
22b0f69706
[UserList] Request banner card art for visible rows and hovered popup (#7172)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-24 18:25:14 +02:00
BruebachL
fecbbab983
[Client] Replace playmat crop spinboxes with a direct manipulation preview (#7161)
* [Client] Replace playmat crop spinboxes with a direct manipulation preview

The numeric fields exposed raw parameters with no relation to what the
game draws, accepted values the renderer clamps away, and no way to see
the result before committing

The preview now renders through the exact game pipeline into a viewport
shaped like a fresh board stack plus table area, with dimmed strips
marking where a developed table crops further. Drag pans, wheel zooms,
arrow keys nudge, plus and minus zoom, Backspace or Esc restores the
crop as of focus gain and lets Esc close the dialog when unchanged.
Focus ring and accessible name and description cover keyboard and screen
reader users, new paints use palette roles so themes recolor them

Took 25 minutes

Took 3 minutes


Took 54 seconds

* Remove stale constant

Took 3 minutes


Took 26 seconds

* Rebase

Took 2 minutes


Took 3 seconds

* Add editor spinboxes again

Took 4 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-24 18:22:48 +02:00
BruebachL
0d0488cb5b
[Client] Edit banner crop by direct manipulation in the card art dialog (#7162)
The offset and zoom fields exposed raw numbers with no relation to the
strip, and the stored printing reset to the first local printing on
every open

The preview now paints through UserListPainter::drawCardArt itself, so
what you see is exactly what the user list renders. Drag pans the art
vertically at output scale, wheel zooms, arrow keys nudge, plus and
minus zoom, Backspace or Esc restores the crop as of focus gain and lets
Esc close the dialog when unchanged. Margins stay explicit spinboxes
since they trim the strip sides with no natural drag mapping. Legacy
stored zoom below the gesture floor is normalized once on open, focus
ring and accessible name and description cover keyboard and screen
reader users, all strings set in retranslateUi

Took 7 minutes

# Commit time for manual adjustment:
# Took 55 seconds


Took 41 seconds

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-24 18:01:59 +02:00
RickyRister
c3599be89b
[HomeTab] Fix incorrect handling of invalid backgroundSource setting (#7180)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
2026-08-23 23:58:43 -07:00
BruebachL
a571a9aa04
[UserList] Restore accent-tinted rows for regular users in light mode (#7171)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 23:00:08 +02:00
BruebachL
648b472bfb
[UserList] Prevent failed loads from poisoning the banner card art cache (#7170)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 22:46:07 +02:00
BruebachL
daa0dcb2ea
[UserList] Keep banner art when a params-less user copy arrives (#7173)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 22:45:49 +02:00
BruebachL
21633eb0ec
[UserList] Raise banner card art cache to 1024 entries (#7169)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 22:33:26 +02:00
BruebachL
25a9e37ff8
[Client] Restore stored banner printing when the art dialog opens (#7157)
Two gaps made opening and confirming the banner dialog silently switch
the banner to the default art of the first local printing. The caller
dropped the card provider id when constructing the initial params, and
the constructor left the printing combo wherever onCardNameChanged put
it, which is always the first printing

Pass the provider id through, restore it in the combo when it resolves
locally, and keep it verbatim when it does not

Took 2 minutes

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 17:28:37 +02:00
BruebachL
bb0a96984d
[Game] Derive playmat sampling window from shared clamped helpers (#7159)
* [Game] Derive playmat sampling window from shared clamped helpers

The crop formula computed the sampled window inline with an unclamped
zoom floor, so stored vertical offsets below half of travel were dead
and extreme zooms could sample outside the art

Remap verticalOffset to place the window top edge within its travel,
floor zoom at visible width over min card side with a 4.0 ceiling,
clamp pan along the margin sum constant segment, and expose
playmatClampedZoom, playmatWindowSide and aspectFitRect so the game
renderer and any editor share one geometry model

Zoom 1 rendering is bit identical to before

Took 7 seconds

* Comments.

Took 29 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 17:26:15 +02:00
BruebachL
c42fb6691d
[Client] Fix user list banner art rendering under display scaling (#7160)
Cached card art pixmaps carry the screen device pixel ratio, so both
banner painters did their crop math on scaled pixels and blitted the
result at raw over logical size, clipping art into its top left quadrant
on any display above 100 percent

Normalize a local copy to DPR 1 before crop math in UserListPainter and
the popup header, clamp srcX and srcY bounds against stored zoom below 1,
keep shared cache entries untouched

Took 15 minutes

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 11:44:59 +02:00
BruebachL
8a5723c0b5
[Client] Show latency in status bar and server tab indicator (#7154)
* [Client] Show live connection latency in the status bar

Add a permanent status-bar label fed by ConnectionController's
pingStatsUpdated: shows the latest round-trip time, hides while
disconnected or without samples, and carries a tooltip with
Last/Median/95th percentile/Maximum over the rolling sample window
(mirrored into the accessible description). The server tab gets the
same stats as its tooltip.

Took 2 minutes

Took 2 minutes

Took 1 minute

Took 48 seconds

Took 25 seconds

Took 4 minutes

* [Client] Graph connection latency history in the status bar

Add LatencyGraphWidget, a size-agnostic bar sparkline over the rolling
sample window: heights scale to the window's own range while colors map
onto an absolute quality ramp, so a steady good ping stays green. Embed
it in the new LatencyStatusWidget together with the textual ping
readout and feed both through ConnectionController's forwarded signals;
the whole area hides while disconnected or without samples.

Took 9 minutes

Took 14 seconds

* [Client] Show latency details when clicking the ping display

Clicking the status bar ping area opens a popup with a larger instance
of the latency graph plus the numeric statistics, selectable and
mirrored into the accessible name. Qt::Popup closes it on any outside
click; contents refresh live while open.


Took 33 seconds

* Fixup from core commit

Took 6 minutes

Took 5 seconds

Took 5 minutes

* Lint.

Took 12 minutes

* Consolidate.

Took 6 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 02:25:04 +02:00
BruebachL
fc0199d3db
[GamesModel] Clear games types before merging (#7156)
Took 7 minutes

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-23 01:47:48 +02:00
BruebachL
ed4eb1cb31
[Server/Client/Protocol] Reporting users + moderation queue functionality (#7091)
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run
* [Server/Client/Protocol] Reporting users + moderation queue functionality

Took 6 minutes

Took 3 minutes

Took 8 seconds

Took 11 minutes

Took 12 minutes

Took 7 minutes

Took 15 seconds

Took 2 minutes

Took 1 minute


Took 30 seconds

Took 16 seconds

* CI Fix

Took 6 minutes

* CI Fix

Took 6 minutes

* [Protocol] Add moderation investigation commands

Adds the protocol layer for the moderation investigation suite:
- Command_GetUserSessions/GetUserAlts/GetModeratorLastLogins/ResetUserPassword/RemoveUserAvatar (1013-1017)
- Response extensions 1215-1219 with ServerInfo messages for sessions, alts, and staff logins
- last_login on Response_ReportUserInfo and warning_il on Response_WarnList

Took 2 minutes

* [Utility] Add warning categories parser with infraction levels

Parses the server's 'officialwarnings' setting (comma-separated, optional
'|IL' suffix) into WarningCategory structs so the client can display the
infraction level of each warning category. Includes GTest coverage.

* [Server] Add moderation investigation tools

Implements the server side of the moderation suite:
- getUserSessions/getUserAlts/getModeratorLastLogins/removeUserAvatar DB methods
- Handlers for all five new commands with audit records (PASSWORD_RESET,
  REMOVE_USER_AVATAR); password resets return a generated temporary password
- cmdGetWarnList now reports per-category infraction levels from the
  officialwarnings setting; cmdReportUserInfo reports last_login
- Update servatrice.ini.example with the warning taxonomy
- Password/avatar mutations report RespNameNotFound when the user does not exist

* [Client] Add moderation tab with investigate, password reset, and avatar removal

- New Moderation tab: search a user to show account info, alternate
  accounts, login sessions, and staff last logins; actions to reset the
  user's password (shows the generated temporary password) and remove the
  user's avatar
- 'Investigate user' entry in the user context menu opens the tab pre-loaded
  for that user
- Warning dialog shows the infraction level of each warning category
- Tab wired into TabSupervisor with a moderator-gated menu action, shortcut,
  and tabs.ini persistence (default closed)

* [Server/Client/Protocol] Address PR #7091 review: security, bug, and perf fixes

Security:
- Promote RESET_USER_PASSWORD to admin-only dispatch (was moderator-accessible)
- Reject password reset on users with equal/higher privilege than caller
- Notify affected user via Event_NotifyUser::CUSTOM when password is reset
- Add server-side category whitelist for reports
- Drop reporter name fallback in comment/details authorization (ID-only)
- Force password change: new DB column + login enforcement + client disconnect

Bugs:
- XSS via QTextEdit::append() → insertPlainText() in report tab and utils
- allNotified initialized to true even with empty recipients list
- Warning combo box: use currentData() instead of baked-in display text
- Report resolution now records who resolved (resolved_by column + audit)

Performance:
- IP-correlation subquery: add 6-month window + LIMIT 200
- getUserSessions: clamp limit to 500

Non-blocking:
- Palette-aware colors in report_utils.cpp (dark/light mode)
- Report list pagination: offset/limit fields + total_count in response
- SessionCommand enum gap comment for reserved values 1201-1203

Schema: 36→37 (force_password_change), 37→38 (resolved_by)

Took 12 minutes


Took 16 seconds

* Fix macOs pedantry

Took 5 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-21 15:00:13 +02:00
BruebachL
9eafd90a91
[Game] Playmats (#7101)
* [Game] Playmats

Took 19 seconds

Took 1 minute

* [Playmats] Add fixed override and configurable fallbacks to settings.

Took 29 minutes

Took 43 seconds

* Add main to test.

Took 1 minute

Took 29 seconds

* Move settings to own group

Took 11 minutes

* Some attempts to refresh macOS compositor

Took 2 minutes

* Try something else

Took 17 minutes

* Don't manipulate live list

Took 11 minutes

* Change things about resolution, address comments.

Took 45 minutes

Took 12 minutes

* Comments.

Took 14 minutes

Took 8 seconds

* Re-order settings menu location

Took 2 minutes

* Rename PlaymatResolution to Info and add enums

Took 8 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-21 10:40:49 +02:00
BruebachL
74a454552a
[Cards] Artist attribution (#7092)
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run
* [Cards] Artist attribution

Took 7 minutes

Took 4 minutes

* Nudge attribution pill on home screen to align

Took 3 minutes


Took 28 seconds

Took 38 seconds

* Lint.

Took 3 minutes

* Lint.

Took 2 minutes

* Fix rebase whoopsie

Took 5 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-21 02:54:36 +02:00
BruebachL
7c550ee505
[Game] Add an invite button to non-started and not full games (#7143)
* [Client] Send game invites from the user context menu via a private message

The user context menu gains an "Invite to Game" submenu listing the
inviteable games in the room (the inviter's own games, honoring the
buddy-only setting). Picking one opens a private message to the target
user with a cockatrice://joingame link naming the game, so the target
gets a clickable invite instead of a raw URL. Multi-game rooms offer a
picker; a single inviteable game sends directly. Sending a message to
an offline user no longer swallows the draft — it reports that the
user is offline and keeps the typed text.

Took 1 minute

* [Client] Add invite-to-game dialog to the game window

Took 15 seconds

* [Client] Open the invite dialog taller by default without enforcing a minimum size

* Move button to bottom

Took 3 minutes

* Address comments.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 21:37:15 +02:00
BruebachL
a8bacc5296
[VDS] Add async-scanned model and sort/filter proxy (#7105)
* [VDS] Add async-scanned model and sort/filter proxy (model layer)


Took 1 minute

Took 27 seconds

* Address comments

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 11:20:26 +02:00
BruebachL
765ebf8fb1
[UserList] Context menu invite (#7138)
* [Client] Send game invites from the user context menu via a private message

The user context menu gains an "Invite to Game" submenu listing the
inviteable games in the room (the inviter's own games, honoring the
buddy-only setting). Picking one opens a private message to the target
user with a cockatrice://joingame link naming the game, so the target
gets a clickable invite instead of a raw URL. Multi-game rooms offer a
picker; a single inviteable game sends directly. Sending a message to
an offline user no longer swallows the draft — it reports that the
user is offline and keeps the typed text.

Took 50 seconds


Took 3 minutes

* [Client] Extract sendPrivateMessage() to fix invite message draft overwrite

sendInviteMessage() was calling sayEdit->setText(text) then sendMessage(),
which overwrites any text the user had typed.  Extract the command-building
and sending logic into a new sendPrivateMessage(const QString &text) method
that takes the text directly.  sendMessage() now calls it after its guards
and clears sayEdit; sendInviteMessage() calls it directly without touching
the input field at all.

Took 33 minutes

* Rename method, address comments.

Took 5 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 10:49:19 +02:00
BruebachL
b2cdf44bbd
[UserList] Show amount of online buddies (#7126)
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 15 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run
* [UserList] Show amount of online buddies

Took 11 minutes

* [UserList] Replace early return with if-else in updateSectionDivider

RickyRister nit: the code is easier to follow with a standard if-else
branch instead of an early return for the Buddy section.

Took 1 minute

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 03:58:41 +02:00
BruebachL
60ee81cfbe
[Client] Route cockatrice:// link clicks from chat to the intent chain (#7136)
* [Client] Route cockatrice:// link clicks from chat to the intent chain

A cockatrice:// link clicked in chat is currently handed to the OS (or
does nothing in-process). Clicks now emit a cockatriceLinkActivated signal
that travels ChatView -> Tab -> TabSupervisor -> MainWindow, which feeds
the URL through the same IntentUrlParser the OS activation path uses, so
the join runs entirely in-process. card/user schemes and all other links
behave as before.

* [Client] Route cockatrice:// link clicks from the in-game chat to the intent chain

* [Client] Reuse one IntentUrlParser instance for cockatrice:// links

Took 59 seconds

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 01:03:37 +02:00
BruebachL
3de7882f0c
[UserList] Fix context menu crash by correctly parenting (#7145)
Took 5 minutes

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 00:53:43 +02:00
BruebachL
fe53f9c3eb
[Chat] Render game link buttons (#7135)
* [Chat] Render cockatrice://joingame links in chat as clickable buttons

Words starting with cockatrice:// become button-style anchors labelled with
the game description, id and server (falling back to id + server for links
built without a description). The description is spliced via the multi-arg
arg() overloads so a title containing "%…" cannot corrupt the label.

Keyboard link access is enabled so the anchors are reachable without a mouse.

* [Chat] Fix percent-encoding and scheme gating in game-link chat labels

Game descriptions containing '%' were rendered as '%25' in the chat
button label because QUrlQuery's default decode leaves %25 untouched.
Use QUrl::FullyDecoded for the description item, and restrict the
invite-button treatment to cockatrice://joingame links; any other
cockatrice:// scheme now falls through to plain text.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 00:26:33 +02:00
BruebachL
f466a25893
[Client] Keep the message draft and notify when the recipient is offline (#7142)
* [Client] Keep the message draft and notify when the recipient is offline

* Don't blindly assume a user is online.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-08-17 00:16:55 +02:00