diff --git a/Cargo.lock b/Cargo.lock index cc96303..11c2c3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -167,6 +167,12 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +[[package]] +name = "bytecount" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" + [[package]] name = "byteorder" version = "1.5.0" @@ -179,6 +185,37 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.20", + "serde", + "serde_json", +] + [[package]] name = "cc" version = "1.0.83" @@ -206,7 +243,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -249,6 +286,21 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crypto-common" version = "0.1.6" @@ -269,16 +321,6 @@ dependencies = [ "darling_macro 0.13.4", ] -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - [[package]] name = "darling" version = "0.20.3" @@ -303,20 +345,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", -] - [[package]] name = "darling_core" version = "0.20.3" @@ -328,7 +356,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -342,17 +370,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.3" @@ -361,7 +378,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -453,7 +470,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -489,6 +506,31 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "finl_unicode" version = "1.2.0" @@ -581,7 +623,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -650,6 +692,12 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "h2" version = "0.3.21" @@ -875,7 +923,7 @@ checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ "socket2 0.5.5", "widestring", - "windows-sys", + "windows-sys 0.48.0", "winreg", ] @@ -918,6 +966,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "lock_api" version = "0.4.11" @@ -987,6 +1041,21 @@ dependencies = [ "unicase", ] +[[package]] +name = "mini-moka" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c325dfab65f261f386debee8b0969da215b3fa0037e74c8a1234db7ba986d803" +dependencies = [ + "crossbeam-channel", + "crossbeam-utils", + "dashmap", + "skeptic", + "smallvec", + "tagptr", + "triomphe", +] + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1004,7 +1073,7 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1166,6 +1235,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + [[package]] name = "option-ext" version = "0.2.0" @@ -1198,7 +1273,7 @@ dependencies = [ "libc", "redox_syscall 0.4.1", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1241,31 +1316,31 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "poise" -version = "0.5.5" -source = "git+https://github.com/serenity-rs/poise.git?branch=serenity-next#b1d6bf643e877b5d689207d275a3b75363b0784b" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1819d5a45e3590ef33754abce46432570c54a120798bdbf893112b4211fa09a6" dependencies = [ "async-trait", "derivative", - "futures-core", "futures-util", - "log", - "once_cell", "parking_lot", "poise_macros", "regex", "serenity", "tokio", + "tracing", ] [[package]] name = "poise_macros" -version = "0.5.5" -source = "git+https://github.com/serenity-rs/poise.git?branch=serenity-next#b1d6bf643e877b5d689207d275a3b75363b0784b" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fa2c123c961e78315cd3deac7663177f12be4460f5440dbf62a7ed37b1effea" dependencies = [ - "darling 0.14.4", + "darling 0.20.3", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1282,13 +1357,24 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] +[[package]] +name = "pulldown-cmark" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -1297,9 +1383,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1423,6 +1509,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", + "rustls-native-certs", "rustls-pemfile", "serde", "serde_json", @@ -1453,7 +1540,7 @@ dependencies = [ [[package]] name = "revanced-discord-bot" -version = "2.6.2" +version = "2.7.0" dependencies = [ "base64 0.21.5", "bson", @@ -1487,7 +1574,7 @@ dependencies = [ "libc", "spin", "untrusted", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1524,6 +1611,19 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "rustls" version = "0.21.8" @@ -1536,6 +1636,18 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.3" @@ -1561,6 +1673,24 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1587,6 +1717,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.9.0" @@ -1601,6 +1754,9 @@ name = "semver" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -1610,9 +1766,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.190" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] @@ -1628,20 +1784,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "indexmap 2.0.2", "itoa", @@ -1702,13 +1858,14 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] name = "serenity" -version = "0.11.6" -source = "git+https://github.com/serenity-rs/serenity?rev=a0c102f9acfd8d7184650815e06e0301954cb9e7#a0c102f9acfd8d7184650815e06e0301954cb9e7" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385647faa24a889929028973650a4f158fb1b4272b2fcf94feb9fcc3c009e813" dependencies = [ "arrayvec", "async-trait", @@ -1732,6 +1889,7 @@ dependencies = [ "tokio-tungstenite", "tracing", "typemap_rev", + "typesize", "url", ] @@ -1786,6 +1944,21 @@ dependencies = [ "libc", ] +[[package]] +name = "skeptic" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" +dependencies = [ + "bytecount", + "cargo_metadata", + "error-chain", + "glob", + "pulldown-cmark", + "tempfile", + "walkdir", +] + [[package]] name = "slab" version = "0.4.9" @@ -1818,7 +1991,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1863,9 +2036,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1893,6 +2066,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "take_mut" version = "0.2.2" @@ -1905,6 +2084,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "thiserror" version = "1.0.50" @@ -1922,7 +2114,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -1981,9 +2173,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -1994,18 +2186,18 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.5", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -2074,7 +2266,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -2112,6 +2304,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + [[package]] name = "trust-dns-proto" version = "0.21.2" @@ -2206,6 +2404,35 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typesize" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36924509726e38224322c8c90ddfbf4317324338327b7c11b7cf8672cb786da1" +dependencies = [ + "chrono", + "dashmap", + "hashbrown 0.14.2", + "mini-moka", + "parking_lot", + "secrecy", + "serde_json", + "time", + "typesize-derive", + "url", +] + +[[package]] +name = "typesize-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b122284365ba8497be951b9a21491f70c9688eb6fddc582931a0703f6a00ece" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "unicase" version = "2.7.0" @@ -2282,6 +2509,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -2318,7 +2555,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -2352,7 +2589,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2414,6 +2651,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2426,7 +2672,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -2435,7 +2681,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -2444,13 +2699,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 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.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -2459,42 +2729,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winreg" version = "0.50.0" @@ -2502,7 +2814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2531,7 +2843,7 @@ checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a8ee3e8..a1a536e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://revanced.app" license = "GPL-3.0" name = "revanced-discord-bot" repository = "https://github.com/revanced/revanced-discord-bot" -version = "2.6.2" +version = "2.7.0" edition = "2021" [profile.release] @@ -19,7 +19,7 @@ panic = "abort" bson = "2.4" serde_with_macros = "3.4.0" mongodb = "2.4.0" -poise = { git = "https://github.com/serenity-rs/poise.git", branch = "serenity-next" } +poise = "0.6.1" decancer = "1.5.4" tokio = { version = "1.26.0", features = ["rt-multi-thread"] } dotenv = "0.15.0" @@ -28,7 +28,7 @@ serde_json = "1.0.94" regex = "1.7.3" serde_regex = "1.1.0" reqwest = { version = "0.11.15", features = [ - "rustls-tls", + "rustls-tls-native-roots", "json", ], default-features = false } chrono = "0.4.24" diff --git a/configuration.example.json b/configuration.example.json index 741fb48..d910f34 100644 --- a/configuration.example.json +++ b/configuration.example.json @@ -7,8 +7,7 @@ 0 ] }, - "logging_channel": 0, - "cure_on_presence_update": false + "logging_channel": 0 }, "administrators": { "roles": [ diff --git a/configuration.revanced.json b/configuration.revanced.json index 59ddd3e..1bbb492 100644 --- a/configuration.revanced.json +++ b/configuration.revanced.json @@ -1,4 +1,5 @@ -{ "general": { +{ + "general": { "embed_color": 5150960, "mute": { "role": 953984696491061289, @@ -9,8 +10,7 @@ ] }, "media_channels": [], - "logging_channel": 1027892160797872179, - "cure_on_presence_update": true + "logging_channel": 1027892160797872179 }, "administrators": { "roles": [ @@ -596,4 +596,4 @@ } } ] -} +} \ No newline at end of file diff --git a/src/commands/configuration.rs b/src/commands/configuration.rs index e379d1f..47f08c1 100644 --- a/src/commands/configuration.rs +++ b/src/commands/configuration.rs @@ -18,11 +18,15 @@ pub async fn reload(ctx: Context<'_>) -> Result<(), Error> { debug!("{} reloaded the configuration.", ctx.author().name); ctx.send( - CreateReply::new().ephemeral(true).embed( - CreateEmbed::new() - .description("Successfully reloaded configuration.") - .color(embed_color), - ), + CreateReply { + embeds: vec![ + CreateEmbed::new() + .description("Reloading configuration...") + .color(embed_color), + ], + ephemeral: Some(true), + ..Default::default() + } ) .await?; @@ -37,11 +41,15 @@ pub async fn stop(ctx: Context<'_>) -> Result<(), Error> { let color = ctx.data().read().await.configuration.general.embed_color; ctx.send( - CreateReply::new().ephemeral(true).embed( - CreateEmbed::new() - .description("Stopped the bot.") - .color(color), - ), + CreateReply { + ephemeral: Some(true), + embeds: vec![ + CreateEmbed::new() + .description("Stopping the bot...") + .color(color), + ], + ..Default::default() + } ) .await?; diff --git a/src/commands/misc.rs b/src/commands/misc.rs index 0a249eb..234f598 100644 --- a/src/commands/misc.rs +++ b/src/commands/misc.rs @@ -15,8 +15,12 @@ pub async fn reply( ctx: &Context<'a>, content: &str, ) -> Result, poise::serenity_prelude::Error> { - ctx.send(CreateReply::new().ephemeral(true).content(content)) - .await + ctx.send(CreateReply { + ephemeral: Some(true), + content: Some(content.to_string()), + ..Default::default() + }) + .await } let http = &ctx.serenity_context().http; diff --git a/src/commands/moderation.rs b/src/commands/moderation.rs index 8cb8079..af77188 100644 --- a/src/commands/moderation.rs +++ b/src/commands/moderation.rs @@ -1,30 +1,17 @@ - - - use bson::{doc, Document}; use chrono::Utc; use mongodb::options::{UpdateModifications, UpdateOptions}; use poise::serenity_prelude::{ - self as serenity, - CreateEmbed, - CreateEmbedFooter, - EditMessage, - GetMessages, - Mentionable, - UserId, + self as serenity, CreateEmbed, CreateEmbedFooter, EditMessage, GetMessages, Mentionable, UserId, }; use poise::CreateReply; use tracing::{debug, trace}; -use crate::db::model::{Muted}; +use crate::db::model::Muted; use crate::utils::bot::get_member; use crate::utils::macros::to_user; use crate::utils::moderation::{ - ban_moderation, - queue_unmute_member, - respond_moderation, - BanKind, - ModerationKind, + ban_moderation, queue_unmute_member, respond_moderation, BanKind, ModerationKind, }; use crate::utils::parse_duration; use crate::{Context, Error}; @@ -208,15 +195,14 @@ pub async fn purge( let author = ctx.author(); let handle = ctx - .send( - CreateReply::new().embed( - CreateEmbed::new() - .title("Purging messages") - .description("Accumulating...") - .color(embed_color) - .thumbnail(&image), - ), - ) + .send(CreateReply { + embeds: vec![CreateEmbed::new() + .title("Purging messages") + .description("Accumulating...") + .color(embed_color) + .thumbnail(&image)], + ..Default::default() + }) .await?; let mut response = handle.message().await?; diff --git a/src/events/guild_member_addition.rs b/src/events/guild_member_addition.rs index 5f3ba0e..bfdef1f 100644 --- a/src/events/guild_member_addition.rs +++ b/src/events/guild_member_addition.rs @@ -1,9 +1,14 @@ use super::*; use crate::utils::decancer::cure; use crate::utils::moderation::mute_on_join; +use crate::BotData; -pub async fn guild_member_addition(ctx: &serenity::Context, new_member: &mut serenity::Member) { - mute_on_join(ctx, new_member).await; +pub async fn guild_member_addition( + ctx: &serenity::Context, + new_member: &serenity::Member, + data: &BotData, +) { + mute_on_join(ctx, new_member, data).await; cure(ctx, &None, new_member).await; } diff --git a/src/events/guild_member_update.rs b/src/events/guild_member_update.rs index 80467ef..4ab99a9 100644 --- a/src/events/guild_member_update.rs +++ b/src/events/guild_member_update.rs @@ -5,7 +5,6 @@ pub async fn guild_member_update( ctx: &serenity::Context, old_if_available: &Option, new: &Option, - _: &GuildMemberUpdateEvent, ) { if let Some(member) = new { cure(ctx, old_if_available, member).await; diff --git a/src/events/interaction.rs b/src/events/interaction.rs index ad346a2..63a6ff0 100644 --- a/src/events/interaction.rs +++ b/src/events/interaction.rs @@ -1,15 +1,15 @@ use chrono::{Duration, Utc}; use poise::serenity_prelude::{ - ComponentInteraction, - ComponentInteractionData, - ComponentInteractionDataKind, + ComponentInteraction, ComponentInteractionData, ComponentInteractionDataKind, }; use super::*; -use crate::utils; +use crate::{utils, BotData}; + pub async fn interaction_create( ctx: &serenity::Context, interaction: &serenity::Interaction, + data: &BotData, ) -> Result<(), serenity::prelude::SerenityError> { if let serenity::Interaction::Component(ComponentInteraction { data: @@ -22,7 +22,7 @@ pub async fn interaction_create( }) = interaction { if custom_id.starts_with("poll") { - handle_poll(ctx, interaction, custom_id).await? + handle_poll(ctx, interaction, custom_id, data).await? } } @@ -33,6 +33,7 @@ pub async fn handle_poll( ctx: &serenity::Context, interaction: &serenity::Interaction, custom_id: &str, + data: &BotData, ) -> Result<(), serenity::prelude::SerenityError> { fn parse(str: &str) -> T where @@ -49,5 +50,5 @@ pub async fn handle_poll( let min_join_date = serenity::Timestamp::from(Utc::now() - Duration::days(min_age)); - utils::poll::handle_poll(ctx, interaction, poll_id, min_join_date).await + utils::poll::handle_poll(ctx, interaction, poll_id, min_join_date, data).await } diff --git a/src/events/message_create.rs b/src/events/message_create.rs index a856000..22ee825 100644 --- a/src/events/message_create.rs +++ b/src/events/message_create.rs @@ -1,10 +1,15 @@ use super::*; use crate::utils::code_embed::utils::code_preview; use crate::utils::message_response::handle_message_response; +use crate::BotData; -pub async fn message_create(ctx: &serenity::Context, new_message: &serenity::Message) { +pub async fn message_create( + ctx: &serenity::Context, + new_message: &serenity::Message, + data: &BotData, +) { tokio::join!( - handle_message_response(ctx, new_message), + handle_message_response(ctx, new_message, data), code_preview(ctx, new_message) ); } diff --git a/src/events/mod.rs b/src/events/mod.rs index dc9e1d3..32ff5a3 100644 --- a/src/events/mod.rs +++ b/src/events/mod.rs @@ -1,124 +1,37 @@ use std::sync::Arc; -use poise::serenity_prelude::prelude::RwLock; -use poise::serenity_prelude::{ - self as serenity, - GuildMemberUpdateEvent, - Member, - Presence, - ShardManager, - UserId, -}; -use tracing::log::error; - -use crate::{Data, Error}; +use crate::{BotData, Data, Error}; +use poise::serenity_prelude::{self as serenity, Member}; +use tokio::sync::RwLock; mod guild_member_addition; mod guild_member_update; mod interaction; mod message_create; -mod presence_update; mod ready; -pub struct Handler { - options: poise::FrameworkOptions, - data: T, - bot_id: RwLock>, - shard_manager: RwLock>>, -} - -// Custom handler to dispatch poise events -impl Handler { - pub fn new(options: poise::FrameworkOptions, data: T) -> Self { - Self { - options, - data, - shard_manager: RwLock::new(None), - bot_id: RwLock::new(None), - } - } - - pub async fn set_shard_manager(&self, shard_manager: Arc) { - *self.shard_manager.write().await = Some(shard_manager); - } - - async fn dispatch_poise_event(&self, event: &serenity::FullEvent) { - let framework_data = poise::FrameworkContext { - bot_id: self.bot_id.read().await.unwrap(), - options: &self.options, - user_data: &self.data, - shard_manager: &(*self.shard_manager.read().await).clone().unwrap(), /* Shard manager can be read between all poise events without locks */ - }; - poise::dispatch_event(framework_data, event).await; - } -} - -// Manually dispatch events from serenity to poise -#[serenity::async_trait] -impl serenity::EventHandler for Handler>> { - async fn guild_member_addition( - &self, - ctx: serenity::Context, - mut new_member: serenity::Member, - ) { - guild_member_addition::guild_member_addition(&ctx, &mut new_member).await; - } - - async fn presence_update(&self, ctx: serenity::Context, new_data: Presence) { - presence_update::presence_update(&ctx, &new_data).await; - } - - async fn guild_member_update( - &self, - ctx: serenity::Context, - old_if_available: Option, - new: Option, - event: GuildMemberUpdateEvent, - ) { - guild_member_update::guild_member_update(&ctx, &old_if_available, &new, &event).await; - } - - async fn message(&self, ctx: serenity::Context, new_message: serenity::Message) { - message_create::message_create(&ctx, &new_message).await; - - self.dispatch_poise_event(&serenity::FullEvent::Message { - ctx, - new_message, - }) - .await; - } - - async fn message_update( - &self, - ctx: serenity::Context, - old_if_available: Option, - new: Option, - event: serenity::MessageUpdateEvent, - ) { - self.dispatch_poise_event(&serenity::FullEvent::MessageUpdate { - ctx, +pub async fn event_handler( + ctx: &serenity::Context, + event: &serenity::FullEvent, + data: &BotData, +) -> Result<(), Error> { + match event { + serenity::FullEvent::Ready { .. } => ready::load_muted_members(ctx, data).await, + serenity::FullEvent::Message { new_message } => { + message_create::message_create(ctx, new_message, data).await; + }, + serenity::FullEvent::GuildMemberAddition { new_member } => { + guild_member_addition::guild_member_addition(ctx, new_member, data).await + }, + serenity::FullEvent::GuildMemberUpdate { old_if_available, new, - event, - }) - .await; - } - - async fn ready(&self, ctx: serenity::Context, ready: serenity::Ready) { - *self.bot_id.write().await = Some(ready.user.id); - - ready::load_muted_members(&ctx, &ready).await; - } - - async fn interaction_create(&self, ctx: serenity::Context, interaction: serenity::Interaction) { - if let Err(e) = interaction::interaction_create(&ctx, &interaction).await { - error!("Failed to handle interaction: {:?}.", e); - } - - self.dispatch_poise_event(&serenity::FullEvent::InteractionCreate { - ctx, - interaction, - }) - .await; + .. + } => guild_member_update::guild_member_update(ctx, old_if_available, new).await, + serenity::FullEvent::InteractionCreate { interaction } => { + interaction::interaction_create(ctx, interaction, data).await? + }, + _ => {}, } + Ok(()) } diff --git a/src/events/presence_update.rs b/src/events/presence_update.rs deleted file mode 100644 index 6a9bcf6..0000000 --- a/src/events/presence_update.rs +++ /dev/null @@ -1,25 +0,0 @@ -use super::*; -use crate::model::application::Configuration; -use crate::utils::bot::get_data_lock; -use crate::utils::decancer::cure; - -pub async fn presence_update(ctx: &serenity::Context, new_data: &Presence) { - let data = get_data_lock(ctx).await; - let configuration: &Configuration = &data.read().await.configuration; - - if !configuration.general.cure_on_presence_update { - return; - } - - cure( - ctx, - &None, - &new_data - .guild_id - .unwrap() - .member(&ctx.http, new_data.user.id) - .await - .unwrap(), - ) - .await; -} diff --git a/src/events/ready.rs b/src/events/ready.rs index a802dc5..e3e18f9 100644 --- a/src/events/ready.rs +++ b/src/events/ready.rs @@ -2,11 +2,9 @@ use chrono::Utc; use super::*; use crate::db::model::Muted; -use crate::utils::bot::get_data_lock; use crate::utils::moderation::queue_unmute_member; -pub async fn load_muted_members(ctx: &serenity::Context, _: &serenity::Ready) { - let data = get_data_lock(ctx).await; +pub async fn load_muted_members(ctx: &serenity::Context, data: &Arc>) { let data = &mut *data.write().await; let mute_role_id = data.configuration.general.mute.role; diff --git a/src/main.rs b/src/main.rs index 65adf44..ba4dd42 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use api::client::Api; use commands::{configuration, misc, moderation}; use db::database::Database; -use events::Handler; +use events::event_handler; use poise::serenity_prelude::prelude::{RwLock, TypeMapKey}; use poise::serenity_prelude::{CreateEmbed, UserId}; use poise::CreateReply; @@ -23,11 +23,12 @@ mod logger; mod model; mod utils; +type BotData = Arc>; type Error = Box; -type Context<'a> = poise::Context<'a, Arc>, Error>; +type Context<'a> = poise::Context<'a, BotData, Error>; impl TypeMapKey for Data { - type Value = Arc>; + type Value = BotData; } pub struct Data { @@ -40,13 +41,9 @@ pub struct Data { #[tokio::main] async fn main() { - // Initialize the logging framework logger::init(); - - // Load environment variables from .env file dotenv::dotenv().ok(); - // Define poise framework commands (also in src/commands/mod.rs for serenity framework's manually dispatched events) let mut commands = vec![ configuration::register(), configuration::reload(), @@ -73,65 +70,73 @@ async fn main() { .into_iter() .collect(); - let data = Arc::new(RwLock::new(Data { - configuration, - database: Arc::new( - Database::new( - &env::var("MONGODB_URI").expect("MONGODB_URI environment variable not set"), - "revanced_discord_bot", - ) - .await - .unwrap(), - ), - pending_unmutes: HashMap::new(), - poll_secret: env::var("POLL_SECRET").expect("POLL_SECRET environment variable not set"), - api: Api::new( - reqwest::Url::parse( - &env::var("API_SERVER").expect("API_SERVER environment variable not set"), - ) - .expect("Invalid API_SERVER"), - env::var("API_CLIENT_ID").expect("API_CLIENT_ID environment variable not set"), - env::var("API_CLIENT_SECRET").expect("API_CLIENT_SECRET environment variable not set"), - ), - })); - - let handler = Arc::new(Handler::new( - poise::FrameworkOptions { - owners, - commands, - on_error: |error| { - Box::pin(async { - poise::samples::on_error(error) - .await - .unwrap_or_else(|error| tracing::error!("{}", error)); - }) - }, - command_check: Some(|ctx| { + poise::serenity_prelude::ClientBuilder::new( + env::var("DISCORD_AUTHORIZATION_TOKEN").unwrap(), + poise::serenity_prelude::GatewayIntents::non_privileged() + | poise::serenity_prelude::GatewayIntents::MESSAGE_CONTENT + | poise::serenity_prelude::GatewayIntents::GUILD_MEMBERS + | poise::serenity_prelude::GatewayIntents::GUILD_PRESENCES, + ) + .framework( + poise::Framework::builder() + .setup(move |_ctx, _ready, _framework| { Box::pin(async move { - if let Some(member) = ctx.author_member().await { - let data_lock = &ctx.data().read().await; - let configuration = &data_lock.configuration; - let administrators = &configuration.administrators; + Ok(Arc::new(RwLock::new(Data { + configuration, + database: Arc::new( + Database::new( + &env::var("MONGODB_URI").unwrap(), + "revanced_discord_bot", + ) + .await + .unwrap(), + ), + pending_unmutes: HashMap::new(), + poll_secret: env::var("POLL_SECRET").unwrap(), + api: Api::new( + reqwest::Url::parse(&env::var("API_SERVER").unwrap()).unwrap(), + env::var("API_CLIENT_ID").unwrap(), + env::var("API_CLIENT_SECRET").unwrap(), + ), + }))) + }) + }) + .options(poise::FrameworkOptions { + owners, + commands, + on_error: |error| { + Box::pin(async { + poise::samples::on_error(error) + .await + .unwrap_or_else(|error| tracing::error!("{}", error)); + }) + }, + command_check: Some(|ctx| { + Box::pin(async move { + if let Some(member) = ctx.author_member().await { + let data_lock = &ctx.data().read().await; + let configuration = &data_lock.configuration; + let administrators = &configuration.administrators; - if !(administrators - .users - // Check if the user is an administrator - .contains(&member.user.id.get()) - || administrators - .roles - .iter() - // Has one of the administative roles - .any(|&role_id| { - member - .roles - .iter() - .any(|member_role| member_role.get() == role_id) - })) - { - if let Err(e) = ctx - .send( - CreateReply::new().ephemeral(true).embed( - CreateEmbed::new() + if !(administrators + .users + // Check if the user is an administrator + .contains(&member.user.id.get()) + || administrators + .roles + .iter() + // Has one of the administative roles + .any(|&role_id| { + member + .roles + .iter() + .any(|member_role| member_role.get() == role_id) + })) + { + if let Err(e) = ctx + .send(CreateReply { + ephemeral: Some(true), + embeds: vec![CreateEmbed::new() .title("Permission error") .description( "You do not have permission to use this command.", @@ -139,48 +144,30 @@ async fn main() { .color(configuration.general.embed_color) .thumbnail(member.user.avatar_url().unwrap_or_else( || member.user.default_avatar_url(), - )), - ), - ) - .await - { - error!("Error sending message: {:?}", e) + ))], + ..Default::default() + }) + .await + { + error!("Error sending message: {:?}", e) + } + trace!("{} is not an administrator.", member.user.name); + return Ok(false); // Not an administrator, don't allow command execution } - trace!("{} is not an administrator.", member.user.name); - return Ok(false); // Not an administrator, don't allow command execution } - } - Ok(true) - }) - }), - event_handler: |event, _framework, _data| { - Box::pin(async move { - tracing::trace!("{:?}", event.snake_case_name()); - Ok(()) - }) - }, - ..Default::default() - }, - data.clone(), // Pass configuration as user data for the framework - )); - - let mut client = poise::serenity_prelude::Client::builder( - env::var("DISCORD_AUTHORIZATION_TOKEN") - .expect("DISCORD_AUTHORIZATION_TOKEN environment variable not set"), - poise::serenity_prelude::GatewayIntents::non_privileged() - | poise::serenity_prelude::GatewayIntents::MESSAGE_CONTENT - | poise::serenity_prelude::GatewayIntents::GUILD_MEMBERS - | poise::serenity_prelude::GatewayIntents::GUILD_PRESENCES, + Ok(true) + }) + }), + event_handler: |ctx, event, _framework, data| { + Box::pin(event_handler(ctx, event, data)) + }, + ..Default::default() + }) + .build(), ) - .event_handler_arc(handler.clone()) + .await + .unwrap() + .start() .await .unwrap(); - - client.data.write().await.insert::(data); - - handler - .set_shard_manager(client.shard_manager.clone()) - .await; - - client.start().await.unwrap(); } diff --git a/src/model/application.rs b/src/model/application.rs index 7cbbf75..19deefe 100644 --- a/src/model/application.rs +++ b/src/model/application.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use std::fs::{self, File}; use std::io::{Read, Result, Write}; use std::path::Path; @@ -66,18 +67,17 @@ pub struct General { pub embed_color: i32, pub mute: Mute, pub logging_channel: u64, - pub cure_on_presence_update: bool, } #[derive(Default, Serialize, Deserialize)] pub struct Mute { pub role: u64, - pub take: Vec, + pub take: HashSet, } #[derive(Default, Serialize, Deserialize)] pub struct Administrators { - pub roles: Vec, - pub users: Vec, + pub roles: HashSet, + pub users: HashSet, } #[derive(Serialize, Deserialize)] @@ -147,15 +147,15 @@ pub struct Author { #[derive(Serialize, Deserialize)] pub struct Includes { - pub channels: Option>, - pub roles: Option>, + pub channels: Option>, + pub roles: Option>, #[serde(rename = "match", with = "serde_regex")] pub match_field: Vec, } #[derive(Serialize, Deserialize)] pub struct Excludes { - pub roles: Option>, + pub roles: Option>, } #[derive(Serialize, Deserialize)] diff --git a/src/utils/bot.rs b/src/utils/bot.rs index 5410d82..8a00a3f 100644 --- a/src/utils/bot.rs +++ b/src/utils/bot.rs @@ -1,21 +1,11 @@ -use std::sync::Arc; - use poise::serenity_prelude::{self as serenity}; use crate::model::application::Configuration; -use crate::Data; pub fn load_configuration() -> Configuration { Configuration::load().expect("Failed to load configuration") } -// Share the lock reference between the threads in serenity framework -pub async fn get_data_lock( - ctx: &serenity::Context, -) -> Arc> { - ctx.data.read().await.get::().unwrap().clone() -} - pub async fn get_member( ctx: &serenity::Context, guild_id: serenity::GuildId, diff --git a/src/utils/message.rs b/src/utils/message.rs index ff9785e..5754ab7 100644 --- a/src/utils/message.rs +++ b/src/utils/message.rs @@ -3,7 +3,10 @@ use poise::serenity_prelude::{CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, use poise::CreateReply; pub fn clone_message(message: &Message) -> CreateReply { - let mut reply = CreateReply::new().content(message.content.as_str()); + let mut reply = CreateReply { + content: Some(message.content.clone()), + ..Default::default() + }; if let Some(embed) = message.embeds.first() { let mut new_embed = CreateEmbed::new(); diff --git a/src/utils/message_response.rs b/src/utils/message_response.rs index eaff0bd..93aed2e 100644 --- a/src/utils/message_response.rs +++ b/src/utils/message_response.rs @@ -1,29 +1,30 @@ + + use chrono::{DateTime, Duration, NaiveDateTime, Utc}; use poise::serenity_prelude::{ - CreateEmbed, - CreateEmbedAuthor, - CreateEmbedFooter, - CreateMessage, - EditThread, - GetMessages, + CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, CreateMessage, EditThread, GetMessages, }; use regex::Regex; + use tracing::log::error; use super::*; -use crate::utils::bot::get_data_lock; +use crate::{BotData}; pub fn contains_match(regex: &[Regex], text: &str) -> bool { regex.iter().any(|r| r.is_match(text)) } -pub async fn handle_message_response(ctx: &serenity::Context, new_message: &serenity::Message) { +pub async fn handle_message_response( + ctx: &serenity::Context, + new_message: &serenity::Message, + data: &BotData, +) { if new_message.guild_id.is_none() || new_message.author.bot { return; } - let data_lock = get_data_lock(ctx).await; - let responses = &data_lock.read().await.configuration.message_responses; + let responses = &data.read().await.configuration.message_responses; let message = &new_message.content; let mut guild_message = None; @@ -130,40 +131,37 @@ pub async fn handle_message_response(ctx: &serenity::Context, new_message: &sere } if let Err(err) = channel_id - .send_message( - &ctx.http, - { - let mut message = CreateMessage::default(); - message = if let Some(reference) = message_reference { - message.reference_message(reference) - } else { - message.reference_message(new_message) - }; + .send_message(&ctx.http, { + let mut message = CreateMessage::default(); + message = if let Some(reference) = message_reference { + message.reference_message(reference) + } else { + message.reference_message(new_message) + }; - match &response.response.embed { - Some(embed) => message.embed( - CreateEmbed::new() - .title(&embed.title) - .description(&embed.description) - .color(embed.color) - .fields(embed.fields.iter().map(|field| { - (field.name.clone(), field.value.clone(), field.inline) - })) - .footer( - CreateEmbedFooter::new(&embed.footer.text) - .icon_url(&embed.footer.icon_url), - ) - .thumbnail(&embed.thumbnail.url) - .image(&embed.image.url) - .author( - CreateEmbedAuthor::new(&embed.author.name) - .icon_url(&embed.author.icon_url), - ), - ), - None => message.content(response.response.message.as_ref().unwrap()), - } - }, - ) + match &response.response.embed { + Some(embed) => message.embed( + CreateEmbed::new() + .title(&embed.title) + .description(&embed.description) + .color(embed.color) + .fields(embed.fields.iter().map(|field| { + (field.name.clone(), field.value.clone(), field.inline) + })) + .footer( + CreateEmbedFooter::new(&embed.footer.text) + .icon_url(&embed.footer.icon_url), + ) + .thumbnail(&embed.thumbnail.url) + .image(&embed.image.url) + .author( + CreateEmbedAuthor::new(&embed.author.name) + .icon_url(&embed.author.icon_url), + ), + ), + None => message.content(response.response.message.as_ref().unwrap()), + } + }) .await { error!( diff --git a/src/utils/moderation.rs b/src/utils/moderation.rs index b1c8c8c..728a3fe 100644 --- a/src/utils/moderation.rs +++ b/src/utils/moderation.rs @@ -3,40 +3,32 @@ use std::sync::{Arc, Mutex}; use mongodb::options::FindOptions; use poise::serenity_prelude::{ - ChannelId, - CreateEmbed, - CreateEmbedFooter, - CreateMessage, - GuildId, - Mentionable, - User, - UserId, + ChannelId, CreateEmbed, CreateEmbedFooter, CreateMessage, GuildId, Mentionable, User, UserId, }; use poise::CreateReply; use serenity::prelude::SerenityError; + use tokio::task::JoinHandle; use tracing::{debug, error, warn}; -use super::bot::get_data_lock; use super::*; use crate::db::database::Database; use crate::db::model::Muted; use crate::model::application::{Configuration, Mute}; use crate::utils::bot::get_member; -use crate::{Context, Error}; +use crate::{BotData, Context, Error}; pub enum ModerationKind { Mute(User, User, String, Option, Option), /* User, Command author, Reason, Expires, Error */ Unmute(User, User, Option), // User, Command author, Error - Ban(User, User, Option, Option), // User, Command author, Reason, Error - Unban(User, User, Option), // User, Command author, Error + Ban(User, User, Option, Option), // User, Command author, Reason, Error + Unban(User, User, Option), // User, Command author, Error } pub enum BanKind { Ban(User, Option, Option), // User, Amount of days to delete messages, Reason Unban(User), // User } -pub async fn mute_on_join(ctx: &serenity::Context, new_member: &mut serenity::Member) { - let data = get_data_lock(ctx).await; +pub async fn mute_on_join(ctx: &serenity::Context, new_member: &serenity::Member, data: &BotData) { let data = data.read().await; if let Ok(mut cursor) = data @@ -103,7 +95,7 @@ pub fn queue_unmute_member( .ok_or("User was not muted.")?; // Update roles if they didn't leave the guild. - if let Some(mut member) = get_member(&ctx, guild_id, user_id).await? { + if let Some(member) = get_member(&ctx, guild_id, user_id).await? { let http = &ctx.http; if let Some(taken_roles) = db_result.taken_roles { @@ -255,11 +247,11 @@ pub async fn respond_moderation<'a>( let send_ephemeral = *send_ephemeral.lock().unwrap(); let reply = ctx - .send( - CreateReply::new() - .embed(create_embed()) - .ephemeral(send_ephemeral), - ) + .send(CreateReply { + ephemeral: Some(send_ephemeral), + embeds: vec![create_embed()], + ..Default::default() + }) .await?; let response = reply.message().await?; diff --git a/src/utils/poll.rs b/src/utils/poll.rs index 8dfe356..3523727 100644 --- a/src/utils/poll.rs +++ b/src/utils/poll.rs @@ -1,17 +1,16 @@ + + use base64::Engine; use poise::serenity_prelude::{ - CreateActionRow, - CreateButton, - CreateEmbed, - CreateEmbedFooter, - CreateInteractionResponseMessage, - ReactionType, - Timestamp, + CreateActionRow, CreateButton, CreateEmbed, CreateEmbedFooter, + CreateInteractionResponseMessage, ReactionType, Timestamp, }; use reqwest::StatusCode; + use tracing::log::{error, trace}; -use super::bot::get_data_lock; +use crate::{BotData}; + use super::*; pub async fn handle_poll( @@ -19,10 +18,10 @@ pub async fn handle_poll( interaction: &serenity::Interaction, poll_id: u64, min_join_date: Timestamp, + data: &BotData, ) -> Result<(), serenity::prelude::SerenityError> { trace!("Handling poll: {}.", poll_id); - let data = get_data_lock(ctx).await; let data = data.read().await; let component = &interaction.clone().message_component().unwrap();