init
This commit is contained in:
commit
5f3f9d6652
|
@ -0,0 +1,4 @@
|
|||
/target
|
||||
**/*.rs.bk
|
||||
.vscode
|
||||
Cargo.lock
|
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "rusty_rat"
|
||||
version = "0.1.0"
|
||||
authors = ["Raatty <'me@raatty.club'>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
serenity = "0.7.1"
|
||||
reqwest = { version = "0.9.22", default-features = false }
|
||||
serde = { version = "1.0.101", features = ["derive"] }
|
||||
rand = "0.6"
|
||||
typemap = "0.3"
|
||||
chrono = "0.4"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
panic = 'abort'
|
||||
lto = true
|
||||
opt-level = "z"
|
|
@ -0,0 +1,25 @@
|
|||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandError, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
#[command]
|
||||
#[description = "displays your avatar"]
|
||||
pub fn avatar(ctx: &mut Context, msg: &Message, _args: Args) -> CommandResult {
|
||||
let guild = &msg.guild_id.ok_or(CommandError("no guild".to_owned()))?;
|
||||
let member = guild.member(&ctx, &msg.author)?;
|
||||
let name = member.display_name();
|
||||
if let Some(user_avatar) = &msg.author.avatar_url() {
|
||||
msg.channel_id
|
||||
.send_message(&ctx.http, |m| {
|
||||
m.embed(|e| {
|
||||
e.title(format!("Heres {}'s avatar", name))
|
||||
.image(user_avatar)
|
||||
})
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
extern crate reqwest;
|
||||
extern crate serde;
|
||||
use serde::Deserialize;
|
||||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
utils::Colour,
|
||||
};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
const DOG_URLS: [&'static str; 3] = [
|
||||
"https://dog.ceo/api/breed/{}/images/random",
|
||||
"https://dog.ceo/api/breeds/list",
|
||||
"https://dog.ceo/api/breeds/image/random",
|
||||
];
|
||||
|
||||
fn get_dog(url: &str) -> Result<String, reqwest::Error> {
|
||||
let mut resp = reqwest::get(url)?;
|
||||
let jresp: HashMap<String, String> = resp.json()?;
|
||||
let dog_url = &jresp["message"];
|
||||
Ok(dog_url.to_string())
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[description = "sends a pic of a random pug"]
|
||||
pub fn pug(ctx: &mut Context, msg: &Message, _args: Args) -> CommandResult {
|
||||
let url = get_dog(&DOG_URLS[0].replace("{}", "pug"))?;
|
||||
msg.channel_id
|
||||
.send_message(&ctx.http, |m| {
|
||||
m.embed(|e| e.image(url).colour(Colour::BLUE))
|
||||
})
|
||||
.ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DogList {
|
||||
#[allow(dead_code)]
|
||||
status: String,
|
||||
message: Vec<String>,
|
||||
}
|
||||
|
||||
fn get_dog_list() -> Result<DogList, reqwest::Error> {
|
||||
let mut resp = reqwest::get(DOG_URLS[1])?;
|
||||
let dlist: DogList = resp.json()?;
|
||||
Ok(dlist)
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[description = "sends a pic of a random dog of a given bread"]
|
||||
pub fn dog(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
match args.single::<String>() {
|
||||
Ok(ref breed) if breed == "list" => {
|
||||
let list_of_breads = get_dog_list()?;
|
||||
msg.channel_id
|
||||
.say(
|
||||
&ctx.http,
|
||||
format!(
|
||||
"**Here is a list of valid dog breads**\n{:?}",
|
||||
list_of_breads.message
|
||||
),
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
Ok(bread) => {
|
||||
let url = get_dog(&DOG_URLS[0].replace("{}", &bread))?;
|
||||
msg.channel_id
|
||||
.send_message(&ctx.http, |m| {
|
||||
m.embed(|e| e.image(url).colour(Colour::BLUE))
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(_) => {
|
||||
let url = get_dog(&DOG_URLS[2])?;
|
||||
msg.channel_id
|
||||
.send_message(&ctx.http, |m| {
|
||||
m.embed(|e| e.image(url).colour(Colour::BLUE))
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
#[command]
|
||||
#[aliases("crc")]
|
||||
#[description = "paper sizzors rock basicly"]
|
||||
pub fn cat_rat_cheese(ctx: &mut Context, msg: &Message, _args: Args) -> CommandResult {
|
||||
if let Ok(sent_msg) = msg.channel_id.say(
|
||||
&ctx.http,
|
||||
"react with your choice, wait for the 3 reactions to load tho",
|
||||
) {
|
||||
for e in &['🐀', '🧀', '🐱'] {
|
||||
sent_msg.react(&ctx, *e).ok();
|
||||
}
|
||||
use crate::events;
|
||||
ctx.data
|
||||
.write()
|
||||
.get_mut::<events::CRCGameStateStore>()
|
||||
.expect("Expected CRCGameStateStore")
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(
|
||||
sent_msg.id.into(),
|
||||
events::CRCGameState {
|
||||
player_id: msg.author.id.into(),
|
||||
player_score: 0,
|
||||
bot_score: 0,
|
||||
},
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
utils,
|
||||
};
|
||||
|
||||
#[command]
|
||||
#[description = "echos the message given"]
|
||||
pub fn echo(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
|
||||
msg.channel_id
|
||||
.say(
|
||||
&ctx.http,
|
||||
utils::content_safe(&ctx, args.rest(), &utils::ContentSafeOptions::default()),
|
||||
)
|
||||
.ok();
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
extern crate rand;
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
const EIGHTBALL_RESPONCES: [&'static str; 20] = [
|
||||
"it is certain",
|
||||
"it is decidedly so",
|
||||
"without a doubt",
|
||||
"yes definitely",
|
||||
"you may rely on it",
|
||||
"as I see it, yes",
|
||||
"most likely",
|
||||
"outlook good",
|
||||
"yes",
|
||||
"signs point to yes",
|
||||
"reply hazy, try again",
|
||||
"ask again later",
|
||||
"better not tell you now",
|
||||
"cannot predict now",
|
||||
"concentrate and ask again",
|
||||
"don't count on it",
|
||||
"my reply is no",
|
||||
"my sources say no",
|
||||
"outlook not so good",
|
||||
"very doubtful",
|
||||
];
|
||||
|
||||
#[command("8ball")]
|
||||
#[description = "asks the magic cheese ball you deepest desires"]
|
||||
pub fn eightball(ctx: &mut Context, msg: &Message, _args: Args) -> CommandResult {
|
||||
let mut rng = thread_rng();
|
||||
if let Some(choice) = EIGHTBALL_RESPONCES.choose(&mut rng) {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, format!("🧀The cheese says {}", choice))
|
||||
.ok();
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
mod crc;
|
||||
mod echo;
|
||||
pub mod eightball;
|
||||
mod spam;
|
||||
|
||||
pub use crc::*;
|
||||
pub use echo::*;
|
||||
pub use eightball::*;
|
||||
pub use spam::*;
|
|
@ -0,0 +1,28 @@
|
|||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
utils,
|
||||
};
|
||||
|
||||
#[command]
|
||||
#[description = "spams a given message a maximum of 10 times"]
|
||||
#[usage("<count> <message>")]
|
||||
pub fn spam(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
if let Ok(count) = args.single::<u32>() {
|
||||
if count <= 10 {
|
||||
let to_spam = args.rest();
|
||||
for _ in 0..count {
|
||||
msg.channel_id
|
||||
.say(
|
||||
&ctx.http,
|
||||
utils::content_safe(&ctx, to_spam, &utils::ContentSafeOptions::default()),
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
} else {
|
||||
msg.channel_id.say(&ctx.http, "no thats too many").ok();
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
mod discord;
|
||||
mod dogs;
|
||||
mod fun;
|
||||
mod runescape;
|
||||
mod utility;
|
||||
|
||||
pub use discord::*;
|
||||
pub use dogs::*;
|
||||
pub use fun::*;
|
||||
pub use runescape::*;
|
||||
pub use utility::*;
|
|
@ -0,0 +1,194 @@
|
|||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
#[command]
|
||||
#[description = "echos the message given"]
|
||||
pub fn profile(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
|
||||
let rsn = args.rest().replace(" ", "%20");
|
||||
let mut resp = reqwest::get(&format!(
|
||||
"https://apps.runescape.com/runemetrics/profile/profile?user={}&activities=20",
|
||||
rsn
|
||||
))?;
|
||||
let profile: Profile = match resp.json::<Profile>() {
|
||||
Ok(p) => p,
|
||||
Err(why) => {
|
||||
println!("{}", why);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let quest_total = profile.questscomplete + profile.questsstarted + profile.questsnotstarted;
|
||||
let right = format!(
|
||||
"**Quests:** {}/{} ({} in progress)
|
||||
**Rank:** {}
|
||||
**Total level:** {}
|
||||
**Total XP:** {}
|
||||
**Combat level:** {}",
|
||||
profile.questscomplete,
|
||||
quest_total,
|
||||
profile.questsstarted,
|
||||
profile.rank.clone().unwrap_or("none".to_string()),
|
||||
profile.totalskill,
|
||||
profile.totalxp,
|
||||
profile.combatlevel
|
||||
);
|
||||
let mut stats_extended: Vec<SkillValueExtended> = profile
|
||||
.skillvalues
|
||||
.iter()
|
||||
.map(|s| SkillValueExtended::from(s))
|
||||
.collect();
|
||||
stats_extended.sort_by(|s1, s2| ORDER[s1.id as usize].cmp(&ORDER[s2.id as usize]));
|
||||
let mut left = String::new();
|
||||
for i in 0..27 {
|
||||
if i % 3 == 0 {
|
||||
left.push('\n')
|
||||
}
|
||||
let stat = &stats_extended[i];
|
||||
left.push_str(&format!("{}{}", EMOJIS[stat.id as usize], stat.level));
|
||||
}
|
||||
msg.channel_id.send_message(&ctx.http, |m| {
|
||||
m.embed(|e| {
|
||||
e.author(|a| a.name(format!("RuneMetrics profile of: {}", profile.name)))
|
||||
.field("Levels", left, true)
|
||||
.field("Info", right, true)
|
||||
})
|
||||
})?;
|
||||
let mut activities_out = String::new();
|
||||
for (i, a) in profile.activities.iter().enumerate() {
|
||||
{
|
||||
activities_out.push_str(&format!("**{}** {}\n```{}```", a.date, a.text, a.details));
|
||||
}
|
||||
if i == 10 {
|
||||
msg.channel_id.say(&ctx.http, &activities_out)?;
|
||||
activities_out.clear();
|
||||
}
|
||||
}
|
||||
if !activities_out.is_empty() {
|
||||
msg.channel_id.say(&ctx.http, &activities_out)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Activity {
|
||||
date: String,
|
||||
details: String,
|
||||
text: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Profile {
|
||||
magic: u32,
|
||||
questsstarted: u32,
|
||||
totalskill: u32,
|
||||
questscomplete: u32,
|
||||
questsnotstarted: u32,
|
||||
totalxp: u32,
|
||||
ranged: u32,
|
||||
activities: Vec<Activity>,
|
||||
skillvalues: Vec<SkillValue>,
|
||||
name: String,
|
||||
rank: Option<String>,
|
||||
melee: u32,
|
||||
combatlevel: u32,
|
||||
#[serde(alias = "loggedIn")]
|
||||
logged_in: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct SkillValue {
|
||||
level: u32,
|
||||
xp: u32,
|
||||
rank: Option<u32>,
|
||||
id: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SkillValueExtended {
|
||||
level: u32,
|
||||
xp: u32,
|
||||
rank: Option<u32>,
|
||||
id: u32,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl std::convert::From<&SkillValue> for SkillValueExtended {
|
||||
fn from(sv: &SkillValue) -> Self {
|
||||
Self {
|
||||
name: SKILL_NAMES[sv.id as usize].to_string(),
|
||||
level: sv.level,
|
||||
xp: sv.xp,
|
||||
rank: sv.rank,
|
||||
id: sv.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SKILL_NAMES: [&'static str; 27] = [
|
||||
"Attack",
|
||||
"Defence",
|
||||
"Strength",
|
||||
"Constitution",
|
||||
"Ranged",
|
||||
"Prayer",
|
||||
"Magic",
|
||||
"Cooking",
|
||||
"Woodcutting",
|
||||
"Fletching",
|
||||
"Fishing",
|
||||
"Firemaking",
|
||||
"Crafting",
|
||||
"Smithing",
|
||||
"Mining",
|
||||
"Herblore",
|
||||
"Agility",
|
||||
"Thieving",
|
||||
"Slayer",
|
||||
"Farming",
|
||||
"Runecrafting",
|
||||
"Hunter",
|
||||
"Construction",
|
||||
"Summoning",
|
||||
"Dungeoneering",
|
||||
"Divination",
|
||||
"Invention",
|
||||
];
|
||||
|
||||
static ORDER: [u32; 27] = [
|
||||
1, 7, 4, 2, 10, 13, 16, 12, 18, 17, 9, 15, 14, 6, 3, 8, 5, 11, 20, 21, 19, 23, 22, 24, 25, 26,
|
||||
27,
|
||||
];
|
||||
|
||||
static EMOJIS: [&'static str; 27] = [
|
||||
"<:Attack:406361343223136256>",
|
||||
"<:Defence:406361343348834304>",
|
||||
"<:Strength:406361343357222914>",
|
||||
"<:Constitution:406361343222874112>",
|
||||
"<:Ranged:406361343298502658>",
|
||||
"<:Prayer:406361343445434390>",
|
||||
"<:Magic:406361343608881152>",
|
||||
"<:Cooking:406361343361548298>",
|
||||
"<:Woodcutting:406361343718064128>",
|
||||
"<:Fletching:406361343353159691>",
|
||||
"<:Fishing:406361343583846410>",
|
||||
"<:Firemaking:406361343718064129>",
|
||||
"<:Crafting:406361343168610305>",
|
||||
"<:Smithing:406361343487115265>",
|
||||
"<:Mining:406361343583584256>",
|
||||
"<:Herblore:406361343554355210>",
|
||||
"<:Agility:406361343210553344>",
|
||||
"<:Thieving:406361343302696962>",
|
||||
"<:Slayer:406361343407685633>",
|
||||
"<:Farming:406361343407423498>",
|
||||
"<:Runecrafting:406361343596298250>",
|
||||
"<:Hunter:406361343474532353>",
|
||||
"<:Construction:406361343302565888>",
|
||||
"<:Summoning:406361343843631107>",
|
||||
"<:Dungeoneering:406361343386451979>",
|
||||
"<:Divination:406361343374131211>",
|
||||
"<:Invention:406361343591972864>",
|
||||
];
|
|
@ -0,0 +1,21 @@
|
|||
use serenity::prelude::Context;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
#[command]
|
||||
#[description = "responds with pong"]
|
||||
pub fn ping(ctx: &mut Context, message: &Message, _args: Args) -> CommandResult {
|
||||
let now = message.timestamp;
|
||||
let mut msg = message.channel_id.say(&ctx.http, "Pong! 🏓")?;
|
||||
let msg_timestamp = msg.timestamp;
|
||||
msg.edit(&ctx, |m| {
|
||||
m.content(format!(
|
||||
"Pong! 🏓 **took {}ms**",
|
||||
(msg_timestamp - now).num_milliseconds()
|
||||
))
|
||||
})
|
||||
.ok();
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
use serenity::{
|
||||
model::{channel::ReactionType, prelude::*},
|
||||
prelude::TypeMapKey,
|
||||
prelude::{Context, EventHandler},
|
||||
};
|
||||
|
||||
extern crate rand;
|
||||
use rand::{
|
||||
distributions::{Distribution, Standard},
|
||||
Rng,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::{Arc, Mutex};
|
||||
pub struct Handler;
|
||||
|
||||
impl EventHandler for Handler {
|
||||
fn ready(&self, ctx: Context, r: Ready) {
|
||||
println!("Successfully logged in as {}", r.user.name);
|
||||
println!("Can see {} guilds", r.guilds.len());
|
||||
let game = Activity::listening("CHEESE");
|
||||
let status = OnlineStatus::DoNotDisturb;
|
||||
|
||||
ctx.set_presence(Some(game), status);
|
||||
}
|
||||
fn message(&self, ctx: Context, new_message: Message) {
|
||||
if new_message.mentions_user_id(140652945032216576) {
|
||||
new_message.react(&ctx, '🐀').ok();
|
||||
}
|
||||
}
|
||||
fn reaction_add(&self, context: Context, reaction: Reaction) {
|
||||
let reaction_clone = reaction.clone();
|
||||
if let ReactionType::Unicode(emoji) = reaction.emoji {
|
||||
match emoji.as_ref() {
|
||||
"🐱" | "🐀" | "🧀" => play_crc(reaction_clone, context, &emoji),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn play_crc(reaction: Reaction, mut context: Context, emoji: &str) {
|
||||
let game_store = {
|
||||
let mut data = context.data.write();
|
||||
data.get_mut::<CRCGameStateStore>()
|
||||
.expect("Expected CRCGameStateStore")
|
||||
.clone()
|
||||
};
|
||||
let mut remove_message = false;
|
||||
if let Some(current_game) = game_store
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_mut(&u64::from(reaction.message_id))
|
||||
{
|
||||
if reaction.user_id != current_game.player_id {
|
||||
return;
|
||||
}
|
||||
let message = current_game
|
||||
.play(CRCChoices::try_from(emoji).unwrap())
|
||||
.to_string();
|
||||
let mut score_message = format!(
|
||||
"your score: {} - my score {}\n{}",
|
||||
current_game.player_score, current_game.bot_score, message
|
||||
)
|
||||
.to_string();
|
||||
if current_game.player_score == 3 {
|
||||
score_message.push_str("\n**You win!**");
|
||||
remove_message = true;
|
||||
} else if current_game.bot_score == 3 {
|
||||
score_message.push_str("\n**I win :)**");
|
||||
remove_message = true;
|
||||
}
|
||||
if let Ok(mut discord_message) = reaction.message(&mut context.http) {
|
||||
discord_message
|
||||
.edit(&context, |e| e.content(score_message))
|
||||
.ok();
|
||||
};
|
||||
reaction.delete(&context).ok();
|
||||
};
|
||||
if remove_message {
|
||||
game_store
|
||||
.lock()
|
||||
.unwrap()
|
||||
.remove(&reaction.message_id.into());
|
||||
}
|
||||
}
|
||||
#[derive(PartialEq)]
|
||||
pub enum CRCChoices {
|
||||
Cat,
|
||||
Rat,
|
||||
Cheese,
|
||||
}
|
||||
impl Distribution<CRCChoices> for Standard {
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> CRCChoices {
|
||||
match rng.gen_range(0, 3) {
|
||||
0 => CRCChoices::Cat,
|
||||
1 => CRCChoices::Rat,
|
||||
_ => CRCChoices::Cheese,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl TryFrom<&str> for CRCChoices {
|
||||
type Error = String;
|
||||
fn try_from(emoji: &str) -> Result<CRCChoices, Self::Error> {
|
||||
use CRCChoices::*;
|
||||
match emoji {
|
||||
"🐀" => Ok(Rat),
|
||||
"🐱" => Ok(Cat),
|
||||
"🧀" => Ok(Cheese),
|
||||
_ => Err("naughty emoji".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CRCGameState {
|
||||
pub player_id: u64,
|
||||
pub player_score: u8,
|
||||
pub bot_score: u8,
|
||||
}
|
||||
|
||||
impl CRCGameState {
|
||||
pub fn play(&mut self, player: CRCChoices) -> String {
|
||||
let bot = rand::random::<CRCChoices>();
|
||||
use CRCChoices::*;
|
||||
|
||||
let message_tail = if bot == player {
|
||||
"draw"
|
||||
} else if player == Rat {
|
||||
if bot == Cheese {
|
||||
self.player_score += 1;
|
||||
"your rat eats the cheese and you win!"
|
||||
} else {
|
||||
self.bot_score += 1;
|
||||
"my cat eats your rat and I win"
|
||||
}
|
||||
} else if player == Cheese {
|
||||
if bot == Rat {
|
||||
self.bot_score += 1;
|
||||
"bots rat eats the cheese and you lose"
|
||||
} else {
|
||||
self.player_score += 1;
|
||||
"my cat eats your rat and I win"
|
||||
}
|
||||
} else if player == Cat {
|
||||
if bot == Rat {
|
||||
self.player_score += 1;
|
||||
"your cat eats the rat so you win..."
|
||||
} else {
|
||||
self.bot_score += 1;
|
||||
"your cat eats the cheese but it gets poisoned and dies, I win"
|
||||
}
|
||||
} else {
|
||||
"bug report plz"
|
||||
};
|
||||
format!("bot picked {} {}", bot, message_tail)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for CRCChoices {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let string_form = match self {
|
||||
CRCChoices::Rat => "🐀",
|
||||
CRCChoices::Cat => "🐱",
|
||||
CRCChoices::Cheese => "🧀",
|
||||
};
|
||||
write!(f, "{}", string_form)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CRCGameStateStore;
|
||||
impl TypeMapKey for CRCGameStateStore {
|
||||
type Value = Arc<Mutex<HashMap<u64, CRCGameState>>>;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use serenity::{
|
||||
client::Client,
|
||||
framework::standard::{
|
||||
help_commands,
|
||||
macros::{group, help},
|
||||
Args, CommandGroup, CommandResult, HelpOptions, StandardFramework,
|
||||
},
|
||||
model::prelude::*,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use std::env;
|
||||
use std::sync::{Arc, Mutex};
|
||||
mod commands;
|
||||
use commands::{
|
||||
AVATAR_COMMAND, CAT_RAT_CHEESE_COMMAND, DOG_COMMAND, ECHO_COMMAND, EIGHTBALL_COMMAND,
|
||||
PING_COMMAND, PROFILE_COMMAND, PUG_COMMAND, SPAM_COMMAND,
|
||||
};
|
||||
mod events;
|
||||
|
||||
#[help]
|
||||
fn my_help(
|
||||
ctx: &mut Context,
|
||||
msg: &Message,
|
||||
args: Args,
|
||||
help_options: &'static HelpOptions,
|
||||
groups: &[&'static CommandGroup],
|
||||
owners: HashSet<UserId>,
|
||||
) -> CommandResult {
|
||||
help_commands::with_embeds(ctx, msg, args, &help_options, groups, owners)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("token"), events::Handler)
|
||||
.expect("Error creating client");
|
||||
client.with_framework(
|
||||
StandardFramework::new()
|
||||
.configure(|c| c.prefix("&"))
|
||||
.help(&MY_HELP)
|
||||
.group(&FUN_GROUP)
|
||||
.group(&DISCORD_GROUP)
|
||||
.group(&UTILITY_GROUP)
|
||||
.group(&DOGS_GROUP)
|
||||
.group(&RUNESCAPE_GROUP),
|
||||
);
|
||||
{
|
||||
let mut data = client.data.write();
|
||||
let crc_game: HashMap<u64, events::CRCGameState> = HashMap::new();
|
||||
data.insert::<events::CRCGameStateStore>(Arc::new(Mutex::new(crc_game)));
|
||||
}
|
||||
if let Err(why) = client.start() {
|
||||
println!("An error occurred while running the client: {:?}", why);
|
||||
}
|
||||
}
|
||||
|
||||
group!({
|
||||
name: "fun",
|
||||
options: {},
|
||||
commands: [cat_rat_cheese, echo, spam, eightball],
|
||||
});
|
||||
|
||||
group!({
|
||||
name: "discord",
|
||||
options: {},
|
||||
commands: [avatar]
|
||||
});
|
||||
|
||||
group!({
|
||||
name: "utility",
|
||||
options: {},
|
||||
commands: [ping]
|
||||
});
|
||||
|
||||
group!({
|
||||
name: "dogs",
|
||||
options: {},
|
||||
commands: [pug, dog]
|
||||
});
|
||||
|
||||
group!({
|
||||
name: "runescape",
|
||||
options: {},
|
||||
commands: [profile]
|
||||
});
|
Loading…
Reference in New Issue