mirror of
https://github.com/KaitlynEthylia/Disco
synced 2024-11-10 06:34:23 +00:00
Initial Commit
This commit is contained in:
commit
2c4fcd7bc0
8 changed files with 1281 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
525
Cargo.lock
generated
Normal file
525
Cargo.lock
generated
Normal file
|
@ -0,0 +1,525 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is-terminal",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "disco"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"dirs",
|
||||
"discord-rich-presence",
|
||||
"mlua",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discord-rich-presence"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47fc4beffb85ee1461588499073a4d9c20dcc7728c4b13d6b282ab6c508947e5"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mlua"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07366ed2cd22a3b000aed076e2b68896fb46f06f1f5786c5962da73c0af01577"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"cc",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
"rustc-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||
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 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f"
|
||||
dependencies = [
|
||||
"bitflags 2.3.3",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.181"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d3e73c93c3240c0bda063c239298e633114c69a888c3e37ca8bb33f343e9890"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.181"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be02f6cb0cd3a5ec20bbcfbcbd749f57daddb1a0882dc2e46a6c236c90b977ed"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
|
||||
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",
|
||||
]
|
||||
|
||||
[[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.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[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.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[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.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
17
Cargo.toml
Normal file
17
Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "disco-rpc"
|
||||
version = "0.1.0"
|
||||
description = "A customisable client for Discord rich presence using simple Lua configuration."
|
||||
authors = ["Kaitlyn~Ethylia <kaitlyyn.ethylia@proton.me>"]
|
||||
edition = "2021"
|
||||
repository = "https://github.com/KaitlynEthylia/Disco"
|
||||
license = "Unlicense"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.3.19", features = ["derive"] }
|
||||
dirs = "5.0.1"
|
||||
discord-rich-presence = "0.2.3"
|
||||
mlua = { version = "0.8.9", features = ["lua54", "send"] }
|
||||
|
||||
[features]
|
||||
unsafe = []
|
24
LICENSE
Normal file
24
LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
235
README.md
Normal file
235
README.md
Normal file
|
@ -0,0 +1,235 @@
|
|||
<div align="center">
|
||||
|
||||
[Installation](#installation) |
|
||||
[Usage](#usage) |
|
||||
[Configuration](#configuration) |
|
||||
[Example](#example)
|
||||
|
||||
# Disco
|
||||
|
||||
[![Github](https://img.shields.io/badge/Github-KaitlynEthylia%2FDisco-cec2fc?logo=github&style=for-the-badge)](https://github.com/KaitlynEthylia/Disco)
|
||||
[![Crates.io](https://img.shields.io/crates/v/disco-rpc?color=%23f7b679&logo=rust&style=for-the-badge)](https://crates.io/crates/disco-rpc)
|
||||
[![Unlicense](https://img.shields.io/crates/l/terny?color=bfdfff&logo=unlicense&style=for-the-badge)](https://unlicense.org/)
|
||||
|
||||
Disco is a customisable client for Discord rich presence using
|
||||
simple Lua configuration.
|
||||
|
||||
</div>
|
||||
|
||||
<a id="installation" />
|
||||
|
||||
## Installation
|
||||
|
||||
Disco can be installed from crates.io or manually installed from
|
||||
GitHub.
|
||||
|
||||
### Creates.io
|
||||
|
||||
Assuming you already have the rust toolchain installed, you can simply
|
||||
install disco by running
|
||||
|
||||
```sh
|
||||
cargo install disco-rpc
|
||||
```
|
||||
|
||||
To allow Lua to call external C libraries, the `unsafe` feature flag
|
||||
also needs to be enabled.
|
||||
|
||||
```sh
|
||||
cargo install disco-rpc --features unsafe
|
||||
```
|
||||
|
||||
### GitHub
|
||||
|
||||
Prebuilt binaries are currently provided for x86_64-linux-gnu both
|
||||
with and without the unsafe flag. Disco can also be built from source
|
||||
via cargo
|
||||
|
||||
```sh
|
||||
git clone https://github.com/KaitlynEthylia/Disco
|
||||
cd Disco
|
||||
cargo install --path .
|
||||
```
|
||||
|
||||
As with the crates.io installation, `--features unsafe` my optionally
|
||||
be appended to the final command.
|
||||
|
||||
<a id="usage" />
|
||||
|
||||
## Usage
|
||||
|
||||
Running the command `disco` will automatically look for a Lua file to
|
||||
read configuration from as described in the
|
||||
[configuration section](#configuration). There are a handful of
|
||||
arguments that may be passed to the command to adjust how it runs.
|
||||
|
||||
Naturally, the `-h, --help` and `-V, --version` flags exist. As well,
|
||||
there is a `-p --print-config-path` flag, which will prevent the
|
||||
programme from running and print the location that it would otherwise
|
||||
look for a configuration file.
|
||||
The other flags that actually affect the programme are:
|
||||
|
||||
**-c, --config <CONFIG>**: Overrides the default path to look for configuration.
|
||||
<br />
|
||||
**-i, --client-id <CLIENT_ID>**: Sets the ID of the application to connect as. Takes precedent over Lua configuration.
|
||||
<br />
|
||||
**-r, --retry-after <DELAY>**: If connecting to Discord fails, retry after DELAY seconds [default: 0]
|
||||
<br />
|
||||
**-q, --quiet**: Don't print any text to the console.
|
||||
|
||||
<a id="configuration" />
|
||||
|
||||
## Configuration
|
||||
|
||||
Disco will look for a config file by first seeing if one has been
|
||||
given in the command line via the `-c` flag. If not, it will look at
|
||||
the `DISCO_CONFIG` environment variable. If that is not set, it will
|
||||
then check `$XDG_CONFIG_HOME/disco.lua` and lastly `$HOME/disco.lua`.
|
||||
|
||||
If it still cannot find a config file, it will error. There is no
|
||||
default configuration.
|
||||
|
||||
The rich presence is made up of a series of variable that can be set
|
||||
in the config file.
|
||||
|
||||
| Variable | Type | Description |
|
||||
| -------- | ---- | ----------- |
|
||||
| Active | boolean | Whether or not to display the rich presence. |
|
||||
| Details | string | The first line of the rich presence. |
|
||||
| State | string | The second line of the rich presence. |
|
||||
| Timestaamp | Timestamp | A timestamp to count up or count down, appears in the same location as State. Note that the timestamp can be buggy. If the rich presence is not displaying, you may have set this value incorrectly, remove it and see if that solves the issue. |
|
||||
| LargeImage | Image | The main image on the left hand side of the presence. |
|
||||
| SmallImage | Image | The image in the bottom left corner of the large image. |
|
||||
| Button1 | Button | A button that can direct to a URL. |
|
||||
| Button2 | Button | A second button that can direct to a URL. Discord only supports a maximum of 2. |
|
||||
|
||||
the types Timestamp, Image, and Button are not part of lua, they each
|
||||
represent:
|
||||
| Type | Explanation | Examples |
|
||||
| ---- | ----------- | -------- |
|
||||
| Timestamp | a table containing an option `start` key, and an optional `_end` key. alternatively, a single integer equivelelent to setting `start` but not `_end`. | `{ start = 12345, _end = 23456 }` or `10000`. |
|
||||
| Image | a URL to the image or a table whose first element is a URL, and with a key `text` representing the text that appears when hovering over the image. | `'https://example.com/image.png'` or `{ 'https://example.com/image.png', text = "Some Image" }`. |
|
||||
| Button | a URL to be directed to, or a table whose first element is the text to display on the image, and with a key `url` which is the url to be directed to. | `'https://example.org'` or `{ 'Example Website', url = 'https://example.org' }`. |
|
||||
|
||||
Each of these variables can be set in 3 different ways:
|
||||
|
||||
- It can be set simply by assigning the variable the value. We will
|
||||
call this a 'static' variable, because its value will not change
|
||||
throughout the programme.
|
||||
|
||||
```lua
|
||||
State = "Some Text"
|
||||
```
|
||||
|
||||
- It can be set via a table. The second element being a function that
|
||||
returns the value, and the first element being the number of seconds
|
||||
between successive calls of this function. This we will call a
|
||||
'polled' variable.
|
||||
|
||||
```lua
|
||||
State = { 60, function()
|
||||
return os.date("%H:%M")
|
||||
end }
|
||||
```
|
||||
|
||||
Here it runs the `os.date()` function every 60 seconds to get the
|
||||
system time.
|
||||
|
||||
- Lastly, it can be set via a coroutine. This coroutine will
|
||||
continually be resumed, and should yield a value to set each time.
|
||||
|
||||
```lua
|
||||
State = coroutine.create(function()
|
||||
for i = 1, 10, 1 do
|
||||
coroutine.yield("Number: " .. i)
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
In this example, the coroutine counts up to ten and then stops
|
||||
returning. Once it stops, the final value remains.
|
||||
This example is contrived, but a more complex example can be seen
|
||||
in [the example section](#example)
|
||||
|
||||
Disco may also call external lua libraries, however, if that
|
||||
library requires C libraries, the `unsafe` feature flag will need to
|
||||
be enabled.
|
||||
|
||||
```lua
|
||||
-- requires the `http` library to be installed, as well as the
|
||||
-- `unsafe` feature to be enabled.
|
||||
local request = require 'http.request'
|
||||
|
||||
local _, stream = request.new_from_uri('https://api.rot26.org/encrypt/test'):go()
|
||||
State = stream:get_body_as_string()
|
||||
```
|
||||
|
||||
<a id="example"/>
|
||||
|
||||
## Example
|
||||
|
||||
Here is my personal configuration that I use on my Arch Linux +
|
||||
Hyprland setup so show some details. This isn't exactly what I use
|
||||
but I have modified it slightly to demonstrate some features that
|
||||
I didn't use, such as polling.
|
||||
|
||||
```lua
|
||||
-- ID of the client I created for ArchLinux via
|
||||
-- https://discord.com/developers/applications
|
||||
ClientID = 1137762526541656105
|
||||
|
||||
-- Display the rich presence
|
||||
Active = true
|
||||
|
||||
-- Show what time it is on my machine on the first line, rerun
|
||||
-- the function every 60 seconds.
|
||||
Details = { 60, function()
|
||||
return "My Time: " .. os.date("%H:%M")
|
||||
end }
|
||||
|
||||
-- Plug into the Hyprland socket to show which window is currently
|
||||
-- active, and update every time I switch window.
|
||||
State = coroutine.create(function()
|
||||
local handle = io.popen([[
|
||||
socat -u UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - |
|
||||
stdbuf -o0 awk -F '>>|,' '/^activewindow>>/{ $2 = toupper(substr($2, 1, 1)) substr($2, 2); print $2}'
|
||||
]])
|
||||
if not handle then return end
|
||||
for line in handle:lines() do
|
||||
coroutine.yield("Using: " .. line)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Display the Arch Linux logo
|
||||
LargeImage = {
|
||||
'https://seeklogo.com/images/A/arch-linux-logo-3C25E68BA9-seeklogo.com.png',
|
||||
text = 'Arch Linux',
|
||||
}
|
||||
|
||||
-- Include the Hyprland logo in the corner
|
||||
SmallImage = {
|
||||
'https://i.imgur.com/PanwaBQ.png',
|
||||
text = 'Hyprland',
|
||||
}
|
||||
|
||||
-- A really cool button
|
||||
Button1 = {
|
||||
'Press This Button!',
|
||||
url = 'https://youtu.be/dQw4w9WgXcQ',
|
||||
}
|
||||
```
|
||||
|
||||
## Before Release
|
||||
|
||||
Things that intend to be done before i could be happy calling this a
|
||||
1.0.0 project.
|
||||
|
||||
- [ ] Provide extra utilitly functions to make some tasks easier.
|
||||
- [ ] Test compaility on non x86_64-linux-gnu machines, and fix where possible.
|
||||
- [ ] Provide bash, zsh, and fish completions with the releases.
|
||||
- [ ] Provide template systemd and potentially runit and openrc services for running on startup.
|
||||
- [ ] Fix bugs that are more than likely to show up, and provide friendlier error handling.
|
||||
|
||||
None of these goals are particularly quick and easy, so they are
|
||||
likely to only end up completed if enough interest is shown in the
|
||||
tool.
|
118
src/activity.rs
Normal file
118
src/activity.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum ActivityDataTag {
|
||||
Active,
|
||||
State,
|
||||
Details,
|
||||
Timestamp,
|
||||
FirstButton,
|
||||
SecondButton,
|
||||
LargeImage,
|
||||
SmallImage,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ActivityData {
|
||||
Active(bool),
|
||||
State(String),
|
||||
Details(String),
|
||||
Timestamp(Timestamp),
|
||||
FirstButton(Button),
|
||||
SecondButton(Button),
|
||||
LargeImage(Image),
|
||||
SmallImage(Image),
|
||||
}
|
||||
|
||||
use mlua::{Error::FromLuaConversionError, FromLua, Lua, Result, Table, Value};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Image {
|
||||
pub asset: String,
|
||||
pub text: Option<String>,
|
||||
}
|
||||
|
||||
impl<'lua> FromLua<'lua> for Image {
|
||||
fn from_lua(lua_value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let typename = lua_value.type_name();
|
||||
match typename {
|
||||
"table" => {
|
||||
let table: Table = Table::from_lua(lua_value, lua)?;
|
||||
Ok(Image {
|
||||
asset: table.get(1)?,
|
||||
text: table.get("text")?,
|
||||
})
|
||||
},
|
||||
"string" => Ok(Image {
|
||||
asset: String::from_lua(lua_value, lua)?,
|
||||
text: None,
|
||||
}),
|
||||
_ => Err(FromLuaConversionError {
|
||||
from: typename,
|
||||
to: "Image",
|
||||
message: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Button {
|
||||
pub text: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
impl<'lua> FromLua<'lua> for Button {
|
||||
fn from_lua(lua_value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let typename = lua_value.type_name();
|
||||
match typename {
|
||||
"table" => {
|
||||
let table: Table = Table::from_lua(lua_value, lua)?;
|
||||
Ok(Button {
|
||||
text: table.get(1)?,
|
||||
url: table.get("url")?,
|
||||
})
|
||||
},
|
||||
"string" => {
|
||||
let url = String::from_lua(lua_value, lua)?;
|
||||
Ok(Button {
|
||||
text: url.clone(),
|
||||
url,
|
||||
})
|
||||
},
|
||||
_ => Err(FromLuaConversionError {
|
||||
from: typename,
|
||||
to: "Button",
|
||||
message: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Timestamp {
|
||||
pub start: Option<i64>,
|
||||
pub end: Option<i64>,
|
||||
}
|
||||
|
||||
impl<'lua> FromLua<'lua> for Timestamp {
|
||||
fn from_lua(lua_value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let typename = lua_value.type_name();
|
||||
match typename {
|
||||
"table" => {
|
||||
let table: Table = Table::from_lua(lua_value, lua)?;
|
||||
Ok(Timestamp {
|
||||
start: table.get("start")?,
|
||||
end: table.get("_end")?,
|
||||
})
|
||||
},
|
||||
"number" => Ok(Timestamp {
|
||||
start: Option::from_lua(lua_value, lua)?,
|
||||
end: None,
|
||||
}),
|
||||
_ => Err(FromLuaConversionError {
|
||||
from: typename,
|
||||
to: "Timestamp",
|
||||
message: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
105
src/lua.rs
Normal file
105
src/lua.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
use std::{
|
||||
sync::mpsc::Sender,
|
||||
thread::{self, JoinHandle},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use mlua::prelude::*;
|
||||
|
||||
use crate::{
|
||||
activity::{ActivityData, ActivityDataTag, Button, Image, Timestamp},
|
||||
get_lua,
|
||||
};
|
||||
|
||||
enum Variable<T> {
|
||||
Poll(u64),
|
||||
Listen,
|
||||
Static(T),
|
||||
}
|
||||
|
||||
impl<'lua, T: FromLua<'lua>> FromLua<'lua> for Variable<T> {
|
||||
fn from_lua(lua_value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
|
||||
Ok(match lua_value.type_name() {
|
||||
"table" => {
|
||||
let tbl = LuaTable::from_lua(lua_value, lua)?;
|
||||
let rate = tbl.get(1);
|
||||
match rate {
|
||||
Ok(rate) => Self::Poll(rate),
|
||||
Err(_) => Self::Static(T::from_lua(LuaValue::Table(tbl), lua)?),
|
||||
}
|
||||
},
|
||||
"thread" => Self::Listen,
|
||||
_ => Self::Static(T::from_lua(lua_value, lua)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + for<'lua> FromLua<'lua> + Send + 'static> Variable<T> {
|
||||
fn watch<F: Fn(T) + Send + 'static>(
|
||||
self,
|
||||
name: &'static str,
|
||||
data: String,
|
||||
dofun: F,
|
||||
) -> Option<JoinHandle<()>> {
|
||||
match self {
|
||||
Self::Static(val) => {
|
||||
dofun(val);
|
||||
None
|
||||
},
|
||||
Self::Poll(rate) => Some(thread::spawn(move || {
|
||||
let lua = get_lua();
|
||||
lua.load(&data).exec().unwrap();
|
||||
let fun: LuaFunction = lua
|
||||
.globals()
|
||||
.get::<_, LuaTable>(name)
|
||||
.unwrap()
|
||||
.get(2)
|
||||
.unwrap();
|
||||
loop {
|
||||
let val: T = fun.call(()).unwrap();
|
||||
dofun(val);
|
||||
thread::sleep(Duration::from_secs(rate))
|
||||
}
|
||||
})),
|
||||
Self::Listen => Some(thread::spawn(move || {
|
||||
let lua = get_lua();
|
||||
lua.load(&data).exec().unwrap();
|
||||
let thread: LuaThread = lua.globals().get(name).unwrap();
|
||||
loop {
|
||||
match thread.resume::<_, Option<T>>(()) {
|
||||
Ok(Some(val)) => dofun(val),
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! watchtype {
|
||||
($var:ident, $ty:ty, $name:ident, $send:ident, $ctx:ident, $env:ident) => {
|
||||
$env.get::<_, Variable<$ty>>($name)?
|
||||
.watch($name, $ctx.clone(), move |val| {
|
||||
$send.send(ActivityData::$var(val)).unwrap()
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
pub fn create_watcher(
|
||||
name: &'static str,
|
||||
send: Sender<ActivityData>,
|
||||
ctx: &String,
|
||||
env: &LuaTable,
|
||||
tag: &ActivityDataTag,
|
||||
) -> Result<Option<JoinHandle<()>>, LuaError> {
|
||||
Ok(match tag {
|
||||
ActivityDataTag::Active => watchtype!(Active, bool, name, send, ctx, env),
|
||||
ActivityDataTag::State => watchtype!(State, String, name, send, ctx, env),
|
||||
ActivityDataTag::Details => watchtype!(Details, String, name, send, ctx, env),
|
||||
ActivityDataTag::Timestamp => watchtype!(Timestamp, Timestamp, name, send, ctx, env),
|
||||
ActivityDataTag::FirstButton => watchtype!(FirstButton, Button, name, send, ctx, env),
|
||||
ActivityDataTag::SecondButton => watchtype!(SecondButton, Button, name, send, ctx, env),
|
||||
ActivityDataTag::LargeImage => watchtype!(LargeImage, Image, name, send, ctx, env),
|
||||
ActivityDataTag::SmallImage => watchtype!(SmallImage, Image, name, send, ctx, env),
|
||||
})
|
||||
}
|
256
src/main.rs
Normal file
256
src/main.rs
Normal file
|
@ -0,0 +1,256 @@
|
|||
use std::sync::mpsc;
|
||||
use std::time::Duration;
|
||||
use std::{env, path::PathBuf};
|
||||
use std::{fs, thread};
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use dirs::config_dir;
|
||||
use discord_rich_presence::activity::{Activity, Assets, Button, Timestamps};
|
||||
use discord_rich_presence::{DiscordIpc, DiscordIpcClient};
|
||||
use mlua::Lua;
|
||||
|
||||
use crate::activity::ActivityData;
|
||||
use crate::activity::ActivityDataTag::*;
|
||||
use crate::activity::{Button as DiscoButton, Image, Timestamp};
|
||||
use crate::lua::create_watcher;
|
||||
|
||||
mod activity;
|
||||
mod lua;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Command {
|
||||
/// Overrides the default path to look for configuration.
|
||||
#[arg(short, long)]
|
||||
config: Option<PathBuf>,
|
||||
|
||||
/// Sets the ID of the application to connect as. Takes prescedent over Lua configuration.
|
||||
#[arg(short = 'i', long)]
|
||||
client_id: Option<String>,
|
||||
|
||||
/// If connecting to Discord fails, retry after DELAY seconds.
|
||||
#[arg(short, long, value_name = "DELAY", default_value_t = 0)]
|
||||
retry_after: u64,
|
||||
|
||||
/// Don't print any text to the console.
|
||||
#[arg(short, long)]
|
||||
quiet: bool,
|
||||
|
||||
#[arg(short, long)]
|
||||
print_config_path: bool,
|
||||
}
|
||||
|
||||
pub fn get_lua() -> Lua {
|
||||
#[cfg(not(feature = "unsafe"))]
|
||||
return Lua::new();
|
||||
#[cfg(feature = "unsafe")]
|
||||
unsafe {
|
||||
return Lua::unsafe_new();
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Command::parse();
|
||||
let path = match args.config {
|
||||
Some(path) => path,
|
||||
None => env::var("DISCO_CONFIG")
|
||||
.map(|val| PathBuf::from(val))
|
||||
.unwrap_or(
|
||||
config_dir()
|
||||
.expect(
|
||||
"Could not find a place to look for config. Please
|
||||
specify a file in the command line or set
|
||||
DISCO_CONFIG variable.",
|
||||
)
|
||||
.join("disco.lua"),
|
||||
),
|
||||
};
|
||||
|
||||
if args.print_config_path {
|
||||
println!("{:?}", path);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = fs::read(&path).expect(&format!("Failed to read config file at {path:?}"));
|
||||
let file = String::from_utf8(data).expect("Contents of config file is not valid UTF-8");
|
||||
|
||||
let lua = get_lua();
|
||||
lua.load(&file).exec().unwrap();
|
||||
let env = lua.globals();
|
||||
|
||||
let client_id = match args.client_id {
|
||||
Some(id) => id,
|
||||
None => env
|
||||
.get("ClientID")
|
||||
.expect("No client id available. Set ClientID in {path} or with --client-id"),
|
||||
};
|
||||
|
||||
if !args.quiet {
|
||||
println!("Client ID: {client_id}");
|
||||
}
|
||||
|
||||
let mut client =
|
||||
DiscordIpcClient::new(&client_id).expect("Failed to create Discord IPC Client");
|
||||
let mut ret = client.connect();
|
||||
match args.retry_after {
|
||||
0 => {
|
||||
if let Err(_) = ret {
|
||||
panic!("Failed to connect to Discord IPC. Please make sure Discord is open.");
|
||||
}
|
||||
},
|
||||
n => {
|
||||
while let Err(_) = ret {
|
||||
println!("Failed to connect to Discord IPC. Retrying in {n} seconds...");
|
||||
thread::sleep(Duration::from_secs(n));
|
||||
ret = client.connect();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let (send, recv) = mpsc::channel::<ActivityData>();
|
||||
|
||||
let values = vec![
|
||||
("State", State),
|
||||
("Details", Details),
|
||||
("Timestamp", Timestamp),
|
||||
("Button1", FirstButton),
|
||||
("Button2", SecondButton),
|
||||
("LargeImage", LargeImage),
|
||||
("SmallImage", SmallImage),
|
||||
("Active", Active),
|
||||
];
|
||||
|
||||
values.iter().for_each(|(name, ty)| {
|
||||
let ret = create_watcher(name, send.clone(), &file, &env, &ty);
|
||||
if let Err(_) = ret {
|
||||
if !args.quiet {
|
||||
println!("No value for {name}");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mut activity = DiscoActivity::new();
|
||||
|
||||
loop {
|
||||
match recv.recv() {
|
||||
Ok(val) => {
|
||||
if !args.quiet {
|
||||
println!("New Value: {val:?}");
|
||||
}
|
||||
match val {
|
||||
ActivityData::Active(val) => {
|
||||
if !val {
|
||||
let _ = client.clear_activity();
|
||||
}
|
||||
activity.active = val
|
||||
},
|
||||
ActivityData::State(val) => activity.state = Some(val),
|
||||
ActivityData::Details(val) => activity.details = Some(val),
|
||||
ActivityData::Timestamp(val) => activity.timestamp = Some(val),
|
||||
ActivityData::FirstButton(val) => activity.button1 = Some(val),
|
||||
ActivityData::SecondButton(val) => activity.button2 = Some(val),
|
||||
ActivityData::LargeImage(val) => activity.large_image = Some(val),
|
||||
ActivityData::SmallImage(val) => activity.small_image = Some(val),
|
||||
}
|
||||
activity.process(&mut client, args.quiet);
|
||||
},
|
||||
Err(_) => {
|
||||
if !args.quiet {
|
||||
println!("Exiting...");
|
||||
}
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct DiscoActivity {
|
||||
active: bool,
|
||||
state: Option<String>,
|
||||
details: Option<String>,
|
||||
timestamp: Option<Timestamp>,
|
||||
button1: Option<DiscoButton>,
|
||||
button2: Option<DiscoButton>,
|
||||
large_image: Option<Image>,
|
||||
small_image: Option<Image>,
|
||||
}
|
||||
|
||||
impl DiscoActivity {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
active: false,
|
||||
state: None,
|
||||
details: None,
|
||||
timestamp: None,
|
||||
button1: None,
|
||||
button2: None,
|
||||
large_image: None,
|
||||
small_image: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn process(&self, client: &mut DiscordIpcClient, quiet: bool) {
|
||||
if self.active {
|
||||
let mut activity = Activity::new();
|
||||
|
||||
if let Some(val) = &self.state {
|
||||
activity = activity.state(val);
|
||||
}
|
||||
if let Some(val) = &self.details {
|
||||
activity = activity.details(val);
|
||||
}
|
||||
|
||||
if let Some(val) = &self.timestamp {
|
||||
let mut timestamps = Timestamps::new();
|
||||
if let Some(val) = val.start {
|
||||
timestamps = timestamps.start(val);
|
||||
}
|
||||
if let Some(val) = val.end {
|
||||
timestamps = timestamps.end(val);
|
||||
}
|
||||
activity = activity.timestamps(timestamps);
|
||||
}
|
||||
|
||||
let mut buttons = Vec::with_capacity(2);
|
||||
let mut buttons_set = false;
|
||||
if let Some(val) = &self.button1 {
|
||||
buttons.push(Button::new(&val.text, &val.url));
|
||||
buttons_set = true;
|
||||
}
|
||||
if let Some(val) = &self.button2 {
|
||||
buttons.push(Button::new(&val.text, &val.url));
|
||||
buttons_set = true;
|
||||
}
|
||||
if buttons_set {
|
||||
activity = activity.buttons(buttons);
|
||||
}
|
||||
|
||||
let mut assets = Assets::new();
|
||||
let mut assets_set = false;
|
||||
if let Some(val) = &self.large_image {
|
||||
if let Some(val) = &val.text {
|
||||
assets = assets.large_text(&val);
|
||||
}
|
||||
assets = assets.large_image(&val.asset);
|
||||
assets_set = true;
|
||||
}
|
||||
if let Some(val) = &self.small_image {
|
||||
if let Some(val) = &val.text {
|
||||
assets = assets.small_text(&val);
|
||||
}
|
||||
assets = assets.small_image(&val.asset);
|
||||
assets_set = true;
|
||||
}
|
||||
if assets_set {
|
||||
activity = activity.assets(assets);
|
||||
}
|
||||
|
||||
if !quiet {
|
||||
println!("DEBUG: {self:#?}");
|
||||
}
|
||||
client.set_activity(activity).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue