An (unofficial) open source Rust implementation of the Discord Game SDK.

Overview

⚔️ discord-sdk

Embark Embark Crates.io Docs dependency status Build status

An (unofficial) open source Rust implementation of the Discord Game SDK.

Why not use this?

  • This project is not official and is using a largely undocumented protocol that Discord could change/break at any time in the future.
  • There is already a Rust wrapper for the official Game SDK.
  • Your project is not also in Rust. We may add a C API for this crate in the future, but for now this is a Rust only project.

Why use this?

  • You use Rust for your project and want to integrate features such as rich presence/activities provided by Discord.
  • You don't want to have a dependency on a closed source, shared library.
  • You like to live dangerously (though this library does also have some automated tests!).

Implemented Features

TODO: Achievements

Activities (Rich Presence)

Commands

Events

Other

TODO: Applications

TODO: Voice

TODO: Images

Lobbies

Commands

Events

Other

TODO: Networking

Overlay

NOTE: These are only tested insofar as the protocol is (probably) correct, however, the overlay is currently extremely limited, and so we were unable to test that the overlay commands actually function correctly since our primary project is Vulkan.

Note, there are a few other cases that overlay will not work with. The overlay is currently not supported for Mac, games with Vulkan support, and generally old games.

Also note, the SDK itself and its documentation uses the utterly confusing terminology of Un/Locked when talking about the overlay, this crate instead uses Visibility, as in Visible or Hidden.

Commands

Events

TODO: Relationships

TODO: Storage

TODO?: Store

Users

Commands

Events

Testing

Unfortunately Discord does not provide a convenient way to perform automated testing, as it requires an actual working Discord application to be running and logged in, which makes automated (particularly headless) testing...annoying.

For now, it's required that you manually spin up 2 different Discord applications (eg, Stable and Canary) and log in with separate accounts on the same machine, then run one test at a time.

Activities

NOTE: This test does not work on Windows due to a bug in Discord with the Invite command.

cargo test --features local-testing test_activity

Lobbies

NOTE: This a does not test the lobby search functionality as that command seems to be non-functioning and never returns results, even if the REST equivalent does return the expected results.

cargo test --features local-testing test_local_lobbies

Contribution

Contributor Covenant

We welcome community contributions to this project.

Please read our Contributor Guide for more information on how to get started. Please also read our Contributor Terms before you make any contributions.

Any contribution intentionally submitted for inclusion in an Embark Studios project, shall comply with the Rust standard licensing model (MIT + Apache 2.0) and therefore be dual licensed as described below, without any additional terms or conditions:

License

This [contribution] is dual licensed under EITHER OF

at your option.

For clarity, "your" refers to Embark or any other licensee/user of the contribution.

Comments
  • Fix IPC socket location

    Fix IPC socket location

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    The /run/user/x/discord-ipc-y no longer seems as accurate as previously and fails to connect. /run/user/x/com.discordapp.Discord/discord-ipc-y does work though.

    sudo netstat -l -p | rg /run/user/ still lists the old path though: unix 2 [ ACC ] STREAM LISTENING 586043 376511/Discord --ty /run/user/1000/discord-ipc-0 So I would expect to find the socket when running ls /run/user/1000 which I don't. I checked the file descriptors directly of the pid: ls /proc/376511/fd | rg 586043 and do find the socket: lrwx------@ 64 oskar 25 Nov 12:56  36 -> socket:[586043] Confirming it's a unix socket: sudo grep -slw 586043 /proc/net/* /proc/net/unix

    I don't really now why that socket can't be found so instead of completely replacing I added it as a fallback. I suspect the same thing might be happening on Windows so want to confirm that before merging this. In that case I can fix Windows in the same pr.

    opened by Nehliin 5
  • Make the timestamp system in Activity closer to that of the Discord SDK, and more user friendly

    Make the timestamp system in Activity closer to that of the Discord SDK, and more user friendly

    Checklist

    • [X] I have read the Contributor Guide
    • [X] I have read and agree to the Code of Conduct
    • [X] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    After working with this crate in a recent project, the largest headache I encountered was the lack of ability to set just a start timestamp on activity (to get the (xx:xx elapsed) message in my status).

    This PR adds two new methods to ActivityBuilder and slightly changes IntoTimestamp and Timestamps to add this ability.

    I have added ActivityBuilder::start_timestamp and ActivityBuilder::end_timestamp which both set only their respective timestamp values when called. ~~I have also deprecated ActivityBuilder::timestamps (although this can be undone)~~, and changed its code to just call start_timestamp and end_timestamp. (Important note, calling both methods together will set a time range, like timestamps does)

    Both the start_timestamp and end_timestamp now take a generic T: IntoTimestamp instead of an impl IntoTimestamp since the Rust compiler seems to dislike the old way, throwing errors when the method is called.

    I have added an IntoTimestamp impl for i64, so crate users can easily enter a unix timestamp as an integer (more useful for testing than anything).

    Finally, to make setting only one timestamp at a time possible, I have added serde annotations to Timestamps to skip serialization of empty fields.

    I'll be keeping an eye on this PR for any requested changes, or comments.

    Related Issues

    None

    opened by ewpratten 2
  • Fix discord app registration on Windows

    Fix discord app registration on Windows

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Discord app registration was broken on at Win 11 (unclear if it worked on previous versions) due to the verbatim prefix (\\?\) that was added to the exe path. Apparently this isn't supported when the path with the prefix is saved in the registry as the shell open command. It would simply fail to open the registered app.

    I also compared to some other games I had registered and tweaked the DefaultIcon location (+ path to strip the prefix) as well as some other register key values to more closely mimic how the "official" registration is done. Code for the official version can be found here.

    Tested on Win 11 and could confirm the app launched correctly

    opened by Nehliin 0
  • Add support for Voice

    Add support for Voice

    Even though Voice is being deprecated, we're hoping to use Lobbies in the short term to get voice chat support. This works well, but one missing piece is that when joined to a lobby voice channel, you hear everyone, and everyone can hear you, which is fine for internal playtests, but might be a bit tedious with real users. Adding support for the Voice API in the SDK would allow us to add support for self muting and un/muting of other players in the lobby.

    enhancement 
    opened by Jake-Shadle 0
  • Fix relationship_update activity

    Fix relationship_update activity

    Gives relationship_update events their own activity type to avoid future differences between the formats, still sharing some types though.

    Also fixes an issue where timestamps converted from Discord's i64 representation, which is in milliseconds, but was converted as if it was in seconds. :stuck_out_tongue:

    Also fixes an issue where the strings such as state and details in the SET_ACTIVITY command must either be null/missing or else have something other than whitespace.

    Resolves: #13

    opened by Jake-Shadle 0
  • Timestamps in presence info of `relationship_update` are strings instead of ints

    Timestamps in presence info of `relationship_update` are strings instead of ints

    "{"cmd":"DISPATCH","data":{"type":1,"user":{"id":"123414231424","username":"name","discriminator":"52","avatar":"f62f2a755cb18c94dc5cda94441024f1","bot":false,"flags":0,"premium_type":0},"presence":{"status":"dnd","activity":{"assets":{"large_image":"spotify:ab67616d0000b273d1e326d10706f3d8562d77f8","large_text":"To the Moon"},"created_at":"1628629162447","details":"To the Moon","flags":48,"id":"spotify:1","name":"Spotify","party":{"id":"spotify:216453179196440576"},"session_id":"6bb1ddaea510750e905615286709d632","state":"Rob Curly","sync_id":"2qZFCu2kYtAagNQA7NZfCq","timestamps":{"end":"1628629327961","start":"1628629161811"},"type":2}}},"evt":"RELATIONSHIP_UPDATE","nonce":null}"
    
    bug 
    opened by Jake-Shadle 0
  • Add deprecation warning in README

    Add deprecation warning in README

    This hasn't been officially announced by Discord yet, but the Voice, Lobbies, and Networking functionality will be deprecated and removed sometime in the future. Since only the lobbies functionality has been implemented thusfar, we will mark that functionality as deprecated once it is official.

    opened by Jake-Shadle 0
  • Auto release script

    Auto release script

    cargo-release unfortunately calls the hook before it modifies any files, so just made my own script to do the release and file copying before tagging and pushing.

    opened by Jake-Shadle 0
  • Flesh out + examples

    Flesh out + examples

    Large refactoring both internally in the SDK but also the whole repo in order to have isolated examples that can have their own dependencies, but can still be run with a simple cargo run --example <name>.

    This also adds some "helper" DiscordHandler implementations both for testing and "real" usage which are now used in tests/examples.

    Adds a super simple LobbyStates helper that can be used to maintain the state of the lobbies as events are sent from Discord to show the state of members/metadata/etc. Users can use this or roll their own if they want to, unlike the official SDK which maintains the lobby state itself and has awkward methods to read the state from the SDK.

    Added 2 more examples:

    • repl - A simple CLI you can issue commands in to do things like create lobbies, update activity, etc
    • overlay - A simple egui/OpenGL application to attempt to show overlay stuff. I still wasn't able to get Discord overlay to work on Windows, but hey, I tried!
    opened by Jake-Shadle 0
  • Move off tokio fork

    Move off tokio fork

    We're currently using a fork of tokio 1.7 to add some needed methods to NamedPipeClient as it is brand new in 1.7, this is necessary for us to be able to publish new releases.

    opened by Jake-Shadle 0
  • Initial implementation

    Initial implementation

    This adds the base groundwork for replicating the official SDK as well as (mostly) complete implementations of the Activities, Lobbies, and Overlay portions of the SDK.

    The current implementation is largely hands off, meaning that it is up to the user to manage the actual state, unlike the official SDK. For example, if you create a lobby, and wanted to present the state of the lobby in a UI (the users in the lobby, whether those users are speaking, what messages had been sent to the lobby, and any metadata associated with the lobby or the users) you would need to keep the state of the lobby updated with all of the various events (member connected/disconnected/updated, member start/stop speaking, lobby updated) to accurately represent the complete lobby state as Discord would see it.

    One other thing, we are using a fork of tokio as named pipe support on Windows is extremely new, and was missing a few small methods that we need to be able to use the same exact I/O loop code on both Unix and Windows without having to have a separate special path just for Windows.

    opened by Jake-Shadle 0
  • Add mock server

    Add mock server

    Since Discord themselves don't provide any kind of headless test server for RPCs, there's no good way to do automated testing in a normal headless environment since it requires installing the full Discord app, and logging into it, which, AFAICT, is impossible in a headless environment as Discord doesn't support command line arguments.

    While testing locally in a regular desktop environment works, this is tedious and easy to miss stuff, especially from outside contributors, so I think it makes sense to make a unix domain socket/named pipe server that tests can fill out with preplanned responses/events to add a bit more sanity checking to CI.

    enhancement 
    opened by Jake-Shadle 0
Releases(0.3.2)
  • 0.3.2(Jan 5, 2023)

  • 0.3.1(Nov 25, 2022)

  • 0.3.0(Mar 2, 2022)

  • 0.2.1(Sep 29, 2021)

  • 0.2.0(Sep 29, 2021)

    Changed

    • PR#18 combined the voice_mute and voice_deafen RPCs into a single update_voice_settings RPC.

    Fixed

    • PR#18 fixed the deserialization of activity timestamps in relationship update events.
    • PR#18 fixed the disconnect_lobby_voice method to actually send the correct RPC.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.4(Sep 16, 2021)

  • 0.1.3(Aug 23, 2021)

    Changed

    • PR#16 exposed the Snowflake type publicly, as there are cases where you might need to use it directly as it is the underlying type for most of the unique identifiers throught the SDK.

    Fixed

    • PR#16 fixed regions to use kebab-case instead of snake_case, and add the st-pete region, which is apparently a voice region that can be used, but isn't listed in /voice/regions.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.2(Aug 11, 2021)

    Fixed

    • PR#14 fixed an issue where the RELATIONSHIP_UPDATE event actually uses stringized timestamps in the activity information, rather than the normal i64 timestamps in eg SET_ACTIVITY.
    • PR#14 fixed an issue with timestamps being converted into chrono::DateTime<Utc> with the wrong unit, resulting in date times far in the future.
    • PR#14 added more sanitization to crate::activity::ActivityBuilder to prevent strings with just whitespace being sent to Discord as that results in API failures.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.1(Jul 28, 2021)

  • 0.1.0(Jul 21, 2021)

  • 0.0.1(Jul 21, 2021)

Owner
Embark
The future belongs to the curious
Embark
RusTTS is an unofficial Coqui TTS implementation.

RusTTS RusTTS is an unofficial Coqui TTS implementation. Currently, only the YourTTS for [ TTS & VC ] has been implemented. So, feel free to contribut

UlagBulag Village 13 Sep 12, 2022
Solana Game Server is a decentralized game server running on Solana, designed for game developers

Solana Game Server* is the first decentralized Game Server (aka web3 game server) designed for game devs. (Think web3 SDK for game developers as a ser

Tardigrade Life Sciences, Inc 16 Dec 1, 2022
NeosPeeps is tool that allows for listing your NeosVR friends quickly, without having to actually open the whole game

Neos Peeps NeosPeeps is tool that allows for listing your NeosVR friends quickly, without having to actually open the whole game. It also has a bunch

LJ 6 Sep 12, 2022
Rust SDK for working with RIS-Live real-time BGP data stream.

ris-live-rs Provides parsing functions for RIS-Live real-time BGP message stream JSON data. The main parsing function, parse_ris_live_message converts

BGPKIT 10 Oct 11, 2022
A Team Fortress 2 SDK written in Rust that I update every now and then

tf-rs A Team Fortress 2 SDK written in Rust that I update every now and then. Most of this has been written in early November. I've published it so th

cristei 2 Dec 17, 2022
Victorem - easy UDP game server and client framework for creating simple 2D and 3D online game prototype in Rust.

Victorem Easy UDP game server and client framework for creating simple 2D and 3D online game prototype in Rust. Example Cargo.toml [dependencies] vict

Victor Winbringer 27 Jan 7, 2023
2-player game made with Rust and "ggez" engine, based on "Conway's Game of Life"

fight-for-your-life A 2-player game based on the "Conway's Game of Life", made with Rust and the game engine "ggez". Create shapes on the grid that wi

Petros 3 Oct 25, 2021
A tetris game I wrote in rust using ncurses. I'm sure that there's a better way to write a tetris game, and the code may be sus, but it techinically works

rustetris A tetris game I wrote in rust using ncurses. I'm sure that there's a better way to write a tetris game, and the code may be sus, but it tech

Eric G 3 Oct 15, 2022
A game of snake written in Rust using the Bevy game engine, targeting WebGL2

Snake using the Bevy Game Engine Prerequisites cargo install cargo-make Build and serve WASM version Set your local ip address in Makefile.toml (loca

Michael Dorst 0 Dec 26, 2021
Wasm game of life - A Rust and WebAssembly tutorial implementing the Game of Life

wasm_game_of_life Conway's Game of Life in Rust and WebAssembly Contributing | Chat Built with ?? ?? by The Rust and WebAssembly Working Group About T

Rust and WebAssembly 236 Dec 24, 2022
Conway's Game of Life implemented for Game Boy Advance in Rust

game-of-life An implementation of a Conway's Game of Life environment on GBA. The ultimate game should have two modes: Edit and Run mode which can be

Shane Snover 1 Feb 16, 2022
2d Endless Runner Game made with Bevy Game Engine

Cute-runner A 2d Endless Runner Game made with Bevy Game Engine. Table of contents Project Infos Usage Screenshots Disclaimer Project Infos Date: Sept

JoaoMarinho 2 Jul 15, 2022
A game for the game jam "1-Button Jam 2021"

One click ninja A game for the game jam "1-Button Jam 2021" written in Rust with the Bevy engine. A rhythm game, where you play a soldier that can def

Alex Helfet 7 Apr 12, 2022
My first attempt at game programming. This is a simple target shooting game built in macroquad.

sergio My first attempt at game programming. This is a simple target shooting game built in macroquad. Rules Hit a target to increase score by 1 Score

Laz 1 Jan 11, 2022
A game made in one week for the Bevy engine's first game jam

¿Quien es el MechaBurro? An entry for the first Bevy game jam following the theme of "Unfair Advantage." It was made in one week using the wonderful B

mike 20 Dec 23, 2022
A Client/Server game networking plugin using QUIC, for the Bevy game engine.

Bevy Quinnet A Client/Server game networking plugin using QUIC, for the Bevy game engine. Bevy Quinnet QUIC as a game networking protocol Features Roa

Gilles Henaux 65 Feb 20, 2023
Managed game servers, matchmaking, and DDoS mitigation that lets you focus on building your game

Managed game servers, matchmaking, and DDoS mitigation that lets you focus on building your game. Home - Docs - Twitter - Discord ?? Features Everythi

Rivet 58 Jun 25, 2023
Discord RIch Presence in Rust, with native Bevy support

Discord Presence The root project for both Bevy Discord Presence and regular Discord Presence, both contained in the crates directory. TODO Allow invi

Juliette Cordor 22 Nov 29, 2022
The fastest and highest quality audio player for Discord.

ying The fastest and highest quality audio player for Discord. Driven by a custom I/O engine and executed via ultra low overhead light threads, this l

David 5 Nov 19, 2023