Update to serenity v0.9.1 and make the bot fully async

This commit is contained in:
Agatha Lovelace 2020-11-22 22:51:15 +02:00
parent 70b75923b5
commit 30a4e1abd6
11 changed files with 739 additions and 576 deletions

454
Cargo.lock generated
View File

@ -21,6 +21,33 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
[[package]]
name = "async-trait"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.48",
]
[[package]]
name = "async-tungstenite"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce503a5cb1e7450af7d211b86b84807791b251f335b2f43f1e26b85a416f315"
dependencies = [
"futures-io",
"futures-util",
"log 0.4.8",
"pin-project 1.0.1",
"tokio",
"tokio-rustls",
"tungstenite",
"webpki-roots",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -48,18 +75,18 @@ dependencies = [
"safemem",
]
[[package]]
name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
name = "base64"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bitflags"
version = "0.9.1"
@ -83,9 +110,9 @@ dependencies = [
[[package]]
name = "brainfrick"
version = "1.1.1"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c064ec9b9efbe8e711d8edce078facdfc2e99b5147572e616ecdb76c5686d43"
checksum = "b24bc4629eeab19ec9771bb4899b3e7916e320dd1825b5e715c1db6e5328bc10"
dependencies = [
"itertools",
]
@ -128,19 +155,10 @@ checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
dependencies = [
"num-integer",
"num-traits 0.2.11",
"serde 1.0.116",
"serde 1.0.117",
"time",
]
[[package]]
name = "cloudabi"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
dependencies = [
"bitflags 1.2.1",
]
[[package]]
name = "colored"
version = "2.0.0"
@ -154,13 +172,23 @@ dependencies = [
[[package]]
name = "command_attr"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c27d6155f93d880b6379d93ddc9b2417b3b69b715360c5f25525e4576338a381"
checksum = "8dc8da29004a4dd9b89d21b2e17ccd372c1ff085bdab9e22b989096db1289d01"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.36",
"syn 1.0.48",
]
[[package]]
name = "console_error_panic_hook"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
dependencies = [
"cfg-if",
"wasm-bindgen",
]
[[package]]
@ -276,6 +304,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
dependencies = [
"matches",
"percent-encoding 2.1.0",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
@ -298,6 +336,20 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "futures"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.5"
@ -305,6 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@ -328,7 +381,7 @@ dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote 1.0.3",
"syn 1.0.36",
"syn 1.0.48",
]
[[package]]
@ -352,12 +405,14 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project",
"pin-project 0.4.8",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
@ -476,7 +531,7 @@ dependencies = [
"itoa 0.4.5",
"log 0.4.8",
"net2",
"pin-project",
"pin-project 0.4.8",
"time",
"tokio",
"tower-service",
@ -504,7 +559,7 @@ dependencies = [
"futures-util",
"hyper 0.13.4",
"log 0.4.8",
"rustls 0.18.0",
"rustls",
"tokio",
"tokio-rustls",
"webpki",
@ -563,15 +618,6 @@ dependencies = [
"bytes",
]
[[package]]
name = "instant"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66"
dependencies = [
"cfg-if",
]
[[package]]
name = "iovec"
version = "0.1.4"
@ -610,9 +656,9 @@ checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
[[package]]
name = "js-sys"
version = "0.3.37"
version = "0.3.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055"
checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8"
dependencies = [
"wasm-bindgen",
]
@ -651,15 +697,6 @@ version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
[[package]]
name = "lock_api"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.3.9"
@ -904,32 +941,6 @@ dependencies = [
"regex",
]
[[package]]
name = "parking_lot"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
dependencies = [
"cfg-if",
"cloudabi",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi 0.3.8",
]
[[package]]
name = "percent-encoding"
version = "1.0.1"
@ -948,7 +959,16 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c"
dependencies = [
"pin-project-internal",
"pin-project-internal 0.4.8",
]
[[package]]
name = "pin-project"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841"
dependencies = [
"pin-project-internal 1.0.1",
]
[[package]]
@ -959,7 +979,18 @@ checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.36",
"syn 1.0.48",
]
[[package]]
name = "pin-project-internal"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.48",
]
[[package]]
@ -968,6 +999,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"
[[package]]
name = "pin-project-lite"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
[[package]]
name = "pin-utils"
version = "0.1.0"
@ -1000,9 +1037,9 @@ checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
[[package]]
name = "proc-macro2"
version = "1.0.19"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid 0.2.0",
]
@ -1108,9 +1145,9 @@ checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]]
name = "regex"
version = "1.3.9"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
dependencies = [
"aho-corasick",
"memchr",
@ -1120,9 +1157,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.18"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
[[package]]
name = "remove_dir_all"
@ -1150,11 +1187,11 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.10.8"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e"
checksum = "fb15d6255c792356a0f578d8a645c677904dc02e862bebe2ecc18e0c01b9a0ce"
dependencies = [
"base64 0.12.3",
"base64 0.13.0",
"bytes",
"encoding_rs",
"futures-core",
@ -1172,17 +1209,18 @@ dependencies = [
"mime_guess",
"native-tls 0.2.4",
"percent-encoding 2.1.0",
"pin-project-lite",
"rustls 0.18.0",
"serde 1.0.116",
"pin-project-lite 0.2.0",
"rustls",
"serde 1.0.117",
"serde_json 1.0.48",
"serde_urlencoded 0.6.1",
"serde_urlencoded 0.7.0",
"tokio",
"tokio-rustls",
"tokio-tls",
"url 2.1.1",
"url 2.2.0",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test",
"web-sys",
"webpki-roots",
"winreg",
@ -1214,27 +1252,15 @@ dependencies = [
"percent-encoding 2.1.0",
"rand 0.7.3",
"regex",
"reqwest 0.10.8",
"serde 1.0.116",
"reqwest 0.10.9",
"serde 1.0.117",
"serenity",
"sys-info",
"tokio",
"toml",
"urbandict",
]
[[package]]
name = "rustls"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1"
dependencies = [
"base64 0.11.0",
"log 0.4.8",
"ring",
"sct",
"webpki",
]
[[package]]
name = "rustls"
version = "0.18.0"
@ -1271,10 +1297,10 @@ dependencies = [
]
[[package]]
name = "scopeguard"
version = "1.1.0"
name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "sct"
@ -1338,11 +1364,11 @@ checksum = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af"
[[package]]
name = "serde"
version = "1.0.116"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [
"serde_derive 1.0.116",
"serde_derive 1.0.117",
]
[[package]]
@ -1367,13 +1393,13 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.116"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.36",
"syn 1.0.48",
]
[[package]]
@ -1396,7 +1422,7 @@ checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
dependencies = [
"itoa 0.4.5",
"ryu",
"serde 1.0.116",
"serde 1.0.117",
]
[[package]]
@ -1413,41 +1439,41 @@ dependencies = [
[[package]]
name = "serde_urlencoded"
version = "0.6.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
dependencies = [
"dtoa",
"form_urlencoded",
"itoa 0.4.5",
"serde 1.0.116",
"url 2.1.1",
"ryu",
"serde 1.0.117",
]
[[package]]
name = "serenity"
version = "0.8.7"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e304a606c9601e538849c67b19af64e114e14ac633093e5e05188a9274f507c2"
checksum = "9fbd2938b8859261d418ba8325a795000e37e9cba1b19d4e978775c5e34dc997"
dependencies = [
"base64 0.12.3",
"async-trait",
"async-tungstenite",
"base64 0.13.0",
"bitflags 1.2.1",
"bytes",
"chrono",
"command_attr",
"flate2",
"log 0.4.8",
"parking_lot",
"reqwest 0.10.8",
"rustls 0.17.0",
"serde 1.0.116",
"futures",
"reqwest 0.10.9",
"serde 1.0.117",
"serde_json 1.0.48",
"static_assertions",
"threadpool",
"tungstenite",
"typemap",
"url 2.1.1",
"tokio",
"tracing",
"tracing-futures",
"typemap_rev",
"url 2.2.0",
"uwl",
"webpki",
"webpki-roots",
]
[[package]]
@ -1500,9 +1526,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.36"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250"
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
dependencies = [
"proc-macro2",
"quote 1.0.3",
@ -1561,15 +1587,6 @@ dependencies = [
"lazy_static 1.4.0",
]
[[package]]
name = "threadpool"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
dependencies = [
"num_cpus",
]
[[package]]
name = "time"
version = "0.1.42"
@ -1583,9 +1600,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "0.2.22"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
checksum = "a6d7ad61edd59bfcc7e80dababf0f4aed2e6d5e0ba1659356ae889752dfc12ff"
dependencies = [
"bytes",
"fnv",
@ -1594,8 +1611,20 @@ dependencies = [
"memchr",
"mio",
"num_cpus",
"pin-project-lite",
"pin-project-lite 0.1.4",
"slab",
"tokio-macros",
]
[[package]]
name = "tokio-macros"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.48",
]
[[package]]
@ -1605,7 +1634,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "228139ddd4fea3fa345a29233009635235833e52807af7ea6448ead03890d6a9"
dependencies = [
"futures-core",
"rustls 0.18.0",
"rustls",
"tokio",
"webpki",
]
@ -1630,17 +1659,17 @@ dependencies = [
"futures-core",
"futures-sink",
"log 0.4.8",
"pin-project-lite",
"pin-project-lite 0.1.4",
"tokio",
]
[[package]]
name = "toml"
version = "0.5.6"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
dependencies = [
"serde 1.0.116",
"serde 1.0.117",
]
[[package]]
@ -1649,6 +1678,48 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
[[package]]
name = "tracing"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27"
dependencies = [
"cfg-if",
"pin-project-lite 0.1.4",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.48",
]
[[package]]
name = "tracing-core"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
dependencies = [
"lazy_static 1.4.0",
]
[[package]]
name = "tracing-futures"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
dependencies = [
"pin-project 0.4.8",
"tracing",
]
[[package]]
name = "traitobject"
version = "0.1.0"
@ -1676,7 +1747,7 @@ dependencies = [
"log 0.4.8",
"rand 0.7.3",
"sha-1",
"url 2.1.1",
"url 2.2.0",
"utf-8",
]
@ -1687,13 +1758,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
[[package]]
name = "typemap"
version = "0.3.3"
name = "typemap_rev"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6"
dependencies = [
"unsafe-any",
]
checksum = "078d41124321488746becfa144977b9b54667af408ff933cbbce9d83e7796ac9"
[[package]]
name = "typenum"
@ -1749,15 +1817,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "unsafe-any"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f"
dependencies = [
"traitobject",
]
[[package]]
name = "untrusted"
version = "0.7.0"
@ -1789,10 +1848,11 @@ dependencies = [
[[package]]
name = "url"
version = "2.1.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
dependencies = [
"form_urlencoded",
"idna 0.2.0",
"matches",
"percent-encoding 2.1.0",
@ -1846,36 +1906,36 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasm-bindgen"
version = "0.2.60"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f"
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
dependencies = [
"cfg-if",
"serde 1.0.116",
"serde 1.0.117",
"serde_json 1.0.48",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.60"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd"
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
dependencies = [
"bumpalo",
"lazy_static 1.4.0",
"log 0.4.8",
"proc-macro2",
"quote 1.0.3",
"syn 1.0.36",
"syn 1.0.48",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.10"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a"
checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da"
dependencies = [
"cfg-if",
"js-sys",
@ -1885,9 +1945,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.60"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4"
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
dependencies = [
"quote 1.0.3",
"wasm-bindgen-macro-support",
@ -1895,22 +1955,46 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.60"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931"
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.36",
"syn 1.0.48",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.60"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639"
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
[[package]]
name = "wasm-bindgen-test"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34d1cdc8b98a557f24733d50a1199c4b0635e465eecba9c45b214544da197f64"
dependencies = [
"console_error_panic_hook",
"js-sys",
"scoped-tls",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test-macro",
]
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8fb9c67be7439ee8ab1b7db502a49c05e51e2835b66796c705134d9b8e1a585"
dependencies = [
"proc-macro2",
"quote 1.0.3",
]
[[package]]
name = "web-sys"
@ -1934,9 +2018,9 @@ dependencies = [
[[package]]
name = "webpki-roots"
version = "0.19.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739"
checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f"
dependencies = [
"webpki",
]

View File

@ -7,25 +7,30 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serenity = "0.8.7"
serenity = "0.9.1"
rand = "0.7.3"
toml = "0.5.6"
toml = "0.5.7"
sys-info = "0.7.0"
urbandict = "0.2.0"
owoify = "0.1.5"
lazy_static = "1.4.0"
colored = "2.0.0"
brainfrick = "1.1.1"
brainfrick = "1.1.2"
percent-encoding = "2.1.0"
regex = "1.3.9"
regex = "1.4.2"
[patch.crates-io]
openssl = { git = "https://github.com/ishitatsuyuki/rust-openssl", branch = "0.9.x" }
[dependencies.serde]
version = "1.0.116"
version = "1.0.117"
features = ["derive"]
[dependencies.reqwest]
version = "0.10.8"
version = "0.10.9"
features = ["blocking", "json"]
[dependencies.tokio]
version = "0.2.23"
features = ["macros"]

View File

@ -1,5 +1,5 @@
use serenity::{
framework::standard::{macros::command, Args, CommandError, CommandResult},
framework::standard::{macros::command, Args, CommandResult},
model::channel::Message,
prelude::*,
};
@ -7,12 +7,12 @@ use serenity::{
// brainfuck interpreter
#[command]
#[aliases("bf", "brainfrick")]
fn brainfuck(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn brainfuck(ctx: &Context, message: &Message, args: Args) -> CommandResult {
use brainfrick::Brainfuck;
let input = match args.rest().trim() {
"" => {
return Err(CommandError(s!("Called without input!")));
return Err("Called without input!".into());
}
v => v,
};
@ -20,33 +20,43 @@ fn brainfuck(ctx: &mut Context, message: &Message, args: Args) -> CommandResult
match output {
Ok(v) => {
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Brainfuck interpreter")
.description(format!(
"Input\n```brainfuck\n{}\n```\nOutput:\n```{}\n```",
input, v
))
.author(|a| {
a.name(&message.author.name)
.icon_url(message.author.avatar_url().unwrap())
})
.colour(0xffd1dc)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Brainfuck interpreter")
.description(format!(
"Input\n```brainfuck\n{}\n```\nOutput:\n```{}\n```",
input, v
))
.author(|a| {
a.name(&message.author.name)
.icon_url(message.author.avatar_url().unwrap())
})
.colour(0xffd1dc)
})
})
});
.await;
}
Err(err) => {
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Brainfuck interpreter")
.description(format!("Error at:\n```\n{}:{}\n```", err.line(), err.col()))
.author(|a| {
a.name(&message.author.name)
.icon_url(message.author.avatar_url().unwrap())
})
.colour(0xff6961)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Brainfuck interpreter")
.description(format!(
"Error at:\n```\n{}:{}\n```",
err.line(),
err.col()
))
.author(|a| {
a.name(&message.author.name)
.icon_url(message.author.avatar_url().unwrap())
})
.colour(0xff6961)
})
})
});
.await;
}
}

View File

@ -1,5 +1,5 @@
use serenity::{
framework::standard::{macros::command, Args, CommandError, CommandResult},
framework::standard::{macros::command, Args, CommandResult},
model::channel::Message,
prelude::*,
};
@ -7,30 +7,33 @@ use serenity::{
// Urban Dictionary lookup
#[command]
#[aliases("what's this")]
fn define(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn define(ctx: &Context, message: &Message, args: Args) -> CommandResult {
let text: String = args.rest().trim().to_string();
let defs = &urbandict::get_definitions(&text);
if !args.is_empty() {
match defs {
Err(_e) => {
return Err(CommandError(s!("Invalid query >w<")));
return Err("Invalid query >w<".into());
}
Ok(v) => {
if !v.is_empty() {
let def = &v[0];
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Query: {}, Author: {}", text, def.author))
.field(
"Definition: ",
def.definition.replace(|c| c == '[' || c == ']', ""),
false,
)
.color(0xffd1dc)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Query: {}, Author: {}", text, def.author))
.field(
"Definition: ",
def.definition.replace(|c| c == '[' || c == ']', ""),
false,
)
.color(0xffd1dc)
})
})
});
.await;
} else {
return Err(CommandError(s!("No results!")));
return Err("No results!".into());
}
}
}

View File

@ -1,10 +1,10 @@
use serenity::{
framework::standard::{macros::command, Args, CommandError, CommandResult},
framework::standard::{macros::command, Args, CommandResult},
model::channel::Message,
prelude::*,
};
#[command]
fn embed(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn embed(ctx: &Context, message: &Message, args: Args) -> CommandResult {
use serde::Deserialize;
use serenity::utils::Colour;
use std::{fs, io::prelude::*};
@ -29,7 +29,7 @@ fn embed(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
let mut help_string = String::new();
file.read_to_string(&mut help_string)?;
let _ = message.channel_id.say(&ctx.http, help_string);
let _ = message.channel_id.say(&ctx.http, help_string).await;
return Ok(());
}
@ -37,82 +37,86 @@ fn embed(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
let input_embed: EmbedProperties = match toml::from_str(&args.rest().trim()) {
Ok(v) => v,
Err(e) => {
return Err(CommandError(format!("Deserialization error: {:?}", e)));
return Err(format!("Deserialization error: {:?}", e).into());
}
};
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
// Set embed author unless empty
if input_embed.author.is_some() {
let auth = input_embed.author.unwrap();
e.author(|a| {
//assuming first array element is name and second is icon url
a.name(auth.0);
a.icon_url(auth.1);
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
// Set embed author unless empty
if input_embed.author.is_some() {
let auth = input_embed.author.unwrap();
e.author(|a| {
//assuming first array element is name and second is icon url
a.name(auth.0);
a.icon_url(auth.1);
a
});
}
a
});
}
// Set embed colour unless empty
if input_embed.colour.is_some() {
e.color(Colour::new(
u32::from_str_radix(&input_embed.colour.unwrap(), 16)
.ok()
.unwrap_or(0x000000),
));
}
// Set embed colour unless empty
if input_embed.colour.is_some() {
e.color(Colour::new(
u32::from_str_radix(&input_embed.colour.unwrap(), 16)
.ok()
.unwrap_or(0x000000),
));
}
// Set embed description unless empty
if input_embed.description.is_some() {
e.description(input_embed.description.unwrap());
}
// Set embed fields unless empty
if input_embed.fields.is_some() {
e.fields(input_embed.fields.unwrap());
}
// Set embed description unless empty
if input_embed.description.is_some() {
e.description(input_embed.description.unwrap());
}
// Set embed fields unless empty
if input_embed.fields.is_some() {
e.fields(input_embed.fields.unwrap());
}
// Set embed footer unless empty
if input_embed.footer.is_some() {
let foot = input_embed.footer.unwrap();
e.footer(|f| {
//assuming first array element is name and second is icon url
f.text(foot.0);
f.icon_url(foot.1);
// Set embed footer unless empty
if input_embed.footer.is_some() {
let foot = input_embed.footer.unwrap();
e.footer(|f| {
//assuming first array element is name and second is icon url
f.text(foot.0);
f.icon_url(foot.1);
f
});
}
f
});
}
if input_embed.image.is_some() {
e.image(input_embed.image.unwrap());
}
if input_embed.image.is_some() {
e.image(input_embed.image.unwrap());
}
if input_embed.thumbnail.is_some() {
e.thumbnail(input_embed.thumbnail.unwrap());
}
if input_embed.thumbnail.is_some() {
e.thumbnail(input_embed.thumbnail.unwrap());
}
if input_embed.timestamp.is_some() {
e.timestamp(input_embed.timestamp.unwrap());
}
if input_embed.timestamp.is_some() {
e.timestamp(input_embed.timestamp.unwrap());
}
if input_embed.title.is_some() {
e.title(input_embed.title.unwrap());
}
if input_embed.title.is_some() {
e.title(input_embed.title.unwrap());
}
if input_embed.url.is_some() {
e.url(input_embed.url.unwrap());
}
if input_embed.url.is_some() {
e.url(input_embed.url.unwrap());
}
e
});
m
});
e
});
m
})
.await;
let _ = message
.channel_id
.say(&ctx.http, format!("Embed requested by: {}", message.author));
.say(&ctx.http, format!("Embed requested by: {}", message.author))
.await;
Ok(())
}

View File

@ -1,6 +1,6 @@
use regex::Regex;
use serenity::{
framework::standard::{macros::command, Args, CommandError, CommandResult},
framework::standard::{macros::command, Args, CommandResult},
model::channel::Message,
prelude::*,
utils::parse_emoji,
@ -8,29 +8,24 @@ use serenity::{
#[command]
#[aliases("e")]
fn emote(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn emote(ctx: &Context, message: &Message, args: Args) -> CommandResult {
let input = match args.rest().trim() {
"" => {
return Err(CommandError(s!("Called without input!")));
return Err("Called without input!".into());
}
v => v,
};
dbg!(input);
let re = Regex::new(r"<a{0,1}:\w+:\d+>").unwrap();
let emojis = match re.captures(input) {
None => {
return Err(CommandError(s!("No custom emojis found in the message!")));
return Err("No custom emojis found in the message!".into());
}
Some(v) => v,
};
dbg!(&emojis);
let url = parse_emoji(&emojis[0]).unwrap().url();
let _ = message.channel_id.say(&ctx.http, url);
let _ = message.channel_id.say(&ctx.http, url).await;
Ok(())
}

View File

@ -5,53 +5,56 @@ use serenity::{
};
#[command]
fn help(ctx: &mut Context, message: &Message) -> CommandResult {
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Availble commands:")
.description("All commands are case-insensitive")
.fields(vec![
("owo!init", "Introduce me", true),
("owo!ping", "Pong", true),
("owo!sausage", "Sosig", true),
("owo!help", "Help the fellow humanz!", true),
("owo!info", "Show information about me!", true),
(
"owo!what's this ``word``",
"Find a definition of word",
true,
),
(
"owo!embed ``[args]`` *OR* help",
"Create an embed from a Toml object",
true,
),
("owo!desc", "Display channel's topic", true),
(
"owo!pinned ``num`` ``<channel>``",
"Display channel's Nth pinned message. Channel name is optional",
true,
),
("owo!pfp ``@username``", "Post user's profile picture", true),
("owo!brainfuck ``input``", "Execute input code", true),
("owo!ship ``[names]``", "*Shipping intensifies*", true),
("owo!headpat ``name``", "Headpat someone", true),
("owo!owo ``text``", "owoify input text", true),
("owo!lyrics ``name``", "Get song lyrics", true),
(
"owo!e ``emote``",
"Get a bigger version of a custom emote",
true,
),
("\u{200B}", "**Admin commands:**", false),
("owo!halt", "Kill the bot process", true),
("owo!status ``[args]``", "Sets the bot status", true),
("owo!servers", "List the servers I'm in", true),
("owo!host", "Display host info", true),
])
.color(0xffd1dc)
async fn help(ctx: &Context, message: &Message) -> CommandResult {
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Availble commands:")
.description("All commands are case-insensitive")
.fields(vec![
("owo!init", "Introduce me", true),
("owo!ping", "Pong", true),
("owo!sausage", "Sosig", true),
("owo!help", "Help the fellow humanz!", true),
("owo!info", "Show information about me!", true),
(
"owo!what's this ``word``",
"Find a definition of word",
true,
),
(
"owo!embed ``[args]`` *OR* help",
"Create an embed from a Toml object",
true,
),
("owo!desc", "Display channel's topic", true),
(
"owo!pinned ``num`` ``<channel>``",
"Display channel's Nth pinned message. Channel name is optional",
true,
),
("owo!pfp ``@username``", "Post user's profile picture", true),
("owo!brainfuck ``input``", "Execute input code", true),
("owo!ship ``[names]``", "*Shipping intensifies*", true),
("owo!headpat ``name``", "Headpat someone", true),
("owo!owo ``text``", "owoify input text", true),
("owo!lyrics ``name``", "Get song lyrics", true),
(
"owo!e ``emote``",
"Get a bigger version of a custom emote",
true,
),
("\u{200B}", "**Admin commands:**", false),
("owo!halt", "Kill the bot process", true),
("owo!status ``[args]``", "Sets the bot status", true),
("owo!servers", "List the servers I'm in", true),
("owo!host", "Display host info", true),
])
.color(0xffd1dc)
})
})
});
.await;
Ok(())
}

View File

@ -1,10 +1,11 @@
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use serde::Deserialize;
use serenity::{
framework::standard::{macros::command, Args, CommandError, CommandResult},
framework::standard::{macros::command, Args, CommandResult},
model::channel::Message,
prelude::*,
};
use std::env;
#[derive(Deserialize)]
struct Response {
@ -19,35 +20,38 @@ struct Content {
}
#[command]
fn lyrics(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
// the website used to get song lyrics
async fn lyrics(ctx: &Context, message: &Message, args: Args) -> CommandResult {
// TODO: use https://orion.apiseeds.com/api/music/lyric/:artist/:track instead
let mut url = String::from("https://mourits.xyz:2096/?q=");
// check if input is not empty
let input = match args.rest().trim() {
"" => {
return Err(CommandError(s!("Called without input!")));
return Err("Called without input!".into());
}
v => v,
};
// encode into url
url += &s!(percent_encode(input.as_bytes(), NON_ALPHANUMERIC));
let request = match reqwest::blocking::get(&url) {
let request = match reqwest::get(&url).await {
Ok(v) => v,
Err(e) => return Err(CommandError(s!(e))),
Err(e) => return Err(e.into()),
};
let resp: Response = match request.json() {
let resp: Response = match request.json().await {
Ok(v) => v,
Err(_) => return Err(CommandError(s!("Could not find lyrics"))),
Err(_) => return Err("Could not find lyrics".into()),
};
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("{} by {}", resp.song, resp.artist))
.description(resp.result.lyrics)
.colour(0xffd1dc)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("{} by {}", resp.song, resp.artist))
.description(resp.result.lyrics)
.colour(0xffd1dc)
})
})
});
.await;
Ok(())
}

View File

@ -1,73 +1,69 @@
use serenity::{
framework::standard::{macros::command, Args, CommandError, CommandResult},
framework::standard::{macros::command, Args, CommandResult},
model::{channel::Message, id::ChannelId},
prelude::*,
};
// Prints Nth pinned message
#[command]
fn pinned(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult {
#[only_in(guilds)]
async fn pinned(ctx: &Context, message: &Message, mut args: Args) -> CommandResult {
// defaults to latest pinned message if no args are provided
let mut idx = args.single::<usize>().unwrap_or(1);
// Makes pinned messages 1-indexed
if idx != 0 {
idx -= 1;
}
let target_channel = match args.single::<ChannelId>() {
Ok(v) => v,
Err(_) => message.channel_id,
};
let pinned = match target_channel.pins(&ctx.http) {
let pinned = match target_channel.pins(&ctx.http).await {
Ok(v) => v,
Err(e) => {
return Err(CommandError(s!(format!(
"Could not get pinned messages! Error: {}",
e
))));
return Err(format!("Could not get pinned messages! Error: {}", e).into());
}
};
if pinned.is_empty() {
return Err(CommandError(s!("No pinned messages found!")));
return Err("No pinned messages found!".into());
}
if idx > pinned.len() - 1 {
return Err(CommandError(s!("Index out of bounds!")));
return Err("Index out of bounds!".into());
}
let channel = match pinned[idx].channel(&ctx) {
Some(g) => g,
None => return Err(CommandError(s!("Could not get Channel"))),
let guild_id = match message.guild_id {
Some(id) => id,
None => return Err("Could not find Guild Id".into()),
};
let guild_arc = match channel.guild() {
Some(a) => a,
None => return Err(CommandError(s!("Could not find Guild Arc"))),
};
let guild = guild_arc.read();
let guild_id = guild.guild_id;
let msg_link = format!(
"https://discordapp.com/channels/{}/{}/{}",
"https://discord.com/channels/{}/{}/{}",
guild_id, &pinned[idx].channel_id, &pinned[idx].id
);
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Pinned message #{}", idx + 1))
.description(&pinned[idx].content)
.field("🔗 link", format!("[original message]({})", msg_link), true)
.timestamp(&pinned[idx].timestamp);
e.author(|a| {
a.name(&pinned[idx].author.name)
.icon_url(&pinned[idx].author.avatar_url().unwrap())
});
e.colour(0xffd1dc);
if !&pinned[idx].attachments.is_empty() {
e.image(&pinned[idx].attachments[0].url);
}
// TODO: change link formatting
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Pinned message #{}", idx + 1))
.description(&pinned[idx].content)
.field("🔗 link", format!("[original message]({})", msg_link), true)
.timestamp(&pinned[idx].timestamp);
e.author(|a| {
a.name(&pinned[idx].author.name)
.icon_url(&pinned[idx].author.avatar_url().unwrap())
});
e.colour(0xffd1dc);
if !&pinned[idx].attachments.is_empty() {
e.image(&pinned[idx].attachments[0].url);
}
e
e
})
})
});
.await;
Ok(())
}

View File

@ -7,7 +7,7 @@ use serenity::{
};
#[command]
fn ship(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn ship(ctx: &Context, message: &Message, args: Args) -> CommandResult {
use rand::{rngs::StdRng, SeedableRng};
// Get input names
@ -42,20 +42,23 @@ fn ship(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
};
if let Err(e) = shipname {
let _ = message.channel_id.say(&ctx.http, e);
let _ = message.channel_id.say(&ctx.http, e).await;
} else {
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Original names: {}", args.rest().trim()))
.description(format!(
"Ship name:\n**{}**\nCompatibility: **{}%**\n{}",
shipname.unwrap(),
compat,
compbar
))
.color(0xffd1dc)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Original names: {}", args.rest().trim()))
.description(format!(
"Ship name:\n**{}**\nCompatibility: **{}%**\n{}",
shipname.unwrap(),
compat,
compbar
))
.color(0xffd1dc)
})
})
});
.await;
}
Ok(())

View File

@ -7,16 +7,21 @@ extern crate lazy_static;
use colored::*;
use rand::Rng;
use serenity::{
async_trait,
client::{
bridge::gateway::{ShardId, ShardManager},
bridge::gateway::{GatewayIntents, ShardId, ShardManager},
Client,
},
framework::standard::{
macros::{check, command, group},
Args, CheckResult, CommandError, CommandOptions, CommandResult, DispatchError, Reason,
StandardFramework,
macros::{check, command, group, hook},
Args, CheckResult, CommandOptions, CommandResult, DispatchError, Reason, StandardFramework,
},
model::{
channel::{Message, ReactionType},
gateway::Ready,
id::UserId,
user::OnlineStatus,
},
model::{channel::Message, gateway::Ready, id::UserId, user::OnlineStatus},
prelude::*,
};
use std::{env, process, sync::Arc};
@ -38,8 +43,9 @@ impl TypeMapKey for ShardManagerContainer {
type Value = Arc<Mutex<ShardManager>>;
}
#[async_trait]
impl EventHandler for Handler {
fn ready(&self, ctx: Context, ready: Ready) {
async fn ready(&self, ctx: Context, ready: Ready) {
if let Some(shard) = ready.shard {
println!(
"INFO: {} is connected on shard {}/{}!\nuwu",
@ -50,16 +56,64 @@ impl EventHandler for Handler {
let activity = Activity::listening("catgirls nyaaing");
let status = OnlineStatus::Online;
ctx.set_presence(Some(activity), status);
ctx.set_presence(Some(activity), status).await;
}
}
fn message(&self, ctx: Context, message: Message) {
async fn message(&self, ctx: Context, message: Message) {
let text = &message.content.to_lowercase();
if text.contains("good")
&& (text.contains("discordinator") || text.contains("discordinyator"))
{
let _ = message.channel_id.say(&ctx.http, "nyaa~ 💞");
let _ = message.channel_id.say(&ctx.http, "nyaa~ 💞").await;
}
}
}
#[hook]
async fn dispatch_error(ctx: &Context, msg: &Message, error: DispatchError) {
if let DispatchError::CheckFailed("Owner", Reason::Unknown) = error {
// triggers if user is not owner
let _ = msg.channel_id.say(&ctx.http, "nyo").await;
} else if let DispatchError::Ratelimited(_) = error {
// triggers if rate limited
eprintln!(
"{}",
format!(
"Rate limited in {} with message {}",
s!(msg.channel_id).purple().bold(),
msg.content.purple()
)
);
}
}
#[hook]
async fn after(ctx: &Context, msg: &Message, command_name: &str, command_result: CommandResult) {
// prints error in chat
match command_result {
Ok(()) => (),
Err(why) => {
let _ = msg
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Error in **{}**", command_name))
.description(&why.to_string())
/*.thumbnail("https://i.imgur.com/VzOEz2E.png") oh no */
.colour(0xff6961)
})
})
.await;
// prints error in console
eprintln!(
"{}",
format!(
"Error in {}: {}",
command_name.purple(),
&why.to_string().red().bold()
)
);
}
}
}
@ -77,71 +131,46 @@ lazy_static! {
vec![UserId(254310746450690048), UserId(687740609703706630)];
}
fn main() {
let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("Invalid token"), Handler)
#[tokio::main]
async fn main() {
let framework = StandardFramework::new()
.configure(|c| {
c.with_whitespace(true)
.owners(OWNERS.clone().into_iter().collect())
.prefixes(vec!["owo!", "OwO!", "aga"])
.no_dm_prefix(true)
.case_insensitivity(true)
.by_space(false)
})
.group(&GENERAL_GROUP)
.on_dispatch_error(dispatch_error)
.after(after);
let mut client = Client::builder(&env::var("DISCORD_TOKEN").expect("Invalid token"))
.event_handler(Handler)
.framework(framework)
.intents({
let mut intents = GatewayIntents::all();
intents.remove(GatewayIntents::GUILD_PRESENCES);
intents
})
.await
.expect("Error creating client");
// Updates stored data, used for ping command
{
let mut data = client.data.write();
let mut data = client.data.write().await;
data.insert::<ShardManagerContainer>(Arc::clone(&client.shard_manager));
}
client.with_framework(
StandardFramework::new()
.configure(|c| {
c.with_whitespace(true)
.owners(OWNERS.clone().into_iter().collect())
.prefixes(vec!["owo!", "OwO!", "aga"])
.no_dm_prefix(true)
.case_insensitivity(true)
.by_space(false)
})
.on_dispatch_error(|ctx, msg, error| {
if let DispatchError::CheckFailed("Owner", Reason::Unknown) = error {
// triggers if user is not owner
let _ = msg.channel_id.say(&ctx.http, "nyo");
} else if let DispatchError::Ratelimited(_) = error {
// triggers if rate limited
eprintln!(
"{}",
format!(
"Rate limited in {} with message {}",
s!(msg.channel_id).purple().bold(),
msg.content.purple()
)
);
}
})
.after(|ctx, msg, cmd_name, error| {
// prints error in chat
if let Err(why) = error {
let _ = msg.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Error in **{}**", cmd_name))
.description(&why.0)
/*.thumbnail("https://i.imgur.com/VzOEz2E.png") oh no */
.colour(0xff6961)
})
});
// prints error in console
eprintln!(
"{}",
format!("Error in {}: {}", cmd_name.purple(), &why.0.red().bold())
);
}
})
.group(&GENERAL_GROUP),
);
if let Err(e) = client.start() {
if let Err(e) = client.start().await {
eprintln!("An error occurred while running the client: {:?}", e);
}
}
#[check]
#[name = "Owner"]
fn owner_check(_: &mut Context, msg: &Message, _: &mut Args, _: &CommandOptions) -> CheckResult {
async fn owner_check(_: &Context, msg: &Message, _: &mut Args, _: &CommandOptions) -> CheckResult {
if OWNERS.clone().contains(&msg.author.id) {
CheckResult::Success
} else {
@ -151,75 +180,72 @@ fn owner_check(_: &mut Context, msg: &Message, _: &mut Args, _: &CommandOptions)
#[check]
#[name = "Server"]
fn server_check(_: &mut Context, msg: &Message, _: &mut Args, _: &CommandOptions) -> CheckResult {
async fn server_check(_: &Context, msg: &Message, _: &mut Args, _: &CommandOptions) -> CheckResult {
(msg.guild_id == Some(serenity::model::id::GuildId(687011389294116875))).into()
}
#[command]
fn init(ctx: &mut Context, message: &Message) -> CommandResult {
async fn init(ctx: &Context, message: &Message) -> CommandResult {
let responses = [
"Discordinator9000 is gonna hug nya'll!",
"Nyaa~!",
"Hewwo uwu",
];
let num = rand::thread_rng().gen_range(0, responses.len());
let _ = message.channel_id.say(&ctx.http, responses[num]);
let _ = message.channel_id.say(&ctx.http, responses[num]).await;
Ok(())
}
#[command]
fn ping(ctx: &mut Context, message: &Message) -> CommandResult {
async fn ping(ctx: &Context, message: &Message) -> CommandResult {
// I have no idea if this works but its 5æm and I need to sleep help
let data = ctx.data.read();
let data = ctx.data.read().await;
let shard_manager = match data.get::<ShardManagerContainer>() {
Some(v) => v,
None => {
return Err(CommandError(s!(
"There was a problem getting the shard manager!"
)))
}
None => return Err("There was a problem getting the shard manager!".into()),
};
let manager = shard_manager.lock();
let runners = manager.runners.lock();
let manager = shard_manager.lock().await;
let runners = manager.runners.lock().await;
let runner = match runners.get(&ShardId(ctx.shard_id)) {
Some(v) => v,
None => return Err(CommandError(s!("No shard found!"))),
None => return Err("No shard found!".into()),
};
let ping = match runner.latency {
Some(v) => v.as_millis(),
None => return Err(CommandError(s!("Could not get latency!"))),
None => return Err("Could not get latency!".into()),
};
let _ = message
.channel_id
.say(&ctx, format!("Pong! Latency: {}ms", ping));
.say(&ctx, format!("Pong! Latency: {}ms", ping))
.await;
Ok(())
}
#[command]
#[checks(Owner)]
fn echo(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn echo(ctx: &Context, message: &Message, args: Args) -> CommandResult {
let input: String = args.rest().trim().to_string();
if args.is_empty() {
return Err(CommandError(s!("Called without input")));
return Err("Called without input".into());
}
let _ = message.channel_id.say(&ctx.http, input);
let _ = message.channel_id.say(&ctx.http, input).await;
Ok(())
}
#[command]
#[checks(Owner)]
fn halt(ctx: &mut Context) -> CommandResult {
async fn halt(ctx: &Context) -> CommandResult {
// Workaround for discord not doing this automatically
ctx.set_presence(None, OnlineStatus::Offline);
ctx.set_presence(None, OnlineStatus::Offline).await;
use std::{thread, time};
// Sleep for 1s
@ -231,11 +257,11 @@ fn halt(ctx: &mut Context) -> CommandResult {
// set bot's status to input text
#[command]
#[checks(Owner)]
fn status(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult {
async fn status(ctx: &Context, message: &Message, mut args: Args) -> CommandResult {
use serenity::model::gateway::Activity;
if args.is_empty() {
return Err(CommandError(s!("Called without args!")));
return Err("Called without args!".into());
}
let mut input = args.single::<String>()?;
@ -256,60 +282,70 @@ fn status(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult
};
let status = OnlineStatus::Online;
ctx.set_presence(Some(activity), status);
let _ = message.react(&ctx.http, "💜");
ctx.set_presence(Some(activity), status).await;
let _ = message
.react(&ctx.http, ReactionType::Unicode("💜".into()))
.await;
Ok(())
}
#[command]
#[checks(Owner)]
fn servers(ctx: &mut Context, message: &Message) -> CommandResult {
async fn servers(ctx: &Context, message: &Message) -> CommandResult {
let mut list = String::new();
let cache = ctx.cache.read();
for (index, guild_lock) in cache.guilds.values().enumerate() {
let guild = guild_lock.read();
list += &format!("{}: {}\n", index, guild.name);
let cache = &ctx.cache;
for (index, guild) in cache.guilds().await.iter().enumerate() {
let name = guild
.name(&ctx.cache)
.await
.unwrap_or_else(|| s!("unknown"));
list += &format!("{}: {}\n", index, name);
}
let _ = message
.channel_id
// Add zero width space to all mentions
.say(&ctx.http, list.replace("@", "@\u{200B}"));
.say(&ctx.http, list.replace("@", "@\u{200B}"))
.await;
Ok(())
}
#[command]
#[checks(Owner)]
fn host(ctx: &mut Context, message: &Message) -> CommandResult {
let _ = message.channel_id.say(
&ctx.http,
format!(
"OS: {os}; {release}\nHost: {host}\nCPU: {cpu}MHz",
os = sys_info::os_type()?,
host = sys_info::hostname()?,
release = sys_info::linux_os_release()?
.pretty_name
.unwrap_or_else(|| s!("Unknown")),
cpu = sys_info::cpu_speed()?
),
);
async fn host(ctx: &Context, message: &Message) -> CommandResult {
let _ = message
.channel_id
.say(
&ctx.http,
format!(
"OS: {os}; {release}\nHost: {host}\nCPU: {cpu}MHz",
os = sys_info::os_type()?,
host = sys_info::hostname()?,
release = sys_info::linux_os_release()?
.pretty_name
.unwrap_or_else(|| s!("Unknown")),
cpu = sys_info::cpu_speed()?
),
)
.await;
Ok(())
}
// generate a random number using a keysmash as seed
#[command]
fn bottom_rng(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult {
async fn bottom_rng(ctx: &Context, message: &Message, mut args: Args) -> CommandResult {
use rand::{rngs::StdRng, SeedableRng};
// get N last messages, otherwise 10
let num = args.single::<u64>().unwrap_or(10);
let messages = message
.channel_id
.messages(&ctx.http, |get| get.before(message.id).limit(num));
.messages(&ctx.http, |get| get.before(message.id).limit(num))
.await;
if let Err(e) = messages {
return Err(CommandError(s!(format!("Error: {}", e))));
return Err(format!("Error: {}", e).into());
} else {
let mut messages = messages?;
// remove all messages by other users
@ -319,13 +355,16 @@ fn bottom_rng(ctx: &mut Context, message: &Message, mut args: Args) -> CommandRe
input += &format!("{} ", msg.content);
}
let result: u64 = StdRng::seed_from_u64(calculate_hash(&input)).gen_range(0, 100);
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Bottom RNG")
.description(format!("Result: {}", result))
.color(0x800869)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Bottom RNG")
.description(format!("Result: {}", result))
.color(0x800869)
})
})
});
.await;
}
Ok(())
@ -333,11 +372,11 @@ fn bottom_rng(ctx: &mut Context, message: &Message, mut args: Args) -> CommandRe
#[command]
#[aliases("pat")]
fn headpat(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn headpat(ctx: &Context, message: &Message, args: Args) -> CommandResult {
let args = args.rest().trim();
if args.is_empty() {
return Err(CommandError(s!("Please specify a username!")));
return Err("Please specify a username!".into());
}
// Get username from first mention, otherwise use input text
@ -346,16 +385,20 @@ fn headpat(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
_ => message.mentions[0].name.as_str(),
};
if let Err(e) = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Sending headpats to **{}**...", name))
if let Err(e) = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Sending headpats to **{}**...", name))
.image(
"https://i.pinimg.com/originals/83/1a/90/831a903eab6d827dcfd298b9e3196e30.jpg",
)
.description("[Source](https://www.pinterest.com/pin/377809856242075277/)")
})
})
}) {
let _ = message.channel_id.say(&ctx.http, format!("{:?}", e));
.await
{
let _ = message.channel_id.say(&ctx.http, format!("{:?}", e)).await;
};
Ok(())
@ -363,7 +406,7 @@ fn headpat(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
// send a random uwu image
#[command]
fn uwu(ctx: &mut Context, message: &Message) -> CommandResult {
async fn uwu(ctx: &Context, message: &Message) -> CommandResult {
let images = [
"https://i.redditmedia.com/qDD9W7NJqTAk31y061TuRW9R8qOcCuEmmCWyOsUEavE.png?fit=crop&crop=faces%2Centropy&arh=2&w=640&s=ebdd3f1970b4fe70ccd24a1958e7fc32",
"https://www.shitpostbot.com/img/sourceimages/smash-that-mfuckn-uwu-button-57b5aa1de9fe4.jpeg",
@ -377,59 +420,65 @@ fn uwu(ctx: &mut Context, message: &Message) -> CommandResult {
"https://i.redd.it/ifwsmbme48q41.jpg"
];
let num = rand::thread_rng().gen_range(0, images.len());
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.image(images[num]);
e.footer(|f| f.text(format!("Source: {}", images[num])));
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.image(images[num]);
e.footer(|f| f.text(format!("Source: {}", images[num])));
e
e
})
})
});
.await;
Ok(())
}
#[command]
fn gayculator(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult {
async fn gayculator(ctx: &Context, message: &Message, mut args: Args) -> CommandResult {
let number_32: i32 = args.single::<i32>().unwrap_or(1);
let result = if number_32 % 2 == 0 {
"much straight"
} else {
"large gay"
};
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Gayness level:")
.description(result)
.color(0xffd1dc)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Gayness level:")
.description(result)
.color(0xffd1dc)
})
})
});
.await;
Ok(())
}
#[command]
#[aliases("sosig")]
fn sausage(ctx: &mut Context, message: &Message) -> CommandResult {
async fn sausage(ctx: &Context, message: &Message) -> CommandResult {
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e
.title("Dongle!")
.image("https://cdn.discordapp.com/attachments/689023662489468966/712283397015470120/26029881886330_4.gif")
})
});
}).await;
Ok(())
}
#[command]
fn info(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn info(ctx: &Context, message: &Message, args: Args) -> CommandResult {
if !args.is_empty() {
return Err(CommandError(s!("Called with args!")));
return Err("Called with args!".into());
}
let num = ctx.cache.read().guilds.len();
let num = ctx.cache.guilds().await.len();
// get developer's username
let aganame = OWNERS.clone()[0].to_user(ctx.http.clone())?.tag();
let aganame = OWNERS.clone()[0].to_user(ctx.http.clone()).await?.tag();
let _ = message.channel_id.send_message(&ctx.http, |m| m
.embed(|e| e
.title("Discordinator9000's info:")
@ -441,12 +490,12 @@ fn info(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
.text("Written in Rust using Serenity, OwOify and a few other libraries"))
.thumbnail("https://cdn.discordapp.com/attachments/687011390434967621/704118007563157544/discordinator.png")
.color(0xffd1dc)
));
)).await;
Ok(())
}
#[command]
fn pfp(ctx: &mut Context, message: &Message) -> CommandResult {
async fn pfp(ctx: &Context, message: &Message) -> CommandResult {
// Get username from first mention, otherwise use current username
let user = match message.mentions.len() {
0 => &message.author,
@ -455,31 +504,35 @@ fn pfp(ctx: &mut Context, message: &Message) -> CommandResult {
let pfp = match user.avatar_url() {
Some(v) => v,
None => return Err(CommandError(s!("The user does not have an avatar"))),
None => return Err("The user does not have an avatar".into()),
};
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("{}'s profile picture", user.name))
.image(pfp)
.color(0xffd1dc)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("{}'s profile picture", user.name))
.image(pfp)
.color(0xffd1dc)
})
})
});
.await;
Ok(())
}
// Text owoification
#[command]
fn owo(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
async fn owo(ctx: &Context, message: &Message, args: Args) -> CommandResult {
use owoify::OwOifiable;
let lastmsg = match message
.channel_id
.messages(&ctx.http, |get| get.before(message.id).limit(1))
.await
{
Ok(v) => v,
Err(_) => return Err(CommandError(s!("Could not get last message!"))),
Err(_) => return Err("Could not get last message!".into()),
};
let lastmsg = &lastmsg[0].content;
@ -488,28 +541,28 @@ fn owo(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
true => s!(lastmsg),
false => args.rest().trim().to_string(),
};
let _ = message.channel_id.say(&ctx.http, input.owoify());
let _ = message.channel_id.say(&ctx.http, input.owoify()).await;
Ok(())
}
// Prints channel topic
#[command]
#[only_in(guilds)]
#[aliases("description", "topic")]
fn desc(ctx: &mut Context, message: &Message) -> CommandResult {
let channel_lock = match message.channel(&ctx) {
async fn desc(ctx: &Context, message: &Message) -> CommandResult {
let channel = match message.channel(&ctx).await {
Some(ch) => ch,
None => {
return Err(CommandError(s!("Could not get channel!")));
return Err("Could not get channel!".into());
}
};
let channel_lock = match channel_lock.guild() {
let channel = match channel.guild() {
Some(g) => g,
None => {
return Err(CommandError(s!("Could not get guild!")));
return Err("Could not get guild channel!".into());
}
};
let channel = channel_lock.read();
let topic = if channel.topic.clone().unwrap() != "" {
channel.topic.clone().unwrap()
@ -517,13 +570,16 @@ fn desc(ctx: &mut Context, message: &Message) -> CommandResult {
String::from("No channel topic found")
};
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Channel's topic:")
.description(topic)
.color(0xffd1dc)
let _ = message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Channel's topic:")
.description(topic)
.color(0xffd1dc)
})
})
});
.await;
Ok(())
}