diff --git a/Cargo.lock b/Cargo.lock index eee1ca6..f1c2dd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1224,9 +1224,9 @@ dependencies = [ [[package]] name = "minecraft-data-rs" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6878c011df73cf61f64b8c55022a2b9b713233d234a8083d2e8a01057921856e" +checksum = "2e1b246bcfc363acfa56bb9414deee90e194a9de2fbfb8c43442da0d77663de4" dependencies = [ "include_dir", "itertools", diff --git a/Cargo.toml b/Cargo.toml index ab87193..e86aa75 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ tokio = { version = "1.4.0", features = ["macros", "rt-multi-thread"] } serde_derive = "1.0.125" serde = "1.0.125" thiserror = "1.0.24" -minecraft-data-rs = "0.2.0" +minecraft-data-rs = "0.3.0" songbird = "0.1.5" serde_json = "1.0.64" rand = "0.8.3" diff --git a/src/commands/minecraft/item.rs b/src/commands/minecraft/item.rs index 496e173..a8cc563 100644 --- a/src/commands/minecraft/item.rs +++ b/src/commands/minecraft/item.rs @@ -1,8 +1,10 @@ use serenity::client::Context; -use serenity::framework::standard::{macros::command, Args, CommandError, CommandResult}; +use serenity::framework::standard::{macros::command, Args, CommandResult}; use serenity::model::channel::Message; use crate::commands::common::handle_autodelete; +use crate::messages::minecraft::item::create_item_message; +use crate::providers::minecraft::get_item_full_information; use crate::utils::context_data::Store; #[command] @@ -18,50 +20,10 @@ pub(crate) async fn item(ctx: &Context, msg: &Message, args: Args) -> CommandRes let item_name = args.message().to_lowercase(); log::debug!("Searching for item '{}'", item_name); - let items_by_name = store.minecraft_data_api.items.items_by_name()?; - let item = items_by_name - .get(&item_name) - .ok_or(CommandError::from(format!( - "The item `{}` could not be found", - item_name - )))?; - let enchantments_by_category = store - .minecraft_data_api - .enchantments - .enchantments_by_category()?; - log::trace!("Item is {:?}", item); + let information = get_item_full_information(&item_name, &store.minecraft_data_api)?; + log::trace!("Item full information is {:?}", information); + create_item_message(ctx, msg.channel_id, information).await?; - msg.channel_id - .send_message(ctx, |m| { - m.embed(|mut e| { - e = e - .title(&*item.display_name) - .thumbnail(format!( - "https://minecraftitemids.com/item/128/{}.png", - item.name - )) - .field("Name", &*item.name, false) - .field("Stack Size", item.stack_size, false); - if let Some(durability) = item.durability { - e = e.field("Durability", durability, true); - } - if let Some(variations) = &item.variations { - e = e.field("Variations", format!("{:?}", variations), false); - } - if let Some(enchant_categories) = &item.enchant_categories { - let item_enchantments = enchant_categories - .into_iter() - .filter_map(|c| enchantments_by_category.get(c)) - .flatten() - .map(|e| e.display_name.clone()) - .collect::>(); - e = e.field("Enchantments", item_enchantments.join(", "), false); - } - - e - }) - }) - .await?; handle_autodelete(ctx, msg).await?; Ok(()) diff --git a/src/messages/minecraft/item.rs b/src/messages/minecraft/item.rs new file mode 100644 index 0000000..5a62994 --- /dev/null +++ b/src/messages/minecraft/item.rs @@ -0,0 +1,53 @@ +use crate::providers::minecraft::ItemFullInformation; +use crate::utils::error::BotResult; +use serenity::client::Context; +use serenity::model::channel::Message; +use serenity::model::prelude::ChannelId; + +pub async fn create_item_message( + ctx: &Context, + channel_id: ChannelId, + item: ItemFullInformation, +) -> BotResult { + let message = channel_id + .send_message(ctx, |m| { + m.embed(|mut e| { + e = e + .title(&item.name) + .thumbnail(format!( + "https://minecraftitemids.com/item/128/{}.png", + item.id + )) + .field("Name", &item.name, false) + .field("Stack Size", item.stack_size, false); + + if let Some(durability) = item.durability { + e.field("Durability", durability, true); + } + + if let Some(food) = &item.food { + e.field("Saturation", food.saturation, true); + } + + if let Some(block) = &item.block { + e.field("Hardness", block.hardness.unwrap_or(0f32), true) + .field( + "Blast Resistance", + block.blast_resistance.unwrap_or(0f32), + true, + ) + .field("Transparent", block.transparent, true) + .field("Emission Level", block.emit_light, true); + } + + if !item.enchantments.is_empty() { + e.field("Enchantments", item.enchantments.join(", "), false); + } + + e + }) + }) + .await?; + + Ok(message) +} diff --git a/src/messages/minecraft/mod.rs b/src/messages/minecraft/mod.rs new file mode 100644 index 0000000..a35e98d --- /dev/null +++ b/src/messages/minecraft/mod.rs @@ -0,0 +1 @@ +pub mod item; diff --git a/src/messages/mod.rs b/src/messages/mod.rs index 3b74e13..43c3c2f 100644 --- a/src/messages/mod.rs +++ b/src/messages/mod.rs @@ -5,6 +5,7 @@ use serenity::client::Context; use std::time::{Duration, SystemTime}; pub mod gifs; +pub mod minecraft; pub mod music; pub mod sauce; diff --git a/src/providers/minecraft.rs b/src/providers/minecraft.rs new file mode 100644 index 0000000..1d9b8ff --- /dev/null +++ b/src/providers/minecraft.rs @@ -0,0 +1,47 @@ +use crate::utils::error::{BotError, BotResult}; +use minecraft_data_rs::api::Api; +use minecraft_data_rs::models::block::Block; +use minecraft_data_rs::models::food::Food; + +#[derive(Clone, Debug)] +pub struct ItemFullInformation { + pub id: String, + pub name: String, + pub enchantments: Vec, + pub durability: Option, + pub stack_size: u8, + pub food: Option, + pub block: Option, +} + +pub fn get_item_full_information(name: &str, api: &Api) -> BotResult { + let items_by_name = api.items.items_by_name()?; + let item = items_by_name.get(name).ok_or(BotError::Msg(format!( + "The item `{}` could not be found", + name + )))?; + let enchantments_by_category = api.enchantments.enchantments_by_category()?; + let mut enchantments = Vec::new(); + + if let Some(enchant_categories) = &item.enchant_categories { + enchantments = enchant_categories + .into_iter() + .filter_map(|c| enchantments_by_category.get(c)) + .flatten() + .map(|e| e.display_name.clone()) + .collect::>(); + } + let food_by_name = api.foods.foods_by_name()?; + let blocks_by_name = api.blocks.blocks_by_name()?; + + log::trace!("Item is {:?}", item); + Ok(ItemFullInformation { + id: item.name.clone(), + name: item.display_name.clone(), + enchantments, + durability: item.durability.clone(), + stack_size: item.stack_size, + food: food_by_name.get(name).cloned(), + block: blocks_by_name.get(name).cloned(), + }) +} diff --git a/src/providers/mod.rs b/src/providers/mod.rs index b26a4ed..f162fdb 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod music; pub(crate) mod qalc; pub(crate) mod settings; +pub(crate) mod minecraft;