From b72cffe3a9024ac948efcfb0c9e47a34333e77a3 Mon Sep 17 00:00:00 2001 From: evann Date: Sat, 22 Jul 2023 02:30:24 +0200 Subject: [PATCH] Fixed changes in discord API --- .dockerignore | 3 +- .idea/.gitignore | 8 ++ .idea/Drunk-Venti-Rust.iml | 11 ++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 + Cargo.toml | 4 +- Dockerfile | 30 +++-- src/data/artifacts.rs | 25 ++-- src/data/builds.rs | 8 +- src/data/characters.rs | 12 +- src/data/domains.rs | 10 +- src/data/elements.rs | 8 +- src/data/events.rs | 12 +- src/data/items.rs | 12 +- src/data/weapons.rs | 37 +++--- src/interactions/genshin/artifacts.rs | 15 +-- src/interactions/genshin/build.rs | 162 ++++++++++++++------------ src/interactions/genshin/mod.rs | 2 +- src/interactions/genshin/weapons.rs | 10 +- src/interactions/mod.rs | 11 +- src/interactions/status_message.rs | 88 ++++++-------- src/main.rs | 45 +++---- src/utils/mod.rs | 2 +- src/utils/mongo.rs | 4 +- 24 files changed, 280 insertions(+), 253 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/Drunk-Venti-Rust.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.dockerignore b/.dockerignore index 40d6290..3bfb762 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ .idea/ .github/ -**/.env \ No newline at end of file +**/.env +target \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Drunk-Venti-Rust.iml b/.idea/Drunk-Venti-Rust.iml new file mode 100644 index 0000000..c254557 --- /dev/null +++ b/.idea/Drunk-Venti-Rust.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c4a9614 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 9b0cbe6..bf965eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "drunk-venti-rust" -version = "1.1.1" +version = "1.2.0" edition = "2021" authors = ["Evann Regnault"] license = "MIT" @@ -8,7 +8,7 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serenity = { version = "0.10.9", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "unstable_discord_api", "collector"] } +serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "unstable_discord_api", "collector"] } tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } reqwest = "0.11.7" serde_derive = "1.0.140" diff --git a/Dockerfile b/Dockerfile index 5e66e08..661cdc1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,21 @@ -FROM rust:1.65.0 +FROM rust:slim-bookworm AS base +RUN apt-get update +RUN apt-get install libssl-dev pkg-config -y +RUN cargo install cargo-chef +WORKDIR app -WORKDIR /app +FROM base AS planner +COPY . . +RUN cargo chef prepare --recipe-path recipe.json -COPY . /app +FROM base AS builder +COPY --from=planner /app/recipe.json recipe.json +RUN cargo chef cook --release --recipe-path recipe.json +COPY . . +RUN cargo build --release --bin drunk-venti-rust -RUN cargo install --path . - -#ENV DISCORD_TOKEN=token -#ENV MONGO_HOST=host -#ENV MONGO_PORT=port -#ENV API_HOST=host -#ENV API_PORT=port - -ENTRYPOINT ["drunk-venti-rust"] +FROM debian:bookworm-slim +RUN apt-get update && apt-get install ca-certificates libssl3 -y && apt-get clean autoclean && apt-get autoremove --yes && rm -rf /var/lib/{apt,dpkg,cache,log}/ +WORKDIR /root/ +COPY --from=builder /app/target/release/drunk-venti-rust . +CMD ["./drunk-venti-rust"] \ No newline at end of file diff --git a/src/data/artifacts.rs b/src/data/artifacts.rs index 17e1d20..e4b041d 100644 --- a/src/data/artifacts.rs +++ b/src/data/artifacts.rs @@ -45,8 +45,8 @@ impl Artifact{ let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/artifacts/{}", host, port, artifact); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format") } #[allow(dead_code)] @@ -54,8 +54,8 @@ impl Artifact{ let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/artifacts", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format") } #[allow(dead_code)] @@ -64,15 +64,15 @@ impl Artifact{ let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/artifacts/search/{}", host, port, artifact); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format") } #[allow(dead_code)] pub async fn to_embed(&self) -> CreateEmbed { let mut embed = CreateEmbed::default(); - embed.title(format!("{} | {}", self.name, ":star:".repeat(self.rarity.get(0).expect("").to_owned() as usize))); + embed.title(format!("{} | {}", self.name, ":star:".repeat(self.rarity.first().expect("").to_owned() as usize))); embed.thumbnail(format!("https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/static/images/artifacts/{}_circlet.png", self.id)); @@ -83,15 +83,12 @@ impl Artifact{ ); } - match &self.domain { - Some(d) => { - let domain = Domain::get(d).await; - embed.field("Domain", domain.name(), true); - } - _ => {} + if let Some(d) = &self.domain { + let domain = Domain::get(d).await; + embed.field("Domain", domain.name(), true); } - return embed; + embed } #[allow(dead_code)] diff --git a/src/data/builds.rs b/src/data/builds.rs index 78798ca..f422d6e 100644 --- a/src/data/builds.rs +++ b/src/data/builds.rs @@ -43,8 +43,8 @@ impl Builds { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/builds/{}", host, port, build); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format") } #[allow(dead_code)] @@ -52,8 +52,8 @@ impl Builds { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/builds", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format") } } diff --git a/src/data/characters.rs b/src/data/characters.rs index e8557b5..2568799 100644 --- a/src/data/characters.rs +++ b/src/data/characters.rs @@ -50,8 +50,8 @@ impl Character { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/characters/{}", host, port, character); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format") } #[allow(dead_code)] @@ -59,8 +59,8 @@ impl Character { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/characters", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format") } #[allow(dead_code)] @@ -68,8 +68,8 @@ impl Character { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/characters/search/{}", host, port, character); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format") } } diff --git a/src/data/domains.rs b/src/data/domains.rs index fa0a5e3..25cb89c 100644 --- a/src/data/domains.rs +++ b/src/data/domains.rs @@ -45,8 +45,8 @@ impl Domain { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/domains/{}", host, port, domain); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format") } #[allow(dead_code)] @@ -54,13 +54,13 @@ impl Domain { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/domains", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format") } #[allow(dead_code)] pub fn name(&self) -> String { - return self.name.to_string(); + self.name.to_string() } } diff --git a/src/data/elements.rs b/src/data/elements.rs index 7970ed9..af85cc7 100644 --- a/src/data/elements.rs +++ b/src/data/elements.rs @@ -17,8 +17,8 @@ impl Element { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/elements/{}", host, port, element); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format") } #[allow(dead_code)] @@ -26,8 +26,8 @@ impl Element { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/elements", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format") } } diff --git a/src/data/events.rs b/src/data/events.rs index 2868e47..03f5742 100644 --- a/src/data/events.rs +++ b/src/data/events.rs @@ -30,8 +30,8 @@ impl Event { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/events/current", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format") } #[allow(dead_code)] @@ -39,8 +39,8 @@ impl Event { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/events/upcoming", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format") } #[allow(dead_code)] @@ -48,8 +48,8 @@ impl Event { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/events", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format") } } diff --git a/src/data/items.rs b/src/data/items.rs index b944ddc..eed4ed8 100644 --- a/src/data/items.rs +++ b/src/data/items.rs @@ -18,16 +18,16 @@ impl Item{ let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/items/{}", host, port, item); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format") } #[allow(dead_code)] async fn get_all() -> Vec> { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/items", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format") } #[allow(dead_code)] @@ -35,8 +35,8 @@ impl Item{ let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/items/search/{}", host, port, item); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format") } } diff --git a/src/data/weapons.rs b/src/data/weapons.rs index 1d514c7..c0be46e 100644 --- a/src/data/weapons.rs +++ b/src/data/weapons.rs @@ -56,8 +56,8 @@ impl Weapon { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/weapons/{}", host, port, weapon); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::().await.expect("Wrong json format") } #[allow(dead_code)] @@ -65,8 +65,8 @@ impl Weapon { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/weapons", host, port); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>>().await.expect("Wrong json format") } #[allow(dead_code)] @@ -74,18 +74,18 @@ impl Weapon { let host = env::var("API_HOST").unwrap(); let port = env::var("API_PORT").unwrap(); let url = format!("http://{}:{}/api/weapons/search/{}", host, port, weapon); - let url = Url::parse(&*url).expect("Can't convert url"); - return reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format"); + let url = Url::parse(&url).expect("Can't convert url"); + reqwest::get(url).await.expect("Can't access Url").json::>().await.expect("Wrong json format") } #[allow(dead_code)] pub fn name(&self) -> &str { - return &self.name; + &self.name } #[allow(dead_code)] pub fn id(&self) -> &str { - return &self.id; + &self.id } #[allow(dead_code)] @@ -98,17 +98,14 @@ impl Weapon { embed.thumbnail(format!("https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/static/images/weapons/{}.png", self.id)); // Fields - match self.extras.skill.name.as_ref() { - Some(t) => { - let re = Regex::new("(<|]*)?>").expect("Unknown regex"); - embed.field(format!("Passive : {}", t), - format!("{}", - re.replace_all(self.extras.skill.description.as_ref() - .unwrap_or(&Box::from("")) - .to_string().as_str(), "**")).replace("\\n","\n"), - false); - } - _ => {} + if let Some(t) = self.extras.skill.name.as_ref() { + let re = Regex::new("(<|]*)?>").expect("Unknown regex"); + embed.field(format!("Passive : {}", t), + format!("{}", + re.replace_all(self.extras.skill.description.as_ref() + .unwrap_or(&Box::from("")) + .to_string().as_str(), "**")).replace("\\n","\n"), + false); } embed.field("Main Stat", format!("{}", self.secondary), true); embed.field("Source", format!("{}", self.source), true); @@ -116,7 +113,7 @@ impl Weapon { embed.field("Type", format!("{}", self.weapon_type.name), true); embed.field("Ascension Item", format!("{}", self.ascension.get(0).expect("").items.get(0).expect("").item.name), true); embed.field("\u{200b}", "\u{200b}", true); - return embed; + embed } } diff --git a/src/interactions/genshin/artifacts.rs b/src/interactions/genshin/artifacts.rs index 0b03d90..ecdc0b0 100644 --- a/src/interactions/genshin/artifacts.rs +++ b/src/interactions/genshin/artifacts.rs @@ -1,12 +1,13 @@ use linked_hash_map::LinkedHashMap; use serenity::client::Context; -use serenity::model::interactions::{InteractionApplicationCommandCallbackDataFlags, InteractionResponseType}; -use serenity::model::interactions::application_command::{ApplicationCommandInteraction, ApplicationCommandInteractionDataOption}; -use serenity::model::interactions::message_component::{MessageComponentInteraction}; +use serenity::model::application::interaction::application_command::{ApplicationCommandInteraction, CommandDataOption}; +use serenity::model::application::interaction::InteractionResponseType; +use serenity::model::application::interaction::MessageFlags; +use serenity::model::application::interaction::message_component::MessageComponentInteraction; use crate::data::artifacts::Artifact; use crate::interactions::utils::create_action_row_basic; -pub async fn genshin_artifact_interaction(ctx: &Context, command: &ApplicationCommandInteraction, opt: &ApplicationCommandInteractionDataOption) { +pub async fn genshin_artifact_interaction(ctx: &Context, command: &ApplicationCommandInteraction, opt: &CommandDataOption) { let weapon = opt.options.get(0).expect("No argument for command Genshin artifact") .value.as_ref().expect("").as_str().expect("Not a string"); @@ -25,7 +26,7 @@ pub async fn genshin_artifact_interaction(ctx: &Context, command: &ApplicationCo .interaction_response_data(|d| { d.content("Select an Artifact") .components(|c| c.add_action_row(ar)) - .flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL) + .flags(MessageFlags::EPHEMERAL) }) }).await.expect("Message didn't got sent"); } @@ -37,8 +38,8 @@ pub async fn show_artifact_embed(ctx: &Context, command: &MessageComponentIntera command.create_interaction_response(&ctx.http, |res| { res.kind(InteractionResponseType::UpdateMessage) .interaction_response_data(|d| { - d.embeds(vec!(embed).into_iter()) - .flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL) + d.set_embeds(vec!(embed).into_iter()) + .flags(MessageFlags::EPHEMERAL) }) }).await.expect("Interaction failed"); } \ No newline at end of file diff --git a/src/interactions/genshin/build.rs b/src/interactions/genshin/build.rs index 36c69cf..c1a46d4 100644 --- a/src/interactions/genshin/build.rs +++ b/src/interactions/genshin/build.rs @@ -1,17 +1,24 @@ use std::borrow::{Borrow}; use linked_hash_map::LinkedHashMap; -use serenity::builder::{CreateActionRow, CreateButton, CreateEmbed}; +use serenity::builder::{CreateActionRow, CreateButton, CreateComponents, CreateEmbed}; use serenity::client::Context; -use serenity::model::interactions::{InteractionApplicationCommandCallbackDataFlags, InteractionResponseType}; -use serenity::model::interactions::application_command::{ApplicationCommandInteraction, ApplicationCommandInteractionDataOption}; -use serenity::model::interactions::message_component::{ButtonStyle, MessageComponentInteraction}; +use serenity::model::application::component::ButtonStyle; +use serenity::model::application::interaction::{ + MessageFlags, + InteractionResponseType, + application_command::{ + ApplicationCommandInteraction, + CommandDataOption + }, + message_component::MessageComponentInteraction +}; use crate::data::artifacts::Artifact; use crate::data::builds::{Builds, Role}; use crate::data::characters::Character; use crate::data::weapons::Weapon; use crate::interactions::utils::create_action_row_basic; -pub async fn genshin_build_interaction(ctx: &Context, command: &ApplicationCommandInteraction, opt: &ApplicationCommandInteractionDataOption) { +pub async fn genshin_build_interaction(ctx: &Context, command: &ApplicationCommandInteraction, opt: &CommandDataOption) { let char = opt.options.get(0).expect("No argument for command Genshin builds") .value.as_ref().expect("").as_str().expect("Not a string"); @@ -29,20 +36,17 @@ pub async fn genshin_build_interaction(ctx: &Context, command: &ApplicationComma .interaction_response_data(|d| { d.content("Select a Character") .components(|c| c.add_action_row(ar)) - .flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL) + .flags(MessageFlags::EPHEMERAL) }) }).await.expect("Message didn't got sent"); } fn is_menu(arg: &str) -> bool { - match arg { - "home" | "artifacts" | "weapons" | "notes" => true, - _ => false - } + matches!(arg, "home" | "artifacts" | "weapons" | "notes") } pub async fn build_interact(ctx: &Context, interaction: &MessageComponentInteraction, arguments: String) { - let mut args = arguments.split("_"); + let mut args = arguments.split('_'); let command = args.next(); @@ -74,8 +78,8 @@ pub async fn build_interact(ctx: &Context, interaction: &MessageComponentInterac _ => { let mut character = args.collect::>().join("_"); character = [command.expect(""), character.as_str()].join("_"); - character = character.strip_suffix("_").unwrap_or(character.as_str()).parse().unwrap(); - build_select(&ctx, &interaction, character).await; + character = character.strip_suffix('_').unwrap_or(character.as_str()).parse().unwrap(); + build_select(ctx, interaction, character).await; } } } @@ -127,32 +131,41 @@ async fn build_select(ctx: &Context, command: &MessageComponentInteraction, char let roles = &char.builds; - let roles = roles.into_iter().map(|c| c.name.to_string()).collect::>(); + let roles = roles.iter().map(|c| c.name.to_string()).collect::>(); let mut rolemap = LinkedHashMap::::new(); for i in 0..roles.len() { rolemap.insert(format!("{}_{}", i, character), roles.get(i).expect("").to_string()); } - let ar = create_action_row_basic(rolemap, "build_home"); + let ar = match roles.len() { + 0 => CreateActionRow::default(), + _ =>create_action_row_basic(rolemap, "build_home") + }; command.create_interaction_response(&ctx.http, |res| { res.kind(InteractionResponseType::UpdateMessage) - .interaction_response_data(|d| { - d.components(|c| c.add_action_row(ar)) - .create_embed(|e| { - e.title(format!("{}", char.name)) - .thumbnail(format!("https://github.com/MadeBaruna/paimon-moe/raw/main/static/images/characters/{}.png", char.id)) - .color(char.element.color) - .description("Select a build !") - .footer(|f| { - f.text(format!("Data from : https://paimon.moe/characters/{}", char.id)) - }) - }) + .interaction_response_data(|mut d| { + if !roles.is_empty() { + d = d.components(|c| c.add_action_row(ar)) + } else { + d = d.set_components(CreateComponents::default()) + } + d.embed(|mut e| { + e = e.title(format!("{}", char.name)) + .thumbnail(format!("https://github.com/MadeBaruna/paimon-moe/raw/main/static/images/characters/{}.png", char.id)) + .color(char.element.color) + .description("Select a build !") + .footer(|f| { + f.text(format!("Data from : https://paimon.moe/characters/{}", char.id)) + }); + if roles.is_empty() { + e = e.description("No builds available yet !") + } + e + }) }) }).await.expect("Can't send response"); - - return; } @@ -175,8 +188,8 @@ pub async fn home_embed(role: &Role, character: Character) -> CreateEmbed { } embed.field("Skill Order", - role.talent.to_owned().into_iter().map(|t| format!("- {}\n", t)) - .collect::>().join("").strip_suffix("\n").expect(""), + role.talent.iter().cloned().map(|t| format!("- {}\n", t)) + .collect::>().join("").strip_suffix('\n').expect(""), true, ); @@ -279,6 +292,7 @@ async fn artifact_embed(role: &Role, character: Character) -> CreateEmbed { for art in a { let artifact_name = match art.to_string().as_str() { "+18%_atk_set" => "+18% Atk Set".to_string(), + "+80_em" => "Elemental Mastery +80 Set".to_string(), t => Artifact::get(t).await.name.to_string(), }; artifact_string.push(format!("(2) {}", artifact_name)); @@ -288,17 +302,17 @@ async fn artifact_embed(role: &Role, character: Character) -> CreateEmbed { } all_artefacts_string.push(format!("- {}", str)); } - _ => { all_artefacts_string.push(format!("- TBD")); } + _ => { all_artefacts_string.push("- TBD".to_string()); } } } - if all_artefacts_string.len() > 0 { + if !all_artefacts_string.is_empty() { embed.field("Best Artifacts", all_artefacts_string.join("\n"), false); } else { embed.field("Best Artifacts", "- TBD", false); } embed.field("Sub-stats", { - format!("- {}", role.sub_stats.join("\n-")) + format!("- {}", role.sub_stats.join("\n- ")) }, false); embed.field("Circlet", &role.main_stats.circlet[0], true); @@ -335,10 +349,10 @@ async fn weapons_embed(role: &Role, character: Character) -> CreateEmbed { let weapon = Weapon::get(a.id.borrow()).await; all_weapons_string.push(format!("- {}", weapon.name)); } - _ => { all_weapons_string.push(format!("- TBD")); } + _ => { all_weapons_string.push("- TBD".to_string()); } } } - if all_weapons_string.len() > 0 { + if !all_weapons_string.is_empty() { embed.field("Best Weapons", all_weapons_string.join("\n"), false); } else { embed.field("Best Weapons", "- TBD", false); @@ -358,51 +372,49 @@ async fn note_embed(role: &Role, character: Character) -> CreateEmbed { embed.thumbnail(format!("https://github.com/MadeBaruna/paimon-moe/raw/main/static/images/characters/{}.png", character.id)); embed.color(character.element.color); - match &role.note { - n=> { - let x = n.split("\n"); - let mut first = true; - let mut add_before = ""; - for note_paragraph in x.collect::>() { - if note_paragraph.len() == 0 {continue}; - if note_paragraph.len() < 64 && add_before.len() == 0{ - add_before = note_paragraph; - continue; - } - if add_before.len() > 0 { - let note_paragraph = format!("**{}**\n{}", add_before, note_paragraph); - embed.field(if first { "Notes" } else { "\u{200b}" }, note_paragraph, false); - add_before = ""; - } else { - embed.field(if first { "Notes" } else { "\u{200b}" }, note_paragraph, false); - first = false; - } - + let n = &role.note; + { + let x = n.split('\n'); + let mut first = true; + let mut add_before = ""; + for note_paragraph in x.collect::>() { + if note_paragraph.is_empty() {continue}; + if note_paragraph.len() < 64 && add_before.is_empty(){ + add_before = note_paragraph; + continue; } + if !add_before.is_empty() { + let note_paragraph = format!("**{}**\n{}", add_before, note_paragraph); + embed.field(if first { "Notes" } else { "\u{200b}" }, note_paragraph, false); + add_before = ""; + } else { + embed.field(if first { "Notes" } else { "\u{200b}" }, note_paragraph, false); + first = false; + } + } }; - match &role.tip { - n=> { - let x = n.split("\n"); - let mut first = true; - let mut add_before = ""; - for tip_paragraph in x.collect::>() { - if tip_paragraph.len() == 0 {continue}; - if tip_paragraph.len() < 64 { - add_before = tip_paragraph; - continue; - } - if add_before.len() > 0 { - let tip_paragraph = format!("**{}**\n{}", add_before, tip_paragraph); - embed.field(if first { "Tips" } else { "\u{200b}" }, tip_paragraph, false); - add_before = ""; - } else { - embed.field(if first { "Tips" } else { "\u{200b}" }, tip_paragraph, false); - first = false; - } - + let n = &role.tip; + { + let x = n.split('\n'); + let mut first = true; + let mut add_before = ""; + for tip_paragraph in x.collect::>() { + if tip_paragraph.is_empty() {continue}; + if tip_paragraph.len() < 64 { + add_before = tip_paragraph; + continue; } + if !add_before.is_empty() { + let tip_paragraph = format!("**{}**\n{}", add_before, tip_paragraph); + embed.field(if first { "Tips" } else { "\u{200b}" }, tip_paragraph, false); + add_before = ""; + } else { + embed.field(if first { "Tips" } else { "\u{200b}" }, tip_paragraph, false); + first = false; + } + } }; diff --git a/src/interactions/genshin/mod.rs b/src/interactions/genshin/mod.rs index 174d8b2..5a53e24 100644 --- a/src/interactions/genshin/mod.rs +++ b/src/interactions/genshin/mod.rs @@ -1,5 +1,5 @@ use serenity::client::Context; -use serenity::model::interactions::application_command::ApplicationCommandInteraction; +use serenity::model::application::interaction::application_command::ApplicationCommandInteraction; use crate::interactions::genshin::artifacts::genshin_artifact_interaction; use crate::interactions::genshin::build::genshin_build_interaction; use crate::interactions::genshin::weapons::genshin_weapon_interaction; diff --git a/src/interactions/genshin/weapons.rs b/src/interactions/genshin/weapons.rs index 16de0f5..c7a6c50 100644 --- a/src/interactions/genshin/weapons.rs +++ b/src/interactions/genshin/weapons.rs @@ -1,14 +1,14 @@ use linked_hash_map::LinkedHashMap; use serenity::client::Context; -use serenity::model::interactions::application_command::ApplicationCommandInteraction; -use serenity::model::interactions::application_command::ApplicationCommandInteractionDataOption; -use serenity::model::interactions::InteractionResponseType; +use serenity::model::application::interaction::application_command::ApplicationCommandInteraction; +use serenity::model::application::interaction::InteractionResponseType; +use serenity::model::prelude::application_command::CommandDataOption; use serenity::model::prelude::InteractionApplicationCommandCallbackDataFlags; use serenity::model::prelude::message_component::MessageComponentInteraction; use crate::data::weapons::Weapon; use crate::interactions::utils::create_action_row_basic; -pub async fn genshin_weapon_interaction(ctx: &Context, command: &ApplicationCommandInteraction, opt: &ApplicationCommandInteractionDataOption) { +pub async fn genshin_weapon_interaction(ctx: &Context, command: &ApplicationCommandInteraction, opt: &CommandDataOption) { let weapon = opt.options.get(0).expect("No argument for command Genshin build") .value.as_ref().expect("").as_str().expect("Not a string"); @@ -38,7 +38,7 @@ pub async fn show_weapon_embed(ctx: &Context, command: &MessageComponentInteract command.create_interaction_response(&ctx.http, |res| { res.kind(InteractionResponseType::UpdateMessage) .interaction_response_data(|d| { - d.embeds(vec!(weapon.to_embed()).into_iter()) + d.set_embeds(vec!(weapon.to_embed()).into_iter()) .flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL) }) }).await.expect("The message didn't got sent"); diff --git a/src/interactions/mod.rs b/src/interactions/mod.rs index 44fc3de..cb8b01c 100644 --- a/src/interactions/mod.rs +++ b/src/interactions/mod.rs @@ -1,22 +1,19 @@ pub mod status_message; pub mod genshin; -#[path = "../data/mod.rs"] -mod data; -#[path = "../utils/mod.rs"] -pub mod utils; +use crate::data; +use crate::utils; use serenity::client::Context; -use serenity::model::interactions::{InteractionApplicationCommandCallbackDataFlags, InteractionResponseType}; -use serenity::model::interactions::application_command::ApplicationCommandInteraction; +use serenity::model::application::interaction::{MessageFlags, InteractionResponseType, application_command::ApplicationCommandInteraction}; pub async fn pong(ctx : Context, command : ApplicationCommandInteraction) { let res = command.create_interaction_response(ctx.http, |res| { res.kind(InteractionResponseType::ChannelMessageWithSource) .interaction_response_data(|response| { - response.flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL) + response.flags(MessageFlags::EPHEMERAL) .content("An error has occurred") }) }).await; diff --git a/src/interactions/status_message.rs b/src/interactions/status_message.rs index 35632e1..142e657 100644 --- a/src/interactions/status_message.rs +++ b/src/interactions/status_message.rs @@ -1,4 +1,3 @@ -use std::borrow::Borrow; use std::time::Duration; use rand::Rng; use serenity::{ @@ -7,10 +6,10 @@ use serenity::{ } }; use serenity::builder::CreateEmbed; +use serenity::model::application::interaction::MessageFlags; use serenity::model::id::{ChannelId, MessageId}; +use serenity::model::application::interaction::application_command::ApplicationCommandInteraction; -use serenity::model::interactions::application_command::ApplicationCommandInteraction; -use serenity::model::interactions::InteractionApplicationCommandCallbackDataFlags; use serenity::model::prelude::{InteractionResponseType}; use serenity::utils::Colour; use crate::interactions::data::events::Event; @@ -18,18 +17,18 @@ use crate::utils::mongo::{add_discord_status_message, get_all_status_messages, g pub async fn update_status_message(ctx: Context) { - let forever = tokio::task::spawn(async move { + tokio::task::spawn(async move { let mut interval = tokio::time::interval(Duration::from_secs(60*60)); loop { let mut x = get_all_status_messages().await; x.reverse(); let embeds = create_status_embed().await; for sm in x { - let embeds : Vec = (&embeds).clone(); - let ctx = ctx.borrow().clone(); + let embeds : Vec = embeds.clone(); + let ctx = ctx.clone(); tokio::spawn( async move { if sm.channel_id == 0 { return } - let msg = ChannelId::from(sm.channel_id as u64).message(ctx.borrow().clone().http, sm.message_id as u64).await; + let msg = ChannelId::from(sm.channel_id as u64).message(ctx.clone().http, sm.message_id as u64).await; match msg { Ok(mut m) => { match m.edit(&ctx.http, |f| { @@ -49,7 +48,6 @@ pub async fn update_status_message(ctx: Context) { interval.tick().await; } }); - forever.await.expect("Stopped for some reasons"); } #[allow(dead_code)] @@ -58,10 +56,10 @@ pub async fn create_status_interaction(ctx: Context, command: ApplicationCommand if !altcommand.member.unwrap().permissions.expect("No permissions").manage_messages() { command.create_interaction_response(&ctx.http, |f| { f.kind(InteractionResponseType::ChannelMessageWithSource).interaction_response_data(|r| { - r.create_embed(|e| { + r.embed(|e| { e.title("Command Unsuccessful").description("You do not have the right to manage messages.") .color(Colour::from(0xff0000)) - }).flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL) + }).flags(MessageFlags::EPHEMERAL) }) }).await.expect("Interaction didn't work"); return; @@ -73,19 +71,16 @@ pub async fn create_status_interaction(ctx: Context, command: ApplicationCommand let channel_id = channel_option.keys().next().expect("No options passed"); let message = get_discord_status_message(&command.guild_id.expect("Not in guild").as_u64().to_owned()).await; - match message { - Some(e) => { - let rm = ChannelId::from(e.channel_id as u64) - .message(&ctx.http, MessageId::from(e.message_id as u64)) - .await; - match rm { - msg if rm.is_ok() => { - msg.unwrap().delete(&ctx.http).await.unwrap(); - } - _ => {} + if let Some(e) = message { + let rm = ChannelId::from(e.channel_id as u64) + .message(&ctx.http, MessageId::from(e.message_id as u64)) + .await; + match rm { + msg if rm.is_ok() => { + msg.unwrap().delete(&ctx.http).await.unwrap(); } + _ => {} } - _ => {} }; let msg = channel_id.send_message(&ctx.http, |f| { @@ -104,12 +99,12 @@ pub async fn create_status_interaction(ctx: Context, command: ApplicationCommand command.create_interaction_response(&ctx.http, |r| { r.kind(InteractionResponseType::ChannelMessageWithSource) .interaction_response_data(|d| { - d.create_embed(|e| { + d.embed(|e| { e.title("Command Successful !"); e.color(Colour::new(0x00ff00)); - e.description(format!("Status message created !")) + e.description("Status message created !".to_string()) }) - .flags(InteractionApplicationCommandCallbackDataFlags::EPHEMERAL) + .flags(MessageFlags::EPHEMERAL) }) }).await.unwrap(); } @@ -120,7 +115,7 @@ async fn create_status_embed() -> Vec { let mut current = Event::get_current().await; let mut others = current.clone(); - let mut question_marks = format!(""); + let mut question_marks = String::new(); let mut upcoming = Event::get_upcoming().await; @@ -137,17 +132,11 @@ async fn create_status_embed() -> Vec { embed.title(e.name); embed.color(Colour::new(rand::thread_rng().gen_range(0x000000..0xffffff))); - match &e.image { - Some(url) => { - embed.image(format!("https://github.com/MadeBaruna/paimon-moe/raw/main/static/images/events/{}", url)); - } - _ => {} + if let Some(url) = &e.image { + embed.image(format!("https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/static/images/events/{}", url.replace(' ', "%20"))); }; - match e.url { - Some(t) => { embed.url(format!("{}{}", t, question_marks)); } - _ => {} - }; + if let Some(t) = e.url { embed.url(format!("{}{}", t, question_marks)); }; embed.description(format!("Ends : ", e.end_timestamp.expect("No End Timestamp"))); embeds.push(embed); @@ -164,28 +153,19 @@ async fn create_status_embed() -> Vec { } embeds.push(other_embed); - match upcoming_event { - Some(e) => { - let mut upcoming_embed = CreateEmbed::default(); - question_marks = format!("{}?", question_marks); - upcoming_embed.title(&e.name); - upcoming_embed.description(format!("Starts : ", e.start_timestamp.expect("No Start Timestamp"))); - upcoming_embed.color(Colour::new(rand::thread_rng().gen_range(0x000000..0xffffff))); + if let Some(e) = upcoming_event { + let mut upcoming_embed = CreateEmbed::default(); + question_marks = format!("{}?", question_marks); + upcoming_embed.title(&e.name); + upcoming_embed.description(format!("Starts : ", e.start_timestamp.expect("No Start Timestamp"))); + upcoming_embed.color(Colour::new(rand::thread_rng().gen_range(0x000000..0xffffff))); - match &e.image { - Some(url) => { - upcoming_embed.image(format!("https://github.com/MadeBaruna/paimon-moe/raw/main/static/images/events/{}", url)); - } - _ => {} - }; + if let Some(url) = &e.image { + upcoming_embed.image(format!("https://github.com/MadeBaruna/paimon-moe/raw/main/static/images/events/{}", url)); + }; - match &e.url { - Some(url) => { upcoming_embed.url(format!("{}{}", url, question_marks)); } - _ => {} - }; - embeds.push(upcoming_embed); - } - _ => {} + if let Some(url) = &e.url { upcoming_embed.url(format!("{}{}", url, question_marks)); }; + embeds.push(upcoming_embed); }; embeds diff --git a/src/main.rs b/src/main.rs index 8ded161..afb3a08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,17 +8,18 @@ use serenity::{ async_trait, model::{ gateway::Ready, - interactions::{ - application_command::{ - ApplicationCommand, - ApplicationCommandOptionType, + application::{ + command::{ + Command, + CommandOptionType, }, - Interaction, + interaction::{ + Interaction + } }, }, prelude::*, }; -use serenity::client::bridge::gateway::GatewayIntents; use serenity::model::gateway::Activity; use serenity::model::prelude::OnlineStatus; use crate::interactions::genshin::artifacts::show_artifact_embed; @@ -35,13 +36,16 @@ impl EventHandler for Handler { update_status_message(_ctx.clone()).await; _ctx.set_presence(Some(Activity::playing("getting drunk with Kaeya")), OnlineStatus::Online).await; - let x = ApplicationCommand::get_global_application_commands(&_ctx.http).await.unwrap(); + let x = Command::get_global_application_commands(&_ctx.http).await.unwrap(); + for y in &x { + println!("{}", y.name); + } for i in x { match i.name.as_str() { "genshin" => (), "createstatusmessage" => (), _ => { - let _result_delete = ApplicationCommand::delete_global_application_command(&_ctx.http, i.id).await; + let _result_delete = Command::delete_global_application_command(&_ctx.http, i.id).await; match _result_delete { Ok(()) => { println!("Deleted command {}", i.name) } Err(f) => { println!("An error occurred deleting {} : {}", i.name, f) } @@ -50,35 +54,35 @@ impl EventHandler for Handler { } } - let x = ApplicationCommand::create_global_application_command(&_ctx.http, |command| { + let x = Command::create_global_application_command(&_ctx.http, |command| { command.name("genshin").description("Get Informations about Genshin Impact.").create_option(|option| { option.name("builds") .description("Shows builds for a Genshin Impact Characters") - .kind(ApplicationCommandOptionType::SubCommand) + .kind(CommandOptionType::SubCommand) .create_sub_option(|so| { so.name("character").description("Character to get builds for") - .kind(ApplicationCommandOptionType::String) + .kind(CommandOptionType::String) .required(true) }) }) .create_option(|option| { option.name("weapon") .description("Shows infos on a Genshin Impact weapon.") - .kind(ApplicationCommandOptionType::SubCommand) + .kind(CommandOptionType::SubCommand) .create_sub_option(|so| { so.name("name").description("Weapon you want infos on.") - .kind(ApplicationCommandOptionType::String) + .kind(CommandOptionType::String) .required(true) }) }) .create_option(|option| { option.name("artifact") .description("Shows infos on a Genshin Impact artifact set.") - .kind(ApplicationCommandOptionType::SubCommand) + .kind(CommandOptionType::SubCommand) .create_sub_option(|so| { so.name("artifact") .description("Artifact Set you want infos on.") - .kind(ApplicationCommandOptionType::String) + .kind(CommandOptionType::String) .required(true) }) }) @@ -87,10 +91,10 @@ impl EventHandler for Handler { println!("{}", x.unwrap_err()); } - ApplicationCommand::create_global_application_command(&_ctx.http, |command| { + Command::create_global_application_command(&_ctx.http, |command| { command.name("createstatusmessage").create_option(|opt| { opt.name("channel").description("Channel where to put the status message") - .kind(ApplicationCommandOptionType::Channel) + .kind(CommandOptionType::Channel) .required(true) }).description("Creates a status message of all the current events on Genshin Impact") }).await.expect("Can't create the createstatusmessage command"); @@ -107,7 +111,7 @@ impl EventHandler for Handler { _ => interactions::pong(_ctx, command).await } } else if let Interaction::MessageComponent(component) = _interaction { - let mut args = component.data.custom_id.split("_"); + let mut args = component.data.custom_id.split('_'); let command = args.next(); match command.unwrap() { "weapon" => { @@ -148,14 +152,13 @@ async fn main() { let needed_intents = [ GatewayIntents::GUILDS, GatewayIntents::GUILD_MESSAGES, - GatewayIntents::GUILD_EMOJIS, + GatewayIntents::GUILD_EMOJIS_AND_STICKERS, GatewayIntents::GUILD_WEBHOOKS, GatewayIntents::GUILD_INTEGRATIONS ]; - let mut client = Client::builder(token) + let mut client = Client::builder(token, GatewayIntents::from_iter(needed_intents.into_iter())) .event_handler(Handler) - .intents(GatewayIntents::from_iter(needed_intents.into_iter())) .application_id(application_id) .await .expect("Error creating the client"); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 3454acf..21e9216 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,6 +1,6 @@ use linked_hash_map::LinkedHashMap; use serenity::builder::{CreateActionRow, CreateButton}; -use serenity::model::interactions::message_component::ButtonStyle; +use serenity::model::application::component::ButtonStyle; pub mod mongo; diff --git a/src/utils/mongo.rs b/src/utils/mongo.rs index 2df5f34..bdd84ea 100644 --- a/src/utils/mongo.rs +++ b/src/utils/mongo.rs @@ -42,7 +42,7 @@ pub async fn get_discord_status_message(gid: &u64) -> Option { match infos { Some(i) => { let m_infos: StatusMessage = from_bson(Bson::Document(i)).expect("Can't get"); - return Some(m_infos); + Some(m_infos) } _ => None } @@ -55,7 +55,7 @@ pub async fn get_all_status_messages() -> Vec { let collection: Collection = client.database("drunk_venti").collection::("StatusMessages"); let documents = collection.find(None, None).await.expect("Can't get everything"); let all_docs: Vec = documents.try_collect().await.unwrap_or_else(|_| vec![]); - return all_docs; + all_docs } #[allow(dead_code)]