mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-28 00:42:19 -07:00
8 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6823d54c1e
|
[DeckShare] Browse and open public decks with loading, error and accessibility states (#7245)
* [DeckShare] Browse and open public decks with loading, error and accessibility states Add a public-decks tab that lists decks published by other users using the server's deck visibility feature, previewing each deck's banner card, color identity, tags and upload time without downloading the deck list until the user opens it. - Add a public-decks tab with a shared-settings widget and a remote model that fetches the target user's decks and refreshes both automatically and on user request, with a loading indicator and a server-error message instead of a blank tab when the fetch fails or the connection drops - Render each deck as a focusable preview tile whose banner, color identity, tags and upload time follow the existing Preview settings, with the deck name announced as the tile's accessible name and Space/Enter opening the deck, mirroring the shared-deck preview tile - Show a message box when opening a public deck fails or arrives corrupted - Publish and unpublish decks from the server storage toolbar and context menu, toggling the deck's own visibility bit (what the server persists) rather than the inherited effective state, and batch the visibility refresh until the last in-flight change is acknowledged - Add the Show Upload Time setting so the tile's upload stamp can be hidden like the other preview details - Update the retranslateUi wiring for the new public-decks tab and rename the share action tooltip from "Deck share" to "Share link" * [DeckShare] Adapt deck upload to the server-derived banner and tag protocol The server now derives the banner card and tags from the uploaded deck list itself, so Command_DeckUpload only carries the client-computed color identity. Drop the reserved banner/tag setters from the editor and storage uploads, send the color identity on remote saves, and read tags from the now-repeated ServerInfo_DeckStorage_TreeItem field. * [DeckStorage] Refresh the visibility column with a guarded timer instead of a latch counter A dropped visibility reply used to leave the pendingVisibilityChanges counter permanently positive, so the Public/Private column never refreshed again and nothing reset it on disconnect. A restartable single-shot timer with a boolean guard re-reads the tree whenever publishes quiet down and is stopped on disconnect, so a lost reply costs one stale refresh instead of killing the column for the session. * [DeckStorage] Summarize batch publish failures when the batch drains Each rejected node stacked its own modal dialog, so publishing a ten-deck selection against a rejecting server made the user dismiss ten dialogs one at a time. Failures are now collected while the batch is in flight and shown as a single summary when the visibility refresh timer fires; a reply that lands outside an active batch still reports right away. * [PublicDecks] Time out the loading state so a dropped reply cannot wedge the tab loading only cleared in decksReceived, but the ping sweep can drop a pending command without ever emitting finished, leaving the tab stuck on 'Loading public decks...' and the refresh button permanently inert. A single-shot timer started per refresh clears the latch and reports a timeout; the latch also clears when the client disconnects. * [PublicDecks] Escape remote-crafted text in tooltips and the tab title Deck names and usernames come from other users' records and Qt renders QLabel tooltips as AutoText, so a name like '<h1><table>...' parsed as markup. Escape and bound the deck-name tooltip and escape the username interpolated into the title label. * [DeckStorage] Distinguish an inherited public state in the visibility column The column reported the effective state while publishing toggles the node's own bit, so a private deck inside a public folder already read 'Public' and toggling appeared to do nothing (and toggling again silently unpublished it). The cell now shows 'Public (inherited)' for that case and the tooltip explains why. * [PublicDecks] Run retranslateUi at construction and name the refresh button retranslateUi was never called from the constructor, so the tooltips set there were absent until a language change. Call it before the first refresh, and give the icon-only refresh button an accessible name for screen readers. * [PublicDecks] Keep the empty and status variants correct across language changes retranslateUi unconditionally rewrote the empty label to the 'nothing published' variant, stomping the 'no decks match your filters' choice rebuildGrid had made, and a visible loading message stayed in the old language. Let retranslateUi pick the same variant rebuildGrid does and re-show the status so it retranslates. * [VDS] Share one color-identity match rule between the two deck grids The remote public decks model verbatim-copied updateColorMatches' switch, down to the ExactMatch normalization and the fact that Includes/Excludes do not normalize case. Extract colorIdentityMatches() next to the FilterMode enum and call it from both so the subtle rule cannot drift. * [DeckStorage] Drop the unused tree widget model accessor The accessor handed the model out past the wrapper methods that exist to keep it encapsulated, and nothing in the stack called it. * [DeckShare] End the public-decks files with a trailing newline keeps the final line's diff clean and stops clang-format CI from flagging the files. * [VDS] Reuse the shared quick settings widget for the public decks tab PublicDecksQuickSettingsWidget was VisualDeckStorageQuickSettingsWidget minus the folders, banner and tooltip controls, with identical wiring for the shared keys and a version of the near-identical file to keep in sync by hand. Fold the Show Upload Time checkbox into the shared widget, give it a setPublicDecksMode() that hides the controls that do not apply, and delete the duplicate. * [PublicDecks] Drop stale deck-list replies after the loading timeout A reply that lands after its own loading timeout (the reverse of the ping sweep dropping the command) could stop the newer request's timeout timer and repaint the grid with out-of-date data. Each refresh now captures a monotonically increasing request id, and only the newest request's reply updates the grid. * [PublicDecks] Re-show a displayed failure message on language changes The status label carries both the loading and the failure message, and retranslateUi hid it whenever the model was not loading, so a language change while a server-error or timeout message was on screen swapped it for the (empty) grid. The tab now keeps the last failure text and re-shows it when not loading, clearing it once a new refresh starts. * [DeckStorage] Keep the visibility refresh armed until replies land The single-shot drain was armed with the 500 ms delay at send time, so a round trip slower than that drained before the server applied the change, re-read the old state and never re-armed, leaving the column stale until a manual refresh. The timer is now armed with the full network timeout at send time (a lost reply still costs one stale refresh) and re-armed with the short delay every time a reply lands. * [DeckShare] Close public decks tabs when the client disconnects TabSupervisor::stop() built tabsToDelete from the room and game tabs only, so a public decks tab survived a disconnect, sitting with stale contents and a refresh button that kept hitting the dead client. Its values are now folded into the same cleanup. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
430fc117b4
|
[UserContextMenu] Refactor: Consolidate actions (#7022) | ||
|
|
2914874720
|
[Room][UserList] Introduce style delegate (#6981)
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
* [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>
|
||
|
|
33e0f8699b
|
Standardize Doxygen documentation (#6885) | ||
|
|
d9c65d4ae0
|
[Move refactor] Reparent orphan classes (#6236)
* Move orphaned classes to their correct parent folders. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
Renamed from cockatrice/src/server/user/user_context_menu.h (Browse further)