Add component readers for all the planned components

This commit is contained in:
Eclipse 2024-11-29 15:16:04 +00:00
parent 61f5db1059
commit ea6c3c67f0
No known key found for this signature in database
GPG key ID: 95E6998F82EC938A
8 changed files with 239 additions and 6 deletions

View file

@ -46,4 +46,10 @@ public abstract class DataComponentReader<V> {
// TODO primitives??
return type.getDataComponentFactory().create(type, readDataComponent(node));
}
protected static void requireObject(JsonNode node) throws InvalidCustomMappingsFileException {
if (!node.isObject()) {
throw new InvalidCustomMappingsFileException("Expected an object");
}
}
}

View file

@ -30,7 +30,12 @@ import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
import org.geysermc.geyser.registry.mappings.components.readers.ConsumableReader;
import org.geysermc.geyser.registry.mappings.components.readers.EquippableReader;
import org.geysermc.geyser.registry.mappings.components.readers.FoodReader;
import org.geysermc.geyser.registry.mappings.components.readers.IntComponentReader;
import org.geysermc.geyser.registry.mappings.components.readers.UseCooldownReader;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import java.util.HashMap;
@ -49,5 +54,10 @@ public class DataComponentReaders {
static {
READERS.put(MinecraftKey.key("consumable"), new ConsumableReader());
READERS.put(MinecraftKey.key("equippable"), new EquippableReader());
READERS.put(MinecraftKey.key("food"), new FoodReader());
READERS.put(MinecraftKey.key("max_damage"), new IntComponentReader(DataComponentType.MAX_DAMAGE, 0));
READERS.put(MinecraftKey.key("max_stack_size"), new IntComponentReader(DataComponentType.MAX_STACK_SIZE, 0, 99));
READERS.put(MinecraftKey.key("use_cooldown"), new UseCooldownReader());
}
}

View file

@ -43,10 +43,7 @@ public class ConsumableReader extends DataComponentReader<Consumable> {
@Override
protected Consumable readDataComponent(@NonNull JsonNode node) throws InvalidCustomMappingsFileException {
if (!node.isObject()) {
throw new InvalidCustomMappingsFileException("Expected consumable component to be an object");
}
requireObject(node);
float consumeSeconds = 1.6F;
if (node.has("consume_seconds")) {
consumeSeconds = (float) node.get("consume_seconds").asDouble();
@ -57,6 +54,6 @@ public class ConsumableReader extends DataComponentReader<Consumable> {
animation = Consumable.ItemUseAnimation.valueOf(node.get("animation").asText().toUpperCase()); // TODO maybe not rely on the enum
}
return new Consumable(consumeSeconds, animation, BuiltinSound.ENTITY_GENERIC_EAT, false, List.of()); // TODO
return new Consumable(consumeSeconds, animation, BuiltinSound.ENTITY_GENERIC_EAT, false, List.of()); // TODO are sound and particles supported on bedrock?
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry.mappings.components.readers;
import com.fasterxml.jackson.databind.JsonNode;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
import org.geysermc.geyser.registry.mappings.components.DataComponentReader;
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Equippable;
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound;
public class EquippableReader extends DataComponentReader<Equippable> {
public EquippableReader() {
super(DataComponentType.EQUIPPABLE);
}
@Override
protected Equippable readDataComponent(@NonNull JsonNode node) throws InvalidCustomMappingsFileException {
requireObject(node);
JsonNode slot = node.get("slot");
if (slot == null || !slot.isTextual()) {
throw new InvalidCustomMappingsFileException("Expected slot to be helmet, chestplate, leggings or boots");
}
return new Equippable(EquipmentSlot.valueOf(slot.asText().toUpperCase()), BuiltinSound.ITEM_ARMOR_EQUIP_GENERIC,
null, null, null, false, false, false); // Other properties are unused
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry.mappings.components.readers;
import com.fasterxml.jackson.databind.JsonNode;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
import org.geysermc.geyser.registry.mappings.components.DataComponentReader;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.FoodProperties;
public class FoodReader extends DataComponentReader<FoodProperties> {
public FoodReader() {
super(DataComponentType.FOOD);
}
@Override
protected FoodProperties readDataComponent(@NonNull JsonNode node) throws InvalidCustomMappingsFileException {
requireObject(node);
JsonNode canAlwaysEat = node.get("can_always_eat");
return new FoodProperties(0, 0, canAlwaysEat != null && canAlwaysEat.asBoolean());
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry.mappings.components.readers;
import com.fasterxml.jackson.databind.JsonNode;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
import org.geysermc.geyser.registry.mappings.components.DataComponentReader;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
public class IntComponentReader extends DataComponentReader<Integer> {
private final int minimum;
private final int maximum;
public IntComponentReader(DataComponentType<Integer> type, int minimum, int maximum) {
super(type);
this.minimum = minimum;
this.maximum = maximum;
}
public IntComponentReader(DataComponentType<Integer> type, int minimum) {
this(type, minimum, Integer.MAX_VALUE);
}
@Override
protected Integer readDataComponent(@NonNull JsonNode node) throws InvalidCustomMappingsFileException {
if (!node.isIntegralNumber()) {
throw new InvalidCustomMappingsFileException("Expected an integer number");
}
int value = node.asInt();
if (value < minimum || value > maximum) {
throw new InvalidCustomMappingsFileException("Expected integer to be in the range of [" + minimum + ", " + maximum + "]");
}
return value;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry.mappings.components.readers;
import com.fasterxml.jackson.databind.JsonNode;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
import org.geysermc.geyser.registry.mappings.components.DataComponentReader;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.UseCooldown;
public class UseCooldownReader extends DataComponentReader<UseCooldown> {
public UseCooldownReader() {
super(DataComponentType.USE_COOLDOWN);
}
@Override
protected UseCooldown readDataComponent(@NonNull JsonNode node) throws InvalidCustomMappingsFileException {
requireObject(node);
JsonNode seconds = node.get("seconds");
JsonNode cooldown_group = node.get("cooldown_group");
if (seconds == null || !seconds.isNumber()) {
throw new InvalidCustomMappingsFileException("Expected seconds to be a number");
}
if (cooldown_group == null || !cooldown_group.isTextual()) {
throw new InvalidCustomMappingsFileException("Expected cooldown group to be a resource location");
}
return new UseCooldown((float) seconds.asDouble(), Key.key(cooldown_group.asText()));
}
}

View file

@ -69,7 +69,6 @@ public class CustomItemRegistryPopulator_v2 {
// Load custom items from mappings files
mappingsConfigReader.loadItemMappingsFromJson((id, item) -> {
if (initialCheck(item, items)) {
System.out.println("read item " + id + " item " + item);
customItems.get(id).add(item);
}
});