Main: Is now running with --no-default-features --features core

This commit is contained in:
Natsu Kagami 2020-09-07 02:09:36 -04:00
parent f1719019d1
commit 1508523ca9
Signed by: nki
GPG key ID: 73376E117CD20735
3 changed files with 184 additions and 99 deletions

61
Cargo.lock generated
View file

@ -75,6 +75,16 @@ dependencies = [
"tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "1.0.0"
@ -351,6 +361,18 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
@ -563,6 +585,14 @@ name = "httparse"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hyper"
version = "0.13.5"
@ -1002,6 +1032,11 @@ dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "1.0.6"
@ -1466,6 +1501,14 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "termcolor"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thiserror"
version = "1.0.20"
@ -1858,6 +1901,14 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@ -1893,7 +1944,9 @@ name = "youmubot"
version = "0.1.0"
dependencies = [
"dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serenity 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serenity 0.9.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"youmubot-cf 0.1.0",
"youmubot-core 0.1.0",
"youmubot-db 0.1.0",
@ -1991,6 +2044,7 @@ dependencies = [
"checksum async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7"
"checksum async-trait 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "687c230d85c0a52504709705fc8a53e4a692b83a2184f03dae73e38e1e93a783"
"checksum async-tungstenite 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4187bb446c8ecb8849f17cef7553db8bdb09e482e806257130189958fb42dca7"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
@ -2027,6 +2081,7 @@ dependencies = [
"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum encoding_rs 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171"
"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum flate2 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42"
"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
@ -2051,6 +2106,7 @@ dependencies = [
"checksum http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96816e1d921eca64d208a85aab4f7798455a8e34229ee5a88c935bdee1b78b14"
"checksum hyper-rustls 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08"
"checksum hyper-tls 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3adcd308402b9553630734e9c36b77a7e48b3821251ca2493e8cd596763aafaa"
@ -2102,6 +2158,7 @@ dependencies = [
"checksum proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63"
"checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
"checksum proc-macro2 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "de40dd4ff82d9c9bab6dae29dbab1167e515f8df9ed17d2987cb6012db206933"
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
"checksum quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
@ -2146,6 +2203,7 @@ dependencies = [
"checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
"checksum syn 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "95b5f192649e48a5302a13f2feb224df883b98933222369e4b3b0fe2a5447269"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
"checksum thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
"checksum thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
@ -2192,6 +2250,7 @@ dependencies = [
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"

View file

@ -12,8 +12,10 @@ osu = ["youmubot-osu"]
codeforces = ["youmubot-cf"]
[dependencies]
serenity = "0.8"
serenity = "0.9.0-rc.0"
tokio = "0.2"
dotenv = "0.15"
env_logger = "0.7"
youmubot-db = { path = "../youmubot-db" }
youmubot-prelude = { path = "../youmubot-prelude" }
youmubot-core = { path = "../youmubot-core" }

View file

@ -1,9 +1,10 @@
use dotenv;
use dotenv::var;
use serenity::{
framework::standard::{DispatchError, StandardFramework},
client::bridge::gateway::GatewayIntents,
framework::standard::{macros::hook, CommandResult, DispatchError, StandardFramework},
model::{
channel::{Channel, Message, Reaction},
channel::{Channel, Message},
gateway,
id::{ChannelId, GuildId, UserId},
permissions::Permissions,
@ -21,78 +22,80 @@ impl Handler {
}
}
#[async_trait]
impl EventHandler for Handler {
fn ready(&self, _: Context, ready: gateway::Ready) {
async fn ready(&self, _: Context, ready: gateway::Ready) {
println!("{} is connected!", ready.user.name);
}
fn message(&self, mut ctx: Context, message: Message) {
async fn message(&self, mut ctx: Context, message: Message) {
self.hooks.iter().for_each(|f| f(&mut ctx, &message));
}
fn reaction_add(&self, ctx: Context, reaction: Reaction) {
ctx.data
.get_cloned::<ReactionWatcher>()
.send(reaction, true);
}
fn reaction_remove(&self, ctx: Context, reaction: Reaction) {
ctx.data
.get_cloned::<ReactionWatcher>()
.send(reaction, false);
}
}
/// Returns whether the user has "MANAGE_MESSAGES" permission in the channel.
fn is_channel_mod(ctx: &mut Context, _: Option<GuildId>, ch: ChannelId, u: UserId) -> bool {
match ch.to_channel(&ctx) {
Ok(Channel::Guild(gc)) => {
let gc = gc.read();
gc.permissions_for_user(&ctx, u)
.map(|perms| perms.contains(Permissions::MANAGE_MESSAGES))
.unwrap_or(false)
}
async fn is_channel_mod(ctx: &Context, _: Option<GuildId>, ch: ChannelId, u: UserId) -> bool {
match ch.to_channel(&ctx).await {
Ok(Channel::Guild(gc)) => gc
.permissions_for_user(&ctx, u)
.await
.map(|perms| perms.contains(Permissions::MANAGE_MESSAGES))
.unwrap_or(false),
_ => false,
}
}
fn main() {
#[tokio::main]
async fn main() {
env_logger::init();
// Setup dotenv
if let Ok(path) = dotenv::dotenv() {
println!("Loaded dotenv from {:?}", path);
}
let mut handler = Handler::new();
let handler = Handler::new();
// Set up hooks
#[cfg(feature = "osu")]
handler.hooks.push(youmubot_osu::discord::hook);
#[cfg(feature = "codeforces")]
handler.hooks.push(youmubot_cf::codeforces_info_hook);
// Collect the token
let token = var("TOKEN").expect("Please set TOKEN as the Discord Bot's token to be used.");
// Set up base framework
let fw = setup_framework(&token[..]).await;
// Sets up a client
let mut client = {
// Collect the token
let token = var("TOKEN").expect("Please set TOKEN as the Discord Bot's token to be used.");
// Attempt to connect and set up a framework
Client::new(token, handler).expect("Cannot connect")
Client::new(token)
.framework(fw)
.event_handler(handler)
.intents(
GatewayIntents::GUILDS
| GatewayIntents::GUILD_BANS
| GatewayIntents::GUILD_MESSAGES
| GatewayIntents::GUILD_MESSAGE_REACTIONS
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::DIRECT_MESSAGE_REACTIONS,
)
.await
.unwrap()
};
// Set up base framework
let mut fw = setup_framework(&client);
// Set up announcer handler
let mut announcers = AnnouncerHandler::new(&client);
// Setup each package starting from the prelude.
{
let mut data = client.data.write();
let mut data = client.data.write().await;
let db_path = var("DBPATH")
.map(|v| std::path::PathBuf::from(v))
.unwrap_or_else(|e| {
println!("No DBPATH set up ({:?}), using `/data`", e);
std::path::PathBuf::from("data")
});
youmubot_prelude::setup::setup_prelude(&db_path, &mut data, &mut fw);
youmubot_prelude::setup::setup_prelude(&db_path, &mut data);
// Setup core
#[cfg(feature = "core")]
youmubot_core::setup(&db_path, &client, &mut data).expect("Setup db should succeed");
@ -112,11 +115,10 @@ fn main() {
#[cfg(feature = "codeforces")]
println!("codeforces enabled.");
client.with_framework(fw);
announcers.scan(std::time::Duration::from_secs(120));
tokio::spawn(announcers.scan(std::time::Duration::from_secs(120)));
println!("Starting...");
if let Err(v) = client.start() {
if let Err(v) = client.start().await {
panic!(v)
}
@ -124,71 +126,43 @@ fn main() {
}
// Sets up a framework for a client
fn setup_framework(client: &Client) -> StandardFramework {
async fn setup_framework(token: &str) -> StandardFramework {
let http = serenity::http::Http::new_with_token(token);
// Collect owners
let owner = client
.cache_and_http
.http
let owner = http
.get_current_application_info()
.await
.expect("Should be able to get app info")
.owner;
let fw = StandardFramework::new()
.configure(|c| {
c.with_whitespace(false)
.prefix(&var("PREFIX").unwrap_or("y!".to_owned()))
.delimiters(vec![" / ", "/ ", " /", "/"])
.owners([owner.id].iter().cloned().collect())
})
.help(&youmubot_core::HELP)
.before(|_, msg, command_name| {
println!(
"Got command '{}' by user '{}'",
command_name, msg.author.name
);
true
})
.after(|ctx, msg, command_name, error| match error {
Ok(()) => println!("Processed command '{}'", command_name),
Err(why) => {
let reply = format!("Command '{}' returned error {:?}", command_name, why);
if let Err(_) = msg.reply(&ctx, &reply) {}
println!("{}", reply)
}
})
.on_dispatch_error(|ctx, msg, error| {
msg.reply(
&ctx,
&match error {
DispatchError::Ratelimited(seconds) => format!(
"⏳ You are being rate-limited! Try this again in **{} seconds**.",
seconds
),
DispatchError::NotEnoughArguments { min, given } => format!("😕 The command needs at least **{}** arguments, I only got **{}**!\nDid you know command arguments are separated with a slash (`/`)?", min, given),
DispatchError::TooManyArguments { max, given } => format!("😕 I can only handle at most **{}** arguments, but I got **{}**!", max, given),
DispatchError::OnlyForGuilds => format!("🔇 This command cannot be used in DMs."),
_ => return,
},
)
.unwrap(); // Invoke
})
// Set a function that's called whenever an attempted command-call's
// command could not be found.
.unrecognised_command(|_, _, unknown_command_name| {
println!("Could not find command named '{}'", unknown_command_name);
})
// Set a function that's called whenever a message is not a command.
.normal_message(|_, _| {
// println!("Message is not a command '{}'", message.content);
})
.bucket("voting", |c| {
c.check(|ctx, g, ch, u| !is_channel_mod(ctx, g, ch, u)).delay(120 /* 2 minutes */).time_span(120).limit(1)
})
.bucket("images", |c| c.time_span(60).limit(2))
.bucket("community", |c| {
c.check(|ctx, g, ch, u| !is_channel_mod(ctx, g, ch, u)).delay(30).time_span(30).limit(1)
})
.group(&prelude_commands::PRELUDE_GROUP);
let fw = StandardFramework::new()
.configure(|c| {
c.with_whitespace(false)
.prefix(&var("PREFIX").unwrap_or("y!".to_owned()))
.delimiters(vec![" / ", "/ ", " /", "/"])
.owners([owner.id].iter().cloned().collect())
})
.help(&youmubot_core::HELP)
.before(before_hook)
.after(after_hook)
.on_dispatch_error(on_dispatch_error)
.bucket("voting", |c| {
c.check(|ctx, g, ch, u| Box::pin(async move { !is_channel_mod(ctx, g, ch, u).await }))
.delay(120 /* 2 minutes */)
.time_span(120)
.limit(1)
})
.await
.bucket("images", |c| c.time_span(60).limit(2))
.await
.bucket("community", |c| {
c.check(|ctx, g, ch, u| Box::pin(async move { !is_channel_mod(ctx, g, ch, u).await }))
.delay(30)
.time_span(30)
.limit(1)
})
.await
.group(&prelude_commands::PRELUDE_GROUP);
// groups here
#[cfg(feature = "core")]
let fw = fw
@ -201,3 +175,53 @@ fn setup_framework(client: &Client) -> StandardFramework {
let fw = fw.group(&youmubot_cf::CODEFORCES_GROUP);
fw
}
// Hooks!
#[hook]
async fn before_hook(_: &Context, msg: &Message, command_name: &str) -> bool {
println!(
"Got command '{}' by user '{}'",
command_name, msg.author.name
);
true
}
#[hook]
async fn after_hook(ctx: &Context, msg: &Message, command_name: &str, error: CommandResult) {
match error {
Ok(()) => println!("Processed command '{}'", command_name),
Err(why) => {
let reply = format!("Command '{}' returned error {:?}", command_name, why);
msg.reply(&ctx, &reply).await.ok();
println!("{}", reply)
}
}
}
#[hook]
async fn on_dispatch_error(ctx: &Context, msg: &Message, error: DispatchError) {
msg.reply(
&ctx,
&match error {
DispatchError::Ratelimited(seconds) => format!(
"⏳ You are being rate-limited! Try this again in **{} seconds**.",
seconds
),
DispatchError::NotEnoughArguments { min, given } => {
format!(
"😕 The command needs at least **{}** arguments, I only got **{}**!",
min, given
) + "\nDid you know command arguments are separated with a slash (`/`)?"
}
DispatchError::TooManyArguments { max, given } => format!(
"😕 I can only handle at most **{}** arguments, but I got **{}**!",
max, given
),
DispatchError::OnlyForGuilds => format!("🔇 This command cannot be used in DMs."),
_ => return,
},
)
.await
.ok(); // Invoke
}