Skip to content

Commit c7379e6

Browse files
committed
Add exact message length April fools channel
1 parent 5241262 commit c7379e6

4 files changed

Lines changed: 109 additions & 6 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use crate::discord_bot::april_fools_channel::{AprilFoolsChannel, AprilFoolsMessageContext};
2+
use crate::discord_bot::guild_storage::GuildStorage;
3+
use async_trait::async_trait;
4+
use serde::{Deserialize, Serialize};
5+
use serenity::all::ChannelId;
6+
use serenity::builder::CreateMessage;
7+
8+
pub(crate) struct ExactMessageLength;
9+
10+
pub(crate) static CHANNEL: ExactMessageLength = ExactMessageLength;
11+
12+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
13+
pub(crate) struct ExactMessageLengthData {
14+
pub channel: ChannelId,
15+
pub expected_length: Option<u16>,
16+
}
17+
18+
#[async_trait]
19+
impl AprilFoolsChannel for ExactMessageLength {
20+
async fn get_error(&self, context: &AprilFoolsMessageContext<'_>) -> Option<String> {
21+
let mut storage = GuildStorage::get_mut(context.guild_id).await;
22+
let Some(expected_length_data) = &mut storage.april_fools_channels.exact_message_length
23+
else {
24+
storage.discard();
25+
return None;
26+
};
27+
28+
let message_length = context.content.chars().count();
29+
let mut just_had_67 = false;
30+
31+
if let Some(expected_length) = expected_length_data.expected_length {
32+
if expected_length as usize != message_length {
33+
storage.discard();
34+
return Some(format!("Your message was the wrong length! Expected length {expected_length} but it was {message_length}."));
35+
}
36+
37+
just_had_67 = expected_length == 67;
38+
}
39+
40+
let new_length = reroll_message_length(just_had_67);
41+
expected_length_data.expected_length = Some(new_length);
42+
storage.save().await;
43+
None
44+
}
45+
46+
async fn on_success(&self, context: &AprilFoolsMessageContext<'_>) -> crate::Result<()> {
47+
let storage = GuildStorage::get_mut(context.guild_id).await;
48+
let Some(expected_length) = storage
49+
.april_fools_channels
50+
.exact_message_length
51+
.as_ref()
52+
.and_then(|exact_message_length| exact_message_length.expected_length)
53+
else {
54+
return Ok(());
55+
};
56+
context
57+
.channel_id
58+
.send_message(
59+
&context.context,
60+
CreateMessage::new()
61+
.content(format!("Now expecting message length of {expected_length}")),
62+
)
63+
.await?;
64+
Ok(())
65+
}
66+
}
67+
68+
fn reroll_message_length(just_had_67: bool) -> u16 {
69+
if !just_had_67 && rand::random::<bool>() {
70+
67
71+
} else {
72+
let length = rand::random_range(5..=99);
73+
if length >= 67 {
74+
length + 1
75+
} else {
76+
length
77+
}
78+
}
79+
}

src/discord_bot/april_fools_channel/haiku.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use crate::discord_bot::april_fools_channel::AprilFoolsChannel;
1+
use crate::discord_bot::april_fools_channel::{AprilFoolsChannel, AprilFoolsMessageContext};
22
use arpabet::phoneme::Phoneme;
33
use arpabet::{load_cmudict, Polyphone};
4+
use async_trait::async_trait;
45
use std::collections::BTreeSet;
56
use std::mem;
67

@@ -24,8 +25,10 @@ pub(crate) struct HaikuChannel;
2425

2526
pub(crate) static CHANNEL: HaikuChannel = HaikuChannel;
2627

28+
#[async_trait]
2729
impl AprilFoolsChannel for HaikuChannel {
28-
fn get_error(&self, message: &str) -> Option<String> {
30+
async fn get_error(&self, context: &AprilFoolsMessageContext<'_>) -> Option<String> {
31+
let message = context.content;
2932
if !message.is_ascii() {
3033
return Some(INVALID_CHARACTER.to_owned());
3134
}

src/discord_bot/april_fools_channel/mod.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use crate::discord_bot::april_fools_channel::exact_message_length::ExactMessageLengthData;
12
use crate::discord_bot::guild_storage::GuildStorage;
3+
use async_trait::async_trait;
24
use serde::{Deserialize, Serialize};
35
use serenity::all::{ChannelId, Context, CreateMessage, GuildId, MessageFlags, MessageId, User};
46

7+
mod exact_message_length;
58
mod haiku;
69
mod simple_words;
710

@@ -22,6 +25,8 @@ pub(crate) struct AprilFoolsChannels {
2225
pub simple_words: Option<ChannelId>,
2326
#[serde(default)]
2427
pub haiku: Option<ChannelId>,
28+
#[serde(default)]
29+
pub exact_message_length: Option<ExactMessageLengthData>,
2530
}
2631

2732
pub(crate) async fn get_april_fools_channel(
@@ -34,6 +39,12 @@ pub(crate) async fn get_april_fools_channel(
3439
Some(&simple_words::CHANNEL)
3540
} else if channels.haiku == Some(channel_id) {
3641
Some(&haiku::CHANNEL)
42+
} else if channels
43+
.exact_message_length
44+
.as_ref()
45+
.is_some_and(|exact_message_length| exact_message_length.channel == channel_id)
46+
{
47+
Some(&exact_message_length::CHANNEL)
3748
} else {
3849
None
3950
}
@@ -47,7 +58,7 @@ pub(crate) async fn on_message(
4758
let error_message = if context.has_attachments {
4859
Some(april_fools.has_attachment_message().to_owned())
4960
} else {
50-
april_fools.get_error(context.content)
61+
april_fools.get_error(&context).await
5162
};
5263
if let Some(mut error_message) = error_message {
5364
context
@@ -77,12 +88,15 @@ pub(crate) async fn on_message(
7788
.await?;
7889
}
7990
}
91+
} else {
92+
april_fools.on_success(&context).await?;
8093
}
8194
Ok(())
8295
}
8396

97+
#[async_trait]
8498
pub(crate) trait AprilFoolsChannel: Send + Sync {
85-
fn get_error(&self, message: &str) -> Option<String>;
99+
async fn get_error(&self, context: &AprilFoolsMessageContext<'_>) -> Option<String>;
86100

87101
fn your_original_message_was(&self) -> Option<&'static str> {
88102
Some("Your original message was:")
@@ -91,4 +105,8 @@ pub(crate) trait AprilFoolsChannel: Send + Sync {
91105
fn has_attachment_message(&self) -> &'static str {
92106
"Message has attachment"
93107
}
108+
109+
async fn on_success(&self, _context: &AprilFoolsMessageContext<'_>) -> crate::Result<()> {
110+
Ok(())
111+
}
94112
}

src/discord_bot/april_fools_channel/simple_words.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::discord_bot::april_fools_channel::AprilFoolsChannel;
1+
use crate::discord_bot::april_fools_channel::{AprilFoolsChannel, AprilFoolsMessageContext};
2+
use async_trait::async_trait;
23
use std::collections::HashSet;
34
use std::sync::OnceLock;
45

@@ -17,8 +18,10 @@ pub(crate) struct SimpleWordsChannel;
1718

1819
pub(crate) static CHANNEL: SimpleWordsChannel = SimpleWordsChannel;
1920

21+
#[async_trait]
2022
impl AprilFoolsChannel for SimpleWordsChannel {
21-
fn get_error(&self, message: &str) -> Option<String> {
23+
async fn get_error(&self, context: &AprilFoolsMessageContext<'_>) -> Option<String> {
24+
let message = context.content;
2225
let mut illegal_words = Vec::new();
2326
let mut current_word_start = None;
2427
let mut prev_char = None;

0 commit comments

Comments
 (0)