trurwsuieghfdskg
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.ListBuilder;
|
||||
import com.mojang.serialization.MapLike;
|
||||
import com.mojang.serialization.RecordBuilder;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class DelegatingOps<T> implements DynamicOps<T> {
|
||||
protected final DynamicOps<T> delegate;
|
||||
|
||||
protected DelegatingOps(DynamicOps<T> p_135467_) {
|
||||
this.delegate = p_135467_;
|
||||
}
|
||||
|
||||
public T empty() {
|
||||
return this.delegate.empty();
|
||||
}
|
||||
|
||||
public <U> U convertTo(DynamicOps<U> p_135470_, T p_135471_) {
|
||||
return this.delegate.convertTo(p_135470_, p_135471_);
|
||||
}
|
||||
|
||||
public DataResult<Number> getNumberValue(T p_135518_) {
|
||||
return this.delegate.getNumberValue(p_135518_);
|
||||
}
|
||||
|
||||
public T createNumeric(Number p_135495_) {
|
||||
return this.delegate.createNumeric(p_135495_);
|
||||
}
|
||||
|
||||
public T createByte(byte p_135475_) {
|
||||
return this.delegate.createByte(p_135475_);
|
||||
}
|
||||
|
||||
public T createShort(short p_135497_) {
|
||||
return this.delegate.createShort(p_135497_);
|
||||
}
|
||||
|
||||
public T createInt(int p_135483_) {
|
||||
return this.delegate.createInt(p_135483_);
|
||||
}
|
||||
|
||||
public T createLong(long p_135489_) {
|
||||
return this.delegate.createLong(p_135489_);
|
||||
}
|
||||
|
||||
public T createFloat(float p_135481_) {
|
||||
return this.delegate.createFloat(p_135481_);
|
||||
}
|
||||
|
||||
public T createDouble(double p_135479_) {
|
||||
return this.delegate.createDouble(p_135479_);
|
||||
}
|
||||
|
||||
public DataResult<Boolean> getBooleanValue(T p_135502_) {
|
||||
return this.delegate.getBooleanValue(p_135502_);
|
||||
}
|
||||
|
||||
public T createBoolean(boolean p_135473_) {
|
||||
return this.delegate.createBoolean(p_135473_);
|
||||
}
|
||||
|
||||
public DataResult<String> getStringValue(T p_135522_) {
|
||||
return this.delegate.getStringValue(p_135522_);
|
||||
}
|
||||
|
||||
public T createString(String p_135499_) {
|
||||
return this.delegate.createString(p_135499_);
|
||||
}
|
||||
|
||||
public DataResult<T> mergeToList(T p_135526_, T p_135527_) {
|
||||
return this.delegate.mergeToList(p_135526_, p_135527_);
|
||||
}
|
||||
|
||||
public DataResult<T> mergeToList(T p_135529_, List<T> p_135530_) {
|
||||
return this.delegate.mergeToList(p_135529_, p_135530_);
|
||||
}
|
||||
|
||||
public DataResult<T> mergeToMap(T p_135535_, T p_135536_, T p_135537_) {
|
||||
return this.delegate.mergeToMap(p_135535_, p_135536_, p_135537_);
|
||||
}
|
||||
|
||||
public DataResult<T> mergeToMap(T p_135532_, MapLike<T> p_135533_) {
|
||||
return this.delegate.mergeToMap(p_135532_, p_135533_);
|
||||
}
|
||||
|
||||
public DataResult<Stream<Pair<T, T>>> getMapValues(T p_135516_) {
|
||||
return this.delegate.getMapValues(p_135516_);
|
||||
}
|
||||
|
||||
public DataResult<Consumer<BiConsumer<T, T>>> getMapEntries(T p_135514_) {
|
||||
return this.delegate.getMapEntries(p_135514_);
|
||||
}
|
||||
|
||||
public T createMap(Stream<Pair<T, T>> p_135493_) {
|
||||
return this.delegate.createMap(p_135493_);
|
||||
}
|
||||
|
||||
public DataResult<MapLike<T>> getMap(T p_135512_) {
|
||||
return this.delegate.getMap(p_135512_);
|
||||
}
|
||||
|
||||
public DataResult<Stream<T>> getStream(T p_135520_) {
|
||||
return this.delegate.getStream(p_135520_);
|
||||
}
|
||||
|
||||
public DataResult<Consumer<Consumer<T>>> getList(T p_135508_) {
|
||||
return this.delegate.getList(p_135508_);
|
||||
}
|
||||
|
||||
public T createList(Stream<T> p_135487_) {
|
||||
return this.delegate.createList(p_135487_);
|
||||
}
|
||||
|
||||
public DataResult<ByteBuffer> getByteBuffer(T p_135504_) {
|
||||
return this.delegate.getByteBuffer(p_135504_);
|
||||
}
|
||||
|
||||
public T createByteList(ByteBuffer p_135477_) {
|
||||
return this.delegate.createByteList(p_135477_);
|
||||
}
|
||||
|
||||
public DataResult<IntStream> getIntStream(T p_135506_) {
|
||||
return this.delegate.getIntStream(p_135506_);
|
||||
}
|
||||
|
||||
public T createIntList(IntStream p_135485_) {
|
||||
return this.delegate.createIntList(p_135485_);
|
||||
}
|
||||
|
||||
public DataResult<LongStream> getLongStream(T p_135510_) {
|
||||
return this.delegate.getLongStream(p_135510_);
|
||||
}
|
||||
|
||||
public T createLongList(LongStream p_135491_) {
|
||||
return this.delegate.createLongList(p_135491_);
|
||||
}
|
||||
|
||||
public T remove(T p_135539_, String p_135540_) {
|
||||
return this.delegate.remove(p_135539_, p_135540_);
|
||||
}
|
||||
|
||||
public boolean compressMaps() {
|
||||
return this.delegate.compressMaps();
|
||||
}
|
||||
|
||||
public ListBuilder<T> listBuilder() {
|
||||
return new ListBuilder.Builder<>(this);
|
||||
}
|
||||
|
||||
public RecordBuilder<T> mapBuilder() {
|
||||
return new RecordBuilder.MapBuilder<>(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
|
||||
public class FileToIdConverter {
|
||||
private final String prefix;
|
||||
private final String extension;
|
||||
|
||||
public FileToIdConverter(String p_248876_, String p_251478_) {
|
||||
this.prefix = p_248876_;
|
||||
this.extension = p_251478_;
|
||||
}
|
||||
|
||||
public static FileToIdConverter json(String p_248754_) {
|
||||
return new FileToIdConverter(p_248754_, ".json");
|
||||
}
|
||||
|
||||
public ResourceLocation idToFile(ResourceLocation p_251878_) {
|
||||
return p_251878_.withPath(this.prefix + "/" + p_251878_.getPath() + this.extension);
|
||||
}
|
||||
|
||||
public ResourceLocation fileToId(ResourceLocation p_249595_) {
|
||||
String s = p_249595_.getPath();
|
||||
return p_249595_.withPath(s.substring(this.prefix.length() + 1, s.length() - this.extension.length()));
|
||||
}
|
||||
|
||||
public Map<ResourceLocation, Resource> listMatchingResources(ResourceManager p_252045_) {
|
||||
return p_252045_.listResources(this.prefix, (p_251986_) -> {
|
||||
return p_251986_.getPath().endsWith(this.extension);
|
||||
});
|
||||
}
|
||||
|
||||
public Map<ResourceLocation, List<Resource>> listMatchingResourceStacks(ResourceManager p_249881_) {
|
||||
return p_249881_.listResourceStacks(this.prefix, (p_248700_) -> {
|
||||
return p_248700_.getPath().endsWith(this.extension);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.HolderOwner;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
|
||||
public class HolderSetCodec<E> implements Codec<HolderSet<E>> {
|
||||
private final ResourceKey<? extends Registry<E>> registryKey;
|
||||
private final Codec<Holder<E>> elementCodec;
|
||||
private final Codec<List<Holder<E>>> homogenousListCodec;
|
||||
private final Codec<Either<TagKey<E>, List<Holder<E>>>> registryAwareCodec;
|
||||
private final Codec<net.minecraftforge.registries.holdersets.ICustomHolderSet<E>> forgeDispatchCodec;
|
||||
private final Codec<Either<net.minecraftforge.registries.holdersets.ICustomHolderSet<E>, Either<TagKey<E>, List<Holder<E>>>>> combinedCodec;
|
||||
|
||||
private static <E> Codec<List<Holder<E>>> homogenousList(Codec<Holder<E>> p_206668_, boolean p_206669_) {
|
||||
Codec<List<Holder<E>>> codec = ExtraCodecs.validate(p_206668_.listOf(), ExtraCodecs.ensureHomogenous(Holder::kind));
|
||||
return p_206669_ ? codec : Codec.either(codec, p_206668_).xmap((p_206664_) -> {
|
||||
return p_206664_.map((p_206694_) -> {
|
||||
return p_206694_;
|
||||
}, List::of);
|
||||
}, (p_206684_) -> {
|
||||
return p_206684_.size() == 1 ? Either.right(p_206684_.get(0)) : Either.left(p_206684_);
|
||||
});
|
||||
}
|
||||
|
||||
public static <E> Codec<HolderSet<E>> create(ResourceKey<? extends Registry<E>> p_206686_, Codec<Holder<E>> p_206687_, boolean p_206688_) {
|
||||
return new HolderSetCodec<>(p_206686_, p_206687_, p_206688_);
|
||||
}
|
||||
|
||||
private HolderSetCodec(ResourceKey<? extends Registry<E>> p_206660_, Codec<Holder<E>> p_206661_, boolean p_206662_) {
|
||||
this.registryKey = p_206660_;
|
||||
this.elementCodec = p_206661_;
|
||||
this.homogenousListCodec = homogenousList(p_206661_, p_206662_);
|
||||
this.registryAwareCodec = Codec.either(TagKey.hashedCodec(p_206660_), this.homogenousListCodec);
|
||||
// FORGE: make registry-specific dispatch codec and make forge-or-vanilla either codec
|
||||
this.forgeDispatchCodec = ExtraCodecs.lazyInitializedCodec(() -> net.minecraftforge.registries.ForgeRegistries.HOLDER_SET_TYPES.get().getCodec())
|
||||
.dispatch(net.minecraftforge.registries.holdersets.ICustomHolderSet::type, type -> type.makeCodec(p_206660_, p_206661_, p_206662_));
|
||||
this.combinedCodec = new ExtraCodecs.EitherCodec<>(this.forgeDispatchCodec, this.registryAwareCodec);
|
||||
}
|
||||
|
||||
public <T> DataResult<Pair<HolderSet<E>, T>> decode(DynamicOps<T> p_206696_, T p_206697_) {
|
||||
if (p_206696_ instanceof RegistryOps<T> registryops) {
|
||||
Optional<HolderGetter<E>> optional = registryops.getter(this.registryKey);
|
||||
if (optional.isPresent()) {
|
||||
HolderGetter<E> holdergetter = optional.get();
|
||||
// FORGE: use the wrapped codec to decode custom/tag/list instead of just tag/list
|
||||
return this.combinedCodec.decode(p_206696_, p_206697_).map((p_206682_) -> {
|
||||
return p_206682_.mapFirst((p_206679_) -> {
|
||||
return p_206679_.map(java.util.function.Function.identity(), tagOrList -> tagOrList.map(holdergetter::getOrThrow, HolderSet::direct));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return this.decodeWithoutRegistry(p_206696_, p_206697_);
|
||||
}
|
||||
|
||||
public <T> DataResult<T> encode(HolderSet<E> p_206674_, DynamicOps<T> p_206675_, T p_206676_) {
|
||||
if (p_206675_ instanceof RegistryOps<T> registryops) {
|
||||
Optional<HolderOwner<E>> optional = registryops.owner(this.registryKey);
|
||||
if (optional.isPresent()) {
|
||||
if (!p_206674_.canSerializeIn(optional.get())) {
|
||||
return DataResult.error(() -> {
|
||||
return "HolderSet " + p_206674_ + " is not valid in current registry set";
|
||||
});
|
||||
}
|
||||
|
||||
// FORGE: use the dispatch codec to encode custom holdersets, otherwise fall back to vanilla tag/list
|
||||
if (p_206674_ instanceof net.minecraftforge.registries.holdersets.ICustomHolderSet<E> customHolderSet)
|
||||
return this.forgeDispatchCodec.encode(customHolderSet, p_206675_, p_206676_);
|
||||
return this.registryAwareCodec.encode(p_206674_.unwrap().mapRight(List::copyOf), p_206675_, p_206676_);
|
||||
}
|
||||
}
|
||||
|
||||
return this.encodeWithoutRegistry(p_206674_, p_206675_, p_206676_);
|
||||
}
|
||||
|
||||
private <T> DataResult<Pair<HolderSet<E>, T>> decodeWithoutRegistry(DynamicOps<T> p_206671_, T p_206672_) {
|
||||
return this.elementCodec.listOf().decode(p_206671_, p_206672_).flatMap((p_206666_) -> {
|
||||
List<Holder.Direct<E>> list = new ArrayList<>();
|
||||
|
||||
for(Holder<E> holder : p_206666_.getFirst()) {
|
||||
if (!(holder instanceof Holder.Direct)) {
|
||||
return DataResult.error(() -> {
|
||||
return "Can't decode element " + holder + " without registry";
|
||||
});
|
||||
}
|
||||
|
||||
Holder.Direct<E> direct = (Holder.Direct)holder;
|
||||
list.add(direct);
|
||||
}
|
||||
|
||||
return DataResult.success(new Pair<>(HolderSet.direct(list), p_206666_.getSecond()));
|
||||
});
|
||||
}
|
||||
|
||||
private <T> DataResult<T> encodeWithoutRegistry(HolderSet<E> p_206690_, DynamicOps<T> p_206691_, T p_206692_) {
|
||||
return this.homogenousListCodec.encode(p_206690_.stream().toList(), p_206691_, p_206692_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.Decoder;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.ChatType;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.world.damagesource.DamageType;
|
||||
import net.minecraft.world.item.armortrim.TrimMaterial;
|
||||
import net.minecraft.world.item.armortrim.TrimPattern;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterList;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorPreset;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class RegistryDataLoader {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final List<RegistryDataLoader.RegistryData<?>> WORLDGEN_REGISTRIES = List.of(new RegistryDataLoader.RegistryData<>(Registries.DIMENSION_TYPE, DimensionType.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.BIOME, Biome.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.CHAT_TYPE, ChatType.CODEC), new RegistryDataLoader.RegistryData<>(Registries.CONFIGURED_CARVER, ConfiguredWorldCarver.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.CONFIGURED_FEATURE, ConfiguredFeature.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.PLACED_FEATURE, PlacedFeature.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.STRUCTURE, Structure.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.STRUCTURE_SET, StructureSet.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.PROCESSOR_LIST, StructureProcessorType.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.TEMPLATE_POOL, StructureTemplatePool.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.NOISE_SETTINGS, NoiseGeneratorSettings.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.NOISE, NormalNoise.NoiseParameters.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.DENSITY_FUNCTION, DensityFunction.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.WORLD_PRESET, WorldPreset.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.FLAT_LEVEL_GENERATOR_PRESET, FlatLevelGeneratorPreset.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.TRIM_PATTERN, TrimPattern.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.TRIM_MATERIAL, TrimMaterial.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.DAMAGE_TYPE, DamageType.CODEC), new RegistryDataLoader.RegistryData<>(Registries.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST, MultiNoiseBiomeSourceParameterList.DIRECT_CODEC));
|
||||
public static final List<RegistryDataLoader.RegistryData<?>> DIMENSION_REGISTRIES = List.of(new RegistryDataLoader.RegistryData<>(Registries.LEVEL_STEM, LevelStem.CODEC));
|
||||
|
||||
public static RegistryAccess.Frozen load(ResourceManager p_252046_, RegistryAccess p_249916_, List<RegistryDataLoader.RegistryData<?>> p_250344_) {
|
||||
Map<ResourceKey<?>, Exception> map = new HashMap<>();
|
||||
List<Pair<WritableRegistry<?>, RegistryDataLoader.Loader>> list = p_250344_.stream().map((p_250249_) -> {
|
||||
return p_250249_.create(Lifecycle.stable(), map);
|
||||
}).toList();
|
||||
RegistryOps.RegistryInfoLookup registryops$registryinfolookup = createContext(p_249916_, list);
|
||||
list.forEach((p_255508_) -> {
|
||||
p_255508_.getSecond().load(p_252046_, registryops$registryinfolookup);
|
||||
});
|
||||
list.forEach((p_258223_) -> {
|
||||
Registry<?> registry = p_258223_.getFirst();
|
||||
|
||||
try {
|
||||
registry.freeze();
|
||||
} catch (Exception exception) {
|
||||
map.put(registry.key(), exception);
|
||||
}
|
||||
|
||||
});
|
||||
if (!map.isEmpty()) {
|
||||
logErrors(map);
|
||||
throw new IllegalStateException("Failed to load registries due to above errors");
|
||||
} else {
|
||||
return (new RegistryAccess.ImmutableRegistryAccess(list.stream().map(Pair::getFirst).toList())).freeze();
|
||||
}
|
||||
}
|
||||
|
||||
private static RegistryOps.RegistryInfoLookup createContext(RegistryAccess p_256568_, List<Pair<WritableRegistry<?>, RegistryDataLoader.Loader>> p_255821_) {
|
||||
final Map<ResourceKey<? extends Registry<?>>, RegistryOps.RegistryInfo<?>> map = new HashMap<>();
|
||||
p_256568_.registries().forEach((p_255505_) -> {
|
||||
map.put(p_255505_.key(), createInfoForContextRegistry(p_255505_.value()));
|
||||
});
|
||||
p_255821_.forEach((p_258221_) -> {
|
||||
map.put(p_258221_.getFirst().key(), createInfoForNewRegistry(p_258221_.getFirst()));
|
||||
});
|
||||
return new RegistryOps.RegistryInfoLookup() {
|
||||
public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(ResourceKey<? extends Registry<? extends T>> p_256014_) {
|
||||
return Optional.ofNullable((RegistryOps.RegistryInfo<T>) map.get(p_256014_));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <T> RegistryOps.RegistryInfo<T> createInfoForNewRegistry(WritableRegistry<T> p_256020_) {
|
||||
return new RegistryOps.RegistryInfo<>(p_256020_.asLookup(), p_256020_.createRegistrationLookup(), p_256020_.registryLifecycle());
|
||||
}
|
||||
|
||||
private static <T> RegistryOps.RegistryInfo<T> createInfoForContextRegistry(Registry<T> p_256230_) {
|
||||
return new RegistryOps.RegistryInfo<>(p_256230_.asLookup(), p_256230_.asTagAddingLookup(), p_256230_.registryLifecycle());
|
||||
}
|
||||
|
||||
private static void logErrors(Map<ResourceKey<?>, Exception> p_252325_) {
|
||||
StringWriter stringwriter = new StringWriter();
|
||||
PrintWriter printwriter = new PrintWriter(stringwriter);
|
||||
Map<ResourceLocation, Map<ResourceLocation, Exception>> map = p_252325_.entrySet().stream().collect(Collectors.groupingBy((p_249353_) -> {
|
||||
return p_249353_.getKey().registry();
|
||||
}, Collectors.toMap((p_251444_) -> {
|
||||
return p_251444_.getKey().location();
|
||||
}, Map.Entry::getValue)));
|
||||
map.entrySet().stream().sorted(Entry.comparingByKey()).forEach((p_249838_) -> {
|
||||
printwriter.printf("> Errors in registry %s:%n", p_249838_.getKey());
|
||||
p_249838_.getValue().entrySet().stream().sorted(Entry.comparingByKey()).forEach((p_250688_) -> {
|
||||
printwriter.printf(">> Errors in element %s:%n", p_250688_.getKey());
|
||||
p_250688_.getValue().printStackTrace(printwriter);
|
||||
});
|
||||
});
|
||||
printwriter.flush();
|
||||
LOGGER.error("Registry loading errors:\n{}", (Object)stringwriter);
|
||||
}
|
||||
|
||||
private static String registryDirPath(ResourceLocation p_252033_) {
|
||||
return net.minecraftforge.common.ForgeHooks.prefixNamespace(p_252033_); // FORGE: add non-vanilla registry namespace to loader directory, same format as tag directory (see net.minecraft.tags.TagManager#getTagDir(ResourceKey))
|
||||
}
|
||||
|
||||
static <E> void loadRegistryContents(RegistryOps.RegistryInfoLookup p_256369_, ResourceManager p_256349_, ResourceKey<? extends Registry<E>> p_255792_, WritableRegistry<E> p_256211_, Decoder<E> p_256232_, Map<ResourceKey<?>, Exception> p_255884_) {
|
||||
String s = registryDirPath(p_255792_.location());
|
||||
FileToIdConverter filetoidconverter = FileToIdConverter.json(s);
|
||||
RegistryOps<JsonElement> registryops = RegistryOps.create(JsonOps.INSTANCE, p_256369_);
|
||||
|
||||
for(Map.Entry<ResourceLocation, Resource> entry : filetoidconverter.listMatchingResources(p_256349_).entrySet()) {
|
||||
ResourceLocation resourcelocation = entry.getKey();
|
||||
ResourceKey<E> resourcekey = ResourceKey.create(p_255792_, filetoidconverter.fileToId(resourcelocation));
|
||||
Resource resource = entry.getValue();
|
||||
|
||||
try (Reader reader = resource.openAsReader()) {
|
||||
JsonElement jsonelement = JsonParser.parseReader(reader);
|
||||
if (!net.minecraftforge.common.crafting.conditions.ICondition.shouldRegisterEntry(jsonelement)) continue;
|
||||
DataResult<E> dataresult = p_256232_.parse(registryops, jsonelement);
|
||||
E e = dataresult.getOrThrow(false, (p_248715_) -> {
|
||||
});
|
||||
p_256211_.register(resourcekey, e, resource.isBuiltin() ? Lifecycle.stable() : dataresult.lifecycle());
|
||||
} catch (Exception exception) {
|
||||
p_255884_.put(resourcekey, new IllegalStateException(String.format(Locale.ROOT, "Failed to parse %s from pack %s", resourcelocation, resource.sourcePackId()), exception));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface Loader {
|
||||
void load(ResourceManager p_249926_, RegistryOps.RegistryInfoLookup p_256258_);
|
||||
}
|
||||
|
||||
public static record RegistryData<T>(ResourceKey<? extends Registry<T>> key, Codec<T> elementCodec) {
|
||||
Pair<WritableRegistry<?>, RegistryDataLoader.Loader> create(Lifecycle p_251662_, Map<ResourceKey<?>, Exception> p_251565_) {
|
||||
WritableRegistry<T> writableregistry = new MappedRegistry<>(this.key, p_251662_);
|
||||
RegistryDataLoader.Loader registrydataloader$loader = (p_255511_, p_255512_) -> {
|
||||
RegistryDataLoader.loadRegistryContents(p_255512_, p_255511_, this.key, writableregistry, this.elementCodec, p_251565_);
|
||||
};
|
||||
return Pair.of(writableregistry, registrydataloader$loader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.HolderOwner;
|
||||
import net.minecraft.core.Registry;
|
||||
|
||||
public final class RegistryFileCodec<E> implements Codec<Holder<E>> {
|
||||
private final ResourceKey<? extends Registry<E>> registryKey;
|
||||
private final Codec<E> elementCodec;
|
||||
private final boolean allowInline;
|
||||
|
||||
public static <E> RegistryFileCodec<E> create(ResourceKey<? extends Registry<E>> p_135590_, Codec<E> p_135591_) {
|
||||
return create(p_135590_, p_135591_, true);
|
||||
}
|
||||
|
||||
public static <E> RegistryFileCodec<E> create(ResourceKey<? extends Registry<E>> p_135593_, Codec<E> p_135594_, boolean p_135595_) {
|
||||
return new RegistryFileCodec<>(p_135593_, p_135594_, p_135595_);
|
||||
}
|
||||
|
||||
private RegistryFileCodec(ResourceKey<? extends Registry<E>> p_135574_, Codec<E> p_135575_, boolean p_135576_) {
|
||||
this.registryKey = p_135574_;
|
||||
this.elementCodec = p_135575_;
|
||||
this.allowInline = p_135576_;
|
||||
}
|
||||
|
||||
public <T> DataResult<T> encode(Holder<E> p_206716_, DynamicOps<T> p_206717_, T p_206718_) {
|
||||
if (p_206717_ instanceof RegistryOps<?> registryops) {
|
||||
Optional<HolderOwner<E>> optional = registryops.owner(this.registryKey);
|
||||
if (optional.isPresent()) {
|
||||
if (!p_206716_.canSerializeIn(optional.get())) {
|
||||
return DataResult.error(() -> {
|
||||
return "Element " + p_206716_ + " is not valid in current registry set";
|
||||
});
|
||||
}
|
||||
|
||||
return p_206716_.unwrap().map((p_206714_) -> {
|
||||
return ResourceLocation.CODEC.encode(p_206714_.location(), p_206717_, p_206718_);
|
||||
}, (p_206710_) -> {
|
||||
return this.elementCodec.encode(p_206710_, p_206717_, p_206718_);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return this.elementCodec.encode(p_206716_.value(), p_206717_, p_206718_);
|
||||
}
|
||||
|
||||
public <T> DataResult<Pair<Holder<E>, T>> decode(DynamicOps<T> p_135608_, T p_135609_) {
|
||||
if (p_135608_ instanceof RegistryOps<?> registryops) {
|
||||
Optional<HolderGetter<E>> optional = registryops.getter(this.registryKey);
|
||||
if (optional.isEmpty()) {
|
||||
return DataResult.error(() -> {
|
||||
return "Registry does not exist: " + this.registryKey;
|
||||
});
|
||||
} else {
|
||||
HolderGetter<E> holdergetter = optional.get();
|
||||
DataResult<Pair<ResourceLocation, T>> dataresult = ResourceLocation.CODEC.decode(p_135608_, p_135609_);
|
||||
if (dataresult.result().isEmpty()) {
|
||||
return !this.allowInline ? DataResult.error(() -> {
|
||||
return "Inline definitions not allowed here";
|
||||
}) : this.elementCodec.decode(p_135608_, p_135609_).map((p_206720_) -> {
|
||||
return p_206720_.mapFirst(Holder::direct);
|
||||
});
|
||||
} else {
|
||||
Pair<ResourceLocation, T> pair = dataresult.result().get();
|
||||
ResourceKey<E> resourcekey = ResourceKey.create(this.registryKey, pair.getFirst());
|
||||
return holdergetter.get(resourcekey).map(DataResult::success).orElseGet(() -> {
|
||||
return DataResult.error(() -> {
|
||||
return "Failed to get element " + resourcekey;
|
||||
});
|
||||
}).map((p_255658_) -> {
|
||||
return Pair.of((Holder<E>)p_255658_, pair.getSecond());
|
||||
}).setLifecycle(Lifecycle.stable());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.elementCodec.decode(p_135608_, p_135609_).map((p_214212_) -> {
|
||||
return p_214212_.mapFirst(Holder::direct);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "RegistryFileCodec[" + this.registryKey + " " + this.elementCodec + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.HolderOwner;
|
||||
import net.minecraft.core.Registry;
|
||||
|
||||
public final class RegistryFixedCodec<E> implements Codec<Holder<E>> {
|
||||
private final ResourceKey<? extends Registry<E>> registryKey;
|
||||
|
||||
public static <E> RegistryFixedCodec<E> create(ResourceKey<? extends Registry<E>> p_206741_) {
|
||||
return new RegistryFixedCodec<>(p_206741_);
|
||||
}
|
||||
|
||||
private RegistryFixedCodec(ResourceKey<? extends Registry<E>> p_206723_) {
|
||||
this.registryKey = p_206723_;
|
||||
}
|
||||
|
||||
public <T> DataResult<T> encode(Holder<E> p_206729_, DynamicOps<T> p_206730_, T p_206731_) {
|
||||
if (p_206730_ instanceof RegistryOps<?> registryops) {
|
||||
Optional<HolderOwner<E>> optional = registryops.owner(this.registryKey);
|
||||
if (optional.isPresent()) {
|
||||
if (!p_206729_.canSerializeIn(optional.get())) {
|
||||
return DataResult.error(() -> {
|
||||
return "Element " + p_206729_ + " is not valid in current registry set";
|
||||
});
|
||||
}
|
||||
|
||||
return p_206729_.unwrap().map((p_206727_) -> {
|
||||
return ResourceLocation.CODEC.encode(p_206727_.location(), p_206730_, p_206731_);
|
||||
}, (p_274804_) -> {
|
||||
return DataResult.error(() -> {
|
||||
return "Elements from registry " + this.registryKey + " can't be serialized to a value";
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return DataResult.error(() -> {
|
||||
return "Can't access registry " + this.registryKey;
|
||||
});
|
||||
}
|
||||
|
||||
public <T> DataResult<Pair<Holder<E>, T>> decode(DynamicOps<T> p_206743_, T p_206744_) {
|
||||
if (p_206743_ instanceof RegistryOps<?> registryops) {
|
||||
Optional<HolderGetter<E>> optional = registryops.getter(this.registryKey);
|
||||
if (optional.isPresent()) {
|
||||
return ResourceLocation.CODEC.decode(p_206743_, p_206744_).flatMap((p_255515_) -> {
|
||||
ResourceLocation resourcelocation = p_255515_.getFirst();
|
||||
return optional.get().get(ResourceKey.create(this.registryKey, resourcelocation)).map(DataResult::success).orElseGet(() -> {
|
||||
return DataResult.error(() -> {
|
||||
return "Failed to get element " + resourcelocation;
|
||||
});
|
||||
}).map((p_256041_) -> {
|
||||
return Pair.of((Holder<E>)p_256041_, (T)p_255515_.getSecond());
|
||||
}).setLifecycle(Lifecycle.stable());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return DataResult.error(() -> {
|
||||
return "Can't access registry " + this.registryKey;
|
||||
});
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "RegistryFixedCodec[" + this.registryKey + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.HolderOwner;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
|
||||
public class RegistryOps<T> extends DelegatingOps<T> {
|
||||
private final RegistryOps.RegistryInfoLookup lookupProvider;
|
||||
|
||||
private static RegistryOps.RegistryInfoLookup memoizeLookup(final RegistryOps.RegistryInfoLookup p_255769_) {
|
||||
return new RegistryOps.RegistryInfoLookup() {
|
||||
private final Map<ResourceKey<? extends Registry<?>>, Optional<? extends RegistryOps.RegistryInfo<?>>> lookups = new HashMap<>();
|
||||
|
||||
public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(ResourceKey<? extends Registry<? extends T>> p_256043_) {
|
||||
return (Optional<RegistryOps.RegistryInfo<T>>) this.lookups.computeIfAbsent(p_256043_, p_255769_::lookup);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> RegistryOps<T> create(DynamicOps<T> p_256342_, final HolderLookup.Provider p_255950_) {
|
||||
return create(p_256342_, memoizeLookup(new RegistryOps.RegistryInfoLookup() {
|
||||
public <E> Optional<RegistryOps.RegistryInfo<E>> lookup(ResourceKey<? extends Registry<? extends E>> p_256323_) {
|
||||
return p_255950_.lookup(p_256323_).map((p_258224_) -> {
|
||||
return new RegistryOps.RegistryInfo<>(p_258224_, p_258224_, p_258224_.registryLifecycle());
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static <T> RegistryOps<T> create(DynamicOps<T> p_256278_, RegistryOps.RegistryInfoLookup p_256479_) {
|
||||
return new RegistryOps<>(p_256278_, p_256479_);
|
||||
}
|
||||
|
||||
private RegistryOps(DynamicOps<T> p_256313_, RegistryOps.RegistryInfoLookup p_255799_) {
|
||||
super(p_256313_);
|
||||
this.lookupProvider = p_255799_;
|
||||
}
|
||||
|
||||
public <E> Optional<HolderOwner<E>> owner(ResourceKey<? extends Registry<? extends E>> p_255757_) {
|
||||
return this.lookupProvider.lookup(p_255757_).map(RegistryOps.RegistryInfo::owner);
|
||||
}
|
||||
|
||||
public <E> Optional<HolderGetter<E>> getter(ResourceKey<? extends Registry<? extends E>> p_256031_) {
|
||||
return this.lookupProvider.lookup(p_256031_).map(RegistryOps.RegistryInfo::getter);
|
||||
}
|
||||
|
||||
public static <E, O> RecordCodecBuilder<O, HolderGetter<E>> retrieveGetter(ResourceKey<? extends Registry<? extends E>> p_206833_) {
|
||||
return ExtraCodecs.retrieveContext((p_274811_) -> {
|
||||
if (p_274811_ instanceof RegistryOps<?> registryops) {
|
||||
return registryops.lookupProvider.lookup(p_206833_).map((p_255527_) -> {
|
||||
return DataResult.success(p_255527_.getter(), p_255527_.elementsLifecycle());
|
||||
}).orElseGet(() -> {
|
||||
return DataResult.error(() -> {
|
||||
return "Unknown registry: " + p_206833_;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a registry ops";
|
||||
});
|
||||
}
|
||||
}).forGetter((p_255526_) -> {
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public static <E> com.mojang.serialization.MapCodec<HolderLookup.RegistryLookup<E>> retrieveRegistryLookup(ResourceKey<? extends Registry<? extends E>> resourceKey) {
|
||||
return ExtraCodecs.retrieveContext(ops -> {
|
||||
if (!(ops instanceof RegistryOps<?> registryOps))
|
||||
return DataResult.error(() -> "Not a registry ops");
|
||||
|
||||
return registryOps.lookupProvider.lookup(resourceKey).map(registryInfo -> {
|
||||
if (!(registryInfo.owner() instanceof HolderLookup.RegistryLookup<E> registryLookup))
|
||||
return DataResult.<HolderLookup.RegistryLookup<E>>error(() -> "Found holder getter but was not a registry lookup for " + resourceKey);
|
||||
|
||||
return DataResult.success(registryLookup, registryInfo.elementsLifecycle());
|
||||
}).orElseGet(() -> DataResult.error(() -> "Unknown registry: " + resourceKey));
|
||||
});
|
||||
}
|
||||
|
||||
public static <E, O> RecordCodecBuilder<O, Holder.Reference<E>> retrieveElement(ResourceKey<E> p_256347_) {
|
||||
ResourceKey<? extends Registry<E>> resourcekey = ResourceKey.createRegistryKey(p_256347_.registry());
|
||||
return ExtraCodecs.retrieveContext((p_274808_) -> {
|
||||
if (p_274808_ instanceof RegistryOps<?> registryops) {
|
||||
return registryops.lookupProvider.lookup(resourcekey).flatMap((p_255518_) -> {
|
||||
return p_255518_.getter().get(p_256347_);
|
||||
}).map(DataResult::success).orElseGet(() -> {
|
||||
return DataResult.error(() -> {
|
||||
return "Can't find value: " + p_256347_;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a registry ops";
|
||||
});
|
||||
}
|
||||
}).forGetter((p_255524_) -> {
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public static record RegistryInfo<T>(HolderOwner<T> owner, HolderGetter<T> getter, Lifecycle elementsLifecycle) {
|
||||
}
|
||||
|
||||
public interface RegistryInfoLookup {
|
||||
<T> Optional<RegistryOps.RegistryInfo<T>> lookup(ResourceKey<? extends Registry<? extends T>> p_256623_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.mojang.serialization.Codec;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
|
||||
public class ResourceKey<T> implements Comparable<ResourceKey<?>> {
|
||||
private static final ConcurrentMap<ResourceKey.InternKey, ResourceKey<?>> VALUES = (new MapMaker()).weakValues().makeMap();
|
||||
private final ResourceLocation registryName;
|
||||
private final ResourceLocation location;
|
||||
|
||||
public static <T> Codec<ResourceKey<T>> codec(ResourceKey<? extends Registry<T>> p_195967_) {
|
||||
return ResourceLocation.CODEC.xmap((p_195979_) -> {
|
||||
return create(p_195967_, p_195979_);
|
||||
}, ResourceKey::location);
|
||||
}
|
||||
|
||||
public static <T> ResourceKey<T> create(ResourceKey<? extends Registry<T>> p_135786_, ResourceLocation p_135787_) {
|
||||
return create(p_135786_.location, p_135787_);
|
||||
}
|
||||
|
||||
public static <T> ResourceKey<Registry<T>> createRegistryKey(ResourceLocation p_135789_) {
|
||||
return create(BuiltInRegistries.ROOT_REGISTRY_NAME, p_135789_);
|
||||
}
|
||||
|
||||
private static <T> ResourceKey<T> create(ResourceLocation p_135791_, ResourceLocation p_135792_) {
|
||||
return (ResourceKey<T>)VALUES.computeIfAbsent(new ResourceKey.InternKey(p_135791_, p_135792_), (p_258225_) -> {
|
||||
return new ResourceKey(p_258225_.registry, p_258225_.location);
|
||||
});
|
||||
}
|
||||
|
||||
private ResourceKey(ResourceLocation p_135780_, ResourceLocation p_135781_) {
|
||||
this.registryName = p_135780_;
|
||||
this.location = p_135781_;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ResourceKey[" + this.registryName + " / " + this.location + "]";
|
||||
}
|
||||
|
||||
public boolean isFor(ResourceKey<? extends Registry<?>> p_135784_) {
|
||||
return this.registryName.equals(p_135784_.location());
|
||||
}
|
||||
|
||||
public <E> Optional<ResourceKey<E>> cast(ResourceKey<? extends Registry<E>> p_195976_) {
|
||||
return this.isFor(p_195976_) ? Optional.of((ResourceKey<E>)this) : Optional.empty();
|
||||
}
|
||||
|
||||
public ResourceLocation location() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public ResourceLocation registry() {
|
||||
return this.registryName;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
return location.equals(((ResourceKey<?>) o).location) && registryName.equals(((ResourceKey<?>) o).registryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ResourceKey<?> o) {
|
||||
int ret = this.registry().compareTo(o.registry());
|
||||
if (ret == 0) ret = this.location().compareTo(o.location());
|
||||
return ret;
|
||||
}
|
||||
|
||||
static record InternKey(ResourceLocation registry, ResourceLocation location) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
package net.minecraft.resources;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.function.UnaryOperator;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ResourceLocation implements Comparable<ResourceLocation> {
|
||||
public static final Codec<ResourceLocation> CODEC = Codec.STRING.comapFlatMap(ResourceLocation::read, ResourceLocation::toString).stable();
|
||||
private static final SimpleCommandExceptionType ERROR_INVALID = new SimpleCommandExceptionType(Component.translatable("argument.id.invalid"));
|
||||
public static final char NAMESPACE_SEPARATOR = ':';
|
||||
public static final String DEFAULT_NAMESPACE = "minecraft";
|
||||
public static final String REALMS_NAMESPACE = "realms";
|
||||
private final String namespace;
|
||||
private final String path;
|
||||
|
||||
protected ResourceLocation(String p_248791_, String p_249394_, @Nullable ResourceLocation.Dummy p_249089_) {
|
||||
this.namespace = p_248791_;
|
||||
this.path = p_249394_;
|
||||
}
|
||||
|
||||
/** @deprecated Forge: Consider using {@link #fromNamespaceAndPath(String, String)} instead, as Mojang made this constructor private in 1.21 */
|
||||
@Deprecated(forRemoval = true, since = "1.20.6")
|
||||
public ResourceLocation(String p_135811_, String p_135812_) {
|
||||
this(assertValidNamespace(p_135811_, p_135812_), assertValidPath(p_135811_, p_135812_), (ResourceLocation.Dummy)null);
|
||||
}
|
||||
|
||||
private ResourceLocation(String[] p_135814_) {
|
||||
this(p_135814_[0], p_135814_[1]);
|
||||
}
|
||||
|
||||
/** @deprecated Forge: Consider using {@link #parse(String)} instead, as Mojang made this constructor private in 1.21 */
|
||||
@Deprecated(forRemoval = true, since = "1.20.6")
|
||||
public ResourceLocation(String p_135809_) {
|
||||
this(decompose(p_135809_, ':'));
|
||||
}
|
||||
|
||||
/** @deprecated Forge: Consider using {@link #bySeparator(String, char)} instead, as Mojang removed this method in 1.21 */
|
||||
@Deprecated(forRemoval = true, since = "1.20.6")
|
||||
public static ResourceLocation of(String p_135823_, char p_135824_) {
|
||||
return new ResourceLocation(decompose(p_135823_, p_135824_));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ResourceLocation tryParse(String p_135821_) {
|
||||
try {
|
||||
return new ResourceLocation(p_135821_);
|
||||
} catch (ResourceLocationException resourcelocationexception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ResourceLocation tryBuild(String p_214294_, String p_214295_) {
|
||||
try {
|
||||
return new ResourceLocation(p_214294_, p_214295_);
|
||||
} catch (ResourceLocationException resourcelocationexception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static String[] decompose(String p_135833_, char p_135834_) {
|
||||
String[] astring = new String[]{"minecraft", p_135833_};
|
||||
int i = p_135833_.indexOf(p_135834_);
|
||||
if (i >= 0) {
|
||||
astring[1] = p_135833_.substring(i + 1);
|
||||
if (i >= 1) {
|
||||
astring[0] = p_135833_.substring(0, i);
|
||||
}
|
||||
}
|
||||
|
||||
return astring;
|
||||
}
|
||||
|
||||
public static DataResult<ResourceLocation> read(String p_135838_) {
|
||||
try {
|
||||
return DataResult.success(new ResourceLocation(p_135838_));
|
||||
} catch (ResourceLocationException resourcelocationexception) {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a valid resource location: " + p_135838_ + " " + resourcelocationexception.getMessage();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return this.namespace;
|
||||
}
|
||||
|
||||
public ResourceLocation withPath(String p_251088_) {
|
||||
return new ResourceLocation(this.namespace, assertValidPath(this.namespace, p_251088_), (ResourceLocation.Dummy)null);
|
||||
}
|
||||
|
||||
public ResourceLocation withPath(UnaryOperator<String> p_250342_) {
|
||||
return this.withPath(p_250342_.apply(this.path));
|
||||
}
|
||||
|
||||
public ResourceLocation withPrefix(String p_250620_) {
|
||||
return this.withPath(p_250620_ + this.path);
|
||||
}
|
||||
|
||||
public ResourceLocation withSuffix(String p_266769_) {
|
||||
return this.withPath(this.path + p_266769_);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.namespace + ":" + this.path;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_135846_) {
|
||||
if (this == p_135846_) {
|
||||
return true;
|
||||
} else if (!(p_135846_ instanceof ResourceLocation)) {
|
||||
return false;
|
||||
} else {
|
||||
ResourceLocation resourcelocation = (ResourceLocation)p_135846_;
|
||||
return this.namespace.equals(resourcelocation.namespace) && this.path.equals(resourcelocation.path);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 31 * this.namespace.hashCode() + this.path.hashCode();
|
||||
}
|
||||
|
||||
public int compareTo(ResourceLocation p_135826_) {
|
||||
int i = this.path.compareTo(p_135826_.path);
|
||||
if (i == 0) {
|
||||
i = this.namespace.compareTo(p_135826_.namespace);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// Normal compare sorts by path first, this compares namespace first.
|
||||
public int compareNamespaced(ResourceLocation o) {
|
||||
int ret = this.namespace.compareTo(o.namespace);
|
||||
return ret != 0 ? ret : this.path.compareTo(o.path);
|
||||
}
|
||||
|
||||
public String toDebugFileName() {
|
||||
return this.toString().replace('/', '_').replace(':', '_');
|
||||
}
|
||||
|
||||
public String toLanguageKey() {
|
||||
return this.namespace + "." + this.path;
|
||||
}
|
||||
|
||||
public String toShortLanguageKey() {
|
||||
return this.namespace.equals("minecraft") ? this.path : this.toLanguageKey();
|
||||
}
|
||||
|
||||
public String toLanguageKey(String p_214297_) {
|
||||
return p_214297_ + "." + this.toLanguageKey();
|
||||
}
|
||||
|
||||
public String toLanguageKey(String p_270871_, String p_270199_) {
|
||||
return p_270871_ + "." + this.toLanguageKey() + "." + p_270199_;
|
||||
}
|
||||
|
||||
public static ResourceLocation read(StringReader p_135819_) throws CommandSyntaxException {
|
||||
int i = p_135819_.getCursor();
|
||||
|
||||
while(p_135819_.canRead() && isAllowedInResourceLocation(p_135819_.peek())) {
|
||||
p_135819_.skip();
|
||||
}
|
||||
|
||||
String s = p_135819_.getString().substring(i, p_135819_.getCursor());
|
||||
|
||||
try {
|
||||
return new ResourceLocation(s);
|
||||
} catch (ResourceLocationException resourcelocationexception) {
|
||||
p_135819_.setCursor(i);
|
||||
throw ERROR_INVALID.createWithContext(p_135819_);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isAllowedInResourceLocation(char p_135817_) {
|
||||
return p_135817_ >= '0' && p_135817_ <= '9' || p_135817_ >= 'a' && p_135817_ <= 'z' || p_135817_ == '_' || p_135817_ == ':' || p_135817_ == '/' || p_135817_ == '.' || p_135817_ == '-';
|
||||
}
|
||||
|
||||
public static boolean isValidPath(String p_135842_) {
|
||||
for(int i = 0; i < p_135842_.length(); ++i) {
|
||||
if (!validPathChar(p_135842_.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isValidNamespace(String p_135844_) {
|
||||
for(int i = 0; i < p_135844_.length(); ++i) {
|
||||
if (!validNamespaceChar(p_135844_.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String assertValidNamespace(String p_250769_, String p_249616_) {
|
||||
if (!isValidNamespace(p_250769_)) {
|
||||
throw new ResourceLocationException("Non [a-z0-9_.-] character in namespace of location: " + p_250769_ + ":" + p_249616_);
|
||||
} else {
|
||||
return p_250769_;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean validPathChar(char p_135829_) {
|
||||
return p_135829_ == '_' || p_135829_ == '-' || p_135829_ >= 'a' && p_135829_ <= 'z' || p_135829_ >= '0' && p_135829_ <= '9' || p_135829_ == '/' || p_135829_ == '.';
|
||||
}
|
||||
|
||||
public static boolean validNamespaceChar(char p_135836_) {
|
||||
return p_135836_ == '_' || p_135836_ == '-' || p_135836_ >= 'a' && p_135836_ <= 'z' || p_135836_ >= '0' && p_135836_ <= '9' || p_135836_ == '.';
|
||||
}
|
||||
|
||||
public static boolean isValidResourceLocation(String p_135831_) {
|
||||
String[] astring = decompose(p_135831_, ':');
|
||||
return isValidNamespace(StringUtils.isEmpty(astring[0]) ? "minecraft" : astring[0]) && isValidPath(astring[1]);
|
||||
}
|
||||
|
||||
private static String assertValidPath(String p_251418_, String p_248828_) {
|
||||
if (!isValidPath(p_248828_)) {
|
||||
throw new ResourceLocationException("Non [a-z0-9/._-] character in path of location: " + p_251418_ + ":" + p_248828_);
|
||||
} else {
|
||||
return p_248828_;
|
||||
}
|
||||
}
|
||||
|
||||
protected interface Dummy {
|
||||
}
|
||||
|
||||
public static class Serializer implements JsonDeserializer<ResourceLocation>, JsonSerializer<ResourceLocation> {
|
||||
public ResourceLocation deserialize(JsonElement p_135851_, Type p_135852_, JsonDeserializationContext p_135853_) throws JsonParseException {
|
||||
return new ResourceLocation(GsonHelper.convertToString(p_135851_, "location"));
|
||||
}
|
||||
|
||||
public JsonElement serialize(ResourceLocation p_135855_, Type p_135856_, JsonSerializationContext p_135857_) {
|
||||
return new JsonPrimitive(p_135855_.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/** Forge: This is a backported method from 1.21, and is the replacement for {@link #ResourceLocation(String, String)}. */
|
||||
public static ResourceLocation fromNamespaceAndPath(String namespace, String path) {
|
||||
return new ResourceLocation(namespace, path);
|
||||
}
|
||||
|
||||
/** Forge: This is a backported method from 1.21, and is the replacement for {@link #ResourceLocation(String)}. */
|
||||
public static ResourceLocation parse(String location) {
|
||||
return new ResourceLocation(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forge: This is a backported method from 1.21, and acts as an alternative to using {@link #parse(String)}. If you
|
||||
* know for sure you are going to be using the {@linkplain #DEFAULT_NAMESPACE default namespace}
|
||||
* ({@code "minecraft"}), use this.
|
||||
*/
|
||||
public static ResourceLocation withDefaultNamespace(String path) {
|
||||
return new ResourceLocation(DEFAULT_NAMESPACE, assertValidPath(DEFAULT_NAMESPACE, path), null);
|
||||
}
|
||||
|
||||
/** Forge: This is a backported method from 1.21, and is the replacement for {@link #of(String, char)}. */
|
||||
public static ResourceLocation bySeparator(String location, char separator) {
|
||||
return of(location, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forge: This is a backported method from 1.21, and is the same as {@link #bySeparator(String, char)} but returns
|
||||
* {@code null} if a resource location cannot be created.
|
||||
*/
|
||||
public static @Nullable ResourceLocation tryBySeparator(String location, char separator) {
|
||||
int i = location.indexOf(separator);
|
||||
if (i >= 0) {
|
||||
String s = location.substring(i + 1);
|
||||
if (!isValidPath(s)) {
|
||||
return null;
|
||||
} else if (i != 0) {
|
||||
String s1 = location.substring(0, i);
|
||||
return isValidNamespace(s1) ? new ResourceLocation(s1, s, null) : null;
|
||||
} else {
|
||||
return new ResourceLocation(DEFAULT_NAMESPACE, s, null);
|
||||
}
|
||||
} else {
|
||||
return isValidPath(location) ? new ResourceLocation(DEFAULT_NAMESPACE, location, null) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
package net.minecraft.resources;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
Reference in New Issue
Block a user