rustcord/src/main.rs

425 lines
13 KiB
Rust

#![allow(clippy::unreadable_literal)]
use owoify::OwOifiable;
use rand::Rng;
use serenity::{
client::Client,
framework::standard::{
macros::{check, command, group},
Args, CheckResult, CommandOptions, CommandResult, DispatchError, Reason, StandardFramework,
},
model::{channel::Message, gateway::Ready, id::UserId, user::OnlineStatus},
prelude::*,
};
use std::{env, process};
struct Handler;
impl EventHandler for Handler {
fn ready(&self, ctx: Context, ready: Ready) {
if let Some(shard) = ready.shard {
println!(
"INFO: {} is connected on shard {}/{}!\n>>",
ready.user.name, shard[0], shard[1]
);
use serenity::model::gateway::Activity;
let activity = Activity::listening("dj0nt");
let status = OnlineStatus::Online;
ctx.set_presence(Some(activity), status);
}
}
}
group!({
name: "general",
options: {},
commands: [init, ping, halt, list_srv, host, ship, headpat, uwu, gayculator, waffle, sausage, ad, help, compare_bot, what, owo, info]
});
fn main() {
let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("Invalid token"), Handler)
.expect("Error creating client");
client.with_framework(
StandardFramework::new()
.configure(|c| {
c.with_whitespace(true)
.owners(vec![UserId(254310746450690048)].into_iter().collect())
.prefixes(vec!["owo ", "OwO "])
.no_dm_prefix(true)
.case_insensitivity(true)
.by_space(false)
})
.on_dispatch_error(|ctx, msg, error| {
if let DispatchError::CheckFailed("Owner", Reason::Unknown) = error {
let _ = msg.channel_id.say(&ctx.http, "no");
} else if let DispatchError::Ratelimited(seconds) = error {
let _ = msg
.channel_id
.say(&ctx.http, &format!("Try again in {} seconds.", seconds));
}
})
.group(&GENERAL_GROUP),
);
if let Err(e) = client.start() {
println!("An error occurred while running the client: {:?}", e);
}
}
#[check]
#[name = "Owner"]
fn owner_check(_: &mut Context, msg: &Message, _: &mut Args, _: &CommandOptions) -> CheckResult {
if msg.author.id == 254310746450690048 {
CheckResult::Success
} else {
CheckResult::Failure(Reason::Unknown)
}
}
#[check]
#[name = "Server"]
fn server_check(_: &mut Context, msg: &Message, _: &mut Args, _: &CommandOptions) -> CheckResult {
(msg.guild_id == Some(serenity::model::id::GuildId(255386835964919810))).into()
}
#[command]
fn init(ctx: &mut Context, message: &Message) -> CommandResult {
let num = rand::thread_rng().gen_range(0, 2);
match num {
0 => {
let _ = message
.channel_id
.say(&ctx.http, "The Discordinator9000 is going sicko mode!");
}
1 => {
let _ = message.channel_id.say(
&ctx.http,
"The Discordinator9000 is ready to take over the world!",
);
}
_ => {
let _ = message.channel_id.say(&ctx.http, "Oopsie woopsie! UwU");
}
}
Ok(())
}
#[command]
fn ping(ctx: &mut Context, message: &Message) -> CommandResult {
let _ = message.reply(&ctx, "Pong!");
Ok(())
}
#[command]
#[checks(Owner)]
fn halt(ctx: &mut Context) -> CommandResult {
ctx.set_presence(None, OnlineStatus::Offline);
use std::{thread, time};
let one_s = time::Duration::new(2, 0);
thread::sleep(one_s);
process::exit(0);
}
#[command]
#[checks(Owner)]
fn list_srv(ctx: &mut 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.push_str(&format!("{}: {}\n", index, guild.name));
}
let _ = message.channel_id.say(
&ctx.http,
list.replace("@everyone", "@\u{200B}everyone").to_string(),
);
Ok(())
}
#[command]
#[checks(Owner)]
fn host(ctx: &mut Context, message: &Message) -> CommandResult {
let _ = message.channel_id.say(
&ctx.http,
format!(
"Debug\nOS: {:?}\nHost: {:?}",
sys_info::os_type().unwrap(),
sys_info::hostname().unwrap()
),
);
Ok(())
}
#[command]
fn ship(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let first = calculate_hash(
&args
.single::<String>()
.unwrap_or_else(|_| "Null".to_string()),
);
let second = calculate_hash(
&args
.single::<String>()
.unwrap_or_else(|_| "Null".to_string()),
);
let mut slider = String::new();
let res = (first % second) / 100000000000000000;
let mut num = 0;
while num < res / 10 {
slider.push('▬');
num += 1;
}
slider.push_str(":heart:");
num = 0;
while num < (10 - res / 10) {
slider.push('▬');
num += 1;
}
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("{}%", res))
.description(slider)
.color(0xff00ce)
})
});
fn calculate_hash<T: Hash>(t: &T) -> u64 {
let mut s = DefaultHasher::new();
t.hash(&mut s);
s.finish()
}
Ok(())
}
#[command]
fn headpat(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
message
.channel_id
.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Sending headpats to **{}**...", args.rest().trim()))
.image("https://i.pinimg.com/originals/83/1a/90/831a903eab6d827dcfd298b9e3196e30.jpg")
.description("[Source](https://www.pinterest.com/pin/377809856242075277/)")
})
})
.expect("Failed to send message!");
Ok(())
}
#[command]
fn uwu(ctx: &mut Context, message: &Message) -> CommandResult {
let num = rand::thread_rng().gen_range(0, 4);
match num {
0 => {
let _ = message.channel_id.send_message(&ctx.http, |m| m
.embed(|e| e
.image("https://i.redditmedia.com/qDD9W7NJqTAk31y061TuRW9R8qOcCuEmmCWyOsUEavE.png?fit=crop&crop=faces%2Centropy&arh=2&w=640&s=ebdd3f1970b4fe70ccd24a1958e7fc32")
));
}
1 => {
let _ = message.channel_id.send_message(&ctx.http, |m| m
.embed(|e| e
.image("https://www.shitpostbot.com/img/sourceimages/smash-that-mfuckn-uwu-button-57b5aa1de9fe4.jpeg")
));
}
2 => {
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e
.image("https://www.shitpostbot.com/img/sourceimages/fallout-nv-owo-57e586ae15322.jpeg")
})
});
}
3 => {
let _ = message.channel_id.send_message(&ctx.http, |m| m
.embed(|e| e
.image("https://i.redditmedia.com/-JaK9YW7mPz2S2xBJmXvW4fZ58uGMa4l6GIgYt3dqZg.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=640&s=ebab29a577346b4d18ec914538b69bb4")
));
}
_ => {
let _ = message.channel_id.say(&ctx.http, "UwU");
}
}
Ok(())
}
#[command]
fn gayculator(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult {
//the amiter check
if message.author.id != 191948420141809665 {
let number_32: i32 = args.single::<i32>().unwrap_or(1);
let result = if number_32 % 2 == 0 {
"much straight".to_string()
} else {
"large gay".to_string()
};
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title("Gayness level:")
.description(result)
.color(0xff00f9)
})
});
}
Ok(())
}
#[command]
fn waffle(ctx: &mut Context, message: &Message) -> CommandResult {
let _ = message.channel_id.say(&ctx.http, "h");
Ok(())
}
#[command]
fn sausage(ctx: &mut 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/379673147764506624/431546724637736971/image.png")
})
});
Ok(())
}
#[command]
#[checks(Server)]
fn ad(ctx: &mut Context, message: &Message) -> CommandResult {
let _ = message.channel_id.send_message(&ctx.http, |m| m
.embed(|e| e
.title(":b:ottom text")
***REMOVED***
.thumbnail("https://i.imgur.com/8MU0gqD.png")
.color(0x00f3ff))
);
Ok(())
}
#[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", false),
("owo ping", "Pong", false),
("owo waffle", "stroopwafel owo", false),
("owo sausage", "sosig", false),
("owo help", "Help the fellow humanz!", false),
("owo info", "Show information about me!", false),
(
"owo compare_bot ``bot's name``",
"Compare me to other robots!",
false,
),
(
"owo what's this ``word``",
"Find a definition of word",
false,
),
(
"owo ship ``name 1`` ``name 2``",
"*shipping intensifies*",
false,
),
("owo headpat ``name``", "Headpat someone", false),
("owo owo ``text``", "owoify input text", false),
("Admin commands:", "\u{200B}", true),
("owo halt", "kill me", false),
("owo list_srv", "list my servers", false),
("owo host", "Display host info", false),
])
.color(0x000000)
})
});
Ok(())
}
#[command]
fn info(ctx: &mut Context, message: &Message) -> CommandResult {
let num = ctx.cache.read().guilds.len();
let _ = message.channel_id.send_message(&ctx.http, |m| m
.embed(|e| e
.title("Discordinator9000's info:")
.description("h")
.field("Author:", "EvilDeaaaadd#9000", false)
.field("Server count:", num , false)
.field("Invite:", "[Invite link](https://discordapp.com/api/oauth2/authorize?client_id=470350233419907129&permissions=2048&scope=bot)", false )
.footer(|f| f
.text("Written in Rust using Serenity, OwOify and a few other libraries"))
.color(0xee657)
));
Ok(())
}
#[command]
#[aliases("compare")]
fn compare_bot(ctx: &mut Context, message: &Message, mut args: Args) -> CommandResult {
//the amiter check
if message.author.id != 191948420141809665 {
let text: String = args
.single::<String>()
.unwrap_or_else(|_| "Null".to_string());
if text.to_lowercase().contains("nib") {
let _ = message.channel_id.say(&ctx.http, "I am superior to NibBot");
} else if text.to_lowercase().contains("amit") {
let _ = message.channel_id.say(&ctx.http, "Amiter is big dumb");
} else if text.to_lowercase().contains("discordinator") {
let _ = message.channel_id.say(&ctx.http, "Option<(!, ())>");
} else {
let _ = message
.channel_id
.say(&ctx.http, format!("Me and {} are friends!", text));
}
}
Ok(())
}
#[command]
#[aliases("what's this")]
fn what(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
let text: String = args.rest().to_string();
let defs = &urbandict::get_definitions(&text.to_string())?;
let def = &defs[0];
let _ = message.channel_id.send_message(&ctx.http, |m| {
m.embed(|e| {
e.title(format!("Author: {}", def.author)).field(
"Definition: ",
def.definition.replace(|c| c == '[' || c == ']', ""),
false,
)
})
});
Ok(())
}
#[command]
fn owo(ctx: &mut Context, message: &Message, args: Args) -> CommandResult {
let input: String = args.rest().trim().to_string();
let _ = message.channel_id.say(&ctx.http, input.owoify());
Ok(())
}