From d0812536d30a323fd91d0439bc813aaca00d6615 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 11:40:09 +0200 Subject: [PATCH 1/9] fix ambigious method error in `GTOreDefinition#veinGenerator` by renaming the 'custom' setter to `customVeinGenerator` in KubeJS --- .../gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java index be7c8395c80..0374e5e65a3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java @@ -26,6 +26,7 @@ import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.latvian.mods.rhino.util.HideFromJS; +import dev.latvian.mods.rhino.util.RemapForJS; import it.unimi.dsi.fastutil.ints.IntIntPair; import lombok.Getter; import lombok.Setter; @@ -303,8 +304,8 @@ public GTOreDefinition cuboidVeinGenerator(Consumer config) } @Tolerate - @Nullable - public VeinGenerator veinGenerator(ResourceLocation id) { + @RemapForJS("customVeinGenerator") + public @Nullable VeinGenerator veinGenerator(ResourceLocation id) { if (veinGenerator == null) { veinGenerator = WorldGeneratorUtils.VEIN_GENERATOR_FUNCTIONS.containsKey(id) ? WorldGeneratorUtils.VEIN_GENERATOR_FUNCTIONS.get(id).apply(this) : null; From 700cc2ed626e31b0beadea7b7dbbc4f79080ba59 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 11:43:19 +0200 Subject: [PATCH 2/9] remove duplicate adjacency condition methods in GTRecipeSchema fixes #3952 --- .../kjs/recipe/GTRecipeSchema.java | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java index 61ab2a31211..637c2c63774 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java @@ -1014,25 +1014,6 @@ public GTRecipeJS adjacentFluids(boolean isReverse, Fluid... fluids) { return addCondition(AdjacentFluidCondition.fromFluids(fluids).setReverse(isReverse)); } - public GTRecipeJS adjacentFluid(Fluid... fluids) { - return adjacentFluid(false, fluids); - } - - public GTRecipeJS adjacentFluid(boolean isReverse, Fluid... fluids) { - return addCondition(AdjacentFluidCondition.fromFluids(fluids).setReverse(isReverse)); - } - - public GTRecipeJS adjacentFluid(ResourceLocation... tagNames) { - return adjacentFluid(false, tagNames); - } - - public GTRecipeJS adjacentFluid(boolean isReverse, ResourceLocation... tagNames) { - List> tags = Arrays.stream(tagNames) - .map(id -> TagKey.create(Registries.FLUID, id)) - .toList(); - return addCondition(AdjacentFluidCondition.fromTags(tags).setReverse(isReverse)); - } - public GTRecipeJS adjacentFluidTag(ResourceLocation... tagNames) { return adjacentFluidTag(false, tagNames); } @@ -1052,14 +1033,6 @@ public GTRecipeJS adjacentBlocks(boolean isReverse, Block... blocks) { return addCondition(AdjacentBlockCondition.fromBlocks(blocks).setReverse(isReverse)); } - public GTRecipeJS adjacentBlock(Block... blocks) { - return adjacentBlock(false, blocks); - } - - public GTRecipeJS adjacentBlock(boolean isReverse, Block... blocks) { - return addCondition(AdjacentBlockCondition.fromBlocks(blocks).setReverse(isReverse)); - } - public GTRecipeJS adjacentBlockTag(ResourceLocation... tagNames) { return adjacentBlockTag(false, tagNames); } @@ -1071,17 +1044,6 @@ public GTRecipeJS adjacentBlockTag(boolean isReverse, ResourceLocation... tagNam return addCondition(AdjacentBlockCondition.fromTags(tags).setReverse(isReverse)); } - public GTRecipeJS adjacentBlock(ResourceLocation... tagNames) { - return adjacentBlock(false, tagNames); - } - - public GTRecipeJS adjacentBlock(boolean isReverse, ResourceLocation... tagNames) { - List> tags = Arrays.stream(tagNames) - .map(id -> TagKey.create(Registries.BLOCK, id)) - .toList(); - return addCondition(AdjacentBlockCondition.fromTags(tags).setReverse(isReverse)); - } - public GTRecipeJS daytime(boolean isNight) { return addCondition(new DaytimeCondition().setReverse(isNight)); } From ecb045d643758f3126a1868ba7444ad0026c4438 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:41:40 +0200 Subject: [PATCH 3/9] Remove a layer of serialization in OreVeinUtil#resolveBiomes --- .../gregtechceu/gtceu/api/codec/JavaOps.java | 439 ++++++++++++++++++ .../api/data/worldgen/ores/OreVeinUtil.java | 33 +- 2 files changed, 455 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java b/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java new file mode 100644 index 00000000000..b38a191c651 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java @@ -0,0 +1,439 @@ +// spotless:off +// MIT License +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// 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. +// spotless:on + +package com.gregtechceu.gtceu.api.codec; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.MapLike; +import com.mojang.serialization.RecordBuilder; +import it.unimi.dsi.fastutil.bytes.ByteArrayList; +import it.unimi.dsi.fastutil.bytes.ByteList; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.longs.LongList; + +import javax.annotation.Nullable; +import java.nio.ByteBuffer; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +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; + +/** + * Ops for pure Java types.
+ * This class MUST NOT discard any information (other than exact compound types) - there should be no data loss between 'create' and 'get' pairs. + *
+ * Copied from a newer version of DataFixerUpper under MIT; original source is + * here. + */ +public class JavaOps implements DynamicOps { + public static final JavaOps INSTANCE = new JavaOps(); + + private JavaOps() { + } + + @Override + public Object empty() { + return null; + } + + @Override + public Object emptyMap() { + return Map.of(); + } + + @Override + public Object emptyList() { + return List.of(); + } + + @Override + public U convertTo(final DynamicOps outOps, final Object input) { + if (input == null) { + return outOps.empty(); + } + if (input instanceof Map) { + return convertMap(outOps, input); + } + if (input instanceof final ByteList value) { + return outOps.createByteList(ByteBuffer.wrap(value.toByteArray())); + } + if (input instanceof final IntList value) { + return outOps.createIntList(value.intStream()); + } + if (input instanceof final LongList value) { + return outOps.createLongList(value.longStream()); + } + if (input instanceof List) { + return convertList(outOps, input); + } + if (input instanceof final String value) { + return outOps.createString(value); + } + if (input instanceof final Boolean value) { + return outOps.createBoolean(value); + } + if (input instanceof final Byte value) { + return outOps.createByte(value); + } + if (input instanceof final Short value) { + return outOps.createShort(value); + } + if (input instanceof final Integer value) { + return outOps.createInt(value); + } + if (input instanceof final Long value) { + return outOps.createLong(value); + } + if (input instanceof final Float value) { + return outOps.createFloat(value); + } + if (input instanceof final Double value) { + return outOps.createDouble(value); + } + if (input instanceof final Number value) { + return outOps.createNumeric(value); + } + throw new IllegalStateException("Don't know how to convert " + input); + } + + @Override + public DataResult getNumberValue(final Object input) { + if (input instanceof final Number value) { + return DataResult.success(value); + } + return DataResult.error(() -> "Not a number: " + input); + } + + @Override + public Object createNumeric(final Number value) { + return value; + } + + @Override + public Object createByte(final byte value) { + return value; + } + + @Override + public Object createShort(final short value) { + return value; + } + + @Override + public Object createInt(final int value) { + return value; + } + + @Override + public Object createLong(final long value) { + return value; + } + + @Override + public Object createFloat(final float value) { + return value; + } + + @Override + public Object createDouble(final double value) { + return value; + } + + @Override + public DataResult getBooleanValue(final Object input) { + if (input instanceof final Boolean value) { + return DataResult.success(value); + } + return DataResult.error(() -> "Not a boolean: " + input); + } + + @Override + public Object createBoolean(final boolean value) { + return value; + } + + @Override + public DataResult getStringValue(final Object input) { + if (input instanceof final String value) { + return DataResult.success(value); + } + return DataResult.error(() -> "Not a string: " + input); + } + + @Override + public Object createString(final String value) { + return value; + } + + @Override + public DataResult mergeToList(final Object input, final Object value) { + if (input == empty()) { + return DataResult.success(List.of(value)); + } + if (input instanceof final List list) { + if (list.isEmpty()) { + return DataResult.success(List.of(value)); + } + return DataResult.success(ImmutableList.builder().addAll(list).add(value).build()); + } + return DataResult.error(() -> "Not a list: " + input); + } + + @Override + public DataResult mergeToList(final Object input, final List values) { + if (input == empty()) { + return DataResult.success(values); + } + if (input instanceof final List list) { + if (list.isEmpty()) { + return DataResult.success(values); + } + return DataResult.success(ImmutableList.builder().addAll(list).addAll(values).build()); + } + return DataResult.error(() -> "Not a list: " + input); + } + + @Override + public DataResult mergeToMap(final Object input, final Object key, final Object value) { + if (input == empty()) { + return DataResult.success(Map.of(key, value)); + } + if (input instanceof final Map map) { + if (map.isEmpty()) { + return DataResult.success(Map.of(key, value)); + } + final ImmutableMap.Builder result = ImmutableMap.builderWithExpectedSize(map.size() + 1); + result.putAll(map); + result.put(key, value); + return DataResult.success(result.buildKeepingLast()); + } + return DataResult.error(() -> "Not a map: " + input); + } + + @Override + public DataResult mergeToMap(final Object input, final Map values) { + if (input == empty()) { + return DataResult.success(values); + } + if (input instanceof final Map map) { + if (map.isEmpty()) { + return DataResult.success(values); + } + final ImmutableMap.Builder result = ImmutableMap.builderWithExpectedSize(map.size() + values.size()); + result.putAll(map); + result.putAll(values); + return DataResult.success(result.buildKeepingLast()); + } + return DataResult.error(() -> "Not a map: " + input); + } + + private static Map mapLikeToMap(final MapLike values) { + return values.entries().collect(ImmutableMap.toImmutableMap(Pair::getFirst, Pair::getSecond)); + } + + @Override + public DataResult mergeToMap(final Object input, final MapLike values) { + if (input == empty()) { + return DataResult.success(mapLikeToMap(values)); + } + if (input instanceof final Map map) { + if (map.isEmpty()) { + return DataResult.success(mapLikeToMap(values)); + } + + final ImmutableMap.Builder result = ImmutableMap.builderWithExpectedSize(map.size()); + result.putAll(map); + values.entries().forEach(e -> result.put(e.getFirst(), e.getSecond())); + return DataResult.success(result.buildKeepingLast()); + } + return DataResult.error(() -> "Not a map: " + input); + } + + private static Stream> getMapEntries(final Map input) { + return input.entrySet().stream().map(e -> Pair.of(e.getKey(), e.getValue())); + } + + @Override + public DataResult>> getMapValues(final Object input) { + if (input instanceof final Map map) { + return DataResult.success(getMapEntries(map)); + } + return DataResult.error(() -> "Not a map: " + input); + } + + @Override + public DataResult>> getMapEntries(final Object input) { + if (input instanceof final Map map) { + return DataResult.success(map::forEach); + } + return DataResult.error(() -> "Not a map: " + input); + } + + @Override + public Object createMap(final Stream> map) { + return map.collect(ImmutableMap.toImmutableMap(Pair::getFirst, Pair::getSecond)); + } + + @Override + public DataResult> getMap(final Object input) { + if (input instanceof final Map map) { + return DataResult.success( + new MapLike<>() { + @Nullable + @Override + public Object get(final Object key) { + return map.get(key); + } + + @Nullable + @Override + public Object get(final String key) { + return map.get(key); + } + + @Override + public Stream> entries() { + return getMapEntries(map); + } + + @Override + public String toString() { + return "MapLike[" + map + "]"; + } + } + ); + } + return DataResult.error(() -> "Not a map: " + input); + } + + @Override + public Object createMap(final Map map) { + return map; + } + + @Override + public DataResult> getStream(final Object input) { + if (input instanceof final List list) { + return DataResult.success(list.stream().map(o -> o)); + } + return DataResult.error(() -> "Not an list: " + input); + } + + @Override + public DataResult>> getList(final Object input) { + if (input instanceof final List list) { + return DataResult.success(list::forEach); + } + return DataResult.error(() -> "Not an list: " + input); + } + + @Override + public Object createList(final Stream input) { + return input.toList(); + } + + @Override + public DataResult getByteBuffer(final Object input) { + if (input instanceof final ByteList value) { + return DataResult.success(ByteBuffer.wrap(value.toByteArray())); + } + return DataResult.error(() -> "Not a byte list: " + input); + } + + @Override + public Object createByteList(final ByteBuffer input) { + // Set .limit to .capacity to match default method + final ByteBuffer wholeBuffer = input.duplicate().clear(); + final ByteArrayList result = new ByteArrayList(); + result.size(wholeBuffer.capacity()); + wholeBuffer.get(0, result.elements(), 0, result.size()); + return result; + } + + @Override + public DataResult getIntStream(final Object input) { + if (input instanceof final IntList value) { + return DataResult.success(value.intStream()); + } + return DataResult.error(() -> "Not an int list: " + input); + } + + @Override + public Object createIntList(final IntStream input) { + return IntArrayList.toList(input); + } + + @Override + public DataResult getLongStream(final Object input) { + if (input instanceof final LongList value) { + return DataResult.success(value.longStream()); + } + return DataResult.error(() -> "Not a long list: " + input); + } + + @Override + public Object createLongList(final LongStream input) { + return LongArrayList.toList(input); + } + + @Override + public Object remove(final Object input, final String key) { + if (input instanceof final Map map) { + final Map result = new LinkedHashMap<>(map); + result.remove(key); + return Map.copyOf(result); + } + return input; + } + + @Override + public RecordBuilder mapBuilder() { + return new FixedMapBuilder<>(this); + } + + @Override + public String toString() { + return "Java"; + } + + private static final class FixedMapBuilder extends RecordBuilder.AbstractUniversalBuilder> { + public FixedMapBuilder(final DynamicOps ops) { + super(ops); + } + + @Override + protected ImmutableMap.Builder initBuilder() { + return ImmutableMap.builder(); + } + + @Override + protected ImmutableMap.Builder append(final T key, final T value, final ImmutableMap.Builder builder) { + return builder.put(key, value); + } + + @Override + protected DataResult build(final ImmutableMap.Builder builder, final T prefix) { + final ImmutableMap result = builder.buildKeepingLast(); + return ops().mergeToMap(prefix, result); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java index cb461179df4..0ac41b3d03a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.api.data.worldgen.ores; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.codec.JavaOps; import com.gregtechceu.gtceu.api.data.worldgen.GTOreDefinition; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.common.data.GTOres; @@ -20,10 +21,7 @@ import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; import com.google.common.base.Suppliers; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.mojang.serialization.JsonOps; +import com.mojang.serialization.Codec; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -37,6 +35,8 @@ @ParametersAreNonnullByDefault public class OreVeinUtil { + private static final Codec> BIOME_HOLDERSET_CODEC = RegistryCodecs.homogeneousList(Registries.BIOME); + private OreVeinUtil() {} public static boolean canPlaceOre(BlockState pState, Function pAdjacentStateAccessor, @@ -115,26 +115,25 @@ static int getMaxIndicatorSearchDistance() { @Nullable public static Supplier> resolveBiomes(List biomes) { - if (biomes.isEmpty()) + if (biomes.isEmpty()) { return null; + } - RegistryOps registryOps = RegistryOps.create(JsonOps.INSTANCE, GTRegistries.builtinRegistry()); - JsonElement codecInput = resolveBiomeCodecInput(biomes); - return Suppliers.memoize(() -> RegistryCodecs.homogeneousList(Registries.BIOME) - .parse(registryOps, codecInput) + RegistryOps registryOps = RegistryOps.create(JavaOps.INSTANCE, GTRegistries.builtinRegistry()); + Object codecInput = resolveBiomeCodecInput(biomes); + return Suppliers.memoize(() -> BIOME_HOLDERSET_CODEC.parse(registryOps, codecInput) .getOrThrow(false, GTCEu.LOGGER::error)); } - private static JsonElement resolveBiomeCodecInput(List biomes) { - if (biomes.size() == 1) - return new JsonPrimitive(biomes.get(0)); + private static Object resolveBiomeCodecInput(List biomes) { + if (biomes.size() == 1) { + return biomes.get(0); + } - if (biomes.stream().anyMatch(filter -> filter.startsWith("#"))) + if (biomes.stream().anyMatch(value -> value.indexOf('#') >= 0)) { throw new IllegalStateException( "Cannot resolve biomes: You may use either a single tag or multiple individual biomes."); - - var jsonArray = new JsonArray(); - biomes.forEach(jsonArray::add); - return jsonArray; + } + return biomes; } } From 3bb878f14130faedc67aa3109a158c1ceb2c5d69 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:44:07 +0200 Subject: [PATCH 4/9] Make BedrockFluidDefinition.Builder and BedrockOreDefinition.Builder use `ResourceLocation...` for the KubeJS dimension setter rather than `String...` --- .../bedrockfluid/BedrockFluidDefinition.java | 8 +++--- .../bedrockore/BedrockOreDefinition.java | 8 +++--- .../gregtechceu/gtceu/utils/RegistryUtil.java | 25 ------------------- 3 files changed, 10 insertions(+), 31 deletions(-) delete mode 100644 src/main/java/com/gregtechceu/gtceu/utils/RegistryUtil.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java index a3222217d25..7b781d8c015 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java @@ -2,7 +2,6 @@ import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier; import com.gregtechceu.gtceu.api.registry.GTRegistries; -import com.gregtechceu.gtceu.utils.RegistryUtil; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; @@ -27,6 +26,7 @@ import java.util.*; import java.util.function.Supplier; +import java.util.stream.Collectors; public class BedrockFluidDefinition { @@ -202,8 +202,10 @@ public Builder dimensions(Set> dimensions) { return this; } - public Builder dimensions(String... dimensions) { - return this.dimensions(new HashSet<>(RegistryUtil.resolveResourceKeys(Registries.DIMENSION, dimensions))); + public Builder dimensions(ResourceLocation... dimensions) { + return this.dimensions(Arrays.stream(dimensions) + .map(id -> ResourceKey.create(Registries.DIMENSION, id)) + .collect(Collectors.toSet())); } @ApiStatus.Internal diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java index 16953e86ea5..a49880f421d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java @@ -3,7 +3,6 @@ import com.gregtechceu.gtceu.api.data.chemical.material.Material; import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier; import com.gregtechceu.gtceu.api.registry.GTRegistries; -import com.gregtechceu.gtceu.utils.RegistryUtil; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; @@ -27,6 +26,7 @@ import lombok.experimental.Accessors; import java.util.*; +import java.util.stream.Collectors; @Accessors(fluent = true, chain = true) public class BedrockOreDefinition { @@ -216,8 +216,10 @@ public Builder dimensions(Set> dimensions) { return this; } - public Builder dimensions(String... dimensions) { - return this.dimensions(new HashSet<>(RegistryUtil.resolveResourceKeys(Registries.DIMENSION, dimensions))); + public Builder dimensions(ResourceLocation... dimensions) { + return this.dimensions(Arrays.stream(dimensions) + .map(id -> ResourceKey.create(Registries.DIMENSION, id)) + .collect(Collectors.toSet())); } public BedrockOreDefinition register() { diff --git a/src/main/java/com/gregtechceu/gtceu/utils/RegistryUtil.java b/src/main/java/com/gregtechceu/gtceu/utils/RegistryUtil.java deleted file mode 100644 index 41d5ea6df1c..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/utils/RegistryUtil.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.gregtechceu.gtceu.utils; - -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; - -import java.util.Arrays; -import java.util.List; - -import javax.annotation.ParametersAreNonnullByDefault; - -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public class RegistryUtil { - - private RegistryUtil() {} - - public static List> resolveResourceKeys(ResourceKey> registryKey, - String... locations) { - return Arrays.stream(locations) - .map(location -> ResourceKey.create(registryKey, new ResourceLocation(location))) - .toList(); - } -} From faba0edf782132b9007d6f6094284f6adcbdc5df Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:45:37 +0200 Subject: [PATCH 5/9] Add non-ambiguous KJS setters for bedrock fluid/ore veins' biomes --- .../bedrockfluid/BedrockFluidDefinition.java | 32 +++++++++++++++++- .../bedrockore/BedrockOreDefinition.java | 33 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java index 7b781d8c015..c16e506e3ad 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockfluid/BedrockFluidDefinition.java @@ -19,6 +19,7 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.latvian.mods.rhino.util.HideFromJS; +import dev.latvian.mods.rhino.util.RemapPrefixForJS; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -139,6 +140,7 @@ public static Builder builder(ResourceLocation name) { return new Builder(name); } + @RemapPrefixForJS("kjs$") @Accessors(chain = true, fluent = true) public static class Builder { @@ -178,12 +180,14 @@ public Builder yield(int min, int max) { return minimumYield(min).maximumYield(max); } + @HideFromJS public Builder biomes(int weight, TagKey biomes) { this.biomes.add(new BiomeWeightModifier(() -> GTRegistries.builtinRegistry() .registryOrThrow(Registries.BIOME).getOrCreateTag(biomes), weight)); return this; } + @HideFromJS @SafeVarargs public final Builder biomes(int weight, ResourceKey... biomes) { this.biomes.add(new BiomeWeightModifier(() -> HolderSet.direct(GTRegistries.builtinRegistry() @@ -191,6 +195,7 @@ public final Builder biomes(int weight, ResourceKey... biomes) { return this; } + @HideFromJS public Builder biomes(int weight, HolderSet biomes) { this.biomes.add(new BiomeWeightModifier(() -> biomes, weight)); return this; @@ -202,12 +207,37 @@ public Builder dimensions(Set> dimensions) { return this; } - public Builder dimensions(ResourceLocation... dimensions) { + // region KubeJS versions of the above methods + + /// This method should only be used in KubeJS. + @SuppressWarnings("unused") + @ApiStatus.Internal + public Builder kjs$biomeTag(int weight, ResourceLocation biomeTag) { + return this.biomes(weight, TagKey.create(Registries.BIOME, biomeTag)); + } + + /// This method should only be used in KubeJS. + @SuppressWarnings({ "unused", "unchecked" }) + @ApiStatus.Internal + public Builder kjs$biomes(int weight, ResourceLocation... biomes) { + ResourceKey[] resourceKeys = new ResourceKey[biomes.length]; + for (int i = 0; i < biomes.length; i++) { + resourceKeys[i] = ResourceKey.create(Registries.BIOME, biomes[i]); + } + return this.biomes(weight, resourceKeys); + } + + /// This method should only be used in KubeJS. + @SuppressWarnings("unused") + @ApiStatus.Internal + public Builder kjs$dimensions(ResourceLocation... dimensions) { return this.dimensions(Arrays.stream(dimensions) .map(id -> ResourceKey.create(Registries.DIMENSION, id)) .collect(Collectors.toSet())); } + // endregion + @ApiStatus.Internal public BedrockFluidDefinition build() { return new BedrockFluidDefinition(weight, minimumYield, maximumYield, depletionAmount, diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java index a49880f421d..37fd9bd09c6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/bedrockore/BedrockOreDefinition.java @@ -19,11 +19,13 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.latvian.mods.rhino.util.HideFromJS; +import dev.latvian.mods.rhino.util.RemapPrefixForJS; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; +import org.jetbrains.annotations.ApiStatus; import java.util.*; import java.util.stream.Collectors; @@ -146,6 +148,7 @@ public static Builder builder(ResourceLocation name) { return new Builder(name); } + @RemapPrefixForJS("kjs$") @Accessors(chain = true, fluent = true) public static class Builder { @@ -192,12 +195,14 @@ public Builder yield(int min, int max) { return this.yield(UniformInt.of(min, max)); } + @HideFromJS public Builder biomes(int weight, TagKey biomes) { this.biomes.add(new BiomeWeightModifier(() -> GTRegistries.builtinRegistry() .registryOrThrow(Registries.BIOME).getOrCreateTag(biomes), weight)); return this; } + @HideFromJS @SafeVarargs public final Builder biomes(int weight, ResourceKey... biomes) { this.biomes.add(new BiomeWeightModifier(() -> HolderSet.direct(GTRegistries.builtinRegistry() @@ -205,6 +210,7 @@ public final Builder biomes(int weight, ResourceKey... biomes) { return this; } + @HideFromJS public Builder biomes(int weight, HolderSet biomes) { this.biomes.add(new BiomeWeightModifier(() -> biomes, weight)); return this; @@ -216,12 +222,37 @@ public Builder dimensions(Set> dimensions) { return this; } - public Builder dimensions(ResourceLocation... dimensions) { + // region KubeJS versions of the above methods + + /// This method should only be used in KubeJS. + @SuppressWarnings("unused") + @ApiStatus.Internal + public Builder kjs$biomeTag(int weight, ResourceLocation biomeTag) { + return this.biomes(weight, TagKey.create(Registries.BIOME, biomeTag)); + } + + /// This method should only be used in KubeJS. + @SuppressWarnings({ "unused", "unchecked" }) + @ApiStatus.Internal + public Builder kjs$biomes(int weight, ResourceLocation... biomes) { + ResourceKey[] resourceKeys = new ResourceKey[biomes.length]; + for (int i = 0; i < biomes.length; i++) { + resourceKeys[i] = ResourceKey.create(Registries.BIOME, biomes[i]); + } + return this.biomes(weight, resourceKeys); + } + + /// This method should only be used in KubeJS. + @SuppressWarnings("unused") + @ApiStatus.Internal + public Builder kjs$dimensions(ResourceLocation... dimensions) { return this.dimensions(Arrays.stream(dimensions) .map(id -> ResourceKey.create(Registries.DIMENSION, id)) .collect(Collectors.toSet())); } + // endregion + public BedrockOreDefinition register() { var definition = new BedrockOreDefinition(weight, size, yield, depletionAmount, depletionChance, depletedYield, materials, biomes, dimensions); From 900f4719a5d2300e1e5b39488e552277de4d88b6 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:57:31 +0200 Subject: [PATCH 6/9] remove remaining ambiguous methods in GTOreDefinition --- .../api/data/worldgen/GTOreDefinition.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java index 0374e5e65a3..1a8e1a98ee5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java @@ -27,11 +27,13 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.latvian.mods.rhino.util.HideFromJS; import dev.latvian.mods.rhino.util.RemapForJS; +import dev.latvian.mods.rhino.util.RemapPrefixForJS; import it.unimi.dsi.fastutil.ints.IntIntPair; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import lombok.experimental.Tolerate; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -46,6 +48,7 @@ @SuppressWarnings("unused") @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault +@RemapPrefixForJS("kjs$") @Accessors(chain = true, fluent = true) public class GTOreDefinition { @@ -179,33 +182,44 @@ public GTOreDefinition weight(int weight) { public GTOreDefinition layer(IWorldGenLayer layer) { this.layer = layer; if (this.dimensionFilter == null || this.dimensionFilter.isEmpty()) { - dimensions(layer.getLevels().toArray(ResourceLocation[]::new)); + dimensions(layer.getLevels().stream() + .map(location -> ResourceKey.create(Registries.DIMENSION, location)) + .collect(Collectors.toSet())); } return this; } + @HideFromJS + public final GTOreDefinition dimensions(Set> dimensions) { + this.dimensionFilter = dimensions; + return this; + } + public GTOreDefinition dimensions(ResourceLocation... dimensions) { - this.dimensionFilter = Arrays.stream(dimensions) + return this.dimensions(Arrays.stream(dimensions) .map(location -> ResourceKey.create(Registries.DIMENSION, location)) - .collect(Collectors.toSet()); - return this; + .collect(Collectors.toSet())); } - public GTOreDefinition biomes(String first, String... biomes) { + /// This method should only be used in KubeJS. + @SuppressWarnings("unused") + @ApiStatus.Internal + public GTOreDefinition kjs$biomes(String first, String... biomes) { // The first param is separate to avoid method confusion with the Lombok-generated fluent getter - List biomeList = Stream.of(Stream.of(first), Arrays.stream(biomes)) - .flatMap(Function.identity()) + List biomeList = Stream.concat(Stream.of(first), Arrays.stream(biomes)) .toList(); this.biomes = OreVeinUtil.resolveBiomes(biomeList); return this; } + @HideFromJS public GTOreDefinition biomes(TagKey biomes) { this.biomes = () -> GTRegistries.builtinRegistry().lookupOrThrow(Registries.BIOME).getOrThrow(biomes); return this; } + @HideFromJS public GTOreDefinition biomes(Supplier> biomes) { this.biomes = biomes; return this; From 8441b10f01e5efda7d9b73e6ab45c2cb460dac81 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:59:49 +0200 Subject: [PATCH 7/9] deprecate `GTOreDefinition#dimensions(ResourceLocation...)` for 'removal' by rename --- .../gtceu/api/data/worldgen/GTOreDefinition.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java index 1a8e1a98ee5..d449ddcf3a7 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTOreDefinition.java @@ -195,6 +195,16 @@ public final GTOreDefinition dimensions(Set> dimensions) { return this; } + /** + * @deprecated Use {@link #dimensions(Set) dimensions(Set<ResourceKey<Level>>)} instead. + * @param dimensions + * @return this builder. + */ + @ApiStatus.ScheduledForRemoval(inVersion = "8.0.0") + @Deprecated(since = "7.4.1", forRemoval = true) + @ApiStatus.Internal + @SuppressWarnings("unused") + // TODO(8.0.0): rename to `kjs$dimensions` public GTOreDefinition dimensions(ResourceLocation... dimensions) { return this.dimensions(Arrays.stream(dimensions) .map(location -> ResourceKey.create(Registries.DIMENSION, location)) From 5a077b52e35812ce7465cb9141bfc6df522d2f5e Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 14:01:49 +0200 Subject: [PATCH 8/9] spotless --- .../gregtechceu/gtceu/api/codec/JavaOps.java | 73 ++++++++++--------- .../api/data/worldgen/ores/OreVeinUtil.java | 3 +- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java b/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java index b38a191c651..38cc797d18b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java +++ b/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java @@ -9,7 +9,6 @@ // // 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. // spotless:on - package com.gregtechceu.gtceu.api.codec; import com.google.common.collect.ImmutableList; @@ -25,8 +24,8 @@ import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongList; +import org.jetbrains.annotations.Nullable; -import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.LinkedHashMap; import java.util.List; @@ -39,16 +38,18 @@ /** * Ops for pure Java types.
- * This class MUST NOT discard any information (other than exact compound types) - there should be no data loss between 'create' and 'get' pairs. + * This class MUST NOT discard any information (other than exact compound types) - + * there should be no data loss between 'create' and 'get' pairs. *
- * Copied from a newer version of DataFixerUpper under MIT; original source is - * here. + * Copied from a newer version of DataFixerUpper under the MIT license. Original source is + * here. */ public class JavaOps implements DynamicOps { + public static final JavaOps INSTANCE = new JavaOps(); - private JavaOps() { - } + private JavaOps() {} @Override public Object empty() { @@ -238,7 +239,8 @@ public DataResult mergeToMap(final Object input, final Map result = ImmutableMap.builderWithExpectedSize(map.size() + values.size()); + final ImmutableMap.Builder result = ImmutableMap + .builderWithExpectedSize(map.size() + values.size()); result.putAll(map); result.putAll(values); return DataResult.success(result.buildKeepingLast()); @@ -297,30 +299,30 @@ public Object createMap(final Stream> map) { public DataResult> getMap(final Object input) { if (input instanceof final Map map) { return DataResult.success( - new MapLike<>() { - @Nullable - @Override - public Object get(final Object key) { - return map.get(key); - } - - @Nullable - @Override - public Object get(final String key) { - return map.get(key); - } - - @Override - public Stream> entries() { - return getMapEntries(map); - } - - @Override - public String toString() { - return "MapLike[" + map + "]"; - } - } - ); + new MapLike<>() { + + @Nullable + @Override + public Object get(final Object key) { + return map.get(key); + } + + @Nullable + @Override + public Object get(final String key) { + return map.get(key); + } + + @Override + public Stream> entries() { + return getMapEntries(map); + } + + @Override + public String toString() { + return "MapLike[" + map + "]"; + } + }); } return DataResult.error(() -> "Not a map: " + input); } @@ -415,7 +417,9 @@ public String toString() { return "Java"; } - private static final class FixedMapBuilder extends RecordBuilder.AbstractUniversalBuilder> { + private static final class FixedMapBuilder extends + RecordBuilder.AbstractUniversalBuilder> { + public FixedMapBuilder(final DynamicOps ops) { super(ops); } @@ -426,7 +430,8 @@ protected ImmutableMap.Builder initBuilder() { } @Override - protected ImmutableMap.Builder append(final T key, final T value, final ImmutableMap.Builder builder) { + protected ImmutableMap.Builder append(final T key, final T value, + final ImmutableMap.Builder builder) { return builder.put(key, value); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java index 0ac41b3d03a..c409b7a2c72 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java @@ -35,7 +35,8 @@ @ParametersAreNonnullByDefault public class OreVeinUtil { - private static final Codec> BIOME_HOLDERSET_CODEC = RegistryCodecs.homogeneousList(Registries.BIOME); + private static final Codec> BIOME_HOLDERSET_CODEC = RegistryCodecs + .homogeneousList(Registries.BIOME); private OreVeinUtil() {} From 6ff1f6b8276a9df5f9b41bb1abcfa0da170ad85f Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Sat, 31 Jan 2026 15:38:16 +0200 Subject: [PATCH 9/9] Revert "Remove a layer of serialization in OreVeinUtil#resolveBiomes" This reverts commit ecb045d6 --- .../gregtechceu/gtceu/api/codec/JavaOps.java | 444 ------------------ .../api/data/worldgen/ores/OreVeinUtil.java | 34 +- 2 files changed, 17 insertions(+), 461 deletions(-) delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java b/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java deleted file mode 100644 index 38cc797d18b..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/codec/JavaOps.java +++ /dev/null @@ -1,444 +0,0 @@ -// spotless:off -// MIT License -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// 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. -// spotless:on -package com.gregtechceu.gtceu.api.codec; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.DynamicOps; -import com.mojang.serialization.MapLike; -import com.mojang.serialization.RecordBuilder; -import it.unimi.dsi.fastutil.bytes.ByteArrayList; -import it.unimi.dsi.fastutil.bytes.ByteList; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.longs.LongArrayList; -import it.unimi.dsi.fastutil.longs.LongList; -import org.jetbrains.annotations.Nullable; - -import java.nio.ByteBuffer; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -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; - -/** - * Ops for pure Java types.
- * This class MUST NOT discard any information (other than exact compound types) - - * there should be no data loss between 'create' and 'get' pairs. - *
- * Copied from a newer version of DataFixerUpper under the MIT license. Original source is - * here. - */ -public class JavaOps implements DynamicOps { - - public static final JavaOps INSTANCE = new JavaOps(); - - private JavaOps() {} - - @Override - public Object empty() { - return null; - } - - @Override - public Object emptyMap() { - return Map.of(); - } - - @Override - public Object emptyList() { - return List.of(); - } - - @Override - public U convertTo(final DynamicOps outOps, final Object input) { - if (input == null) { - return outOps.empty(); - } - if (input instanceof Map) { - return convertMap(outOps, input); - } - if (input instanceof final ByteList value) { - return outOps.createByteList(ByteBuffer.wrap(value.toByteArray())); - } - if (input instanceof final IntList value) { - return outOps.createIntList(value.intStream()); - } - if (input instanceof final LongList value) { - return outOps.createLongList(value.longStream()); - } - if (input instanceof List) { - return convertList(outOps, input); - } - if (input instanceof final String value) { - return outOps.createString(value); - } - if (input instanceof final Boolean value) { - return outOps.createBoolean(value); - } - if (input instanceof final Byte value) { - return outOps.createByte(value); - } - if (input instanceof final Short value) { - return outOps.createShort(value); - } - if (input instanceof final Integer value) { - return outOps.createInt(value); - } - if (input instanceof final Long value) { - return outOps.createLong(value); - } - if (input instanceof final Float value) { - return outOps.createFloat(value); - } - if (input instanceof final Double value) { - return outOps.createDouble(value); - } - if (input instanceof final Number value) { - return outOps.createNumeric(value); - } - throw new IllegalStateException("Don't know how to convert " + input); - } - - @Override - public DataResult getNumberValue(final Object input) { - if (input instanceof final Number value) { - return DataResult.success(value); - } - return DataResult.error(() -> "Not a number: " + input); - } - - @Override - public Object createNumeric(final Number value) { - return value; - } - - @Override - public Object createByte(final byte value) { - return value; - } - - @Override - public Object createShort(final short value) { - return value; - } - - @Override - public Object createInt(final int value) { - return value; - } - - @Override - public Object createLong(final long value) { - return value; - } - - @Override - public Object createFloat(final float value) { - return value; - } - - @Override - public Object createDouble(final double value) { - return value; - } - - @Override - public DataResult getBooleanValue(final Object input) { - if (input instanceof final Boolean value) { - return DataResult.success(value); - } - return DataResult.error(() -> "Not a boolean: " + input); - } - - @Override - public Object createBoolean(final boolean value) { - return value; - } - - @Override - public DataResult getStringValue(final Object input) { - if (input instanceof final String value) { - return DataResult.success(value); - } - return DataResult.error(() -> "Not a string: " + input); - } - - @Override - public Object createString(final String value) { - return value; - } - - @Override - public DataResult mergeToList(final Object input, final Object value) { - if (input == empty()) { - return DataResult.success(List.of(value)); - } - if (input instanceof final List list) { - if (list.isEmpty()) { - return DataResult.success(List.of(value)); - } - return DataResult.success(ImmutableList.builder().addAll(list).add(value).build()); - } - return DataResult.error(() -> "Not a list: " + input); - } - - @Override - public DataResult mergeToList(final Object input, final List values) { - if (input == empty()) { - return DataResult.success(values); - } - if (input instanceof final List list) { - if (list.isEmpty()) { - return DataResult.success(values); - } - return DataResult.success(ImmutableList.builder().addAll(list).addAll(values).build()); - } - return DataResult.error(() -> "Not a list: " + input); - } - - @Override - public DataResult mergeToMap(final Object input, final Object key, final Object value) { - if (input == empty()) { - return DataResult.success(Map.of(key, value)); - } - if (input instanceof final Map map) { - if (map.isEmpty()) { - return DataResult.success(Map.of(key, value)); - } - final ImmutableMap.Builder result = ImmutableMap.builderWithExpectedSize(map.size() + 1); - result.putAll(map); - result.put(key, value); - return DataResult.success(result.buildKeepingLast()); - } - return DataResult.error(() -> "Not a map: " + input); - } - - @Override - public DataResult mergeToMap(final Object input, final Map values) { - if (input == empty()) { - return DataResult.success(values); - } - if (input instanceof final Map map) { - if (map.isEmpty()) { - return DataResult.success(values); - } - final ImmutableMap.Builder result = ImmutableMap - .builderWithExpectedSize(map.size() + values.size()); - result.putAll(map); - result.putAll(values); - return DataResult.success(result.buildKeepingLast()); - } - return DataResult.error(() -> "Not a map: " + input); - } - - private static Map mapLikeToMap(final MapLike values) { - return values.entries().collect(ImmutableMap.toImmutableMap(Pair::getFirst, Pair::getSecond)); - } - - @Override - public DataResult mergeToMap(final Object input, final MapLike values) { - if (input == empty()) { - return DataResult.success(mapLikeToMap(values)); - } - if (input instanceof final Map map) { - if (map.isEmpty()) { - return DataResult.success(mapLikeToMap(values)); - } - - final ImmutableMap.Builder result = ImmutableMap.builderWithExpectedSize(map.size()); - result.putAll(map); - values.entries().forEach(e -> result.put(e.getFirst(), e.getSecond())); - return DataResult.success(result.buildKeepingLast()); - } - return DataResult.error(() -> "Not a map: " + input); - } - - private static Stream> getMapEntries(final Map input) { - return input.entrySet().stream().map(e -> Pair.of(e.getKey(), e.getValue())); - } - - @Override - public DataResult>> getMapValues(final Object input) { - if (input instanceof final Map map) { - return DataResult.success(getMapEntries(map)); - } - return DataResult.error(() -> "Not a map: " + input); - } - - @Override - public DataResult>> getMapEntries(final Object input) { - if (input instanceof final Map map) { - return DataResult.success(map::forEach); - } - return DataResult.error(() -> "Not a map: " + input); - } - - @Override - public Object createMap(final Stream> map) { - return map.collect(ImmutableMap.toImmutableMap(Pair::getFirst, Pair::getSecond)); - } - - @Override - public DataResult> getMap(final Object input) { - if (input instanceof final Map map) { - return DataResult.success( - new MapLike<>() { - - @Nullable - @Override - public Object get(final Object key) { - return map.get(key); - } - - @Nullable - @Override - public Object get(final String key) { - return map.get(key); - } - - @Override - public Stream> entries() { - return getMapEntries(map); - } - - @Override - public String toString() { - return "MapLike[" + map + "]"; - } - }); - } - return DataResult.error(() -> "Not a map: " + input); - } - - @Override - public Object createMap(final Map map) { - return map; - } - - @Override - public DataResult> getStream(final Object input) { - if (input instanceof final List list) { - return DataResult.success(list.stream().map(o -> o)); - } - return DataResult.error(() -> "Not an list: " + input); - } - - @Override - public DataResult>> getList(final Object input) { - if (input instanceof final List list) { - return DataResult.success(list::forEach); - } - return DataResult.error(() -> "Not an list: " + input); - } - - @Override - public Object createList(final Stream input) { - return input.toList(); - } - - @Override - public DataResult getByteBuffer(final Object input) { - if (input instanceof final ByteList value) { - return DataResult.success(ByteBuffer.wrap(value.toByteArray())); - } - return DataResult.error(() -> "Not a byte list: " + input); - } - - @Override - public Object createByteList(final ByteBuffer input) { - // Set .limit to .capacity to match default method - final ByteBuffer wholeBuffer = input.duplicate().clear(); - final ByteArrayList result = new ByteArrayList(); - result.size(wholeBuffer.capacity()); - wholeBuffer.get(0, result.elements(), 0, result.size()); - return result; - } - - @Override - public DataResult getIntStream(final Object input) { - if (input instanceof final IntList value) { - return DataResult.success(value.intStream()); - } - return DataResult.error(() -> "Not an int list: " + input); - } - - @Override - public Object createIntList(final IntStream input) { - return IntArrayList.toList(input); - } - - @Override - public DataResult getLongStream(final Object input) { - if (input instanceof final LongList value) { - return DataResult.success(value.longStream()); - } - return DataResult.error(() -> "Not a long list: " + input); - } - - @Override - public Object createLongList(final LongStream input) { - return LongArrayList.toList(input); - } - - @Override - public Object remove(final Object input, final String key) { - if (input instanceof final Map map) { - final Map result = new LinkedHashMap<>(map); - result.remove(key); - return Map.copyOf(result); - } - return input; - } - - @Override - public RecordBuilder mapBuilder() { - return new FixedMapBuilder<>(this); - } - - @Override - public String toString() { - return "Java"; - } - - private static final class FixedMapBuilder extends - RecordBuilder.AbstractUniversalBuilder> { - - public FixedMapBuilder(final DynamicOps ops) { - super(ops); - } - - @Override - protected ImmutableMap.Builder initBuilder() { - return ImmutableMap.builder(); - } - - @Override - protected ImmutableMap.Builder append(final T key, final T value, - final ImmutableMap.Builder builder) { - return builder.put(key, value); - } - - @Override - protected DataResult build(final ImmutableMap.Builder builder, final T prefix) { - final ImmutableMap result = builder.buildKeepingLast(); - return ops().mergeToMap(prefix, result); - } - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java index c409b7a2c72..cb461179df4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/ores/OreVeinUtil.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.api.data.worldgen.ores; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.codec.JavaOps; import com.gregtechceu.gtceu.api.data.worldgen.GTOreDefinition; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.common.data.GTOres; @@ -21,7 +20,10 @@ import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; import com.google.common.base.Suppliers; -import com.mojang.serialization.Codec; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; +import com.mojang.serialization.JsonOps; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -35,9 +37,6 @@ @ParametersAreNonnullByDefault public class OreVeinUtil { - private static final Codec> BIOME_HOLDERSET_CODEC = RegistryCodecs - .homogeneousList(Registries.BIOME); - private OreVeinUtil() {} public static boolean canPlaceOre(BlockState pState, Function pAdjacentStateAccessor, @@ -116,25 +115,26 @@ static int getMaxIndicatorSearchDistance() { @Nullable public static Supplier> resolveBiomes(List biomes) { - if (biomes.isEmpty()) { + if (biomes.isEmpty()) return null; - } - RegistryOps registryOps = RegistryOps.create(JavaOps.INSTANCE, GTRegistries.builtinRegistry()); - Object codecInput = resolveBiomeCodecInput(biomes); - return Suppliers.memoize(() -> BIOME_HOLDERSET_CODEC.parse(registryOps, codecInput) + RegistryOps registryOps = RegistryOps.create(JsonOps.INSTANCE, GTRegistries.builtinRegistry()); + JsonElement codecInput = resolveBiomeCodecInput(biomes); + return Suppliers.memoize(() -> RegistryCodecs.homogeneousList(Registries.BIOME) + .parse(registryOps, codecInput) .getOrThrow(false, GTCEu.LOGGER::error)); } - private static Object resolveBiomeCodecInput(List biomes) { - if (biomes.size() == 1) { - return biomes.get(0); - } + private static JsonElement resolveBiomeCodecInput(List biomes) { + if (biomes.size() == 1) + return new JsonPrimitive(biomes.get(0)); - if (biomes.stream().anyMatch(value -> value.indexOf('#') >= 0)) { + if (biomes.stream().anyMatch(filter -> filter.startsWith("#"))) throw new IllegalStateException( "Cannot resolve biomes: You may use either a single tag or multiple individual biomes."); - } - return biomes; + + var jsonArray = new JsonArray(); + biomes.forEach(jsonArray::add); + return jsonArray; } }