#[macro_use]
extern crate serenity;
use std::{collections::HashMap, env, fmt::Write, sync::Arc};
use serenity::prelude::*;
use serenity::{
client::bridge::gateway::{ShardId, ShardManager},
framework::standard::{
help_commands, Args, CommandOptions, DispatchError, HelpBehaviour, StandardFramework,
},
model::{channel::Message, gateway::Ready, Permissions},
prelude::*,
utils::{content_safe, ContentSafeOptions},
};
struct ShardManagerContainer;
impl TypeMapKey for ShardManagerContainer {
type Value = Arc<Mutex<ShardManager>>;
}
struct CommandCounter;
impl TypeMapKey for CommandCounter {
type Value = HashMap<String, u64>;
}
struct Handler;
impl EventHandler for Handler {
fn ready(&self, _: Context, ready: Ready) {
println!("{} is connected!", ready.user.name);
}
}
const DISCORD_TOKEN: &str = "LALALA";
fn main() {
let token = DISCORD_TOKEN;
let mut client = Client::new(&token, Handler).expect("Err creating client");
{
let mut data = client.data.lock();
data.insert::<CommandCounter>(HashMap::default());
data.insert::<ShardManagerContainer>(Arc::clone(&client.shard_manager));
}
client.with_framework(
StandardFramework::new()
.configure(|c| {
c.allow_whitespace(true)
.on_mention(true)
.prefix("~")
//.prefix_only_cmd(help)
.delimiters(vec![", ", ",", " "])
})
.before(|ctx, msg, command_name| {
println!(
"Got command '{}' by user '{}'",
command_name, msg.author.name
);
let mut data = ctx.data.lock();
let counter = data
.get_mut::<CommandCounter>()
.expect("Expected CommandCounter in ShareMap.");
let entry = counter.entry(command_name.to_string()).or_insert(0);
*entry += 1;
true // if `before` returns false, command processing doesn't happen.
})
.after(|_, _, command_name, error| match error {
Ok(()) => println!("Processed command '{}'", command_name),
Err(why) => println!("Command '{}' returned error {:?}", command_name, why),
})
//.unrecognised_command(help)
//.message_without_command(help)
.on_dispatch_error(|_ctx, msg, error| {
if let DispatchError::RateLimited(seconds) = error {
let _ = msg
.channel_id
.say(&format!("Try this again in {} seconds.", seconds));
}
})
.customised_help(help_commands::with_embeds, |c| {
c.individual_command_tip("🦀 Bonjour 🦀")
.max_levenshtein_distance(5)
// `{}` refers to a command's name.
.command_not_found_text("Could not find: `{}`.")
})
.command("commands", |c| c.cmd(commands))
.command("say", |c| c.cmd(say))
.command("latency", |c| c.cmd(latency))
.command("nul", |c| c.cmd(nul)),
);
if let Err(why) = client.start() {
println!("Client error: {:?}", why);
}
}
/*
fn add(user: String) {
let path = Path::new("/tmp/hello.txt");
let mut file = match File::open(&path) {
Err(why) => panic!("couldn't open file {}", why.description()),
Ok(file) => file,
};
let mut s = String::new();
match file.read_to_string(&mut s) {
Err(why) => panic!("couldn't read {}: {}", display, why.description()),
Ok(_) => print!("{} contains:\n{}", display, s),
}
for line in s.split("\n") {
if line.starts_with(user) {
let number = line.split(" ").last();
let nb: u64 = number.parse();
number = format!("{}", nb + 1);
}
}
println!("{}", s);
}
*/
command!(nul(ctx, msg, args) {
if args.len() != 1 {
msg.reply("Donne moi **un** nom !");
return Ok(());
}
let user: String = args.iter().next().unwrap().unwrap();
if !user.starts_with("<@") || !user.ends_with(">") {
msg.reply("Le nom est malformé !");
return Ok(());
}
let user_id: u64 = match user[2..user.len() - 1].parse::<u64>() {
Err(_) => {
msg.reply("Le nom est malformé !");
return Ok(());
},
Ok(n) => n,
};
// println!("{:?}", ctx);
let user = serenity::model::id::UserId(user_id);
let user = match user.get() {
Err(_) => {
msg.reply("Utilisateur inconnu");
return Ok(());
},
Ok(u) => u,
};
if let Err(why) = msg.channel_id.say(format!("Shame {}!", user)) {
println!("Error sending message: {:?}", why);
}
});
command!(commands(ctx, msg, _args) {
let mut contents = "Commands used:\n".to_string();
let data = ctx.data.lock();
let counter = data.get::<CommandCounter>().expect("Expected CommandCounter in ShareMap.");
for (k, v) in counter {
let _ = write!(contents, "- {name}: {amount}\n", name=k, amount=v);
}
if let Err(why) = msg.channel_id.say(&contents) {
println!("Error sending message: {:?}", why);
}
});
command!(say(_ctx, msg, args) {
let mut settings = if let Some(guild_id) = msg.guild_id {
ContentSafeOptions::default()
.clean_channel(false)
.display_as_member_from(guild_id)
} else {
ContentSafeOptions::default()
.clean_channel(false)
.clean_role(false)
};
let mut content = content_safe(&args.full(), &settings);
if let Err(why) = msg.channel_id.say(&content) {
println!("Error sending message: {:?}", why);
}
});
command!(latency(ctx, msg, _args) {
let data = ctx.data.lock();
let shard_manager = match data.get::<ShardManagerContainer>() {
Some(v) => v,
None => {
let _ = msg.reply("There was a problem getting the shard manager");
return Ok(());
},
};
let manager = shard_manager.lock();
let runners = manager.runners.lock();
let runner = match runners.get(&ShardId(ctx.shard_id)) {
Some(runner) => runner,
None => {
let _ = msg.reply("No shard found");
return Ok(());
},
};
let _ = msg.reply(&format!("The shard latency is {:?}", runner.latency));
});