diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml new file mode 100644 index 0000000..423e168 --- /dev/null +++ b/.github/workflows/checks.yml @@ -0,0 +1,44 @@ +# Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md + +on: [push, pull_request] + +name: PushCheck + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Run cargo check + uses: actions-rs/cargo@v1 + with: + command: check + + test: + name: Test Suite + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Run cargo test + uses: actions-rs/cargo@v1 + with: + command: test \ No newline at end of file diff --git a/trackscape-discord-api/src/services/osrs_broadcast_handler.rs b/trackscape-discord-api/src/services/osrs_broadcast_handler.rs index 24451eb..0ea49fa 100644 --- a/trackscape-discord-api/src/services/osrs_broadcast_handler.rs +++ b/trackscape-discord-api/src/services/osrs_broadcast_handler.rs @@ -1,12 +1,13 @@ -use log::error; +use log::{error, info}; use num_format::{Locale, ToFormattedString}; use trackscape_discord_shared::database::{DropLogs, RegisteredGuildModel}; use trackscape_discord_shared::ge_api::ge_api::{get_item_value_by_id, GeItemMapping}; use trackscape_discord_shared::osrs_broadcast_extractor::osrs_broadcast_extractor::{ - diary_completed_broadcast_extractor, drop_broadcast_extractor, get_broadcast_type, - invite_broadcast_extractor, levelmilestone_broadcast_extractor, pet_broadcast_extractor, - pk_broadcast_extractor, quest_completed_broadcast_extractor, raid_broadcast_extractor, - xpmilestone_broadcast_extractor, BroadcastType, ClanMessage, + collection_log_broadcast_extractor, diary_completed_broadcast_extractor, + drop_broadcast_extractor, get_broadcast_type, invite_broadcast_extractor, + levelmilestone_broadcast_extractor, pet_broadcast_extractor, pk_broadcast_extractor, + quest_completed_broadcast_extractor, raid_broadcast_extractor, xpmilestone_broadcast_extractor, + BroadcastType, ClanMessage, }; use trackscape_discord_shared::wiki_api::wiki_api::WikiQuest; @@ -280,6 +281,7 @@ impl OSRSBroadcastHandler { } } } + BroadcastType::CollectionLog => self.collection_log_handler(), _ => None, } } @@ -509,6 +511,51 @@ impl OSRSBroadcastHandler { } } } + + fn check_if_allowed_broad_cast(&self, broadcast_type: BroadcastType) -> bool { + let is_disallowed = self + .registered_guild + .disallowed_broadcast_types + .iter() + .find(|&x| { + if broadcast_type.to_string() == x.to_string() { + return true; + } + false + }); + if is_disallowed.is_some() { + return true; + } + false + } + + fn collection_log_handler(&self) -> Option { + let possible_collection_log = + collection_log_broadcast_extractor(self.clan_message.message.clone()); + match possible_collection_log { + None => { + error!( + "Failed to extract collection log info from message: {}", + self.clan_message.message.clone() + ); + None + } + Some(collection_log_broadcast) => { + let is_disallowed = self.check_if_allowed_broad_cast(BroadcastType::CollectionLog); + if is_disallowed { + return None; + } + Some(BroadcastMessageToDiscord { + type_of_broadcast: BroadcastType::CollectionLog, + player_it_happened_to: collection_log_broadcast.player_it_happened_to, + message: self.clan_message.message.clone(), + icon_url: collection_log_broadcast.item_icon, + title: ":tada: New collection log item!".to_string(), + item_quantity: None, + }) + } + } + } } #[cfg(test)] @@ -530,6 +577,7 @@ mod tests { clan_name: "Insomniacs".to_string(), rank: "Recruit".to_string(), icon_id: None, + is_league_world: None, }; let mut registered_guild = RegisteredGuildModel::new(123); @@ -584,6 +632,7 @@ mod tests { clan_name: "Insomniacs".to_string(), rank: "Recruit".to_string(), icon_id: None, + is_league_world: None, }; let mut registered_guild = RegisteredGuildModel::new(123); @@ -637,6 +686,7 @@ mod tests { clan_name: "Insomniacs".to_string(), rank: "Recruit".to_string(), icon_id: None, + is_league_world: None, }; let mut registered_guild = RegisteredGuildModel::new(123); @@ -690,6 +740,7 @@ mod tests { clan_name: "Insomniacs".to_string(), rank: "Recruit".to_string(), icon_id: None, + is_league_world: None, }; let mut registered_guild = RegisteredGuildModel::new(123); @@ -744,6 +795,7 @@ mod tests { clan_name: "Insomniacs".to_string(), rank: "Recruit".to_string(), icon_id: None, + is_league_world: None, }; let mut registered_guild = RegisteredGuildModel::new(123); @@ -795,6 +847,7 @@ mod tests { clan_name: "Insomniacs".to_string(), rank: "Recruit".to_string(), icon_id: None, + is_league_world: None, }; let mut registered_guild = RegisteredGuildModel::new(123); @@ -845,6 +898,7 @@ mod tests { clan_name: "Insomniacs".to_string(), rank: "Recruit".to_string(), icon_id: None, + is_league_world: None, }; let mut registered_guild = RegisteredGuildModel::new(123); diff --git a/trackscape-discord-bot/src/commands/toggle_broadcasts.rs b/trackscape-discord-bot/src/commands/toggle_broadcasts.rs index 1388a82..068512b 100644 --- a/trackscape-discord-bot/src/commands/toggle_broadcasts.rs +++ b/trackscape-discord-bot/src/commands/toggle_broadcasts.rs @@ -50,6 +50,10 @@ pub fn register( BroadcastType::XPMilestone.to_string(), BroadcastType::XPMilestone.to_slug(), ) + .add_string_choice( + BroadcastType::CollectionLog.to_string(), + BroadcastType::CollectionLog.to_slug(), + ) .required(true) }) .create_option(|option| { diff --git a/trackscape-discord-shared/src/osrs_broadcast_extractor.rs b/trackscape-discord-shared/src/osrs_broadcast_extractor.rs index 9599f6e..fa8ef1e 100644 --- a/trackscape-discord-shared/src/osrs_broadcast_extractor.rs +++ b/trackscape-discord-shared/src/osrs_broadcast_extractor.rs @@ -210,6 +210,13 @@ pub mod osrs_broadcast_extractor { pub value: i64, } + pub struct CollectionLogBroadcast { + pub player_it_happened_to: String, + pub item_name: String, + pub log_slots: i64, + pub item_icon: Option, + } + #[derive(PartialEq, Deserialize, Serialize, Debug, Clone)] pub enum BroadcastType { ItemDrop, @@ -222,6 +229,7 @@ pub mod osrs_broadcast_extractor { LootKey, XPMilestone, LevelMilestone, + CollectionLog, Unknown, } @@ -238,6 +246,7 @@ pub mod osrs_broadcast_extractor { BroadcastType::LootKey => "Loot Key".to_string(), BroadcastType::XPMilestone => "XP Milestone".to_string(), BroadcastType::LevelMilestone => "Level Milestone".to_string(), + BroadcastType::CollectionLog => "Collection Log".to_string(), BroadcastType::Unknown => "Unknown".to_string(), } } @@ -254,6 +263,7 @@ pub mod osrs_broadcast_extractor { "Loot Key" => BroadcastType::LootKey, "XP Milestone" => BroadcastType::XPMilestone, "Level Milestone" => BroadcastType::LevelMilestone, + "Collection Log" => BroadcastType::CollectionLog, _ => BroadcastType::Unknown, } } @@ -463,6 +473,24 @@ pub mod osrs_broadcast_extractor { }; } + pub fn collection_log_broadcast_extractor(message: String) -> Option { + let re = regex::Regex::new(r"^(?P[\w\s]+) received a new collection log item: (?P.+?) \((?P\d+)/1477\)").unwrap(); + + if let Some(captures) = re.captures(message.as_str()) { + let name = captures.name("name").unwrap().as_str(); + let item = captures.name("item").unwrap().as_str(); + let number = captures.name("number").unwrap().as_str(); + + return Some(CollectionLogBroadcast { + player_it_happened_to: name.to_string(), + item_name: item.to_string(), + log_slots: number.parse().unwrap(), + item_icon: Some(get_wiki_image_url(item.to_string())), + }); + } + None + } + pub fn get_broadcast_type(message_content: String) -> BroadcastType { if message_content.contains("received a drop:") { return BroadcastType::ItemDrop; @@ -494,6 +522,11 @@ pub mod osrs_broadcast_extractor { if message_content.contains("has reached") && message_content.contains("XP in") { return BroadcastType::XPMilestone; } + + if message_content.contains("received a new collection log item:") { + return BroadcastType::CollectionLog; + } + return BroadcastType::Unknown; } @@ -544,9 +577,9 @@ pub mod osrs_broadcast_extractor { mod tests { use super::*; use crate::osrs_broadcast_extractor::osrs_broadcast_extractor::{ - get_wiki_clan_rank_image_url, DiaryCompletedBroadcast, DiaryTier, InviteBroadcast, - LevelMilestoneBroadcast, PetDropBroadcast, PkBroadcast, QuestCompletedBroadcast, - XPMilestoneBroadcast, + get_wiki_clan_rank_image_url, CollectionLogBroadcast, DiaryCompletedBroadcast, DiaryTier, + InviteBroadcast, LevelMilestoneBroadcast, PetDropBroadcast, PkBroadcast, + QuestCompletedBroadcast, XPMilestoneBroadcast, }; use tracing::info; @@ -673,6 +706,19 @@ mod tests { } } + #[test] + fn test_get_collection_log_type_broadcast() { + let test_collection_logs = get_collection_log_messages(); + for test_collection_log in test_collection_logs { + let broadcast_type = + osrs_broadcast_extractor::get_broadcast_type(test_collection_log.message); + assert!(matches!( + broadcast_type, + osrs_broadcast_extractor::BroadcastType::CollectionLog + )); + } + } + #[test] fn test_raid_extractor() { let possible_raid_broadcasts = get_raid_messages(); @@ -1003,6 +1049,30 @@ mod tests { } } + #[test] + fn test_collection_log_extractor() { + let test_collections = get_collection_log_messages(); + for test_collection in test_collections { + let possible_collection_extract = + osrs_broadcast_extractor::collection_log_broadcast_extractor( + test_collection.message.clone(), + ); + let collection_extract = possible_collection_extract.unwrap(); + assert_eq!( + collection_extract.log_slots, + test_collection.broadcast.log_slots + ); + assert_eq!( + collection_extract.player_it_happened_to, + test_collection.broadcast.player_it_happened_to + ); + assert_eq!( + collection_extract.item_name, + test_collection.broadcast.item_name + ); + } + } + #[test] fn test_rank_is_proper_wiki_image() { let rank = "Deputy Owner"; @@ -1062,6 +1132,11 @@ mod tests { xpmilestone_broadcast: XPMilestoneBroadcast, } + struct TestBroadcast { + message: String, + broadcast: T, + } + fn get_raid_messages() -> Vec { let mut possible_raid_broadcasts: Vec = Vec::new(); possible_raid_broadcasts.push(ItemMessageTest { @@ -1592,4 +1667,49 @@ mod tests { possible_xpmilestone_broadcasts } + + fn get_collection_log_messages() -> Vec> { + let mut test_collection_messages: Vec> = Vec::new(); + test_collection_messages.push(TestBroadcast { + message: "KANlEL OUTIS received a new collection log item: Elite void robe (170/1477)" + .to_string(), + broadcast: CollectionLogBroadcast { + player_it_happened_to: "KANlEL OUTIS".to_string(), + item_name: "Elite void robe".to_string(), + log_slots: 170, + item_icon: Some( + "https://oldschool.runescape.wiki/images/Elite_void_robe_detail.png" + .to_string(), + ), + }, + }); + + test_collection_messages.push(TestBroadcast { + message: "S mf received a new collection log item: Charged ice (161/1477)".to_string(), + broadcast: CollectionLogBroadcast { + player_it_happened_to: "S mf".to_string(), + item_name: "Charged ice".to_string(), + log_slots: 161, + item_icon: Some( + "https://oldschool.runescape.wiki/images/Charged_ice_detail.png".to_string(), + ), + }, + }); + + test_collection_messages.push(TestBroadcast { + message: + "Sad Bug received a new collection log item: Adamant platebody (h1) (895/1477)" + .to_string(), + broadcast: CollectionLogBroadcast { + player_it_happened_to: "Sad Bug".to_string(), + item_name: "Adamant platebody (h1)".to_string(), + log_slots: 895, + item_icon: Some( + "https://oldschool.runescape.wiki/images/Adamant_platebody_(h1)_detail.png" + .to_string(), + ), + }, + }); + test_collection_messages + } }