Replace remaining QPixmap("theme:...") call sites with themePixmap() so icons, replay controls, card backs, and other images resolve to -dark/-light variants under theme schemes. Stem-exact 1:1 migration; behavior unchanged for non-variant themes.
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [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>
* [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>
* [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>
* [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>
* [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>
* [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>
* [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>
* [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>
* [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>
* [Tabs] Add a setting to define startup tab on application launch.
Took 29 minutes
* Naming and sizing
Took 4 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Settings] Shuffle some settings around
Took 21 minutes
Took 1 hour 25 minutes
* [Settings] Camel case everything
* Revert debug schema change
* Add new classes
* Fix card counters writing to global
* Fix CI tests
* Fix Windows CI
* interface() is a protected keyword for MSVC
Took 5 minutes
Took 5 seconds
* [Settings] Keep menu settings on the appearance settings page
Leave the 'Menu settings' group box on the appearance settings page for
now; relocating it to the user interface settings page will be done in a
separate PR.
Took 6 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>
* [Settings] Split cache_settings into multiple files
Took 9 minutes
Took 4 minutes
* [Settings] Fwd declare settings classes in cache_settings
Took 15 minutes
* Fix oracle includes.
Took 8 minutes
* Address comments, fix windows CI
Took 8 minutes
* fix copy constructor visibility
Took 3 minutes
* lint
Took 2 minutes
* Fix native format tests.
Took 5 minutes
* Remove test header guard
Took 4 seconds
* Remove tests invalid in CI environ
Took 24 seconds
* Adjust to rebase.
Took 11 minutes
* Change settings file name.
Took 8 minutes
---------
Co-authored-by: Lukas Brübach <lukas.bruebach@bdosecurity.de>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Room] Additionally show a tab for friends and ignored users instead of just all online users.
Took 21 minutes
Took 12 minutes
* [Room][UserList] Introduce style delegate for user list
- Allow users to set a card name and parameters as their background banner
- Allow mods to white/blacklist cards
- Allow toggling back to the old display style
Took 7 minutes
Took 28 seconds
Took 2 minutes
Took 2 minutes
* Right checkstate.
Took 14 minutes
Took 2 minutes
* Utility for test.
Took 9 minutes
Took 8 seconds
Took 2 seconds
* Lint.
Took 10 minutes
* Algorithm for sql schema migration
Took 13 minutes
* Use {prefix}, bound card name, return errors.
Took 27 seconds
* Convert queue to while loop.
Took 19 seconds
* Hover popup.
Took 36 minutes
Took 1 minute
* More granular signals, popup for user info.
Took 25 minutes
Took 8 seconds
Took 16 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Messages] Add option to ignore private messages from non-buddy users
* [Messages] Exclude Moderator/Admin from non-buddy ignore filter
Moderator and Admin messages should not be filtered out when the
'Ignore private messages from non-buddies' setting is enabled, to
ensure that important warnings from server staff reach users.
* style: Add braces to all control flow statements
Standardize code style by adding explicit braces to all single-statement
control flow blocks (if, else, for, while) across the entire codebase.
Also documents the InsertBraces clang-format option (requires v15+) for
future automated enforcement.
* InsertBraces-check-enabled
* TabArchidekt and Archidekt API integration.
Took 37 seconds
Took 4 minutes
Took 40 seconds
Took 4 minutes
* Lint.
* Lont.
* Search bar, fancier display, resolve providerId
* Delegate click to base.
* Be explicit for pedantic compilers.
* Liiint.
* Leave them default I guess
* Leave them default I guess
* Small fixes.
* New utility display widgets.
* New style for deck listing.
* Lint.
* Lont.
* Scale things.
* Delegate paint to base.
* Use default Archidekt preview image for decks without featured.
* Consistent sizes.
* Increase font size, qt version guard.
* More version guards.
* Clean up filter layout, use mana symbols.
* Set content margins.
* Refresh on filter change.
* Lint.
* Better elision.
* Query actual new endpoints, new query parameters.
* Doxygen, reorder fields in constructor, readability.
* Update page size doc to min size.
* Update initial min deck size value.
* Add label to page selection.
* Okay, so, people upload a lot of 1 card decks frequently.
* Whoops.
* Add a selection combobox for sorting logic.
* Debounce and limit searches.
* Include.
* Lint.
* Don't imply that Archidekt supports multiple cards/commander names.
* Let's not lambda it and slot it instead.
* Overload.
* Add button to home tab.
Took 8 minutes
* Adjust to selection model change.
Took 5 minutes
* Cleanup auto-generated comments.
Took 8 minutes
* Remember card sizes.
Took 1 minute
* Initialize with correct size.
Took 3 minutes
* Use correct placeholders.
Took 2 minutes
* Style lint.
Took 16 minutes
* Parse double-faced cards correctly.
* Parse double-faced cards correctly.
* Allow TabArchidekt to use VDE group/sort/display buttons
* Lint.
* Indicate that things are clickable.
* Min treshold for nicer display.
* Lint.
* We have good labels at home.
* We do a little linting.
* Qt version guards.
* Qt5 is the devil.
* Update comments.
* Lint comments.
* More doxys.
* One more doxy.
* Lint.
* Update.
* Small fixes.
Took 7 minutes
Took 13 seconds
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Cleanup] Unused #includes
Took 44 minutes
* [Cleanup] More unused #includes
Took 55 minutes
* [Cleanup] Include QSet
Took 4 minutes
* [Cleanup] Include QDebug in deck_list.cpp
Took 3 minutes
* [Cleanup] Include protocol stuff in servatrice_database_interface.h
Took 3 minutes
* [Cleanup] Include QDialogButtonBox
Took 8 minutes
* [Cleanup] Include QUrl
Took 8 minutes
* [Cleanup] Include QTextOption in header.
Took 3 minutes
* [Cleanup] Include QMap in user_list_manager.h
Took 8 minutes
* [Cleanup] Adjust qjson
Took 8 minutes
* [Cleanup] include button box.
Took 3 minutes
* [Cleanup] Redo fwd declarations.
* [Cleanup] Redo last removed fwd declarations.
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [DeckList] Disable copy constructor
Took 1 hour 44 minutes
Took 1 minute
# Commit time for manual adjustment:
# Took 28 seconds
Took 33 seconds
* Revert member to pointer.
Took 19 minutes
* Revert pulling up setters/getters now that getDeckList is no longer const.
Took 6 minutes
* Revert more.
Took 2 minutes
* One more fix.
Took 1 minute
* Update cockatrice/src/interface/deck_loader/deck_loader.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>
* A DeckLoader is not a DeckList.
Took 2 hours 39 minutes
* Explicitly initialize base class in copy constructor?
Took 3 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* Have CardDatabase::getPreferredPrintingInfo respect card provider ID overrides (pinned printings)
Took 13 minutes
Took 37 seconds
Took 10 seconds
Took 10 seconds
# Commit time for manual adjustment:
# Took 30 seconds
Took 15 seconds
Took 8 minutes
Took 21 seconds
* Move settings cache and settings card preference provider out of libcockatrice_settings and into cockatrice
Took 52 minutes
Took 9 minutes
Took 1 minute
* Temp cache.
Took 16 minutes
* Dependency Injection for SettingsCache
* Turn SettingsCache into a QSharedPointer.
* Implement interfaces for settings that need it
Took 2 hours 38 minutes
* Adjust oracle.
Took 5 minutes
* Move abstract/noop interfaces to libcockatrice_interfaces so they can be linked against independently.
Took 52 minutes
* Clean up some links.
Took 3 minutes
* Cleanup two includes.
Took 3 minutes
* More fixes.
Took 7 minutes
* More includes that slipped past.
Took 3 minutes
* Stop mocking and start injecting for tests.
Took 15 minutes
* I don't know why remote_client was including main.
Took 4 minutes
* Include.
Took 3 minutes
* Lint.
Took 2 minutes
* Don't use Qt pointers.
Took 1 hour 7 minutes
* Make parser use CardSettingsInterface
Took 13 minutes
* Also adjust constructor lol.
Took 8 minutes
* Lint.
Took 32 minutes
* Revert "Lint."
This reverts commit ecb596c39e.
Took 3 minutes
* Test.
Took 3 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>