Optimize Item Extractor

Reduce JSON file size. All things we put in are already there as components
Replace item searching with a HashMap (which is faster)
This commit is contained in:
Snowiiii 2024-11-17 22:30:38 +01:00
parent 230a99adc5
commit b01b276307
6 changed files with 14260 additions and 21148 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ import com.mojang.serialization.JsonOps
import de.snowii.extractor.Extractor import de.snowii.extractor.Extractor
import net.minecraft.component.ComponentMap import net.minecraft.component.ComponentMap
import net.minecraft.item.Item import net.minecraft.item.Item
import net.minecraft.recipe.Recipe
import net.minecraft.registry.Registries import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKeys import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.RegistryOps import net.minecraft.registry.RegistryOps
@ -20,19 +21,13 @@ class Items : Extractor.Extractor {
override fun extract(server: MinecraftServer): JsonElement { override fun extract(server: MinecraftServer): JsonElement {
val itemsJson = JsonArray() val itemsJson = JsonObject()
for (item in server.registryManager.getOrThrow(RegistryKeys.ITEM).streamEntries().toList()) { for (item in server.registryManager.getOrThrow(RegistryKeys.ITEM).streamEntries().toList()) {
val itemJson = JsonObject() val itemJson = JsonObject()
val realItem: Item = item.value() val realItem: Item = item.value()
itemJson.addProperty("id", Registries.ITEM.getRawId(realItem)) itemJson.addProperty("id", Registries.ITEM.getRawId(realItem))
itemJson.addProperty("name", Registries.ITEM.getId(realItem).toString())
itemJson.addProperty("translation_key", realItem.translationKey)
itemJson.addProperty("max_stack", realItem.maxCount)
itemJson.addProperty("max_durability", realItem.defaultStack.maxDamage)
itemJson.addProperty("break_sound", realItem.breakSound.id().toString())
itemJson.add( itemJson.add(
"components", "components",
ComponentMap.CODEC.encodeStart( ComponentMap.CODEC.encodeStart(
@ -41,7 +36,7 @@ class Items : Extractor.Extractor {
).getOrThrow() ).getOrThrow()
) )
itemsJson.add(itemJson) itemsJson.add(Registries.ITEM.getId(realItem).toString(), itemJson)
} }
return itemsJson return itemsJson
} }

View File

@ -1,35 +1,25 @@
use std::sync::LazyLock; use std::{collections::HashMap, sync::LazyLock};
use serde::Deserialize; use serde::Deserialize;
const ITEMS_JSON: &str = include_str!("../../../assets/items.json"); const ITEMS_JSON: &str = include_str!("../../../assets/items.json");
pub static ITEMS: LazyLock<Vec<Item>> = LazyLock::new(|| { pub static ITEMS: LazyLock<HashMap<String, Item>> = LazyLock::new(|| {
serde_json::from_str(ITEMS_JSON).expect("Could not parse items.json registry.") serde_json::from_str(ITEMS_JSON).expect("Could not parse items.json registry.")
}); });
pub fn get_item<'a>(name: &str) -> Option<&'a Item> { pub fn get_item(name: &str) -> Option<&Item> {
ITEMS.iter().find(|item| item.name == name) ITEMS.get(name)
} }
#[expect(dead_code)]
#[derive(Deserialize, Clone, Debug)] #[derive(Deserialize, Clone, Debug)]
pub struct Item { pub struct Item {
pub id: u16, pub id: u16,
pub name: String, pub components: ItemComponents,
translation_key: String,
pub max_stack: i8,
max_durability: u16,
break_sound: String,
food: Option<FoodComponent>,
} }
#[expect(dead_code)]
#[derive(Deserialize, Clone, Debug)] #[derive(Deserialize, Clone, Debug)]
struct FoodComponent { pub struct ItemComponents {
hunger: u16, #[serde(rename = "minecraft:max_stack_size")]
saturation: f32, pub max_stack_size: u8,
always_edible: bool,
meat: bool,
snack: bool,
} }

View File

@ -552,7 +552,7 @@ impl Player {
} }
async fn pickup_items(&self, item: &Item, mut amount: u32) { async fn pickup_items(&self, item: &Item, mut amount: u32) {
let max_stack = item.max_stack as u8; let max_stack = item.components.max_stack_size;
let mut inventory = self.inventory.lock().await; let mut inventory = self.inventory.lock().await;
let slots = inventory.slots_with_hotbar_first(); let slots = inventory.slots_with_hotbar_first();
@ -578,7 +578,7 @@ impl Player {
amount = amount_left; amount = amount_left;
*slot = Some(ItemStack { *slot = Some(ItemStack {
item_id: item.id, item_id: item.id,
item_count: item.max_stack as u8, item_count: item.components.max_stack_size,
}); });
} else { } else {
*slot = Some(ItemStack { *slot = Some(ItemStack {
@ -610,7 +610,9 @@ impl Player {
return; return;
} }
} }
log::warn!("{amount} items ({}) were discarded because dropping them to the ground is not implemented", item.name); log::warn!(
"{amount} items were discarded because dropping them to the ground is not implemented"
);
} }
/// Add items to inventory if there's space, else drop them to the ground. /// Add items to inventory if there's space, else drop them to the ground.

View File

@ -67,12 +67,12 @@ impl DefaultNameArgConsumer for ItemArgumentConsumer {
} }
impl<'a> FindArg<'a> for ItemArgumentConsumer { impl<'a> FindArg<'a> for ItemArgumentConsumer {
type Data = &'a Item; type Data = (&'a str, &'a Item);
fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result<Self::Data, CommandError> { fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result<Self::Data, CommandError> {
match args.get(name) { match args.get(name) {
Some(Arg::Item(name)) => match item_registry::get_item(name) { Some(Arg::Item(name)) => match item_registry::get_item(name) {
Some(item) => Ok(item), Some(item) => Ok((name, item)),
None => Err(CommandError::GeneralCommandIssue(format!( None => Err(CommandError::GeneralCommandIssue(format!(
"Item {name} does not exist." "Item {name} does not exist."
))), ))),

View File

@ -34,7 +34,7 @@ impl CommandExecutor for GiveExecutor {
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
let targets = PlayersArgumentConsumer.find_arg_default_name(args)?; let targets = PlayersArgumentConsumer.find_arg_default_name(args)?;
let item = ItemArgumentConsumer::find_arg(args, ARG_ITEM)?; let (item_name, item) = ItemArgumentConsumer::find_arg(args, ARG_ITEM)?;
let item_count = match ITEM_COUNT_CONSUMER.find_arg_default_name(args) { let item_count = match ITEM_COUNT_CONSUMER.find_arg_default_name(args) {
Err(_) => 1, Err(_) => 1,
@ -58,11 +58,11 @@ impl CommandExecutor for GiveExecutor {
.send_message(TextComponent::text_string(match targets { .send_message(TextComponent::text_string(match targets {
[target] => format!( [target] => format!(
"Gave {item_count} {} to {}", "Gave {item_count} {} to {}",
item.name, target.gameprofile.name item_name, target.gameprofile.name
), ),
_ => format!( _ => format!(
"Gave {item_count} {} to {} players", "Gave {item_count} {} to {} players",
item.name, item_name,
targets.len() targets.len()
), ),
})) }))