Skip to content

Commit 9135909

Browse files
authored
Leagues support (#51)
* Completely opt in support via the new command `/set_leagues_channel`. You should not get any Leagues broadcasts unless you have this set. This can be the same channel as your broadcast one * On launch, we support Area Unlocks, Combat Masteries, and Relic announcements. The league's rank will be added later. You can also toggle each of these using the `/toggle` command * Normal broadcasts on leagues world like drop logs will happen if you set `/set_leagues_channel` but be prefix letting you know it was a leagues drop. These will also follow the standard broadcast rules you have set. * If there is enough interest, I will go back and personalize the messages and allow blocks for league tiers. Things like 1st area unlock.
1 parent 52df9de commit 9135909

File tree

7 files changed

+283
-22
lines changed

7 files changed

+283
-22
lines changed

justfile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#Just file to build and release the docker image for production
2+
3+
#Image names
4+
shuttle := "trackscape"
5+
worker := "trackscape-worker"
6+
cronWorker := "trackscape-cron-worker"
7+
dockerRepo := "fatfingers23"
8+
tag := "latest"
9+
10+
#Build and release
11+
newRelease:
12+
#Shuttle
13+
docker build --platform linux/amd64 -t {{shuttle}} -f dockerfiles/Shuttle.Dockerfile .
14+
docker tag {{shuttle}}:{{tag}} {{dockerRepo}}/{{shuttle}}:{{tag}}
15+
docker push {{dockerRepo}}/{{shuttle}}:{{tag}}
16+
17+
#Worker
18+
docker build --platform linux/amd64 -t {{worker}} -f dockerfiles/Worker.Dockerfile .
19+
docker tag {{worker}}:{{tag}} {{dockerRepo}}/{{worker}}:{{tag}}
20+
docker push {{dockerRepo}}/{{worker}}:{{tag}}
21+
22+
#Cron Worker
23+
docker build --platform linux/amd64 -t {{cronWorker}} -f dockerfiles/CronWorker.Dockerfile .
24+
docker tag {{cronWorker}}:{{tag}} {{dockerRepo}}/{{cronWorker}}:{{tag}}
25+
docker push {{dockerRepo}}/{{cronWorker}}:{{tag}}

trackscape-discord-api/src/controllers/chat_controller.rs

+34-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{handler, ChatServerHandle};
33
use actix_web::web::Data;
44
use actix_web::{error, post, web, Error, HttpRequest, HttpResponse, Scope};
55
use celery::Celery;
6-
use log::{error, info};
6+
use log::error;
77
use serenity::all::{ChannelId, CreateEmbed, CreateEmbedAuthor};
88
use serenity::builder::CreateMessage;
99
use serenity::http::Http;
@@ -120,7 +120,7 @@ async fn new_clan_chats(
120120

121121
if chat.is_league_world.is_some() {
122122
if chat.is_league_world.unwrap() {
123-
info!("Broadcast from League World")
123+
// info!("Broadcast from League World")
124124
}
125125
}
126126
//Checks to make sure the message has not already been process since multiple people could be submitting them
@@ -148,7 +148,8 @@ async fn new_clan_chats(
148148
}
149149

150150
if registered_guild.clan_name.clone().unwrap() != chat.clan_name {
151-
error!("Clan name does not match the clan name saved in the database");
151+
//TODO may remove. it happens a lot assuming from ppl moving clans
152+
// error!("Clan name does not match the clan name saved in the database");
152153
continue;
153154
}
154155

@@ -242,7 +243,36 @@ async fn new_clan_chats(
242243
let possible_broadcast = handler.extract_message().await;
243244

244245
match possible_broadcast {
245-
None => {}
246+
None => {
247+
if league_world {
248+
let possible_leagues_message = handler.extract_leagues_message().await;
249+
if let Some(leagues_message) = possible_leagues_message {
250+
let mut broadcast_embed = CreateEmbed::new()
251+
.title(leagues_message.title.clone())
252+
.description(leagues_message.message.clone())
253+
.color(0x0000FF)
254+
.timestamp(right_now);
255+
match leagues_message.icon_url {
256+
None => {}
257+
Some(icon_url) => {
258+
broadcast_embed = broadcast_embed.image(icon_url);
259+
}
260+
}
261+
let broadcast_message = CreateMessage::new().embed(broadcast_embed);
262+
//Only send if theres a leagues channel
263+
if let Some(channel_to_send_broadcast) =
264+
registered_guild.leagues_broadcast_channel
265+
{
266+
let new_broad_cast = ChannelId::new(channel_to_send_broadcast)
267+
.send_message(&*discord_http_client, broadcast_message)
268+
.await;
269+
if let Err(e) = new_broad_cast {
270+
error!("Error sending broadcast: {:?}", e);
271+
}
272+
}
273+
}
274+
}
275+
}
246276
Some(broadcast) => {
247277
let _ = mongodb
248278
.broadcasts

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

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
use log::error;
12
use serenity::all::{
23
CommandDataOption, CommandDataOptionValue, CommandOptionType, CreateCommandOption,
34
};
45
use serenity::builder::{CreateCommand, CreateMessage};
56
use serenity::client::Context;
67
use serenity::model::channel::ChannelType;
78
use serenity::model::prelude::Permissions;
8-
use std::any::Any;
99
use tracing::info;
1010
use trackscape_discord_shared::database::BotMongoDb;
1111

12-
pub fn _register() -> CreateCommand {
12+
pub fn register() -> CreateCommand {
1313
CreateCommand::new("set_leagues_channel")
1414
.description("Sets a channel to receive league broadcasts. This is off by default")
1515
.default_member_permissions(Permissions::MANAGE_GUILD)
@@ -32,10 +32,21 @@ pub async fn run(
3232
let option = options.get(0).expect("Expected Channel Id option");
3333

3434
if let CommandDataOptionValue::Channel(channel) = option.value {
35-
if channel.type_id() != ChannelType::Text.type_id() {
35+
let possible_actual_channel = channel.to_channel(&ctx).await;
36+
if possible_actual_channel.is_err() {
37+
error!("Error getting channel: {:?}", possible_actual_channel.err());
38+
return Some("Error getting channel".to_string());
39+
}
40+
let guild_channel = possible_actual_channel
41+
.expect("Expected channel")
42+
.guild()
43+
.expect("Expected guild channel");
44+
45+
if guild_channel.kind != ChannelType::Text {
46+
error!("Please select a text channel.");
3647
return Some("Please select a text channel.".to_string());
3748
}
38-
info!("Channel: {:?}", channel);
49+
3950
let saved_guild_query = db.guilds.get_by_guild_id(guild_id).await;
4051

4152
return match saved_guild_query {

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

+24-5
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,32 @@ pub fn register() -> CreateCommand {
8585
BroadcastType::PersonalBest.to_string(),
8686
BroadcastType::PersonalBest.to_slug(),
8787
)
88+
.add_string_choice(
89+
BroadcastType::AreaUnlock.to_string(),
90+
BroadcastType::AreaUnlock.to_slug(),
91+
)
92+
.add_string_choice(
93+
BroadcastType::LeaguesRank.to_string(),
94+
BroadcastType::LeaguesRank.to_slug(),
95+
)
96+
.add_string_choice(
97+
BroadcastType::CombatMasteries.to_string(),
98+
BroadcastType::CombatMasteries.to_slug(),
99+
)
100+
.add_string_choice(
101+
BroadcastType::RelicTier.to_string(),
102+
BroadcastType::RelicTier.to_slug(),
103+
)
104+
.required(true),
105+
)
106+
.add_option(
107+
CreateCommandOption::new(
108+
CommandOptionType::Boolean,
109+
"toggle",
110+
"Turns on(true) or off(false) the broadcast type.",
111+
)
88112
.required(true),
89113
)
90-
.add_option(CreateCommandOption::new(
91-
CommandOptionType::Boolean,
92-
"toggle",
93-
"Turns on(true) or off(false) the broadcast type.",
94-
))
95114
}
96115

97116
pub async fn run(

trackscape-discord-bot/src/main.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,7 @@ fn get_commands() -> Vec<CreateCommand> {
338338
commands.push(commands::expel_clanmate_command::register());
339339
commands.push(commands::name_change_command::register());
340340
commands.push(commands::manually_run_wom_sync_command::register());
341-
//leagues didnt have any braodcasts this time around and over now
342-
// commands.push(commands::set_leagues_broadcast_channel::register());
341+
commands.push(commands::set_leagues_broadcast_channel::register());
343342
commands
344343
}
345344
pub async fn create_commands_for_guild(guild_id: &GuildId, ctx: Context) {

trackscape-discord-shared/src/osrs_broadcast_extractor.rs

+121-2
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,49 @@ pub mod osrs_broadcast_extractor {
257257
pub time_in_seconds: f64,
258258
}
259259

260+
//Leagues broadcasts
261+
//TODO may come back and add more descriptive broadcasts for Leagues, but right now just going the "firehose" route
262+
// #[derive(Clone, Debug, Serialize, Deserialize)]
263+
// pub struct AreaUnlockBroadcast {
264+
// pub area: String,
265+
// pub player: String
266+
// }
267+
268+
// #[derive(Clone, Debug, Serialize, Deserialize)]
269+
// pub struct LeaguesRankBroadcast {
270+
// pub area: String,
271+
// pub player: String
272+
// }
273+
274+
// #[derive(Clone, Debug, Serialize, Deserialize)]
275+
// pub struct CombatMasteriesBroadcast {
276+
// pub player: String,
277+
// pub combat_mastery: String,
278+
// pub rank: i64,
279+
// }
280+
281+
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
282+
pub enum LeaguesBroadCastType {
283+
AreaUnlock,
284+
LeaguesRank,
285+
CombatMasteries,
286+
RelicTier,
287+
//Normal broadcast but for leagues, like drops
288+
NormalBroadCast
289+
}
290+
291+
impl LeaguesBroadCastType {
292+
pub fn to_broadcast_type(&self) -> BroadcastType {
293+
match self {
294+
LeaguesBroadCastType::AreaUnlock => BroadcastType::AreaUnlock,
295+
LeaguesBroadCastType::LeaguesRank => BroadcastType::LeaguesRank,
296+
LeaguesBroadCastType::CombatMasteries => BroadcastType::CombatMasteries,
297+
LeaguesBroadCastType::RelicTier => BroadcastType::RelicTier,
298+
LeaguesBroadCastType::NormalBroadCast => BroadcastType::Unknown,
299+
}
300+
}
301+
}
302+
260303
#[derive(PartialEq, Deserialize, Serialize, Debug, Clone)]
261304
pub enum BroadcastType {
262305
ItemDrop,
@@ -274,7 +317,12 @@ pub mod osrs_broadcast_extractor {
274317
ExpelledFromClan,
275318
CofferDonation,
276319
CofferWithdrawal,
277-
PersonalBest,
320+
PersonalBest,
321+
//Leagues Broadcasts
322+
AreaUnlock,
323+
LeaguesRank,
324+
CombatMasteries,
325+
RelicTier,
278326
Unknown,
279327
}
280328

@@ -297,7 +345,12 @@ pub mod osrs_broadcast_extractor {
297345
BroadcastType::ExpelledFromClan => "Expelled From Clan".to_string(),
298346
BroadcastType::CofferDonation => "Coffer Donation".to_string(),
299347
BroadcastType::CofferWithdrawal => "Coffer Withdrawal".to_string(),
300-
BroadcastType::PersonalBest => "Personal Best".to_string(),
348+
BroadcastType::PersonalBest => "Personal Best".to_string(),
349+
//Leagues Broadcasts
350+
BroadcastType::AreaUnlock => "Area Unlock".to_string(),
351+
BroadcastType::LeaguesRank => "Leagues Rank".to_string(),
352+
BroadcastType::CombatMasteries => "Combat Masteries".to_string(),
353+
BroadcastType::RelicTier => "Relic Tier".to_string(),
301354
}
302355
}
303356

@@ -315,6 +368,11 @@ pub mod osrs_broadcast_extractor {
315368
"Level Milestone" => BroadcastType::LevelMilestone,
316369
"Collection Log" => BroadcastType::CollectionLog,
317370
"Personal Best" => BroadcastType::PersonalBest,
371+
//Leagues Broadcasts
372+
"Area Unlock" => BroadcastType::AreaUnlock,
373+
"Leagues Rank" => BroadcastType::LeaguesRank,
374+
"Combat Masteries" => BroadcastType::CombatMasteries,
375+
"Relic Tier" => BroadcastType::RelicTier,
318376
_ => BroadcastType::Unknown,
319377
}
320378
}
@@ -338,6 +396,11 @@ pub mod osrs_broadcast_extractor {
338396
BroadcastType::CofferDonation,
339397
BroadcastType::CofferWithdrawal,
340398
BroadcastType::PersonalBest,
399+
//Leagues Broadcasts
400+
BroadcastType::AreaUnlock,
401+
BroadcastType::LeaguesRank,
402+
BroadcastType::CombatMasteries,
403+
BroadcastType::RelicTier,
341404
]
342405
}
343406

@@ -650,6 +713,23 @@ pub mod osrs_broadcast_extractor {
650713
}
651714
}
652715

716+
pub fn leagues_catch_all_broadcast_extractor(
717+
message: String,
718+
) -> Option<LeaguesBroadCastType> {
719+
if message.contains("has earned") && message.contains("Combat mastery") {
720+
return Some(LeaguesBroadCastType::CombatMasteries);
721+
}
722+
723+
if message.contains("has unlocked") && message.contains("League area") {
724+
return Some(LeaguesBroadCastType::AreaUnlock);
725+
}
726+
727+
if message.contains("has unlocked") && message.contains("League relic!") {
728+
return Some(LeaguesBroadCastType::RelicTier);
729+
}
730+
None
731+
}
732+
653733
/// Parses a time string in the format of `HH:MM:SS` or `MM:SS` and returns the time in seconds
654734
pub fn osrs_time_parser(time: &str) -> f64 {
655735
let split_sub_second: Vec<&str> = time.split(".").collect();
@@ -826,6 +906,7 @@ mod tests {
826906
LevelMilestoneBroadcast, PersonalBestBroadcast, PetDropBroadcast, PkBroadcast,
827907
QuestCompletedBroadcast, XPMilestoneBroadcast,
828908
};
909+
use osrs_broadcast_extractor::LeaguesBroadCastType;
829910
use rstest::rstest;
830911
use tracing::info;
831912

@@ -1453,6 +1534,21 @@ mod tests {
14531534
}
14541535
}
14551536

1537+
#[test]
1538+
fn test_leagues_catch_all_broadcast_extractor() {
1539+
let test_leagues_catch_all = get_leagues_catch_all_broadcast_messages();
1540+
for test_leagues_catch_all in test_leagues_catch_all {
1541+
let possible_leagues_catch_all_extract =
1542+
osrs_broadcast_extractor::leagues_catch_all_broadcast_extractor(
1543+
test_leagues_catch_all.message.clone(),
1544+
);
1545+
let leagues_catch_all = possible_leagues_catch_all_extract.unwrap();
1546+
info!("{:?}", leagues_catch_all);
1547+
assert_eq!(leagues_catch_all, test_leagues_catch_all.broadcast);
1548+
}
1549+
}
1550+
1551+
14561552
#[rstest]
14571553
#[case("0:56.40", 56.40)]
14581554
#[case("1:25", 85.0)]
@@ -2302,4 +2398,27 @@ mod tests {
23022398

23032399
messages
23042400
}
2401+
2402+
fn get_leagues_catch_all_broadcast_messages() -> Vec<TestBroadcast<LeaguesBroadCastType>> {
2403+
let mut messages: Vec<TestBroadcast<LeaguesBroadCastType>> = Vec::new();
2404+
2405+
messages.push(TestBroadcast {
2406+
message: "RuneScape Player has earned their 6th Combat mastery point!".to_string(),
2407+
broadcast: LeaguesBroadCastType::CombatMasteries,
2408+
});
2409+
2410+
messages.push(TestBroadcast {
2411+
message: "RuneScape Player has unlocked their 3rd League area!".to_string(),
2412+
broadcast: LeaguesBroadCastType::AreaUnlock,
2413+
});
2414+
2415+
messages.push(TestBroadcast {
2416+
message: "RuneScape Player has unlocked their tier 3 League relic!".to_string(),
2417+
broadcast: LeaguesBroadCastType::RelicTier,
2418+
});
2419+
2420+
//TODO add rank as we find more examples
2421+
2422+
messages
2423+
}
23052424
}

0 commit comments

Comments
 (0)