Skip to content

Commit f7f1a9c

Browse files
committed
[commands] util: steal
1 parent 160c2cf commit f7f1a9c

File tree

5 files changed

+77
-3
lines changed

5 files changed

+77
-3
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ tokio = "0.2"
2323
base64 = "0.12"
2424
chrono = "0.4"
2525
futures-util = "0.3"
26+
http = "0.2"
2627
image = "0.23"
2728
isahc = "0.9"
2829
lazy_static = { version = "1.4", default-features = false }
2930
rand = "0.7"
3031
rarity-permission-calculator = { branch = "main", default-features = false, git = "https://github.com/rarity-rs/permission-calculator" }
32+
regex = "1.3"
3133
serde = "1.0"
3234
serde_json = "1.0"
3335
shellwords = { version = "1.1", default-features = false }

help.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
`owo`: What's this?
1414
`ping`: Pong!
1515
`shuffle`: Shuffle a list of things. Use quotes around "two or more words".
16+
`steal <emoji> [<name>]`: Steal a custom emoji from another server. Optionally provide a new name. Also accepts an image link.
1617

1718
**Information**
1819
Prefix: `katze`

src/commands/util.rs

+71-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1-
use std::fmt::Write;
1+
use std::{convert::TryFrom, fmt::Write};
22

3-
use anyhow::Result;
3+
use anyhow::{anyhow, Result};
44
use chrono::DateTime;
5+
use futures_util::io::AsyncReadExt;
6+
use http::uri::Uri;
7+
use lazy_static::lazy_static;
58
use rand::seq::SliceRandom;
9+
use regex::Regex;
10+
use twilight::model::channel::ReactionType;
611

7-
use crate::model::{MessageContext, Response};
12+
use crate::model::{MessageContext, Response, ResponseReaction};
813

914
const HELP_TEXT: &str = include_str!("../../help.txt");
1015

16+
lazy_static! {
17+
static ref EMOJI: Regex = Regex::new("<:([[:word:]]+):([[:digit:]]+)>").unwrap();
18+
}
19+
1120
pub async fn avatar(context: &mut MessageContext) -> Result<Response> {
1221
let found_user = context.find_member().await?;
1322

@@ -79,3 +88,62 @@ pub async fn shuffle(context: &mut MessageContext) -> Result<Response> {
7988
let reply = context.reply(content).await?;
8089
Ok(Response::Message(reply))
8190
}
91+
92+
pub async fn steal(context: &mut MessageContext) -> Result<Response> {
93+
if let Some(emoji) = context.next() {
94+
// create variables that hold the chain of information priority
95+
let mut uri: Option<Uri> = Uri::try_from(&emoji).ok();
96+
let mut name: Option<String> = None;
97+
98+
// set the uri and name from a custom emoji match
99+
if uri.is_none() {
100+
let caps = EMOJI.captures(&emoji).ok_or_else(|| anyhow!("No match."))?;
101+
let formatted = format!(
102+
"https://cdn.discordapp.com/emojis/{}.png?v=1",
103+
caps.get(2).ok_or_else(|| anyhow!("no match 2"))?.as_str()
104+
);
105+
106+
uri = Uri::try_from(formatted).ok();
107+
name = caps.get(1).map(|m| String::from(m.as_str()));
108+
}
109+
110+
// override the name if there is another argument
111+
if let Some(arg_name) = context.next() {
112+
name = Some(arg_name);
113+
}
114+
115+
// default the name to emoji if none
116+
if name.is_none() {
117+
name = Some("emoji".into());
118+
}
119+
120+
// upload the emoji if everything checks out
121+
if uri.is_some() && name.is_some() {
122+
let mut resp = isahc::get_async(uri.unwrap()).await?;
123+
let mut buffer: Vec<u8> = Vec::new();
124+
resp.body_mut().read_to_end(&mut buffer).await?;
125+
126+
let emoji = context
127+
.http
128+
.create_emoji(
129+
context.message.guild_id.unwrap(),
130+
name.unwrap(),
131+
format!("data:image/png;base64,{}", base64::encode(buffer)),
132+
)
133+
.await?;
134+
135+
context.react(ResponseReaction::Success.value()).await?;
136+
context
137+
.react(ReactionType::Custom {
138+
animated: emoji.animated,
139+
id: emoji.id,
140+
name: Some(emoji.name),
141+
})
142+
.await?;
143+
return Ok(Response::Reaction);
144+
}
145+
}
146+
147+
let reply = context.reply("USAGE: katze steal <emoji> [<name>]").await?;
148+
Ok(Response::Message(reply))
149+
}

src/handler/message.rs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub async fn handle(mut context: MessageContext) -> Result<()> {
3535
}
3636
"show" => commands::rotate::show(&mut context).await,
3737
"shuffle" => commands::util::shuffle(&mut context).await,
38+
"steal" => commands::util::steal(&mut context).await,
3839
_ => Ok(Response::None),
3940
};
4041

0 commit comments

Comments
 (0)