diff --git a/Cargo.lock b/Cargo.lock index 7037ee4..8b4282d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "app_dirs2" @@ -22,13 +22,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.66" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn", ] [[package]] @@ -39,9 +39,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "bitflags" @@ -49,6 +49,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded" + [[package]] name = "bytes" version = "1.4.0" @@ -85,9 +91,9 @@ checksum = "7439becb5fafc780b6f4de382b1a7a3e70234afe783854a4702ee8adbb838609" [[package]] name = "crossbeam-channel" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if", "crossbeam-utils", @@ -95,44 +101,24 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "discord-sdk" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0df260a6baf1d63a08dc38a7b75f30d4722a9eb2bf6d1172d33e0221bd72ae" +checksum = "6e7338aceb4639869595d31c764d43d20e60a4c2d21e7cac95ea767ec2ec7343" dependencies = [ "anyhow", "app_dirs2", "async-trait", "base64", - "bitflags", + "bitflags 2.3.2", "crossbeam-channel", "num-traits", "parking_lot", @@ -144,7 +130,7 @@ dependencies = [ "tokio", "tracing", "url", - "winreg 0.10.1", + "winreg 0.11.0", ] [[package]] @@ -160,38 +146,36 @@ dependencies = [ [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] -name = "getrandom" -version = "0.2.8" +name = "hermit-abi" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ - "cfg-if", "libc", - "wasi", ] [[package]] -name = "hermit-abi" -version = "0.2.6" +name = "home" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "libc", + "windows-sys 0.48.0", ] [[package]] name = "idna" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -216,7 +200,7 @@ dependencies = [ "log", "thiserror", "walkdir", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -227,15 +211,15 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -243,12 +227,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "memchr" @@ -258,14 +239,13 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -279,6 +259,7 @@ name = "northstar-discord-rpc" version = "0.1.0" dependencies = [ "discord-sdk", + "parking_lot", "rrplug", "tokio", "windres", @@ -305,9 +286,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "parking_lot" @@ -321,22 +302,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-targets 0.48.0", ] [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" @@ -346,62 +327,50 @@ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "getrandom", - "redox_syscall", - "thiserror", + "bitflags 1.3.2", ] [[package]] name = "rrplug" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c324c2f1b17388ba8939ca8b5ad7f04685980913985ddcf84b5874fda04540" +version = "2.1.1" +source = "git+https://github.com/R2NorthstarTools/rrplug#242b965603c8be60d82c80722564c65b049b8333" dependencies = [ "log", "once_cell", + "parking_lot", "rrplug_proc", "thiserror", ] [[package]] name = "rrplug_proc" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26446dd47f9472a423826db29c9b273d82010f6bf3520c52fb3ffdd7418dad1b" +version = "2.1.1" +source = "git+https://github.com/R2NorthstarTools/rrplug#242b965603c8be60d82c80722564c65b049b8333" dependencies = [ "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -427,29 +396,29 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn", ] [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" dependencies = [ "itoa", "ryu", @@ -458,13 +427,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395627de918015623b32e7669714206363a7fc00382bf477e72c1f7533e8eafc" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn", ] [[package]] @@ -475,9 +444,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -485,20 +454,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.15" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -507,29 +465,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn", ] [[package]] name = "time" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "serde", "time-core", @@ -537,9 +495,9 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "tinyvec" @@ -558,9 +516,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.26.0" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "libc", @@ -568,7 +526,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -585,35 +543,35 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] [[package]] name = "unicode-bidi" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d502c968c6a838ead8e69b2ee18ec708802f99db92a0d156705ec9ef801993b" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-normalization" @@ -626,9 +584,9 @@ dependencies = [ [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", @@ -688,7 +646,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -697,13 +664,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -712,42 +694,84 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "windres" version = "0.2.2" @@ -770,18 +794,19 @@ dependencies = [ [[package]] name = "winreg" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "76a1a57ff50e9b408431e8f97d5456f2807f8eb2a2cd79b06068fc87f8ecf189" dependencies = [ + "cfg-if", "winapi", ] [[package]] name = "xdg" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6" +checksum = "688597db5a750e9cad4511cb94729a078e274308099a0382b5b8203bbc767fee" dependencies = [ - "dirs", + "home", ] diff --git a/Cargo.toml b/Cargo.toml index 39e6070..f81fd4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,9 +6,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rrplug = { version = "2.0.0", features = ["presence"] } +rrplug = { git = "https://github.com/R2NorthstarTools/rrplug" } discord-sdk = "0.3.2" tokio = "1.26.0" +parking_lot = "0.12.1" [build-dependencies] windres = "0.2.2" diff --git a/manifest/manifest.json b/manifest/manifest.json index 894cb39..f852a90 100644 --- a/manifest/manifest.json +++ b/manifest/manifest.json @@ -1,9 +1,10 @@ { "name": "Northstar.DiscordRPC", - "displayname": "DiscordRPC", + "displayname": "DPRESENCE", + "dependencyName": "DISCORDRPC", "description": "Discord Rich Presence for Northstar", - "api_version": "2", - "version": "2.0", + "api_version": "3", + "version": "3.0", "run_on_server": false, "run_on_client": true } \ No newline at end of file diff --git a/src/discord.rs b/src/discord.rs new file mode 100644 index 0000000..6c7ae73 --- /dev/null +++ b/src/discord.rs @@ -0,0 +1,125 @@ +#![deny(non_snake_case)] + +use std::num::NonZeroU32; + +use discord_sdk::{ + activity::{ActivityBuilder, Assets, PartyPrivacy}, + user::User, + wheel::UserState, + wheel::Wheel, + Discord, DiscordApp, Subscriptions, +}; +use rrplug::prelude::*; + +use crate::exports::PLUGIN; + +/// the discord app's id, taken from older v1 discord rpc +const APP_ID: i64 = 941428101429231617; + +/// struct to hold everything required to run discord rpc +pub struct Client { + pub discord: Discord, + pub user: User, + pub wheel: Wheel, +} + +/// discord rpc update function +/// +/// doesn't run on the titanfall 2 thread since it needs async +pub async fn async_main() { + let activity = &PLUGIN.wait().activity; + + let client = match make_client(Subscriptions::ACTIVITY).await { + Ok(c) => c, + Err(_) => { + log::error!("Is your discord running?"); + return; + } + }; + + match client.discord.clear_activity().await { + Ok(_) => log::info!("cleared activity"), + Err(err) => log::error!("coudln't clear activity because of {:?}", err), + } + + loop { + let data = activity.lock().clone(); + + if let Some(img) = &data.large_image { + if img.is_empty() { + log::warn!("img is empty at {:?}", data.last_state); + } + } + + let mut activity_builder = ActivityBuilder::default() + .details(data.details) + .state(data.state) + .assets(Assets { + large_image: data.large_image, + large_text: data.large_text, + small_image: data.small_image, + small_text: data.small_text, + }); + + if let Some(start) = data.start { + activity_builder = activity_builder.start_timestamp(if start == 0 { 1 } else { start }); + } + if let Some(end) = data.end { + activity_builder = activity_builder.end_timestamp(end); + } + if let Some(party) = data.party { + activity_builder = activity_builder.party( + "whar", + Some(party.0.try_into().unwrap_or(NonZeroU32::new(1).unwrap())), + Some(party.1.try_into().unwrap_or(NonZeroU32::new(1).unwrap())), + PartyPrivacy::Private, + ); + } + + // updates presence here + if let Err(err) = client.discord.update_activity(activity_builder).await { + log::info!("failed to updated discord activity; {err}"); + #[cfg(not(debug_assertions))] + return; + } + + wait(1000); + } +} + +/// discord connection init sourced from https://github.com/EmbarkStudios/discord-sdk/blob/d311db749b7e11cc55cb1a9d7bfd9a95cfe61fd1/examples-shared/src/lib.rs#L16 +pub async fn make_client(subs: Subscriptions) -> Result { + let (wheel, handler) = Wheel::new(Box::new(|err| { + log::warn!("encountered an error {err:?}; shouldn't be fatal"); + })); + + let mut user = wheel.user(); + + let discord = match Discord::new(DiscordApp::PlainId(APP_ID), subs, Box::new(handler)) { + Ok(d) => d, + Err(_) => { + log::error!("unable to create discord client"); + Err(())? + } + }; + + log::info!("waiting for handshake..."); + user.0.changed().await.unwrap(); + + let user = match &*user.0.borrow() { + UserState::Connected(user) => user.clone(), + UserState::Disconnected(err) => { + log::error!("failed to connect to Discord: {}", err); + Err(())? + } + }; + + #[cfg(debug_assertions)] + log::info!("connected to Discord, local user is {:#?}", user); + + Ok(Client { + discord, + user, + wheel, + }) +} diff --git a/src/lib.rs b/src/lib.rs index 8b9bb76..8f08b7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,57 +1,55 @@ -use std::{ - sync::Mutex, - time::{SystemTime, UNIX_EPOCH}, -}; +#![allow(non_snake_case)] -use discord_sdk::{ - activity::{ActivityBuilder, Assets}, - user::User, - wheel::UserState, - wheel::Wheel, - Discord, DiscordApp, Subscriptions, -}; +use parking_lot::Mutex; use rrplug::prelude::*; -use rrplug::wrappers::presence::{GamePresence, GameStateEnum}; use tokio::runtime::Runtime; -/// the discord app's id, taken from older v1 discord rpc -const APP_ID: i64 = 941428101429231617; +use crate::{ + discord::async_main, + presense_bindings::{GameStateStruct, UIPresenceStruct,GameState}, + presence::run_presence_updates, +}; +pub(crate) mod discord; +pub(crate) mod presence; +pub(crate) mod presense_bindings; + +#[deny(non_snake_case)] #[derive(Debug, Default, Clone)] -struct ActivityData { - party: (u32, u32), +#[doc = "struct for all the possible information on the rpc"] +pub struct ActivityData { + party: Option<(u32, u32)>, details: String, state: String, large_image: Option, large_text: Option, small_image: Option, small_text: Option, - end: i64, - start: i64, -} - -pub struct Client { - pub discord: Discord, - pub user: User, - pub wheel: Wheel, + end: Option, + start: Option, + last_state: GameState, } -#[derive(Debug)] -struct DiscordRpc { - activity: Option>, +#[deny(non_snake_case)] +pub struct DiscordRpcPlugin { + pub activity: Mutex, + pub presence_data: Mutex<(GameStateStruct, UIPresenceStruct)>, } -impl Plugin for DiscordRpc { - fn new() -> Self { - Self { activity: None } - } +#[deny(non_snake_case)] +impl Plugin for DiscordRpcPlugin { + fn new(plugin_data: &PluginData) -> Self { + plugin_data.register_sq_functions(presence::fetch_presence); - fn initialize(&mut self, _: &PluginData) { - self.activity = Some(Mutex::new(ActivityData { + let activity = Mutex::new(ActivityData { large_image: Some("northstar".to_string()), state: "Loading...".to_string(), ..Default::default() - })); + }); + Self { + activity, + presence_data: Mutex::new((GameStateStruct::default(), UIPresenceStruct::default())), + } } fn main(&self) { @@ -64,165 +62,15 @@ impl Plugin for DiscordRpc { }; runtime.block_on(async_main()); } - - /// receives presence updates here - fn on_presence_updated(&self, presence: &GamePresence) { - let mut activity = match self.activity.as_ref().unwrap().try_lock() { - Ok(a) => a, - Err(_) => return, - }; - match presence.get_state().unwrap() { - GameStateEnum::InGame => {} - _ => { - let start = SystemTime::now(); - let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap(); // there is no way this fails - activity.start = since_the_epoch.as_secs() as i64; + fn on_sqvm_created(&self, sqvm_handle: &CSquirrelVMHandle) { + match sqvm_handle.get_context() { + ScriptVmType::Client | ScriptVmType::Ui => { + run_presence_updates(unsafe { sqvm_handle.get_sqvm() }) } - }; - - match presence.get_state().unwrap() { - GameStateEnum::Loading => { - activity.party = (0, 0); - activity.details = "".to_string(); - activity.state = "Loading...".to_string(); - activity.large_image = Some("northstar".to_string()); - activity.large_text = Some("Titanfall 2 + Northstar".to_string()); - } - GameStateEnum::MainMenu => { - activity.party = (0, 0); - activity.details = "Main Menu".to_string(); - activity.state = "On Main Menu".to_string(); - activity.large_image = Some("northstar".to_string()); - activity.large_text = Some("Titanfall 2 + Northstar".to_string()); - } - GameStateEnum::Lobby => { - activity.party = (0, 0); - activity.details = "Lobby".to_string(); - activity.state = "In the Lobby".to_string(); - activity.large_image = Some("northstar".to_string()); - activity.large_text = Some("Titanfall 2 + Northstar".to_string()); - } - GameStateEnum::InGame => { - let map_displayname = presence.get_map_displayname(); - - activity.party = ( - presence - .get_current_players() - .try_into() - .unwrap_or_default(), - presence.get_max_players().try_into().unwrap_or_default(), - ); - activity.details = map_displayname.clone(); - activity.state = map_displayname.clone(); - activity.large_image = Some(presence.get_map()); - activity.large_text = Some(map_displayname); - activity.small_image = Some("northstar".to_string()); - activity.small_text = Some("Titanfall 2 + Northstar".to_string()); - if presence.get_playlist() == "campaign" { - activity.party = (0, 0); - activity.end = 0; - } else { - activity.state = presence.get_playlist_displayname(); - activity.details = format!( - "Score: {} - {} (First to {})", - presence.get_own_score(), - presence.get_other_highest_score(), - presence.get_max_score() - ); - - let current_time = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_secs() as i64; - let ig_end = presence.get_timestamp_end() as i64; - activity.end = current_time + ig_end; - } - } - }; - } -} - -entry!(DiscordRpc); - -async fn async_main() { - let activity = PLUGIN.wait().activity.as_ref().unwrap(); - - let client = match make_client(Subscriptions::ACTIVITY).await { - Ok(c) => c, - Err(_) => { - log::error!("Is your discord running?"); - return; + _ => {} } - }; - - match client.discord.clear_activity().await { - Ok(_) => log::info!("cleared activity"), - Err(err) => log::error!("coudln't clear activity because of {:?}", err), - } - - loop { - let data = activity.lock().unwrap().clone(); - - // updates presence here - if let Err(err) = client - .discord - .update_activity( - ActivityBuilder::default() - .details(data.details) - .state(data.state) - .assets(Assets { - large_image: data.large_image, - large_text: data.large_text, - small_image: data.small_image, - small_text: data.small_text, - }) - .start_timestamp(if data.start == 0 { 1 } else { data.start }) - .end_timestamp(data.end), - ) - .await - { - log::info!("failed to updated discord activity; {err}"); - #[cfg(not(debug_assertions))] - return; - } - - wait(1000); } } -/// discord connection init sourced from https://github.com/EmbarkStudios/discord-sdk/blob/d311db749b7e11cc55cb1a9d7bfd9a95cfe61fd1/examples-shared/src/lib.rs#L16 -pub async fn make_client(subs: Subscriptions) -> Result { - let (wheel, handler) = Wheel::new(Box::new(|err| { - log::warn!("encountered an error {err:?}; shouldn't be fatal"); - })); - - let mut user = wheel.user(); - - let discord = match Discord::new(DiscordApp::PlainId(APP_ID), subs, Box::new(handler)) { - Ok(d) => d, - Err(_) => { - log::error!("unable to create discord client"); - Err(())? - } - }; - - log::info!("waiting for handshake..."); - user.0.changed().await.unwrap(); - - let user = match &*user.0.borrow() { - UserState::Connected(user) => user.clone(), - UserState::Disconnected(err) => { - log::error!("failed to connect to Discord: {}", err); - Err(())? - } - }; - - log::info!("connected to Discord, local user is {:#?}", user); - - Ok(Client { - discord, - user, - wheel, - }) -} +entry!(DiscordRpcPlugin); diff --git a/src/presence.rs b/src/presence.rs new file mode 100644 index 0000000..e68e513 --- /dev/null +++ b/src/presence.rs @@ -0,0 +1,178 @@ +#![deny(non_snake_case)] + +use rrplug::prelude::*; +use rrplug::{ + bindings::squirrelclasstypes::ScriptContext, + call_sq_function, + high::{squirrel::compile_string, Handle}, +}; +use std::{ + ops::DerefMut, + time::{SystemTime, UNIX_EPOCH}, +}; + +use crate::presense_bindings::{GameState, GameStateStruct, UIPresenceStruct}; + +// heartbeat for pulling presence +pub fn run_presence_updates(sqvm: Handle<*mut HSquirrelVM>) { + let sqvm = *sqvm.get(); + let sq_functions = SQFUNCTIONS.client.wait(); + + if let Err(err) = compile_string( + sqvm, + sq_functions, + true, + r#" + thread void function() { + wait 1 + for(;;) { + FetchPresence() + wait 1 + } + }() + "#, + ) { + err.log() + } +} + +/// function to pull presence from the sqvm since in runframe it's impossibke to get the output of a function back +#[rrplug::sqfunction(VM = "UiClient", ExportName = "FetchPresence")] +pub fn fetch_presence() { + let plugin = crate::PLUGIN.wait(); + let mut presence_lock = plugin.presence_data.lock(); + let (cl_presence, ui_presence) = presence_lock.deref_mut(); + let sqvm = unsafe { sqvm.as_mut().ok_or_else(|| "None sqvm".to_string())? }; + let context = unsafe { + std::mem::transmute::<_, ScriptContext>( + sqvm.sharedState + .as_ref() + .ok_or_else(|| "None shared state".to_string())? + .cSquirrelVM + .as_ref() + .ok_or_else(|| "None csqvm".to_string())? + .vmContext, + ) + }; + + match context { + ScriptContext::CLIENT => { + if let Err(err) = call_sq_function!( + sqvm, + sq_functions, + "DiscordRPC_GenerateGameState", + cl_presence.clone() + ) { + #[cfg(debug_assertions)] + log::warn!("DiscordRPC_GenerateGameState call failed : {err}"); + #[cfg(not(debug_assertions))] + drop(err); + } else { + *cl_presence = GameStateStruct::get_from_sqvm(sqvm, sq_functions, sqvm._stackbase); + } + } + ScriptContext::UI => { + match call_sq_function!( + sqvm, + sq_functions, + "DiscordRPC_GenerateUIPresence", + ui_presence.clone() + ) { + Err(err) => { + #[cfg(debug_assertions)] + log::warn!("DiscordRPC_GenerateUIPresence call failed : {err}"); + #[cfg(not(debug_assertions))] + drop(err); + } + Ok(_) => { + *ui_presence = + UIPresenceStruct::get_from_sqvm(sqvm, sq_functions, sqvm._stackbase); + } + } + } + _ => {} + } + + on_presence_updated(plugin, cl_presence, ui_presence); + + Ok(()) +} + +/// receives presence updates here +fn on_presence_updated( + plugin: &crate::DiscordRpcPlugin, + cl_presence: &GameStateStruct, + ui_presence: &UIPresenceStruct, +) { + let mut activity = plugin.activity.lock(); + + if activity.last_state != ui_presence.game_state { + activity.start = Some( + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as i64, + ); + activity.last_state = ui_presence.game_state; + } + + match ui_presence.game_state { + GameState::Loading => { + activity.party = None; + activity.details = "".to_string(); + activity.state = "Loading...".to_string(); + activity.large_image = Some("northstar".to_string()); + activity.large_text = Some("Titanfall 2 + Northstar".to_string()); + activity.end = None; + } + GameState::MainMenu => { + activity.party = None; + activity.details = "Main Menu".to_string(); + activity.state = "On Main Menu".to_string(); + activity.large_image = Some("northstar".to_string()); + activity.large_text = Some("Titanfall 2 + Northstar".to_string()); + activity.end = None; + } + GameState::Lobby => { + activity.party = None; + activity.details = "Lobby".to_string(); + activity.state = "In the Lobby".to_string(); + activity.large_image = Some("northstar".to_string()); + activity.large_text = Some("Titanfall 2 + Northstar".to_string()); + activity.end = None; + } + GameState::InGame => { + let map_displayname = cl_presence.map_displayname.clone(); + + activity.party = Some(( + cl_presence.current_players.try_into().unwrap_or_default(), + cl_presence.max_players.try_into().unwrap_or_default(), + )); + activity.details = map_displayname.clone(); + activity.state = map_displayname.clone(); + activity.large_image = Some(cl_presence.map.clone()); + activity.large_text = Some(map_displayname); + activity.small_image = Some("northstar".to_string()); + activity.small_text = Some("Titanfall 2 + Northstar".to_string()); + if cl_presence.playlist == "campaign" { + activity.party = None; + activity.end = None; + } else { + activity.state = cl_presence.playlist_displayname.clone(); + activity.details = format!( + "Score: {} - {} (First to {})", + cl_presence.own_score, cl_presence.other_highest_score, cl_presence.max_score, + ); + + if activity.end.is_none() { + let current_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as i64; + let ig_end = cl_presence.time_end.ceil() as i64; + activity.end = Some(current_time + ig_end); + } + } + } + }; +} diff --git a/src/presense_bindings.rs b/src/presense_bindings.rs new file mode 100644 index 0000000..d47ee6d --- /dev/null +++ b/src/presense_bindings.rs @@ -0,0 +1,44 @@ +#![deny(non_snake_case)] +//! bindings to squirrel structs + +use rrplug::high::squirrel_traits::{GetFromSQObject, GetFromSquirrelVm, PushToSquirrelVm}; +use rrplug::prelude::*; + +#[derive( + PushToSquirrelVm, GetFromSquirrelVm, GetFromSQObject, Clone, Copy, Debug, PartialEq, Eq, +)] +#[repr(i32)] +/// binding to GameState +pub enum GameState { + Loading, + MainMenu, + Lobby, + InGame, +} + +#[derive(PushToSquirrelVm, GetFromSquirrelVm, Default, Clone)] +/// binding to GameStateStruct +pub struct GameStateStruct { + pub map: String, + pub map_displayname: String, + pub playlist: String, + pub playlist_displayname: String, + pub current_players: i32, + pub max_players: i32, + pub own_score: i32, + pub other_highest_score: i32, + pub max_score: i32, + pub time_end: f32, +} + +#[derive(PushToSquirrelVm, GetFromSquirrelVm, Default, Clone)] +/// binding to UIPresenceStruct +pub struct UIPresenceStruct { + pub game_state: GameState, +} + +impl Default for GameState { + fn default() -> Self { + Self::Loading + } +}