Skip to content

Commit 0418d0c

Browse files
authored
Drop broadcast filter list (#59)
* Added filter command, added extra check to broadcast_handler and a new field to the Guild db object * Added a get command to retrieve the current drop broadcast filter list. * Added functionality to add/get/update filters for multiple broadcast types
1 parent 5f0464e commit 0418d0c

File tree

7 files changed

+275
-2
lines changed

7 files changed

+275
-2
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use crate::database::BotMongoDb;
2+
use serenity::all::{CommandDataOption, CommandDataOptionValue, CommandOptionType, CreateCommand, CreateCommandOption};
3+
use serenity::client::Context;
4+
use serenity::model::prelude::Permissions;
5+
use trackscape_discord_shared::database::guilds_db::RegisteredGuildModel;
6+
use trackscape_discord_shared::osrs_broadcast_extractor::osrs_broadcast_extractor::BroadcastType;
7+
8+
pub fn register() -> CreateCommand {
9+
CreateCommand::new("get_custom_drop_broadcast_filter")
10+
.description("Gets the filter list being used to filter broadcasts for the selected broadcast type.")
11+
.default_member_permissions(Permissions::MANAGE_GUILD)
12+
.add_option(
13+
CreateCommandOption::new(
14+
CommandOptionType::String,
15+
"broadcast",
16+
"Broadcast type to return the filter list for.",
17+
)
18+
.add_string_choice(
19+
BroadcastType::ItemDrop.to_string(),
20+
BroadcastType::ItemDrop.to_slug())
21+
.add_string_choice(
22+
BroadcastType::RaidDrop.to_string(),
23+
BroadcastType::RaidDrop.to_slug(),
24+
)
25+
.add_string_choice(
26+
BroadcastType::PetDrop.to_string(),
27+
BroadcastType::PetDrop.to_slug(),
28+
)
29+
.add_string_choice(
30+
BroadcastType::CollectionLog.to_string(),
31+
BroadcastType::CollectionLog.to_slug(),
32+
)
33+
.add_string_choice(
34+
BroadcastType::Quest.to_string(),
35+
BroadcastType::Quest.to_slug(),
36+
)
37+
.add_string_choice(
38+
BroadcastType::Diary.to_string(),
39+
BroadcastType::Diary.to_slug(),
40+
)
41+
.add_string_choice(
42+
BroadcastType::PersonalBest.to_string(),
43+
BroadcastType::PersonalBest.to_slug(),
44+
)
45+
.required(true),
46+
)
47+
}
48+
49+
pub async fn run(
50+
_options: &[CommandDataOption],
51+
_ctx: &Context,
52+
db: &BotMongoDb,
53+
guild_id: u64,
54+
) -> Option<String> {
55+
let saved_guild_query = db.guilds.get_by_guild_id(guild_id).await;
56+
57+
match saved_guild_query {
58+
Ok(saved_guild) => {
59+
let saved_guild = saved_guild.unwrap_or(RegisteredGuildModel::new(guild_id));
60+
let broadcast_type = _options.get(0).expect("Expected a broadcast type option");
61+
return if let CommandDataOptionValue::String(broadcast_type) = broadcast_type.clone().value{
62+
let broadcast_type =
63+
BroadcastType::from_string(broadcast_type.replace("_", " "));
64+
65+
if let Some(ref filter_map) = saved_guild.custom_drop_broadcast_filter {
66+
if let Some(filter_list) = filter_map.get(&broadcast_type) {
67+
Some(format!(
68+
"The current {} filter list is: `{}`",
69+
broadcast_type.to_string(),
70+
filter_list.join(", ")
71+
))
72+
} else {
73+
Some(format!(
74+
"No filter list found for {}. Please set a new filter list.",
75+
broadcast_type.to_string()
76+
))
77+
}
78+
} else {
79+
Some("Error finding filter lists, try again later.".to_string())
80+
}
81+
} else {
82+
Some("Invalid Broadcast Type".to_string())
83+
};
84+
}
85+
Err(_) => {
86+
return Some("There was a technical error. Please try again later.".to_string(),
87+
);
88+
}
89+
90+
}
91+
}

trackscape-discord-bot/src/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ pub mod set_wom_id_command;
1515
pub mod stop_leagues_notifications;
1616
pub mod toggle_broadcasts_command;
1717
pub mod trackscape_command_trait;
18+
pub mod set_custom_drop_broadcast_filter;
19+
pub mod get_custom_drop_broadcast_filter;
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
use crate::database::BotMongoDb;
2+
use serenity::all::{
3+
CommandDataOption, CommandDataOptionValue, CommandOptionType, CreateCommand,
4+
CreateCommandOption,
5+
};
6+
use serenity::client::Context;
7+
use serenity::model::prelude::Permissions;
8+
use trackscape_discord_shared::database::guilds_db::RegisteredGuildModel;
9+
use trackscape_discord_shared::osrs_broadcast_extractor::osrs_broadcast_extractor::BroadcastType;
10+
11+
pub fn register() -> CreateCommand {
12+
CreateCommand::new("set_custom_drop_broadcast_filter")
13+
.description("Sets a list of filter words to use with the selected broadcast type.")
14+
.default_member_permissions(Permissions::MANAGE_GUILD)
15+
.add_option(
16+
CreateCommandOption::new(
17+
CommandOptionType::String,
18+
"broadcast",
19+
"Broadcast type to set a filter list for.",
20+
)
21+
.add_string_choice(
22+
BroadcastType::ItemDrop.to_string(),
23+
BroadcastType::ItemDrop.to_slug(),
24+
)
25+
.add_string_choice(
26+
BroadcastType::RaidDrop.to_string(),
27+
BroadcastType::RaidDrop.to_slug(),
28+
)
29+
.add_string_choice(
30+
BroadcastType::PetDrop.to_string(),
31+
BroadcastType::PetDrop.to_slug(),
32+
)
33+
.add_string_choice(
34+
BroadcastType::CollectionLog.to_string(),
35+
BroadcastType::CollectionLog.to_slug(),
36+
)
37+
.add_string_choice(
38+
BroadcastType::Quest.to_string(),
39+
BroadcastType::Quest.to_slug(),
40+
)
41+
.add_string_choice(
42+
BroadcastType::Diary.to_string(),
43+
BroadcastType::Diary.to_slug(),
44+
)
45+
.add_string_choice(
46+
BroadcastType::PersonalBest.to_string(),
47+
BroadcastType::PersonalBest.to_slug(),
48+
)
49+
.required(true),
50+
)
51+
.add_option(
52+
CreateCommandOption::new(
53+
CommandOptionType::String,
54+
"filter",
55+
"Enter a comma-separated list to filter broadcasts with",
56+
)
57+
.required(true),
58+
)
59+
}
60+
61+
pub async fn run(
62+
command: &Vec<CommandDataOption>,
63+
_ctx: &Context,
64+
db: &BotMongoDb,
65+
guild_id: u64,
66+
) -> Option<String> {
67+
let saved_guild_query = db.guilds.get_by_guild_id(guild_id).await;
68+
match saved_guild_query {
69+
Ok(saved_guild) => {
70+
let mut saved_guild = saved_guild.unwrap_or(RegisteredGuildModel::new(guild_id));
71+
let broadcast_type = command.get(0).expect("Expected a broadcast type option");
72+
73+
let filter = command
74+
.get(1)
75+
.expect("Expected a comma-separated list of values");
76+
77+
return if let CommandDataOptionValue::String(broadcast_type) =
78+
broadcast_type.clone().value
79+
{
80+
if let CommandDataOptionValue::String(filter) = filter.clone().value {
81+
let broadcast_type =
82+
BroadcastType::from_string(broadcast_type.replace("_", " "));
83+
84+
let filter_list: Vec<String> =
85+
filter.split(',').map(|s| s.trim().to_string()).collect();
86+
if let Some(ref mut filter_map) = saved_guild.custom_drop_broadcast_filter {
87+
filter_map.insert(broadcast_type, filter_list.clone());
88+
} else {
89+
let mut new_filter_map = std::collections::HashMap::new();
90+
new_filter_map.insert(broadcast_type, filter_list.clone());
91+
saved_guild.custom_drop_broadcast_filter = Some(new_filter_map);
92+
}
93+
db.guilds.update_guild(saved_guild).await;
94+
None
95+
} else {
96+
Some("Invalid filter.".to_string())
97+
}
98+
} else {
99+
Some("Invalid broadcast type.".to_string())
100+
};
101+
}
102+
Err(_) => {
103+
return Some(
104+
"No saved guild was found. Please try adding and removing the bot".to_string(),
105+
);
106+
}
107+
}
108+
}

trackscape-discord-bot/src/main.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,24 @@ impl EventHandler for Bot {
316316
)
317317
.await
318318
}
319+
"set_custom_drop_broadcast_filter" => {
320+
commands::set_custom_drop_broadcast_filter::run(
321+
&command.data.options,
322+
&ctx,
323+
&self.mongo_db,
324+
command.guild_id.unwrap().get(),
325+
)
326+
.await
327+
}
328+
"get_custom_drop_broadcast_filter" => {
329+
commands::get_custom_drop_broadcast_filter::run(
330+
&command.data.options,
331+
&ctx,
332+
&self.mongo_db,
333+
command.guild_id.unwrap().get(),
334+
)
335+
.await
336+
}
319337
_ => {
320338
info!("not implemented :(");
321339
None
@@ -359,6 +377,8 @@ fn get_commands() -> Vec<CreateCommand> {
359377
commands.push(commands::set_leagues_broadcast_channel::register());
360378
commands.push(commands::stop_leagues_notifications::register());
361379
commands.push(commands::reset_verification_code::register());
380+
commands.push(commands::set_custom_drop_broadcast_filter::register());
381+
commands.push(commands::get_custom_drop_broadcast_filter::register());
362382
commands
363383
}
364384
pub async fn create_commands_for_guild(guild_id: &GuildId, ctx: Context) {

trackscape-discord-shared/src/database/guilds_db.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub struct RegisteredGuildModel {
3434
pub pk_value_threshold: Option<i64>,
3535
pub wom_id: Option<i64>,
3636
pub created_at: Option<DateTime>,
37+
pub custom_drop_broadcast_filter: Option<std::collections::HashMap<BroadcastType, Vec<String>>>,
3738
}
3839

3940
impl RegisteredGuildModel {
@@ -57,6 +58,7 @@ impl RegisteredGuildModel {
5758
pk_value_threshold: None,
5859
wom_id: None,
5960
created_at: DateTime::now().into(),
61+
custom_drop_broadcast_filter: Some(std::collections::HashMap::new()),
6062
}
6163
}
6264

trackscape-discord-shared/src/osrs_broadcast_extractor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ pub mod osrs_broadcast_extractor {
300300
}
301301
}
302302

303-
#[derive(PartialEq, Deserialize, Serialize, Debug, Clone)]
303+
#[derive(PartialEq, Deserialize, Serialize, Debug, Clone, Eq, Hash)]
304304
pub enum BroadcastType {
305305
ItemDrop,
306306
PetDrop,

trackscape-discord-shared/src/osrs_broadcast_handler.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
143143
false => ":tada: New raid drop!".to_string(),
144144
};
145145

146+
if self.check_if_filtered_broad_cast(BroadcastType::RaidDrop,drop_item.player_it_happened_to.clone(), drop_item.item_name.clone()) {
147+
return None;
148+
}
149+
146150
Some(BroadcastMessageToDiscord {
147151
player_it_happened_to: drop_item.player_it_happened_to.clone(),
148152
type_of_broadcast: BroadcastType::RaidDrop,
@@ -200,6 +204,10 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
200204
false => ":tada: New Pet drop!".to_string(),
201205
};
202206

207+
if self.check_if_filtered_broad_cast(BroadcastType::PetDrop, pet_drop.player_it_happened_to.clone(),pet_drop.pet_name.clone()) {
208+
return None;
209+
}
210+
203211
Some(BroadcastMessageToDiscord {
204212
type_of_broadcast: BroadcastType::PetDrop,
205213
player_it_happened_to: pet_drop.player_it_happened_to,
@@ -549,6 +557,10 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
549557
false => ":tada: New High Value drop!".to_string(),
550558
};
551559

560+
if self.check_if_filtered_broad_cast(BroadcastType::ItemDrop, drop_item.player_it_happened_to.clone(),drop_item.item_name.clone()) {
561+
return None;
562+
}
563+
552564
Some(BroadcastMessageToDiscord {
553565
player_it_happened_to: drop_item.player_it_happened_to.clone(),
554566
type_of_broadcast: BroadcastType::ItemDrop,
@@ -668,7 +680,7 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
668680
&& possible_quests.is_some()
669681
&& self.quests.is_some()
670682
{
671-
let quest_name = exported_data.quest_name;
683+
let quest_name = exported_data.quest_name.clone();
672684

673685
let quests = &possible_quests.unwrap();
674686
let possible_difficulty = quests.iter().find(|&x| x.name == quest_name);
@@ -687,6 +699,11 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
687699
true => ":bar_chart: New Leagues quest completed!".to_string(),
688700
false => ":tada: New quest completed!".to_string(),
689701
};
702+
703+
if self.check_if_filtered_broad_cast(BroadcastType::Quest, exported_data.player_it_happened_to.clone(),exported_data.quest_name.clone()) {
704+
return None;
705+
}
706+
690707
Some(BroadcastMessageToDiscord {
691708
type_of_broadcast: BroadcastType::Quest,
692709
player_it_happened_to: exported_data.player_it_happened_to,
@@ -735,6 +752,9 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
735752
true => ":bar_chart: New Leagues diary completed!".to_string(),
736753
false => ":tada: New diary completed!".to_string(),
737754
};
755+
if self.check_if_filtered_broad_cast(BroadcastType::Diary, exported_data.player_it_happened_to.clone(),exported_data.diary_name.clone() + " " + exported_data.diary_tier.to_string().as_str()) {
756+
return None;
757+
}
738758
Some(BroadcastMessageToDiscord {
739759
type_of_broadcast: BroadcastType::Diary,
740760
player_it_happened_to: exported_data.player_it_happened_to,
@@ -794,6 +814,10 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
794814
true => ":bar_chart: New Leagues collection log item!".to_string(),
795815
false => ":tada: New collection log item!".to_string(),
796816
};
817+
818+
if self.check_if_filtered_broad_cast(BroadcastType::CollectionLog,collection_log_broadcast.player_it_happened_to.clone(), collection_log_broadcast.item_name.clone()) {
819+
return None;
820+
}
797821
Some(BroadcastMessageToDiscord {
798822
type_of_broadcast: BroadcastType::CollectionLog,
799823
player_it_happened_to: collection_log_broadcast.player_it_happened_to,
@@ -834,6 +858,10 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
834858
let job = record_new_pb::new(exported_data.clone(), self.registered_guild.guild_id);
835859
let _ = self.job_queue.send_task(job).await;
836860

861+
if self.check_if_filtered_broad_cast(BroadcastType::PersonalBest, exported_data.player.clone(), exported_data.activity.clone()) {
862+
return None;
863+
}
864+
837865
Some(BroadcastMessageToDiscord {
838866
type_of_broadcast: BroadcastType::PersonalBest,
839867
player_it_happened_to: exported_data.player,
@@ -976,6 +1004,28 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
9761004
}
9771005
false
9781006
}
1007+
1008+
fn check_if_filtered_broad_cast(&self, broadcast_type: BroadcastType, broadcast_player: String, broadcast_element: String) -> bool {
1009+
if let Some(ref filter_map) = self.registered_guild.custom_drop_broadcast_filter {
1010+
if let Some(filter_list) = filter_map.get(&broadcast_type) {
1011+
let broadcast_element_lower = broadcast_element.to_lowercase();
1012+
for filter in filter_list {
1013+
if broadcast_element_lower.contains(&filter.to_lowercase()) {
1014+
println!(
1015+
"Filtered out {} broadcast: Player={}, Raid Item={}",
1016+
broadcast_type.to_string(),
1017+
broadcast_player.clone(),
1018+
broadcast_element.clone()
1019+
);
1020+
return true;
1021+
}
1022+
}
1023+
} else {
1024+
return false;
1025+
}
1026+
}
1027+
false
1028+
}
9791029
}
9801030

9811031
#[cfg(test)]

0 commit comments

Comments
 (0)