Skip to content

Commit

Permalink
Personal Best Leaderboards (#28)
Browse files Browse the repository at this point in the history
* Bit more standared on raid names

* pb models

* job appears to be working

* Start of rl commands

* Get longggg boss name

* Ready to to save pb

* Redesign of clan details view for leaderboards

* Decent select bar

* Commiting cause its been a min

* wip it up (members view)

* Clanmate rank comp

* Do activity routing

* Good version 1?

* clean up

* removed comment
  • Loading branch information
fatfingers23 committed Apr 22, 2024
1 parent 0885f02 commit 023861a
Show file tree
Hide file tree
Showing 53 changed files with 1,545 additions and 226 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ Secrets.dev.toml
.shuttle-storage
#trackscape-discord-api/ui
cargo-shuttle
trackscape-discord-ui/bun.lockb
trackscape-discord-ui/bun.lockb
.vscode
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ CC will not be able to be sent to Discord and parsed. This is done by the RuneLi
- [ ] Check your K/D Pk ratio from Discord bot
- [ ] Check your total kills and deaths from Discord bot
- [ ] Check Gold earned and lost from Discord bot
- [ ] In clan leaderboards
- [x] In clan leaderboards
* [x] Collection Log Leaderboards - See where you log stands with the rest of the clan
* [ ] Bossing PB Leaderboards - See where you stand with the rest of the clan for fastest kills
* [x] Bossing PB Leaderboards - See where you stand with the rest of the clan for fastest kills
* Simple Team Bingo - to be determined. May not happen
- [ ] Bingo tiles by certain drops
- [ ] Bingo tiles by sets. Barrows, Godsword, etc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use actix_web::{get, web, Error, HttpResponse, Scope};
use serde::{Deserialize, Serialize};
use trackscape_discord_shared::database::clan_mates::ClanMateModel;
use trackscape_discord_shared::database::BotMongoDb;
use web::Data;

#[derive(Deserialize, Serialize)]
struct ClanViewModel {
id: String,
name: String,
registered_members: u64,
}

#[derive(Deserialize, Serialize)]
struct ClanDetail {
id: String,
name: String,
discord_guild_id: String,
registered_members: u64,
members: Vec<ClanMateModel>,
}

#[get("/activities")]
async fn get_pb_activities(mongodb: Data<BotMongoDb>) -> Result<HttpResponse, Error> {
let result = mongodb.pb_activities.get_activities().await;

match result {
Ok(activities) => Ok(HttpResponse::Ok().json(activities)),
Err(_) => Ok(HttpResponse::InternalServerError().body("Failed to list activities.")),
}
}

pub fn application_data_controller() -> Scope {
web::scope("/resources").service(get_pb_activities)
}
16 changes: 15 additions & 1 deletion trackscape-discord-api/src/controllers/chat_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ async fn new_clan_chats(
}
}
//Checks to make sure the message has not already been process since multiple people could be submitting them
let message_content_hash = hash_string(chat.message.clone());
let message_content_hash =
hash_string(format!("{}{}", chat.message.clone(), chat.sender.clone()));
match cache.get_value(message_content_hash.clone()).await {
Some(_) => continue,
None => {
Expand Down Expand Up @@ -175,6 +176,19 @@ async fn new_clan_chats(
}
//Checks to see if it is a clan broadcast. Clan name and sender are the same if so
if chat.sender != chat.clan_name {
//Handles RL chat commands
if chat.message.starts_with("!") {
let _ = celery
.send_task(
trackscape_discord_shared::jobs::parse_rl_chat_command::parse_command::new(
chat.message.clone(),
chat.sender.clone(),
registered_guild.guild_id,
),
)
.await;
}

//Starts a job to either add the clan mate if not added to guild, or check for rank change
let _ = celery
.send_task(
Expand Down
52 changes: 52 additions & 0 deletions trackscape-discord-api/src/controllers/clan_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,62 @@ async fn broadcasts(
}
}

#[get("/{guild_id}/{activity_id}/personal-bests")]
async fn personal_bests(
mongodb: Data<BotMongoDb>,
path: web::Path<(String, String)>,
) -> Result<HttpResponse, Error> {
let get_variables = path.into_inner();
let guild_id = get_variables.0;
let possible_parsed_guild_id = bson::oid::ObjectId::from_str(guild_id.as_str());
let guild_id = match possible_parsed_guild_id {
Ok(parsed_id) => parsed_id,
Err(_) => {
return Ok(HttpResponse::BadRequest().body("Invalid id format."));
}
};

let activity_id = get_variables.1;
let possible_parsed_activity_id = bson::oid::ObjectId::from_str(activity_id.as_str());
let activity_id = match possible_parsed_activity_id {
Ok(parsed_id) => parsed_id,
Err(_) => {
return Ok(HttpResponse::BadRequest().body("Invalid id format."));
}
};

let registered_guild_query = mongodb.guilds.get_by_id(guild_id).await;
match registered_guild_query {
Ok(possible_registered_guild) => match possible_registered_guild {
None => {
return Ok(HttpResponse::NotFound().body("Clan not found."));
}
Some(registered_guild) => {
let result = mongodb
.pb_records
.get_pb_records_leaderboard(activity_id, registered_guild.guild_id)
.await;
match result {
Ok(records) => Ok(HttpResponse::Ok().json(records)),
Err(err) => {
error!("Failed to get personal bests: {}", err);
Ok(HttpResponse::BadRequest().body("There was an issue with the request"))
}
}
}
},
Err(err) => {
error!("Failed to get clan by id: {}", err);
return Ok(HttpResponse::BadRequest().body("There was an issue with the request"));
}
}
}

pub fn clan_controller() -> Scope {
web::scope("/clans")
.service(list_clans)
.service(detail)
.service(collection_log)
.service(broadcasts)
.service(personal_bests)
}
1 change: 1 addition & 0 deletions trackscape-discord-api/src/controllers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod application_data_controller;
pub mod bot_info_controller;
pub mod chat_controller;
pub mod clan_controller;
Expand Down
2 changes: 2 additions & 0 deletions trackscape-discord-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::controllers::chat_controller::chat_controller;
use actix_cors::Cors;
use actix_web::web::Data;
use actix_web::{guard, web, web::ServiceConfig, Error};
use controllers::application_data_controller::application_data_controller;
use dotenv::dotenv;
use serenity::http::HttpBuilder;
use shuttle_actix_web::ShuttleActixWeb;
Expand Down Expand Up @@ -112,6 +113,7 @@ async fn actix_web(
.service(info_controller())
.service(drop_log_controller())
.service(clan_controller())
.service(application_data_controller())
.wrap(
Cors::default()
.allow_any_origin()
Expand Down
17 changes: 12 additions & 5 deletions trackscape-discord-job-worker/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use anyhow::Result;
use dotenv::dotenv;
use env_logger::Env;
use trackscape_discord_shared::jobs::{
add_job, name_change_job::name_change, new_pb_job::record_new_pb,
parse_rl_chat_command::parse_command, remove_clanmate_job::remove_clanmate,
update_create_clanmate_job::update_create_clanmate, wom_guild_sync_job::wom_guild_sync,
};

#[tokio::main]
async fn main() -> Result<()> {
Expand All @@ -10,11 +15,13 @@ async fn main() -> Result<()> {
let instant_job_app = celery::app!(
broker = RedisBroker { std::env::var("REDIS_ADDR").unwrap_or_else(|_| "redis://127.0.0.1:6379/".into()) },
tasks = [
trackscape_discord_shared::jobs::add_job::run,
trackscape_discord_shared::jobs::update_create_clanmate_job::update_create_clanmate,
trackscape_discord_shared::jobs::remove_clanmate_job::remove_clanmate,
trackscape_discord_shared::jobs::name_change_job::name_change,
trackscape_discord_shared::jobs::wom_guild_sync_job::wom_guild_sync,
add_job::run,
update_create_clanmate,
remove_clanmate,
name_change,
wom_guild_sync,
record_new_pb,
parse_command,
],
// This just shows how we can route certain tasks to certain queues based
// on glob matching.
Expand Down
1 change: 1 addition & 0 deletions trackscape-discord-shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
async-recursion = "1.0.5"
bson = { version = "2.10.0", features = ["chrono-0_4"] }
capitalize = "0.3.3"
tracing = "0.1.37"
num-format = "0.4.4"
futures = "0.3.28"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,26 @@ use mongodb::bson::{doc, DateTime};
use mongodb::{bson, Database};
use serde::{Deserialize, Serialize};

use super::clan_mates::ClanMateModel;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ClanMateCollectionLogTotalModel {
pub guild_id: u64,
pub player_id: bson::oid::ObjectId,
pub total: i64,
pub created_at: DateTime,
pub clan_mate: Option<ClanMateModel>,
}
pub const COLLECTION_LOG_COLLECTION_NAME: &'static str = "clan_mate_collection_log_totals";

impl ClanMateCollectionLogTotalModel {
pub const COLLECTION_NAME: &'static str = "clan_mate_collection_log_totals";
pub fn new(guild_id: u64, player_id: bson::oid::ObjectId, total: i64) -> Self {
Self {
guild_id,
player_id,
total,
created_at: DateTime::now(),
clan_mate: None,
}
}
}
Expand All @@ -49,7 +53,7 @@ pub trait ClanMateCollectionLogTotals {
async fn get_guild_totals(
&self,
guild_id: u64,
) -> Result<Vec<ClanMateCollectionLogTotalsView>, anyhow::Error>;
) -> Result<Vec<ClanMateCollectionLogTotalModel>, anyhow::Error>;
}

#[async_trait]
Expand All @@ -64,9 +68,9 @@ impl ClanMateCollectionLogTotals for ClanMateCollectionLogTotalsDb {
player_id: bson::oid::ObjectId,
total: i64,
) -> Result<(), Error> {
let collection = self
.db
.collection::<ClanMateCollectionLogTotalModel>(COLLECTION_LOG_COLLECTION_NAME);
let collection = self.db.collection::<ClanMateCollectionLogTotalModel>(
ClanMateCollectionLogTotalModel::COLLECTION_NAME,
);

let filter = doc! {
"guild_id": bson::to_bson(&guild_id).unwrap(),
Expand Down Expand Up @@ -99,10 +103,10 @@ impl ClanMateCollectionLogTotals for ClanMateCollectionLogTotalsDb {
async fn get_guild_totals(
&self,
guild_id: u64,
) -> Result<Vec<ClanMateCollectionLogTotalsView>, anyhow::Error> {
let collection = self
.db
.collection::<ClanMateCollectionLogTotalModel>(COLLECTION_LOG_COLLECTION_NAME);
) -> Result<Vec<ClanMateCollectionLogTotalModel>, anyhow::Error> {
let collection = self.db.collection::<ClanMateCollectionLogTotalModel>(
ClanMateCollectionLogTotalModel::COLLECTION_NAME,
);

let filter = doc! {
"guild_id": bson::to_bson(&guild_id).unwrap(),
Expand All @@ -125,12 +129,6 @@ impl ClanMateCollectionLogTotals for ClanMateCollectionLogTotalsDb {
doc! {
"$unwind": "$clan_mate"
},
doc! {
"$project": {
"player_name": "$clan_mate.player_name",
"total": 1
}
},
doc! {
"$sort": {
"total": -1
Expand All @@ -141,12 +139,12 @@ impl ClanMateCollectionLogTotals for ClanMateCollectionLogTotalsDb {
)
.await?;

let mut results: Vec<ClanMateCollectionLogTotalsView> = Vec::new();
let mut results: Vec<ClanMateCollectionLogTotalModel> = Vec::new();

// Iterate through the results and map them to the struct
while let Some(result) = cursor.try_next().await? {
if let Ok(view) =
bson::from_bson::<ClanMateCollectionLogTotalsView>(bson::Bson::Document(result))
bson::from_bson::<ClanMateCollectionLogTotalModel>(bson::Bson::Document(result))
{
results.push(view);
}
Expand Down
4 changes: 2 additions & 2 deletions trackscape-discord-shared/src/database/clan_mates.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::database::clan_mate_collection_log_totals::COLLECTION_LOG_COLLECTION_NAME;
use crate::database::clan_mate_collection_log_totals::ClanMateCollectionLogTotalModel;
use crate::database::ClanMatesDb;
use anyhow::Error;
use async_trait::async_trait;
Expand Down Expand Up @@ -214,7 +214,7 @@ impl ClanMates for ClanMatesDb {
//Removes other data from db may move else where
let collection_log_collection = self
.db
.collection::<ClanMateModel>(COLLECTION_LOG_COLLECTION_NAME);
.collection::<ClanMateCollectionLogTotalModel>(ClanMateCollectionLogTotalModel::COLLECTION_NAME);

let filter = doc! {
"guild_id": bson::to_bson(&guild_id).unwrap(),
Expand Down
Loading

0 comments on commit 023861a

Please sign in to comment.