ENH: add Discord Rich Presence support - #12059
Conversation
Optionally publish current activity to the user's Discord profile: the open project, slicing progress, and live print progress with a completion countdown when a printer is connected. Off by default and opt-in from Preferences, alongside a second toggle that hides project and print job names while keeping progress and status. Only the displayed strings, a printer model name and timestamps leave the machine; no geometry, thumbnails, file paths, G-code or account details. The application talks to a local unix socket or named pipe and opens no network connection. No new third-party dependency. Discord's local IPC is a length-prefixed JSON protocol, implemented directly rather than vendoring discord-rpc into deps/. JSON uses the bundled nlohmann/json. Socket work runs on one worker thread; the GUI thread only stores a snapshot under a mutex. Every wait carries a deadline, so an unresponsive Discord cannot stall the UI or delay shutdown. Discord renders both the elapsed and countdown timers itself from absolute timestamps, so frames are sent only when the state actually changes, rate limited to one per five seconds. Art assets are rasterised from existing icons in resources/images and committed under resources/images/discord for upload to the Discord developer portal. Nothing loads them at runtime. DISCORD_APPLICATION_ID in DiscordPresence.cpp points at a contributor-registered application so the feature can be evaluated as-is. Rich Presence requires an application id, and the owning account controls the name and artwork every user sees, so it should be re-pointed at an application owned by Bambu Lab before release. Partially addresses bambulab#6362. Dynamic model thumbnails and sharing prints into Discord channels are deliberately out of scope: Rich Presence cannot accept image bytes from the application, and channel posting would require a bot identity, an OAuth2 flow and server-side credentials.
| // Contributor-registered application, so the feature can be evaluated as-is. | ||
| // The owning account controls the name and artwork every user sees, so this | ||
| // should be re-pointed at an application owned by Bambu Lab before release. | ||
| static const char *DISCORD_APPLICATION_ID = "1542693447339745472"; |
There was a problem hiding this comment.
we can't use this hardcoded application clident id, maybe a configurable string?
There was a problem hiding this comment.
no id in the source now. added SLIC3R_DISCORD_APP_ID (CMake) which sets the default, discord_rich_presence_app_id in the config overrides it, so you can retarget it without a rebuild. Feature is disabled if neither is set.
-DSLIC3R_DISCORD_APP_ID=1542693447339745472 a test app I set up with the assets from resources/images/discord/.
| int budget_ms = 2000; | ||
|
|
||
| while (written < count) { | ||
| const ssize_t n = ::write(m_fd, src + written, count - written); |
There was a problem hiding this comment.
we should disable or hanle SIGPIPE for write operation
There was a problem hiding this comment.
Fixed per socket without changing the global handler. MSG_NOSIGNAL on Linux and SO_NOSIGPIPE on macOS. The EPIPE was already handled as a write failure.
Remove the hardcoded application id. The SLIC3R_DISCORD_APP_ID CMake cache variable supplies a compile-time default and the discord_rich_presence_app_id config key overrides it at runtime. Writing to the IPC socket after Discord quits raised SIGPIPE, whose default action terminates the process. Suppress it per socket with MSG_NOSIGNAL on Linux and SO_NOSIGPIPE on macOS instead of changig the process-wide signal disposition.
| bool DiscordIPC::write_all(const char *src, size_t count) | ||
| { | ||
| size_t written = 0; | ||
| while (written < count) { |
There was a problem hiding this comment.
can we have a 2000ms timeout like on linux?
Optionally publish current activity to the user's Discord profile: the open project, slicing progress, and live print progress with a completion countdown when a printer is connected.
Off by default and opt-in from Preferences, alongside a second toggle that hides project and print job names while keeping progress and status. Only the displayed strings, a printer model name and timestamps leave the machine; no geometry, thumbnails, file paths, G-code or account details. The application talks to a local unix socket or named pipe and opens no network connection.
No new third-party dependency. Discord's local IPC is a length-prefixed JSON protocol, implemented directly rather than vendoring discord-rpc into deps/. JSON uses the bundled nlohmann/json.
Socket work runs on one worker thread; the GUI thread only stores a snapshot under a mutex. Every wait carries a deadline, so an unresponsive Discord cannot stall the UI or delay shutdown. Discord renders both the elapsed and countdown timers itself from absolute timestamps, so frames are sent only when the state actually changes, rate limited to one per five seconds.
Art assets are rasterised from existing icons in resources/images and committed under resources/images/discord for upload to the Discord developer portal. Nothing loads them at runtime.
DISCORD_APPLICATION_ID in DiscordPresence.cpp points at a contributor-registered application so the feature can be evaluated as-is. Rich Presence requires an application id, and the owning account controls the name and artwork every user sees, so it should be re-pointed at an application owned by Bambu Lab before release.
Partially addresses #6362. Dynamic model thumbnails and sharing prints into Discord channels are deliberately out of scope: Rich Presence cannot accept image bytes from the application, and channel posting would require a bot identity, an OAuth2 flow and server-side credentials.