Remove adventure from API module

This commit is contained in:
Eclipse 2024-12-12 11:26:16 +00:00
parent 774e55625d
commit 1685918212
No known key found for this signature in database
GPG key ID: 95E6998F82EC938A
9 changed files with 122 additions and 28 deletions

View file

@ -9,10 +9,7 @@ dependencies {
api(libs.base.api)
api(libs.math)
// Adventure text serialization
api(libs.bundles.adventure)
// TODO? can we exclude more
// TODO remove MCPL from API
api(libs.mcprotocollib) {
exclude("io.netty", "netty-all")
exclude("net.raphimc", "MinecraftAuth")

View file

@ -25,7 +25,6 @@
package org.geysermc.geyser.api.item.custom;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.api.GeyserApi;
@ -34,6 +33,7 @@ import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.api.item.custom.v2.predicate.ConditionPredicate;
import org.geysermc.geyser.api.item.custom.v2.predicate.RangeDispatchPredicate;
import org.geysermc.geyser.api.util.CreativeCategory;
import org.geysermc.geyser.api.util.Identifier;
import org.geysermc.geyser.api.util.TriState;
import java.util.Objects;
@ -130,8 +130,8 @@ public interface CustomItemData {
}
default CustomItemDefinition.Builder toDefinition(String javaItem) {
// TODO non vanilla, unbreakable predicate?
CustomItemDefinition.Builder definition = CustomItemDefinition.builder(Key.key(javaItem), Key.key(javaItem))
// TODO non vanilla
CustomItemDefinition.Builder definition = CustomItemDefinition.builder(new Identifier(javaItem), new Identifier(javaItem))
.displayName(displayName())
.bedrockOptions(CustomItemBedrockOptions.builder()
.icon(icon())

View file

@ -25,10 +25,10 @@
package org.geysermc.geyser.api.item.custom.v2;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.api.GeyserApi;
import org.geysermc.geyser.api.item.custom.v2.predicate.CustomItemPredicate;
import org.geysermc.geyser.api.util.Identifier;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import java.util.List;
@ -43,7 +43,7 @@ public interface CustomItemDefinition {
* The Bedrock identifier for this custom item. This can't be in the {@code minecraft} namespace. If the {@code minecraft} namespace is given in the builder, the default
* namespace of the implementation is used. For Geyser, the default namespace is the {@code geyser_custom} namespace.
*/
@NonNull Key bedrockIdentifier();
@NonNull Identifier bedrockIdentifier();
/**
* The display name of the item. If none is set, the display name is taken from the item's Bedrock identifier.
@ -55,7 +55,7 @@ public interface CustomItemDefinition {
*
* <p>If multiple item definitions for a model are registered, then only one can have no predicate.</p>
*/
@NonNull Key model();
@NonNull Identifier model();
/**
* The icon used for this item.
@ -64,7 +64,7 @@ public interface CustomItemDefinition {
* the namespace separator replaced with {@code .} and the path separators ({@code /}) replaced with {@code _}.</p>
*/
default @NonNull String icon() {
return bedrockOptions().icon() == null ? bedrockIdentifier().asString().replaceAll(":", ".").replaceAll("/", "_") : bedrockOptions().icon();
return bedrockOptions().icon() == null ? bedrockIdentifier().toString().replaceAll(":", ".").replaceAll("/", "_") : bedrockOptions().icon();
}
/**
@ -104,7 +104,7 @@ public interface CustomItemDefinition {
*/
@NonNull DataComponents components();
static Builder builder(Key identifier, Key itemModel) {
static Builder builder(Identifier identifier, Identifier itemModel) {
return GeyserApi.api().provider(Builder.class, identifier, itemModel);
}

View file

@ -0,0 +1,88 @@
/*
* 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.api.util;
import java.util.function.Function;
public final class Identifier {
private static final String DEFAULT_NAMESPACE = "minecraft";
private final String namespace;
private final String path;
public Identifier(String namespace, String path) {
this.namespace = namespace;
this.path = path;
validate();
}
public Identifier(String identifier) {
String[] split = identifier.split(":");
if (split.length == 1) {
namespace = DEFAULT_NAMESPACE;
path = split[0];
} else if (split.length == 2) {
namespace = split[0];
path = split[1];
} else {
throw new IllegalArgumentException("':' in identifier path: " + identifier);
}
validate();
}
private void validate() {
checkString(namespace, "namespace", Identifier::allowedInNamespace);
checkString(path, "path", Identifier::allowedInPath);
}
public String namespace() {
return namespace;
}
public String path() {
return path;
}
@Override
public String toString() {
return namespace + ":" + path;
}
private static void checkString(String string, String type, Function<Character, Boolean> characterChecker) {
for (int i = 0; i < string.length(); i++) {
if (!characterChecker.apply(string.charAt(i))) {
throw new IllegalArgumentException("Illegal character in " + type + " " + string);
}
}
}
private static boolean allowedInNamespace(char character) {
return character == '_' || character == '-' || character >= 'a' && character <= 'z' || character >= '0' && character <= '9' || character == '.';
}
private static boolean allowedInPath(char character) {
return character == '_' || character == '-' || character >= 'a' && character <= 'z' || character >= '0' && character <= '9' || character == '.' || character == '/';
}
}

View file

@ -25,32 +25,32 @@
package org.geysermc.geyser.item.custom;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.api.item.custom.v2.CustomItemBedrockOptions;
import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.api.item.custom.v2.predicate.CustomItemPredicate;
import org.geysermc.geyser.api.util.Identifier;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public record GeyserCustomItemDefinition(@NonNull Key bedrockIdentifier, String displayName, @NonNull Key model, @NonNull List<CustomItemPredicate> predicates,
public record GeyserCustomItemDefinition(@NonNull Identifier bedrockIdentifier, String displayName, @NonNull Identifier model, @NonNull List<CustomItemPredicate> predicates,
int priority, @NonNull CustomItemBedrockOptions bedrockOptions, @NonNull DataComponents components) implements CustomItemDefinition {
public static class Builder implements CustomItemDefinition.Builder {
private final Key bedrockIdentifier;
private final Key model;
private final Identifier bedrockIdentifier;
private final Identifier model;
private final List<CustomItemPredicate> predicates = new ArrayList<>();
private int priority = 0;
private String displayName;
private CustomItemBedrockOptions bedrockOptions = CustomItemBedrockOptions.builder().build();
private DataComponents components = new DataComponents(new HashMap<>());
public Builder(Key bedrockIdentifier, Key model) {
public Builder(Identifier bedrockIdentifier, Identifier model) {
this.bedrockIdentifier = bedrockIdentifier;
this.displayName = bedrockIdentifier.asString();
this.displayName = bedrockIdentifier.toString();
this.model = model;
}

View file

@ -43,6 +43,7 @@ import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData;
import org.geysermc.geyser.api.item.custom.v2.CustomItemBedrockOptions;
import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.api.pack.PathPackCodec;
import org.geysermc.geyser.api.util.Identifier;
import org.geysermc.geyser.impl.camera.GeyserCameraFade;
import org.geysermc.geyser.impl.camera.GeyserCameraPosition;
import org.geysermc.geyser.event.GeyserEventRegistrar;
@ -90,7 +91,7 @@ public class ProviderRegistryLoader implements RegistryLoader<Map<Class<?>, Prov
providers.put(NonVanillaCustomItemData.Builder.class, args -> new GeyserNonVanillaCustomItemData.Builder());
// items v2
providers.put(CustomItemDefinition.Builder.class, args -> new GeyserCustomItemDefinition.Builder((Key) args[0], (Key) args[1]));
providers.put(CustomItemDefinition.Builder.class, args -> new GeyserCustomItemDefinition.Builder((Identifier) args[0], (Identifier) args[1]));
providers.put(CustomItemBedrockOptions.Builder.class, args -> new GeyserCustomItemBedrockOptions.Builder());
// cameras

View file

@ -41,9 +41,11 @@ import org.geysermc.geyser.api.item.custom.v2.predicate.match.ChargeType;
import org.geysermc.geyser.api.item.custom.v2.predicate.MatchPredicate;
import org.geysermc.geyser.api.item.custom.v2.predicate.match.MatchPredicateProperty;
import org.geysermc.geyser.api.util.CreativeCategory;
import org.geysermc.geyser.api.util.Identifier;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
import org.geysermc.geyser.registry.mappings.components.DataComponentReaders;
import org.geysermc.geyser.registry.mappings.util.CustomBlockMapping;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import java.nio.file.Path;
@ -128,11 +130,11 @@ public class MappingsReader_v2 extends MappingsReader {
throw new InvalidCustomMappingsFileException("An item entry has no model");
}
Key bedrockIdentifier = Key.key(bedrockIdentifierNode.asText());
Identifier bedrockIdentifier = new Identifier(bedrockIdentifierNode.asText());
if (bedrockIdentifier.namespace().equals(Key.MINECRAFT_NAMESPACE)) {
bedrockIdentifier = Key.key(Constants.GEYSER_CUSTOM_NAMESPACE, bedrockIdentifier.value());
bedrockIdentifier = new Identifier(Constants.GEYSER_CUSTOM_NAMESPACE, bedrockIdentifier.path());
}
CustomItemDefinition.Builder builder = CustomItemDefinition.builder(bedrockIdentifier, Key.key(model));
CustomItemDefinition.Builder builder = CustomItemDefinition.builder(bedrockIdentifier, new Identifier(model));
if (node.has("display_name")) {
builder.displayName(node.get("display_name").asText());
@ -151,7 +153,7 @@ public class MappingsReader_v2 extends MappingsReader {
if (componentsNode != null && componentsNode.isObject()) {
componentsNode.fields().forEachRemaining(entry -> {
try {
DataComponentReaders.readDataComponent(components, Key.key(entry.getKey()), entry.getValue());
DataComponentReaders.readDataComponent(components, MinecraftKey.key(entry.getKey()), entry.getValue());
} catch (InvalidCustomMappingsFileException e) {
GeyserImpl.getInstance().getLogger().error("Error reading component " + entry.getKey() + " for item model " + modelNode.textValue(), e);
}
@ -274,8 +276,8 @@ public class MappingsReader_v2 extends MappingsReader {
throw new InvalidCustomMappingsFileException("Unknown charge type " + value);
}
}
case "trim_material" -> builder.predicate(new MatchPredicate<>(MatchPredicateProperty.TRIM_MATERIAL, Key.key(value))); // TODO
case "context_dimension" -> builder.predicate(new MatchPredicate<>(MatchPredicateProperty.CONTEXT_DIMENSION, Key.key(value))); // TODO
case "trim_material" -> builder.predicate(new MatchPredicate<>(MatchPredicateProperty.TRIM_MATERIAL, MinecraftKey.key(value))); // TODO
case "context_dimension" -> builder.predicate(new MatchPredicate<>(MatchPredicateProperty.CONTEXT_DIMENSION, MinecraftKey.key(value))); // TODO
case "custom_model_data" -> {
JsonNode indexNode = node.get("index");
int index = 0;

View file

@ -43,6 +43,7 @@ import org.geysermc.geyser.api.item.custom.v2.CustomItemBedrockOptions;
import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.api.item.custom.v2.predicate.CustomItemPredicate;
import org.geysermc.geyser.api.util.CreativeCategory;
import org.geysermc.geyser.api.util.Identifier;
import org.geysermc.geyser.event.type.GeyserDefineCustomItemsEventImpl;
import org.geysermc.geyser.item.GeyserCustomMappingData;
import org.geysermc.geyser.item.components.WearableSlot;
@ -136,7 +137,7 @@ public class CustomItemRegistryPopulator {
GeyserImpl.getInstance().getLogger().error("Could not find the Java item to add custom item properties to for " + item.bedrockIdentifier());
return false;
}
Key bedrockIdentifier = item.bedrockIdentifier();
Identifier bedrockIdentifier = item.bedrockIdentifier();
if (bedrockIdentifier.namespace().equals(Key.MINECRAFT_NAMESPACE)) {
GeyserImpl.getInstance().getLogger().error("Custom item bedrock identifier namespace can't be minecraft");
return false;

View file

@ -64,6 +64,7 @@ import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.api.item.custom.v2.predicate.CustomItemPredicate;
import org.geysermc.geyser.api.item.custom.v2.predicate.RangeDispatchPredicate;
import org.geysermc.geyser.api.util.CreativeCategory;
import org.geysermc.geyser.api.util.Identifier;
import org.geysermc.geyser.inventory.item.StoredItemMappings;
import org.geysermc.geyser.item.GeyserCustomMappingData;
import org.geysermc.geyser.item.Items;
@ -483,7 +484,7 @@ public class ItemRegistryPopulator {
for (CustomItemDefinition customItem : customItemsToLoad) {
int customProtocolId = nextFreeBedrockId++;
String customItemName = customItem instanceof NonVanillaCustomItemData nonVanillaItem ? nonVanillaItem.identifier() : customItem.bedrockIdentifier().asString(); // TODO non vanilla stuff
String customItemName = customItem instanceof NonVanillaCustomItemData nonVanillaItem ? nonVanillaItem.identifier() : customItem.bedrockIdentifier().toString(); // TODO non vanilla stuff
if (!registeredItemNames.add(customItemName)) {
if (firstMappingsPass) {
GeyserImpl.getInstance().getLogger().error("Custom item name '" + customItemName + "' already exists and was registered again! Skipping...");
@ -505,7 +506,7 @@ public class ItemRegistryPopulator {
// ComponentItemData - used to register some custom properties
componentItemData.add(customMapping.componentItemData());
customItemDefinitions.put(customItem.model(), Pair.of(customItem, customMapping.itemDefinition()));
customItemDefinitions.put(identifierToKey(customItem.model()), Pair.of(customItem, customMapping.itemDefinition()));
registry.put(customMapping.integerId(), customMapping.itemDefinition());
customIdMappings.put(customMapping.integerId(), customMapping.stringId());
@ -728,6 +729,10 @@ public class ItemRegistryPopulator {
componentItemData.add(new ComponentItemData("geysermc:furnace_minecart", builder.build()));
}
public static Key identifierToKey(Identifier identifier) {
return Key.key(identifier.namespace(), identifier.path());
}
/**
* Compares custom item definitions based on their predicates:
*