diff --git a/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java b/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java index 91a39e89f..93affce6a 100644 --- a/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java +++ b/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java @@ -9,10 +9,12 @@ import dev.latvian.mods.kubejs.bindings.ColorWrapper; import dev.latvian.mods.kubejs.bindings.DamageSourceWrapper; import dev.latvian.mods.kubejs.bindings.DirectionWrapper; +import dev.latvian.mods.kubejs.bindings.EntitySelectorWrapper; import dev.latvian.mods.kubejs.bindings.IngredientWrapper; import dev.latvian.mods.kubejs.bindings.ItemWrapper; import dev.latvian.mods.kubejs.bindings.JavaWrapper; import dev.latvian.mods.kubejs.bindings.KMath; +import dev.latvian.mods.kubejs.bindings.NBTWrapper; import dev.latvian.mods.kubejs.bindings.ParticleOptionsWrapper; import dev.latvian.mods.kubejs.bindings.RegistryWrapper; import dev.latvian.mods.kubejs.bindings.SizedIngredientWrapper; @@ -145,7 +147,6 @@ import dev.latvian.mods.kubejs.util.JsonUtils; import dev.latvian.mods.kubejs.util.KubeResourceLocation; import dev.latvian.mods.kubejs.util.NBTIOWrapper; -import dev.latvian.mods.kubejs.util.NBTUtils; import dev.latvian.mods.kubejs.util.NotificationToastData; import dev.latvian.mods.kubejs.util.RegExpKJS; import dev.latvian.mods.kubejs.util.RegistryAccessContainer; @@ -155,7 +156,6 @@ import dev.latvian.mods.kubejs.util.TickDuration; import dev.latvian.mods.kubejs.util.TimeJS; import dev.latvian.mods.kubejs.util.Tristate; -import dev.latvian.mods.kubejs.util.UtilsJS; import dev.latvian.mods.kubejs.util.registrypredicate.RegistryPredicate; import dev.latvian.mods.kubejs.web.LocalWebServerRegistry; import dev.latvian.mods.kubejs.web.local.KubeJSWeb; @@ -491,7 +491,7 @@ public void registerBindings(BindingRegistry bindings) { bindings.add("Item", ItemWrapper.class); bindings.add("Items", Items.class); bindings.add("Ingredient", IngredientWrapper.class); - bindings.add("NBT", NBTUtils.class); + bindings.add("NBT", NBTWrapper.class); bindings.add("NBTIO", NBTIOWrapper.class); bindings.add("Direction", DirectionWrapper.class); bindings.add("Facing", DirectionWrapper.class); @@ -502,6 +502,7 @@ public void registerBindings(BindingRegistry bindings) { bindings.add("SizedIngredient", SizedIngredientWrapper.class); bindings.add("ParticleOptions", ParticleOptionsWrapper.class); bindings.add("Registry", RegistryWrapper.class); + bindings.add("EntitySelector", EntitySelectorWrapper.class); bindings.add("Fluid", FluidWrapper.class); @@ -543,43 +544,43 @@ public void registerTypeWrappers(TypeWrapperRegistry registry) { registry.register(JsonArray.class, JsonUtils::arrayOf); registry.register(JsonElement.class, JsonUtils::of); registry.register(JsonPrimitive.class, JsonUtils::primitiveOf); - registry.register(Path.class, KubeJSTypeWrappers::pathOf); - registry.register(File.class, KubeJSTypeWrappers::fileOf); - registry.register(TemporalAmount.class, TimeJS::temporalAmountOf); - registry.register(Duration.class, TimeJS::durationOf); + registry.register(Path.class, KubeJSTypeWrappers::wrapPath); + registry.register(File.class, KubeJSTypeWrappers::wrapFile); + registry.register(TemporalAmount.class, TimeJS::wrapTemporalAmount); + registry.register(Duration.class, TimeJS::wrapDuration); registry.register(TickDuration.class, TickDuration::wrap); registry.register(ResourceLocation.class, ID::mc); registry.register(KubeResourceLocation.class, KubeResourceLocation::wrap); - registry.register(CompoundTag.class, (from, target) -> NBTUtils.isTagCompound(from), NBTUtils::toTagCompound); - registry.register(CollectionTag.class, (from, target) -> NBTUtils.isTagCollection(from), NBTUtils::toTagCollection); - registry.register(ListTag.class, (from, target) -> NBTUtils.isTagCollection(from), NBTUtils::toTagList); - registry.register(Tag.class, NBTUtils::toTag); + registry.register(CompoundTag.class, (from, target) -> NBTWrapper.isTagCompound(from), NBTWrapper::wrapCompound); + registry.register(CollectionTag.class, (from, target) -> NBTWrapper.isTagCollection(from), NBTWrapper::wrapCollection); + registry.register(ListTag.class, (from, target) -> NBTWrapper.isTagCollection(from), NBTWrapper::wrapListTag); + registry.register(Tag.class, NBTWrapper::wrap); registry.register(DataComponentType.class, DataComponentWrapper::wrapType); registry.register(DataComponentMap.class, DataComponentWrapper::filter, (cx, from, target) -> DataComponentWrapper.mapOf(RegistryAccessContainer.of(cx).nbt(), from)); registry.register(DataComponentPatch.class, DataComponentWrapper::filter, (cx, from, target) -> DataComponentWrapper.patchOf(RegistryAccessContainer.of(cx).nbt(), from)); - registry.register(BlockPos.class, KubeJSTypeWrappers::blockPosOf); - registry.register(Vec3.class, KubeJSTypeWrappers::vec3Of); - registry.register(Vec3i.class, KubeJSTypeWrappers::blockPosOf); + registry.register(BlockPos.class, KubeJSTypeWrappers::wrapBlockPos); + registry.register(Vec3.class, KubeJSTypeWrappers::wrapVec3); + registry.register(Vec3i.class, KubeJSTypeWrappers::wrapBlockPos); registry.register(Item.class, ItemWrapper::wrapItem); registry.register(ItemLike.class, ItemWrapper::wrapItem); registry.registerEnumFromStringCodec(MobCategory.class, MobCategory.CODEC); - registry.register(ItemEnchantments.class, ItemEnchantmentsWrapper::from); + registry.register(ItemEnchantments.class, ItemEnchantmentsWrapper::wrap); registry.register(AABB.class, AABBWrapper::wrap); - registry.register(IntProvider.class, KubeJSTypeWrappers::intProviderOf); - registry.register(FloatProvider.class, KubeJSTypeWrappers::floatProviderOf); - registry.register(NumberProvider.class, KubeJSTypeWrappers::numberProviderOf); + registry.register(IntProvider.class, KubeJSTypeWrappers::wrapIntProvider); + registry.register(FloatProvider.class, KubeJSTypeWrappers::wrapFloatProvider); + registry.register(NumberProvider.class, KubeJSTypeWrappers::wrapNumberProvider); registry.registerEnumFromStringCodec(LootContext.EntityTarget.class, LootContext.EntityTarget.CODEC); registry.registerEnumFromStringCodec(CopyNameFunction.NameSource.class, CopyNameFunction.NameSource.CODEC); - // FIXME registry.register(Enchantment.Cost.class, EnchantmentBuilder::costOf); + // FIXME registry.register(Enchantment.Cost.class, EnchantmentBuilder::wrapCost); registry.registerEnumFromStringCodec(ArmorItem.Type.class, ArmorItem.Type.CODEC); - registry.register(BlockSetType.class, BlockWrapper::setTypeOf); + registry.register(BlockSetType.class, BlockWrapper::wrapSetType); registry.register(BlockState.class, BlockWrapper::wrapBlockState); - registry.register(ItemAbility.class, ItemWrapper::itemAbilityOf); - registry.register(ColorRGBA.class, ColorWrapper::colorRGBAOf); + registry.register(ItemAbility.class, ItemWrapper::wrapItemAbility); + registry.register(ColorRGBA.class, ColorWrapper::wrapColorRGBA); // KubeJS // registry.register(ItemStack.class, ItemWrapper::wrap); @@ -591,28 +592,28 @@ public void registerTypeWrappers(TypeWrapperRegistry registry) { registry.register(FluidStack.class, FluidWrapper::wrap); registry.register(FluidIngredient.class, FluidWrapper::wrapIngredient); registry.register(SizedFluidIngredient.class, FluidWrapper::wrapSizedIngredient); - registry.register(RecipeFilter.class, RecipeFilter::of); + registry.register(RecipeFilter.class, RecipeFilter::wrap); registry.register(SlotFilter.class, SlotFilter::wrap); registry.register(Tier.class, ItemToolTiers::wrap); - registry.register(PlayerSelector.class, PlayerSelector::of); - registry.register(DamageSource.class, DamageSourceWrapper::of); - registry.register(EntitySelector.class, UtilsJS::entitySelector); + registry.register(PlayerSelector.class, PlayerSelector::wrap); + registry.register(DamageSource.class, DamageSourceWrapper::wrap); + registry.register(EntitySelector.class, EntitySelectorWrapper::wrap); registry.register(ReplacementMatch.class, ReplacementMatch::wrap); registry.register(ReplacementMatchInfo.class, ReplacementMatchInfo::wrap); - registry.register(Stat.class, PlayerStatsJS::statOf); - registry.register(MapColor.class, MapColorHelper::of); + registry.register(Stat.class, PlayerStatsJS::wrapStat); + registry.register(MapColor.class, MapColorHelper::wrap); registry.register(SoundType.class, SoundTypeWrapper.INSTANCE); registry.register(ParticleOptions.class, ParticleOptionsWrapper::wrap); - registry.register(ItemTintFunction.class, ItemTintFunction::of); - registry.register(BlockTintFunction.class, BlockTintFunction::of); + registry.register(ItemTintFunction.class, ItemTintFunction::wrap); + registry.register(BlockTintFunction.class, BlockTintFunction::wrap); registry.register(Tristate.class, Tristate::wrap); // components // - registry.register(Component.class, TextWrapper::of); - registry.register(MutableComponent.class, TextWrapper::of); - registry.register(KubeColor.class, ColorWrapper::of); - registry.register(TextColor.class, ColorWrapper::textColorOf); - registry.register(ClickEvent.class, TextWrapper::clickEventOf); + registry.register(Component.class, TextWrapper::wrap); + registry.register(MutableComponent.class, TextWrapper::wrap); + registry.register(KubeColor.class, ColorWrapper::wrap); + registry.register(TextColor.class, ColorWrapper::wrapTextColor); + registry.register(ClickEvent.class, TextWrapper::wrapClickEvent); // codecs registry.registerCodec(Fireworks.class, Fireworks.CODEC); diff --git a/src/main/java/dev/latvian/mods/kubejs/KubeJSTypeWrappers.java b/src/main/java/dev/latvian/mods/kubejs/KubeJSTypeWrappers.java index 1113849b5..c31dc6384 100644 --- a/src/main/java/dev/latvian/mods/kubejs/KubeJSTypeWrappers.java +++ b/src/main/java/dev/latvian/mods/kubejs/KubeJSTypeWrappers.java @@ -1,8 +1,8 @@ package dev.latvian.mods.kubejs; +import dev.latvian.mods.kubejs.bindings.NBTWrapper; import dev.latvian.mods.kubejs.bindings.StringUtilsWrapper; import dev.latvian.mods.kubejs.level.LevelBlock; -import dev.latvian.mods.kubejs.util.NBTUtils; import dev.latvian.mods.kubejs.util.RegistryAccessContainer; import dev.latvian.mods.rhino.Context; import net.minecraft.core.BlockPos; @@ -30,7 +30,7 @@ public interface KubeJSTypeWrappers { @SuppressWarnings("unchecked") - static IntProvider intProviderOf(Context cx, Object o) { + static IntProvider wrapIntProvider(Context cx, Object o) { if (o instanceof Number n) { return ConstantInt.of(n.intValue()); } else if (o instanceof List l && !l.isEmpty()) { @@ -44,7 +44,7 @@ static IntProvider intProviderOf(Context cx, Object o) { if (intBounds != null) { return intBounds; } else if (m.containsKey("clamped")) { - var source = intProviderOf(cx, m.get("clamped")); + var source = wrapIntProvider(cx, m.get("clamped")); var clampTo = parseIntBounds(m); if (clampTo != null) { return ClampedInt.of(source, clampTo.getMinValue(), clampTo.getMaxValue()); @@ -58,7 +58,7 @@ static IntProvider intProviderOf(Context cx, Object o) { } } - var decoded = IntProvider.CODEC.parse(RegistryAccessContainer.of(cx).nbt(), NBTUtils.toTagCompound(cx, m)).result(); + var decoded = IntProvider.CODEC.parse(RegistryAccessContainer.of(cx).nbt(), NBTWrapper.wrapCompound(cx, m)).result(); if (decoded.isPresent()) { return decoded.get(); } @@ -68,7 +68,7 @@ static IntProvider intProviderOf(Context cx, Object o) { } @SuppressWarnings("unchecked") - static FloatProvider floatProviderOf(Context cx, Object o) { + static FloatProvider wrapFloatProvider(Context cx, Object o) { if (o instanceof Number n) { return ConstantFloat.of(n.floatValue()); } else if (o instanceof List l && !l.isEmpty()) { @@ -90,7 +90,7 @@ static FloatProvider floatProviderOf(Context cx, Object o) { } } - var decoded = FloatProvider.CODEC.parse(RegistryAccessContainer.of(cx).nbt(), NBTUtils.toTagCompound(cx, m)).result(); + var decoded = FloatProvider.CODEC.parse(RegistryAccessContainer.of(cx).nbt(), NBTWrapper.wrapCompound(cx, m)).result(); if (decoded.isPresent()) { return decoded.get(); @@ -101,7 +101,7 @@ static FloatProvider floatProviderOf(Context cx, Object o) { } @SuppressWarnings("unchecked") - static NumberProvider numberProviderOf(Object o) { + static NumberProvider wrapNumberProvider(Object o) { if (o instanceof Number n) { var f = n.floatValue(); return UniformGenerator.between(f, f); @@ -124,7 +124,7 @@ static NumberProvider numberProviderOf(Object o) { return ConstantValue.exactly(0); } - static Vec3 vec3Of(@Nullable Object o) { + static Vec3 wrapVec3(@Nullable Object o) { if (o instanceof Vec3 vec) { return vec; } else if (o instanceof Entity entity) { @@ -140,7 +140,7 @@ static Vec3 vec3Of(@Nullable Object o) { return Vec3.ZERO; } - static BlockPos blockPosOf(@Nullable Object o) { + static BlockPos wrapBlockPos(@Nullable Object o) { if (o instanceof BlockPos pos) { return pos; } else if (o instanceof List list && list.size() >= 3) { @@ -183,7 +183,7 @@ private static UniformFloat parseFloatBounds(Map m) { } @Nullable - static Path pathOf(Object o) { + static Path wrapPath(Object o) { try { if (o instanceof Path) { return KubeJSPaths.verifyFilePath((Path) o); @@ -198,7 +198,7 @@ static Path pathOf(Object o) { } @Nullable - static File fileOf(Object o) { + static File wrapFile(Object o) { try { if (o instanceof File) { return KubeJSPaths.verifyFilePath(((File) o).toPath()).toFile(); diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/BlockWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/BlockWrapper.java index 10f26091e..a8fbaef37 100644 --- a/src/main/java/dev/latvian/mods/kubejs/bindings/BlockWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/BlockWrapper.java @@ -138,7 +138,7 @@ public static BlockState parseBlockState(RegistryAccessContainer registries, Str } } - public static BlockSetType setTypeOf(Context cx, Object from, TypeInfo target) { + public static BlockSetType wrapSetType(Context cx, Object from, TypeInfo target) { return switch (from) { case null -> null; case BlockSetType type -> type; diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/ColorWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/ColorWrapper.java index 1e1a13ee1..96344c91e 100644 --- a/src/main/java/dev/latvian/mods/kubejs/bindings/ColorWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/ColorWrapper.java @@ -26,7 +26,7 @@ public interface ColorWrapper { } }); - static KubeColor of(Object o) { + static KubeColor wrap(Object o) { if (o instanceof KubeColor) { return (KubeColor) o; } else if (o instanceof String) { @@ -56,16 +56,16 @@ static KubeColor of(Object o) { return NONE; } - static TextColor textColorOf(Object o) { - return of(o).kjs$createTextColor(); + static TextColor wrapTextColor(Object o) { + return wrap(o).kjs$createTextColor(); } - static ColorRGBA colorRGBAOf(Object o) { - return new ColorRGBA(of(o).kjs$getARGB()); + static ColorRGBA wrapColorRGBA(Object o) { + return new ColorRGBA(wrap(o).kjs$getARGB()); } static KubeColor createMapped(Object o, String... names) { - KubeColor c = of(o); + KubeColor c = wrap(o); for (String s : names) { MAP.put(s, c); diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/DamageSourceWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/DamageSourceWrapper.java index d76b669e2..58900adac 100644 --- a/src/main/java/dev/latvian/mods/kubejs/bindings/DamageSourceWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/DamageSourceWrapper.java @@ -9,7 +9,7 @@ import net.minecraft.world.entity.player.Player; public class DamageSourceWrapper { - public static DamageSource of(RegistryAccessContainer registries, Object from) { + public static DamageSource wrap(RegistryAccessContainer registries, Object from) { return switch (from) { case DamageSource source -> source; case Player player -> registries.damageSources().playerAttack(player); diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/EntitySelectorWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/EntitySelectorWrapper.java new file mode 100644 index 000000000..a33c90ca1 --- /dev/null +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/EntitySelectorWrapper.java @@ -0,0 +1,52 @@ +package dev.latvian.mods.kubejs.bindings; + +import com.mojang.brigadier.StringReader; +import dev.latvian.mods.rhino.util.HideFromJS; +import net.minecraft.advancements.critereon.MinMaxBounds; +import net.minecraft.commands.arguments.selector.EntitySelector; +import net.minecraft.commands.arguments.selector.EntitySelectorParser; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public class EntitySelectorWrapper { + private static final Map ENTITY_SELECTOR_CACHE = new HashMap<>(); + private static final EntitySelector ALL_ENTITIES_SELECTOR = new EntitySelector(EntitySelector.INFINITE, true, false, List.of(), MinMaxBounds.Doubles.ANY, Function.identity(), null, EntitySelectorParser.ORDER_RANDOM, false, null, null, null, true); + + public static EntitySelector of(EntitySelector selector) { + return selector; + } + + @HideFromJS + public static EntitySelector wrap(@Nullable Object o) { + if (o == null) { + return ALL_ENTITIES_SELECTOR; + } else if (o instanceof EntitySelector s) { + return s; + } + + String s = o.toString(); + + if (s.isBlank()) { + return ALL_ENTITIES_SELECTOR; + } + + var sel = ENTITY_SELECTOR_CACHE.get(s); + + if (sel == null) { + sel = ALL_ENTITIES_SELECTOR; + + try { + sel = new EntitySelectorParser(new StringReader(s), true).parse(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + ENTITY_SELECTOR_CACHE.put(s, sel); + return sel; + } +} diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/ItemWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/ItemWrapper.java index dce9d47b7..526474ffd 100644 --- a/src/main/java/dev/latvian/mods/kubejs/bindings/ItemWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/ItemWrapper.java @@ -309,7 +309,7 @@ static ItemStack playerHeadFromSkinHash(String hash) { return playerHeadFromUrl("https://textures.minecraft.net/texture/" + hash); } - static ItemAbility itemAbilityOf(Object object) { + static ItemAbility wrapItemAbility(Object object) { if (object instanceof ItemAbility ta) { return ta; } else if (object != null) { diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/NBTWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/NBTWrapper.java new file mode 100644 index 000000000..bf2d19f81 --- /dev/null +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/NBTWrapper.java @@ -0,0 +1,398 @@ +package dev.latvian.mods.kubejs.bindings; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import dev.latvian.mods.kubejs.util.NBTSerializable; +import dev.latvian.mods.kubejs.util.NBTUtils; +import dev.latvian.mods.kubejs.util.OrderedCompoundTag; +import dev.latvian.mods.rhino.Context; +import dev.latvian.mods.rhino.Undefined; +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CollectionTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.NumericTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.nbt.TagParser; +import net.minecraft.network.FriendlyByteBuf; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public interface NBTWrapper { + static boolean isTagCompound(Object o) { + return o == null || Undefined.isUndefined(o) || o instanceof CompoundTag || o instanceof CharSequence || o instanceof Map || o instanceof JsonElement; + } + + static boolean isTagCollection(Object o) { + return o == null || Undefined.isUndefined(o) || o instanceof CharSequence || o instanceof Collection || o instanceof JsonArray; + } + + @Nullable + static Object fromTag(@Nullable Tag t) { + return switch (t) { + case null -> null; + case EndTag ignore -> null; + case StringTag ignore -> t.getAsString(); + case NumericTag num -> num.getAsNumber(); + case CompoundTag tag -> { + if (tag.isEmpty()) { + yield Map.of(); + } + + var map0 = NBTUtils.accessTagMap(tag); + var map = new LinkedHashMap(map0.size()); + + for (var entry : map0.entrySet()) { + map.put(entry.getKey(), fromTag(entry.getValue())); + } + + yield map; + } + case CollectionTag tag -> { + if (tag.isEmpty()) { + yield List.of(); + } + + var list = new ArrayList<>(tag.size()); + + for (var v : tag) { + list.add(fromTag(v)); + } + + yield list; + } + default -> t; + }; + } + + @Nullable + static Tag toTag(@Nullable Tag tag) { + return tag; + } + + @Nullable + static Tag wrap(Context cx, @Nullable Object v) { + if (v == null || v instanceof EndTag) { + return null; + } else if (v instanceof Tag tag) { + return tag; + } else if (v instanceof NBTSerializable s) { + return s.toNBT(cx); + } else if (v instanceof CharSequence || v instanceof Character) { + return StringTag.valueOf(v.toString()); + } else if (v instanceof Boolean b) { + return ByteTag.valueOf(b); + } else if (v instanceof Number number) { + if (number instanceof Byte) { + return ByteTag.valueOf(number.byteValue()); + } else if (number instanceof Short) { + return ShortTag.valueOf(number.shortValue()); + } else if (number instanceof Integer) { + return IntTag.valueOf(number.intValue()); + } else if (number instanceof Long) { + return LongTag.valueOf(number.longValue()); + } else if (number instanceof Float) { + return FloatTag.valueOf(number.floatValue()); + } + + return DoubleTag.valueOf(number.doubleValue()); + } else if (v instanceof JsonPrimitive json) { + if (json.isNumber()) { + return wrap(cx, json.getAsNumber()); + } else if (json.isBoolean()) { + return ByteTag.valueOf(json.getAsBoolean()); + } else { + return StringTag.valueOf(json.getAsString()); + } + } else if (v instanceof Map map) { + CompoundTag tag = new OrderedCompoundTag(); + + for (Map.Entry entry : map.entrySet()) { + Tag nbt1 = wrap(cx, entry.getValue()); + + if (nbt1 != null) { + tag.put(String.valueOf(entry.getKey()), nbt1); + } + } + + return tag; + } else if (v instanceof JsonObject json) { + CompoundTag tag = new OrderedCompoundTag(); + + for (Map.Entry entry : json.entrySet()) { + Tag nbt1 = wrap(cx, entry.getValue()); + + if (nbt1 != null) { + tag.put(entry.getKey(), nbt1); + } + } + + return tag; + } else if (v instanceof Collection c) { + return wrapCollection0(cx, c); + } else if (v instanceof JsonArray array) { + List list = new ArrayList<>(array.size()); + + for (JsonElement element : array) { + list.add(wrap(cx, element)); + } + + return wrapCollection0(cx, list); + } + + return null; + } + + @Nullable + static CompoundTag wrapCompound(Context cx, @Nullable Object v) { + if (v instanceof CompoundTag nbt) { + return nbt; + } else if (v instanceof CharSequence) { + try { + return TagParser.parseTag(v.toString()); + } catch (Exception ex) { + return null; + } + } else if (v instanceof JsonPrimitive json) { + try { + return TagParser.parseTag(json.getAsString()); + } catch (Exception ex) { + return null; + } + } else if (v instanceof JsonObject json) { + try { + return TagParser.parseTag(json.toString()); + } catch (Exception ex) { + return null; + } + } + + return wrap(cx, v) instanceof CompoundTag nbt ? nbt : null; + } + + @Nullable + static CollectionTag wrapCollection(Context cx, @Nullable Object v) { + if (v instanceof CollectionTag tag) { + return tag; + } else if (v instanceof CharSequence) { + try { + return (CollectionTag) TagParser.parseTag("{a:" + v + "}").get("a"); + } catch (Exception ex) { + return null; + } + } else if (v instanceof JsonArray array) { + List list = new ArrayList<>(array.size()); + + for (JsonElement element : array) { + list.add(wrap(cx, element)); + } + + return wrapCollection0(cx, list); + } + + return v == null ? null : wrapCollection0(cx, (Collection) v); + } + + @Nullable + static ListTag wrapListTag(Context cx, @Nullable Object list) { + return (ListTag) wrapCollection(cx, list); + } + + private static CollectionTag wrapCollection0(Context cx, Collection c) { + if (c.isEmpty()) { + return new ListTag(); + } + + Tag[] values = new Tag[c.size()]; + int s = 0; + byte commmonId = -1; + + for (Object o : c) { + values[s] = wrap(cx, o); + + if (values[s] != null) { + if (commmonId == -1) { + commmonId = values[s].getId(); + } else if (commmonId != values[s].getId()) { + commmonId = 0; + } + + s++; + } + } + + if (commmonId == Tag.TAG_INT) { + int[] array = new int[s]; + + for (int i = 0; i < s; i++) { + array[i] = ((NumericTag) values[i]).getAsInt(); + } + + return new IntArrayTag(array); + } else if (commmonId == Tag.TAG_BYTE) { + byte[] array = new byte[s]; + + for (int i = 0; i < s; i++) { + array[i] = ((NumericTag) values[i]).getAsByte(); + } + + return new ByteArrayTag(array); + } else if (commmonId == Tag.TAG_LONG) { + long[] array = new long[s]; + + for (int i = 0; i < s; i++) { + array[i] = ((NumericTag) values[i]).getAsLong(); + } + + return new LongArrayTag(array); + } else if (commmonId == 0 || commmonId == -1) { + return new ListTag(); + } + + ListTag nbt = new ListTag(); + + for (Tag nbt1 : values) { + if (nbt1 == null) { + return nbt; + } + + nbt.add(nbt1); + } + + return nbt; + } + + static Tag compoundTag() { + return new OrderedCompoundTag(); + } + + static Tag compoundTag(Context cx, Map map) { + OrderedCompoundTag tag = new OrderedCompoundTag(); + + for (var entry : map.entrySet()) { + var tag1 = wrap(cx, entry.getValue()); + + if (tag1 != null) { + tag.put(String.valueOf(entry.getKey()), tag1); + } + } + + return tag; + } + + static Tag listTag() { + return new ListTag(); + } + + static Tag listTag(Context cx, List list) { + ListTag tag = new ListTag(); + + for (Object v : list) { + tag.add(wrap(cx, v)); + } + + return tag; + } + + static Tag byteTag(byte v) { + return ByteTag.valueOf(v); + } + + static Tag b(byte v) { + return ByteTag.valueOf(v); + } + + static Tag shortTag(short v) { + return ShortTag.valueOf(v); + } + + static Tag s(short v) { + return ShortTag.valueOf(v); + } + + static Tag intTag(int v) { + return IntTag.valueOf(v); + } + + static Tag i(int v) { + return IntTag.valueOf(v); + } + + static Tag longTag(long v) { + return LongTag.valueOf(v); + } + + static Tag l(long v) { + return LongTag.valueOf(v); + } + + static Tag floatTag(float v) { + return FloatTag.valueOf(v); + } + + static Tag f(float v) { + return FloatTag.valueOf(v); + } + + static Tag doubleTag(double v) { + return DoubleTag.valueOf(v); + } + + static Tag d(double v) { + return DoubleTag.valueOf(v); + } + + static Tag stringTag(String v) { + return StringTag.valueOf(v); + } + + static Tag intArrayTag(int[] v) { + return new IntArrayTag(v); + } + + static Tag ia(int[] v) { + return new IntArrayTag(v); + } + + static Tag longArrayTag(long[] v) { + return new LongArrayTag(v); + } + + static Tag la(long[] v) { + return new LongArrayTag(v); + } + + static Tag byteArrayTag(byte[] v) { + return new ByteArrayTag(v); + } + + static Tag ba(byte[] v) { + return new ByteArrayTag(v); + } + + static JsonElement toJson(@Nullable Tag t) { + return NBTUtils.toJson(t); + } + + @Nullable + static OrderedCompoundTag read(FriendlyByteBuf buf) { + return NBTUtils.read(buf); + } +} diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/TextWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/TextWrapper.java index 86f625d16..8fcd599f2 100644 --- a/src/main/java/dev/latvian/mods/kubejs/bindings/TextWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/TextWrapper.java @@ -9,6 +9,7 @@ import dev.latvian.mods.kubejs.util.JsonUtils; import dev.latvian.mods.kubejs.util.UtilsJS; import dev.latvian.mods.rhino.Context; +import dev.latvian.mods.rhino.util.HideFromJS; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.StringTag; @@ -32,7 +33,12 @@ @Info("The hub for all things text components. Format text to your hearts content!") public interface TextWrapper { @Info("Returns a Component of the input") - static MutableComponent of(Context cx, @Nullable Object o) { + static MutableComponent of(MutableComponent component) { + return component; + } + + @HideFromJS + static MutableComponent wrap(Context cx, @Nullable Object o) { o = UtilsJS.wrap(o, JSObjectType.ANY); if (o == null) { return Component.literal("null"); @@ -73,7 +79,7 @@ static MutableComponent of(Context cx, @Nullable Object o) { with[i] = e1; if (with[i] instanceof Map || with[i] instanceof Collection) { - with[i] = of(cx, e1); + with[i] = wrap(cx, e1); } i++; @@ -86,7 +92,7 @@ static MutableComponent of(Context cx, @Nullable Object o) { } if (map.containsKey("color")) { - text.kjs$color(ColorWrapper.of(map.get("color"))); + text.kjs$color(ColorWrapper.wrap(map.get("color"))); } text.kjs$bold((Boolean) map.getOrDefault("bold", null)); @@ -97,12 +103,12 @@ static MutableComponent of(Context cx, @Nullable Object o) { text.kjs$insertion((String) map.getOrDefault("insertion", null)); text.kjs$font(map.containsKey("font") ? ResourceLocation.parse(map.get("font").toString()) : null); - text.kjs$click(map.containsKey("click") ? clickEventOf(cx, map.get("click")) : null); - text.kjs$hover(map.containsKey("hover") ? of(cx, map.get("hover")) : null); + text.kjs$click(map.containsKey("click") ? wrapClickEvent(cx, map.get("click")) : null); + text.kjs$hover(map.containsKey("hover") ? wrap(cx, map.get("hover")) : null); if (map.get("extra") instanceof Iterable itr) { for (var e : itr) { - text.append(of(cx, e)); + text.append(wrap(cx, e)); } } @@ -111,7 +117,7 @@ static MutableComponent of(Context cx, @Nullable Object o) { var text = Component.empty(); for (var e1 : list) { - text.append(of(cx, e1)); + text.append(wrap(cx, e1)); } return text; @@ -139,7 +145,12 @@ static boolean isEmpty(Component component) { } @Info("Returns a ClickEvent of the input") - static ClickEvent clickEventOf(Context cx, Object o) { + static ClickEvent clickEventOf(ClickEvent event) { + return event; + } + + @HideFromJS + static ClickEvent wrapClickEvent(Context cx, Object o) { if (o == null) { return null; } else if (o instanceof ClickEvent ce) { diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/event/ServerEvents.java b/src/main/java/dev/latvian/mods/kubejs/bindings/event/ServerEvents.java index aba0f5326..05b3f045d 100644 --- a/src/main/java/dev/latvian/mods/kubejs/bindings/event/ServerEvents.java +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/event/ServerEvents.java @@ -35,6 +35,7 @@ public interface ServerEvents { EventHandler COMMAND_REGISTRY = GROUP.server("commandRegistry", () -> CommandRegistryKubeEvent.class); TargetedEventHandler COMMAND = GROUP.server("command", () -> CommandKubeEvent.class).hasResult().supportsTarget(EventTargetType.STRING); TargetedEventHandler BASIC_COMMAND = GROUP.server("basicCommand", () -> BasicCommandKubeEvent.class).hasResult().requiredTarget(EventTargetType.STRING); + TargetedEventHandler BASIC_PUBLIC_COMMAND = GROUP.server("basicPublicCommand", () -> BasicCommandKubeEvent.class).hasResult().requiredTarget(EventTargetType.STRING); EventHandler RECIPE_MAPPING_REGISTRY = GROUP.server("recipeMappingRegistry", () -> RecipeMappingRegistry.class); EventHandler RECIPE_SCHEMA_REGISTRY = GROUP.server("recipeSchemaRegistry", () -> RecipeSchemaRegistry.class); EventHandler RECIPES = GROUP.server("recipes", () -> RecipesKubeEvent.class); diff --git a/src/main/java/dev/latvian/mods/kubejs/block/BlockBuilder.java b/src/main/java/dev/latvian/mods/kubejs/block/BlockBuilder.java index faa60b905..2207c5317 100644 --- a/src/main/java/dev/latvian/mods/kubejs/block/BlockBuilder.java +++ b/src/main/java/dev/latvian/mods/kubejs/block/BlockBuilder.java @@ -349,7 +349,7 @@ public BlockBuilder mapColor(MapColor m) { @Info("Sets the block's map color dynamically per block state. If unset, defaults to NONE.") public BlockBuilder dynamicMapColor(@Nullable Function m) { - mapColorFn = m == null ? MapColorHelper.NONE : s -> MapColorHelper.of(m.apply(s)); + mapColorFn = m == null ? MapColorHelper.NONE : s -> MapColorHelper.wrap(m.apply(s)); return this; } diff --git a/src/main/java/dev/latvian/mods/kubejs/block/BlockTintFunction.java b/src/main/java/dev/latvian/mods/kubejs/block/BlockTintFunction.java index 0734fd740..08e5ae3e4 100644 --- a/src/main/java/dev/latvian/mods/kubejs/block/BlockTintFunction.java +++ b/src/main/java/dev/latvian/mods/kubejs/block/BlockTintFunction.java @@ -64,7 +64,7 @@ public KubeColor getColor(BlockState state, @Nullable BlockAndTintGetter level, }; @Nullable - static BlockTintFunction of(Context cx, Object o) { + static BlockTintFunction wrap(Context cx, Object o) { if (o == null || Undefined.isUndefined(o)) { return null; } else if (o instanceof BlockTintFunction f) { @@ -73,7 +73,7 @@ static BlockTintFunction of(Context cx, Object o) { var map = new Mapped(); for (int i = 0; i < list.size(); i++) { - var f = of(cx, list.get(i)); + var f = wrap(cx, list.get(i)); if (f != null) { map.map.put(i, f); @@ -100,6 +100,6 @@ static BlockTintFunction of(Context cx, Object o) { return (BlockTintFunction) cx.createInterfaceAdapter(TYPE_INFO, function); } - return new Fixed(ColorWrapper.of(o)); + return new Fixed(ColorWrapper.wrap(o)); } } diff --git a/src/main/java/dev/latvian/mods/kubejs/block/MapColorHelper.java b/src/main/java/dev/latvian/mods/kubejs/block/MapColorHelper.java index d1aeb78a7..821225522 100644 --- a/src/main/java/dev/latvian/mods/kubejs/block/MapColorHelper.java +++ b/src/main/java/dev/latvian/mods/kubejs/block/MapColorHelper.java @@ -90,7 +90,7 @@ private static MapColorHelper add(String id, MapColor color) { add("glow_lichen", MapColor.GLOW_LICHEN); } - public static MapColor of(Object o) { + public static MapColor wrap(Object o) { if (o == null || Undefined.isUndefined(o)) { return MapColor.NONE; } else if (o instanceof MapColor c) { diff --git a/src/main/java/dev/latvian/mods/kubejs/block/state/BlockStatePredicate.java b/src/main/java/dev/latvian/mods/kubejs/block/state/BlockStatePredicate.java index 5236a1443..e6cb95108 100644 --- a/src/main/java/dev/latvian/mods/kubejs/block/state/BlockStatePredicate.java +++ b/src/main/java/dev/latvian/mods/kubejs/block/state/BlockStatePredicate.java @@ -2,13 +2,13 @@ import com.mojang.serialization.DataResult; import dev.latvian.mods.kubejs.bindings.BlockWrapper; +import dev.latvian.mods.kubejs.bindings.NBTWrapper; import dev.latvian.mods.kubejs.level.ruletest.AllMatchRuleTest; import dev.latvian.mods.kubejs.level.ruletest.AlwaysFalseRuleTest; import dev.latvian.mods.kubejs.level.ruletest.AnyMatchRuleTest; import dev.latvian.mods.kubejs.level.ruletest.InvertRuleTest; import dev.latvian.mods.kubejs.recipe.match.ReplacementMatch; import dev.latvian.mods.kubejs.util.ListJS; -import dev.latvian.mods.kubejs.util.NBTUtils; import dev.latvian.mods.kubejs.util.RegExpKJS; import dev.latvian.mods.kubejs.util.RegistryAccessContainer; import dev.latvian.mods.kubejs.util.Tags; @@ -134,7 +134,7 @@ static RuleTest wrapRuleTest(Context cx, Object o) { var nbt = RegistryAccessContainer.of(cx).nbt(); - return Optional.ofNullable(NBTUtils.toTagCompound(cx, o)) + return Optional.ofNullable(NBTWrapper.wrapCompound(cx, o)) .map(tag -> RuleTest.CODEC.parse(nbt, tag)) .flatMap(DataResult::result) .or(() -> Optional.ofNullable(wrap(cx, o).asRuleTest())) diff --git a/src/main/java/dev/latvian/mods/kubejs/color/KubeColor.java b/src/main/java/dev/latvian/mods/kubejs/color/KubeColor.java index 7df2a14e7..ee19be953 100644 --- a/src/main/java/dev/latvian/mods/kubejs/color/KubeColor.java +++ b/src/main/java/dev/latvian/mods/kubejs/color/KubeColor.java @@ -14,7 +14,7 @@ @RemapPrefixForJS("kjs$") public interface KubeColor extends SpecialEquality { - Codec CODEC = KubeJSCodecs.stringResolverCodec(KubeColor::kjs$serialize, ColorWrapper::of); + Codec CODEC = KubeJSCodecs.stringResolverCodec(KubeColor::kjs$serialize, ColorWrapper::wrap); StreamCodec STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC); @RemapForJS("getArgb") @@ -43,7 +43,7 @@ public interface KubeColor extends SpecialEquality { @Override default boolean specialEquals(Context cx, Object o, boolean shallow) { - KubeColor c = ColorWrapper.of(o); + KubeColor c = ColorWrapper.wrap(o); return shallow ? (kjs$getARGB() == c.kjs$getARGB()) : (kjs$getRGB() == c.kjs$getRGB()); } } \ No newline at end of file diff --git a/src/main/java/dev/latvian/mods/kubejs/command/KubeJSCommands.java b/src/main/java/dev/latvian/mods/kubejs/command/KubeJSCommands.java index bb243e7ef..788b315b2 100644 --- a/src/main/java/dev/latvian/mods/kubejs/command/KubeJSCommands.java +++ b/src/main/java/dev/latvian/mods/kubejs/command/KubeJSCommands.java @@ -14,7 +14,9 @@ import dev.latvian.mods.kubejs.KubeJS; import dev.latvian.mods.kubejs.KubeJSPaths; import dev.latvian.mods.kubejs.bindings.TextIcons; +import dev.latvian.mods.kubejs.bindings.TextWrapper; import dev.latvian.mods.kubejs.bindings.event.ServerEvents; +import dev.latvian.mods.kubejs.event.TargetedEventHandler; import dev.latvian.mods.kubejs.net.DisplayClientErrorsPayload; import dev.latvian.mods.kubejs.net.DisplayServerErrorsPayload; import dev.latvian.mods.kubejs.net.ReloadStartupScriptsPayload; @@ -251,9 +253,18 @@ public static void register(CommandDispatcher dispatcher) { for (var id : ServerEvents.BASIC_COMMAND.findUniqueExtraIds(ScriptType.SERVER)) { dispatcher.register(Commands.literal(id) .requires(spOrOP) - .executes(ctx -> customCommand(ctx.getSource(), id, "")) + .executes(ctx -> customCommand(ServerEvents.BASIC_COMMAND, ctx.getSource(), id, "")) .then(Commands.argument("input", StringArgumentType.greedyString()) - .executes(ctx -> customCommand(ctx.getSource(), id, StringArgumentType.getString(ctx, "input"))) + .executes(ctx -> customCommand(ServerEvents.BASIC_COMMAND, ctx.getSource(), id, StringArgumentType.getString(ctx, "input"))) + ) + ); + } + + for (var id : ServerEvents.BASIC_PUBLIC_COMMAND.findUniqueExtraIds(ScriptType.SERVER)) { + dispatcher.register(Commands.literal(id) + .executes(ctx -> customCommand(ServerEvents.BASIC_PUBLIC_COMMAND, ctx.getSource(), id, "")) + .then(Commands.argument("input", StringArgumentType.greedyString()) + .executes(ctx -> customCommand(ServerEvents.BASIC_PUBLIC_COMMAND, ctx.getSource(), id, StringArgumentType.getString(ctx, "input"))) ) ); } @@ -280,13 +291,15 @@ private static int help(CommandSourceStack source) { return Command.SINGLE_SUCCESS; } - private static int customCommand(CommandSourceStack source, String id, String input) { - if (ServerEvents.BASIC_COMMAND.hasListeners(id)) { - var result = ServerEvents.BASIC_COMMAND.post(new BasicCommandKubeEvent(source.getLevel(), source.getEntity(), BlockPos.containing(source.getPosition()), id, input.trim()), id); + private static int customCommand(TargetedEventHandler event, CommandSourceStack source, String id, String input) { + if (event.hasListeners(id)) { + var result = event.post(new BasicCommandKubeEvent(source.getLevel(), source.getEntity(), BlockPos.containing(source.getPosition()), id, input.trim()), id); if (result.value() instanceof Throwable ex) { source.sendFailure(Component.literal(ex.toString())); return 0; + } else if (result.value() != null && result.cx() != null) { + source.sendSuccess(() -> TextWrapper.wrap(result.cx(), result.value()), false); } return 1; diff --git a/src/main/java/dev/latvian/mods/kubejs/core/PlayerSelector.java b/src/main/java/dev/latvian/mods/kubejs/core/PlayerSelector.java index b432e287d..5ecaab14e 100644 --- a/src/main/java/dev/latvian/mods/kubejs/core/PlayerSelector.java +++ b/src/main/java/dev/latvian/mods/kubejs/core/PlayerSelector.java @@ -12,7 +12,7 @@ @FunctionalInterface public interface PlayerSelector { - static PlayerSelector of(Object o) { + static PlayerSelector wrap(Object o) { if (o instanceof ServerPlayer sp) { return identity(sp); } else if (o instanceof UUID uuid) { diff --git a/src/main/java/dev/latvian/mods/kubejs/core/mixin/CompoundTagMixin.java b/src/main/java/dev/latvian/mods/kubejs/core/mixin/CompoundTagMixin.java index b304b7f1a..9d2ea9138 100644 --- a/src/main/java/dev/latvian/mods/kubejs/core/mixin/CompoundTagMixin.java +++ b/src/main/java/dev/latvian/mods/kubejs/core/mixin/CompoundTagMixin.java @@ -1,6 +1,5 @@ package dev.latvian.mods.kubejs.core.mixin; -import dev.latvian.mods.kubejs.util.NBTUtils; import dev.latvian.mods.rhino.Context; import dev.latvian.mods.rhino.NativeJavaMap; import dev.latvian.mods.rhino.Scriptable; @@ -11,17 +10,21 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import java.util.Map; @Mixin(CompoundTag.class) public abstract class CompoundTagMixin implements CustomJavaToJsWrapper { + @Unique + private static final TypeInfo KJS$MAP_TYPE = TypeInfo.RAW_MAP.withParams(TypeInfo.STRING, TypeInfo.of(Tag.class)); + @Shadow @Final public Map tags; @Override public Scriptable convertJavaToJs(Context cx, Scriptable scope, TypeInfo target) { - return new NativeJavaMap(cx, scope, this, tags, NBTUtils.STRING_TAG_MAP_TYPE); + return new NativeJavaMap(cx, scope, this, tags, KJS$MAP_TYPE); } } diff --git a/src/main/java/dev/latvian/mods/kubejs/event/EventHandler.java b/src/main/java/dev/latvian/mods/kubejs/event/EventHandler.java index 748a7f916..4c0502b79 100644 --- a/src/main/java/dev/latvian/mods/kubejs/event/EventHandler.java +++ b/src/main/java/dev/latvian/mods/kubejs/event/EventHandler.java @@ -241,7 +241,7 @@ protected EventResult postInternal(ScriptTypeHolder type, @Nullable Object extra eventResult = exit.result; } catch (Throwable error) { scriptType.console.error("Internal Error in '" + this + "'", error); - eventResult = EventResult.Type.ERROR.exit(error).result; + eventResult = EventResult.Type.ERROR.exit(null, error).result; } event.afterPosted(eventResult); diff --git a/src/main/java/dev/latvian/mods/kubejs/event/EventResult.java b/src/main/java/dev/latvian/mods/kubejs/event/EventResult.java index d08c9a6da..c2bcce618 100644 --- a/src/main/java/dev/latvian/mods/kubejs/event/EventResult.java +++ b/src/main/java/dev/latvian/mods/kubejs/event/EventResult.java @@ -1,5 +1,6 @@ package dev.latvian.mods.kubejs.event; +import dev.latvian.mods.rhino.Context; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.common.util.TriState; import org.jetbrains.annotations.Nullable; @@ -14,33 +15,41 @@ public enum Type { INTERRUPT_FALSE, INTERRUPT_TRUE; - public final EventResult defaultResult; - public final EventExit defaultExit; + private final EventResult defaultResult; + private final EventExit defaultExit; Type() { - this.defaultResult = new EventResult(this, null); + this.defaultResult = new EventResult(null, this, null); this.defaultExit = new EventExit(this.defaultResult); } - public EventExit exit(@Nullable Object value) { - return value == null ? defaultExit : new EventExit(new EventResult(this, value)); + public EventExit exit(@Nullable Context cx, @Nullable Object value) { + return value == null ? defaultExit : new EventExit(new EventResult(cx, this, value)); } } public static final EventResult PASS = Type.PASS.defaultResult; + private final Context cx; private final Type type; private final Object value; - private EventResult(Type type, @Nullable Object value) { + private EventResult(@Nullable Context cx, Type type, @Nullable Object value) { + this.cx = cx; this.type = type; this.value = value; } + @Nullable + public Context cx() { + return cx; + } + public Type type() { return type; } + @Nullable public Object value() { return value; } diff --git a/src/main/java/dev/latvian/mods/kubejs/event/KubeEvent.java b/src/main/java/dev/latvian/mods/kubejs/event/KubeEvent.java index 94f7b3f42..64814e1ec 100644 --- a/src/main/java/dev/latvian/mods/kubejs/event/KubeEvent.java +++ b/src/main/java/dev/latvian/mods/kubejs/event/KubeEvent.java @@ -59,7 +59,7 @@ default Object exit(Context cx) throws EventExit { `cancel` denotes a `false` outcome. """) default Object cancel(Context cx, @Nullable Object value) throws EventExit { - throw EventResult.Type.INTERRUPT_FALSE.exit(mapExitValue(cx, value)); + throw EventResult.Type.INTERRUPT_FALSE.exit(cx, mapExitValue(cx, value)); } @Info(""" @@ -68,7 +68,7 @@ default Object cancel(Context cx, @Nullable Object value) throws EventExit { `success` denotes a `true` outcome. """) default Object success(Context cx, @Nullable Object value) throws EventExit { - throw EventResult.Type.INTERRUPT_TRUE.exit(mapExitValue(cx, value)); + throw EventResult.Type.INTERRUPT_TRUE.exit(cx, mapExitValue(cx, value)); } @Info(""" @@ -77,7 +77,7 @@ default Object success(Context cx, @Nullable Object value) throws EventExit { `exit` denotes a `default` outcome. """) default Object exit(Context cx, @Nullable Object value) throws EventExit { - throw EventResult.Type.INTERRUPT_DEFAULT.exit(mapExitValue(cx, value)); + throw EventResult.Type.INTERRUPT_DEFAULT.exit(cx, mapExitValue(cx, value)); } @HideFromJS diff --git a/src/main/java/dev/latvian/mods/kubejs/item/ItemEnchantmentsWrapper.java b/src/main/java/dev/latvian/mods/kubejs/item/ItemEnchantmentsWrapper.java index b38dc31c7..5be595010 100644 --- a/src/main/java/dev/latvian/mods/kubejs/item/ItemEnchantmentsWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/item/ItemEnchantmentsWrapper.java @@ -12,7 +12,7 @@ public class ItemEnchantmentsWrapper { public static final TypeInfo MAP_TYPE = TypeInfo.RAW_MAP.withParams(TypeInfo.of(Holder.class).withParams(TypeInfo.of(Enchantment.class)), TypeInfo.INT); - public static ItemEnchantments from(Context cx, Object from) { + public static ItemEnchantments wrap(Context cx, Object from) { if (from instanceof ItemEnchantments e) { return e; } else if (from instanceof Map || from instanceof NativeJavaMap) { diff --git a/src/main/java/dev/latvian/mods/kubejs/item/ItemTintFunction.java b/src/main/java/dev/latvian/mods/kubejs/item/ItemTintFunction.java index 6e56e1135..2d0ba1998 100644 --- a/src/main/java/dev/latvian/mods/kubejs/item/ItemTintFunction.java +++ b/src/main/java/dev/latvian/mods/kubejs/item/ItemTintFunction.java @@ -83,7 +83,7 @@ public KubeColor getColor(ItemStack stack, int index) { }; @Nullable - static ItemTintFunction of(Context cx, Object o) { + static ItemTintFunction wrap(Context cx, Object o) { if (o == null || Undefined.isUndefined(o)) { return null; } else if (o instanceof ItemTintFunction f) { @@ -92,7 +92,7 @@ static ItemTintFunction of(Context cx, Object o) { var map = new Mapped(); for (int i = 0; i < list.size(); i++) { - var f = of(cx, list.get(i)); + var f = wrap(cx, list.get(i)); if (f != null) { map.map.put(i, f); @@ -116,6 +116,6 @@ static ItemTintFunction of(Context cx, Object o) { return (ItemTintFunction) cx.createInterfaceAdapter(TYPE_INFO, function); } - return new Fixed(ColorWrapper.of(o)); + return new Fixed(ColorWrapper.wrap(o)); } } \ No newline at end of file diff --git a/src/main/java/dev/latvian/mods/kubejs/player/PlayerStatsJS.java b/src/main/java/dev/latvian/mods/kubejs/player/PlayerStatsJS.java index cbe604986..2c7888838 100644 --- a/src/main/java/dev/latvian/mods/kubejs/player/PlayerStatsJS.java +++ b/src/main/java/dev/latvian/mods/kubejs/player/PlayerStatsJS.java @@ -19,7 +19,7 @@ public PlayerStatsJS(Player p, StatsCounter s) { statFile = s; } - public static Stat statOf(Object o) { + public static Stat wrapStat(Object o) { if (o instanceof Stat s) { return s; } else if (o instanceof ResourceLocation rl) { diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/component/TimeComponent.java b/src/main/java/dev/latvian/mods/kubejs/recipe/component/TimeComponent.java index 29ad0823e..8bd5833b9 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/component/TimeComponent.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/component/TimeComponent.java @@ -34,7 +34,7 @@ public TickDuration wrap(Context cx, KubeRecipe recipe, Object from) { if (from instanceof Number n) { return new TickDuration((long) (n.doubleValue() * scale)); } else { - return new TickDuration(TimeJS.durationOf(from).toMillis() / 50L); + return new TickDuration(TimeJS.wrapDuration(from).toMillis() / 50L); } } diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/filter/RecipeFilter.java b/src/main/java/dev/latvian/mods/kubejs/recipe/filter/RecipeFilter.java index e06d5e98b..22291994b 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/filter/RecipeFilter.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/filter/RecipeFilter.java @@ -21,7 +21,7 @@ public interface RecipeFilter { boolean test(Context cx, RecipeLikeKJS r); - static RecipeFilter of(Context cx, @Nullable Object o) { + static RecipeFilter wrap(Context cx, @Nullable Object o) { if (o == null || o == ConstantFilter.TRUE) { return ConstantFilter.TRUE; } else if (o == ConstantFilter.FALSE) { @@ -49,7 +49,7 @@ static RecipeFilter of(Context cx, @Nullable Object o) { var predicate = new OrFilter(); for (var o1 : list) { - var p = of(cx, o1); + var p = wrap(cx, o1); if (p == ConstantFilter.TRUE) { return ConstantFilter.TRUE; @@ -70,11 +70,11 @@ static RecipeFilter of(Context cx, @Nullable Object o) { var predicate = new AndFilter(); if (map.get("or") != null) { - predicate.list.add(of(cx, map.get("or"))); + predicate.list.add(wrap(cx, map.get("or"))); } if (map.get("not") != null) { - predicate.list.add(new NotFilter(of(cx, map.get("not")))); + predicate.list.add(new NotFilter(wrap(cx, map.get("not")))); } try { diff --git a/src/main/java/dev/latvian/mods/kubejs/util/NBTUtils.java b/src/main/java/dev/latvian/mods/kubejs/util/NBTUtils.java index 0bfaee18a..f82f40d55 100644 --- a/src/main/java/dev/latvian/mods/kubejs/util/NBTUtils.java +++ b/src/main/java/dev/latvian/mods/kubejs/util/NBTUtils.java @@ -6,31 +6,18 @@ import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import dev.latvian.mods.rhino.Context; -import dev.latvian.mods.rhino.Undefined; -import dev.latvian.mods.rhino.type.TypeInfo; import io.netty.buffer.ByteBufInputStream; import io.netty.handler.codec.EncoderException; -import net.minecraft.nbt.ByteArrayTag; -import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.CollectionTag; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.EndTag; -import net.minecraft.nbt.FloatTag; -import net.minecraft.nbt.IntArrayTag; -import net.minecraft.nbt.IntTag; import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.LongArrayTag; -import net.minecraft.nbt.LongTag; import net.minecraft.nbt.NbtAccounter; import net.minecraft.nbt.NbtFormatException; import net.minecraft.nbt.NumericTag; -import net.minecraft.nbt.ShortTag; import net.minecraft.nbt.StreamTagVisitor; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; -import net.minecraft.nbt.TagParser; import net.minecraft.nbt.TagType; import net.minecraft.nbt.TagTypes; import net.minecraft.network.FriendlyByteBuf; @@ -39,337 +26,12 @@ import java.io.DataInput; import java.io.DataInputStream; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public interface NBTUtils { - TypeInfo STRING_TAG_MAP_TYPE = TypeInfo.RAW_MAP.withParams(TypeInfo.STRING, TypeInfo.of(Tag.class)); - - @Nullable - static Object fromTag(@Nullable Tag t) { - if (t == null || t instanceof EndTag) { - return null; - } else if (t instanceof StringTag) { - return t.getAsString(); - } else if (t instanceof NumericTag num) { - return num.getAsNumber(); - } - - return t; - } - - @Nullable - static Tag toTag(Context cx, @Nullable Object v) { - if (v == null || v instanceof EndTag) { - return null; - } else if (v instanceof Tag tag) { - return tag; - } else if (v instanceof NBTSerializable s) { - return s.toNBT(cx); - } else if (v instanceof CharSequence || v instanceof Character) { - return StringTag.valueOf(v.toString()); - } else if (v instanceof Boolean b) { - return ByteTag.valueOf(b); - } else if (v instanceof Number number) { - if (number instanceof Byte) { - return ByteTag.valueOf(number.byteValue()); - } else if (number instanceof Short) { - return ShortTag.valueOf(number.shortValue()); - } else if (number instanceof Integer) { - return IntTag.valueOf(number.intValue()); - } else if (number instanceof Long) { - return LongTag.valueOf(number.longValue()); - } else if (number instanceof Float) { - return FloatTag.valueOf(number.floatValue()); - } - - return DoubleTag.valueOf(number.doubleValue()); - } else if (v instanceof JsonPrimitive json) { - if (json.isNumber()) { - return toTag(cx, json.getAsNumber()); - } else if (json.isBoolean()) { - return ByteTag.valueOf(json.getAsBoolean()); - } else { - return StringTag.valueOf(json.getAsString()); - } - } else if (v instanceof Map map) { - CompoundTag tag = new OrderedCompoundTag(); - - for (Map.Entry entry : map.entrySet()) { - Tag nbt1 = toTag(cx, entry.getValue()); - - if (nbt1 != null) { - tag.put(String.valueOf(entry.getKey()), nbt1); - } - } - - return tag; - } else if (v instanceof JsonObject json) { - CompoundTag tag = new OrderedCompoundTag(); - - for (Map.Entry entry : json.entrySet()) { - Tag nbt1 = toTag(cx, entry.getValue()); - - if (nbt1 != null) { - tag.put(entry.getKey(), nbt1); - } - } - - return tag; - } else if (v instanceof Collection c) { - return toTagCollection(cx, c); - } else if (v instanceof JsonArray array) { - List list = new ArrayList<>(array.size()); - - for (JsonElement element : array) { - list.add(toTag(cx, element)); - } - - return toTagCollection(cx, list); - } - - return null; - } - - static boolean isTagCompound(Object o) { - return o == null || Undefined.isUndefined(o) || o instanceof CompoundTag || o instanceof CharSequence || o instanceof Map || o instanceof JsonElement; - } - - @Nullable - static CompoundTag toTagCompound(Context cx, @Nullable Object v) { - if (v instanceof CompoundTag nbt) { - return nbt; - } else if (v instanceof CharSequence) { - try { - return TagParser.parseTag(v.toString()); - } catch (Exception ex) { - return null; - } - } else if (v instanceof JsonPrimitive json) { - try { - return TagParser.parseTag(json.getAsString()); - } catch (Exception ex) { - return null; - } - } else if (v instanceof JsonObject json) { - try { - return TagParser.parseTag(json.toString()); - } catch (Exception ex) { - return null; - } - } - - return toTag(cx, v) instanceof CompoundTag nbt ? nbt : null; - } - - static boolean isTagCollection(Object o) { - return o == null || Undefined.isUndefined(o) || o instanceof CharSequence || o instanceof Collection || o instanceof JsonArray; - } - - @Nullable - static CollectionTag toTagCollection(Context cx, @Nullable Object v) { - if (v instanceof CollectionTag tag) { - return tag; - } else if (v instanceof CharSequence) { - try { - return (CollectionTag) TagParser.parseTag("{a:" + v + "}").get("a"); - } catch (Exception ex) { - return null; - } - } else if (v instanceof JsonArray array) { - List list = new ArrayList<>(array.size()); - - for (JsonElement element : array) { - list.add(toTag(cx, element)); - } - - return toTagCollection(cx, list); - } - - return v == null ? null : toTagCollection(cx, (Collection) v); - } - - @Nullable - static ListTag toTagList(Context cx, @Nullable Object list) { - return (ListTag) toTagCollection(cx, list); - } - - static CollectionTag toTagCollection(Context cx, Collection c) { - if (c.isEmpty()) { - return new ListTag(); - } - - Tag[] values = new Tag[c.size()]; - int s = 0; - byte commmonId = -1; - - for (Object o : c) { - values[s] = toTag(cx, o); - - if (values[s] != null) { - if (commmonId == -1) { - commmonId = values[s].getId(); - } else if (commmonId != values[s].getId()) { - commmonId = 0; - } - - s++; - } - } - - if (commmonId == Tag.TAG_INT) { - int[] array = new int[s]; - - for (int i = 0; i < s; i++) { - array[i] = ((NumericTag) values[i]).getAsInt(); - } - - return new IntArrayTag(array); - } else if (commmonId == Tag.TAG_BYTE) { - byte[] array = new byte[s]; - - for (int i = 0; i < s; i++) { - array[i] = ((NumericTag) values[i]).getAsByte(); - } - - return new ByteArrayTag(array); - } else if (commmonId == Tag.TAG_LONG) { - long[] array = new long[s]; - - for (int i = 0; i < s; i++) { - array[i] = ((NumericTag) values[i]).getAsLong(); - } - - return new LongArrayTag(array); - } else if (commmonId == 0 || commmonId == -1) { - return new ListTag(); - } - - ListTag nbt = new ListTag(); - - for (Tag nbt1 : values) { - if (nbt1 == null) { - return nbt; - } - - nbt.add(nbt1); - } - - return nbt; - } - - static Tag compoundTag() { - return new OrderedCompoundTag(); - } - - static Tag compoundTag(Context cx, Map map) { - OrderedCompoundTag tag = new OrderedCompoundTag(); - - for (var entry : map.entrySet()) { - var tag1 = toTag(cx, entry.getValue()); - - if (tag1 != null) { - tag.put(String.valueOf(entry.getKey()), tag1); - } - } - - return tag; - } - - static Tag listTag() { - return new ListTag(); - } - - static Tag listTag(Context cx, List list) { - ListTag tag = new ListTag(); - - for (Object v : list) { - tag.add(toTag(cx, v)); - } - - return tag; - } - - static Tag byteTag(byte v) { - return ByteTag.valueOf(v); - } - - static Tag b(byte v) { - return ByteTag.valueOf(v); - } - - static Tag shortTag(short v) { - return ShortTag.valueOf(v); - } - - static Tag s(short v) { - return ShortTag.valueOf(v); - } - - static Tag intTag(int v) { - return IntTag.valueOf(v); - } - - static Tag i(int v) { - return IntTag.valueOf(v); - } - - static Tag longTag(long v) { - return LongTag.valueOf(v); - } - - static Tag l(long v) { - return LongTag.valueOf(v); - } - - static Tag floatTag(float v) { - return FloatTag.valueOf(v); - } - - static Tag f(float v) { - return FloatTag.valueOf(v); - } - - static Tag doubleTag(double v) { - return DoubleTag.valueOf(v); - } - - static Tag d(double v) { - return DoubleTag.valueOf(v); - } - - static Tag stringTag(String v) { - return StringTag.valueOf(v); - } - - static Tag intArrayTag(int[] v) { - return new IntArrayTag(v); - } - - static Tag ia(int[] v) { - return new IntArrayTag(v); - } - - static Tag longArrayTag(long[] v) { - return new LongArrayTag(v); - } - - static Tag la(long[] v) { - return new LongArrayTag(v); - } - - static Tag byteArrayTag(byte[] v) { - return new ByteArrayTag(v); - } - - static Tag ba(byte[] v) { - return new ByteArrayTag(v); - } - - static void quoteAndEscapeForJS(StringBuilder stringBuilder, String string) { + static void quoteAndEscape(StringBuilder stringBuilder, String string) { int start = stringBuilder.length(); stringBuilder.append(' '); char c = 0; @@ -462,6 +124,10 @@ static OrderedCompoundTag read(FriendlyByteBuf buf) { } } + static Map accessTagMap(CompoundTag tag) { + return tag.tags; + } + TagType COMPOUND_TYPE = new TagType.VariableSize<>() { @Override public OrderedCompoundTag load(DataInput dataInput, NbtAccounter accounter) throws IOException { @@ -580,10 +246,6 @@ private static String readString(DataInput dataInput, NbtAccounter nbtAccounter) } }; - static Map accessTagMap(CompoundTag tag) { - return tag.tags; - } - TagType LIST_TYPE = new TagType.VariableSize<>() { @Override public ListTag load(DataInput dataInput, NbtAccounter accounter) throws IOException { diff --git a/src/main/java/dev/latvian/mods/kubejs/util/TickDuration.java b/src/main/java/dev/latvian/mods/kubejs/util/TickDuration.java index fdd3da984..0954ba2a2 100644 --- a/src/main/java/dev/latvian/mods/kubejs/util/TickDuration.java +++ b/src/main/java/dev/latvian/mods/kubejs/util/TickDuration.java @@ -22,7 +22,7 @@ public static TickDuration wrap(Object from) { if (from instanceof Number n) { return new TickDuration(n.longValue()); } else { - return new TickDuration(TimeJS.durationOf(from).toMillis() / 50L); + return new TickDuration(TimeJS.wrapDuration(from).toMillis() / 50L); } } diff --git a/src/main/java/dev/latvian/mods/kubejs/util/TimeJS.java b/src/main/java/dev/latvian/mods/kubejs/util/TimeJS.java index acbc6cd8b..e70f0fb35 100644 --- a/src/main/java/dev/latvian/mods/kubejs/util/TimeJS.java +++ b/src/main/java/dev/latvian/mods/kubejs/util/TimeJS.java @@ -14,10 +14,10 @@ public interface TimeJS { Pattern TEMPORAL_AMOUNT_PATTERN = Pattern.compile("(\\d+)\\s*(y|M|d|w|h|m|s|ms|ns|t)\\b"); - Codec DURATION = KubeJSCodecs.stringResolverCodec(Duration::toString, TimeJS::durationOf); - StreamCodec DURATION_STREAM = ByteBufCodecs.STRING_UTF8.map(TimeJS::durationOf, Duration::toString); + Codec DURATION = KubeJSCodecs.stringResolverCodec(Duration::toString, TimeJS::wrapDuration); + StreamCodec DURATION_STREAM = ByteBufCodecs.STRING_UTF8.map(TimeJS::wrapDuration, Duration::toString); - static TemporalAmount temporalAmountOf(Object o) { + static TemporalAmount wrapTemporalAmount(Object o) { if (o instanceof TemporalAmount d) { return d; } else if (o instanceof Number n) { @@ -71,10 +71,10 @@ static long tickDurationOf(Object o) { return json.getAsLong(); } - var t = temporalAmountOf(o); + var t = wrapTemporalAmount(o); - if (t instanceof TickDuration d) { - return d.ticks(); + if (t instanceof TickDuration(long ticks)) { + return ticks; } else if (t instanceof Duration d) { return d.toMillis() / 50L; } else { @@ -82,13 +82,13 @@ static long tickDurationOf(Object o) { } } - static Duration durationOf(Object o) { - var t = temporalAmountOf(o); + static Duration wrapDuration(Object o) { + var t = wrapTemporalAmount(o); if (t instanceof Duration d) { return d; - } else if (t instanceof TickDuration d) { - return Duration.ofMillis(d.ticks() * 50L); + } else if (t instanceof TickDuration(long ticks)) { + return Duration.ofMillis(ticks * 50L); } else { var d = Duration.ZERO; diff --git a/src/main/java/dev/latvian/mods/kubejs/util/UtilsJS.java b/src/main/java/dev/latvian/mods/kubejs/util/UtilsJS.java index 2f06306cd..1d991f7d6 100644 --- a/src/main/java/dev/latvian/mods/kubejs/util/UtilsJS.java +++ b/src/main/java/dev/latvian/mods/kubejs/util/UtilsJS.java @@ -3,7 +3,6 @@ import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import com.mojang.brigadier.StringReader; import dev.latvian.mods.kubejs.bindings.event.BlockEvents; import dev.latvian.mods.kubejs.bindings.event.ItemEvents; import dev.latvian.mods.kubejs.block.BlockModificationKubeEvent; @@ -11,9 +10,6 @@ import dev.latvian.mods.kubejs.script.ScriptType; import dev.latvian.mods.rhino.Wrapper; import dev.latvian.mods.rhino.type.TypeUtils; -import net.minecraft.advancements.critereon.MinMaxBounds; -import net.minecraft.commands.arguments.selector.EntitySelector; -import net.minecraft.commands.arguments.selector.EntitySelectorParser; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.EndTag; import net.minecraft.nbt.NumericTag; @@ -31,10 +27,8 @@ import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.function.Consumer; -import java.util.function.Function; import java.util.function.Predicate; public class UtilsJS { @@ -43,9 +37,6 @@ public class UtilsJS { public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; public static final Predicate ALWAYS_TRUE = o -> true; - private static final Map ENTITY_SELECTOR_CACHE = new HashMap<>(); - private static final EntitySelector ALL_ENTITIES_SELECTOR = new EntitySelector(EntitySelector.INFINITE, true, false, List.of(), MinMaxBounds.Doubles.ANY, Function.identity(), null, EntitySelectorParser.ORDER_RANDOM, false, null, null, null, true); - // TODO: Remove this garbage @Nullable public static Object wrap(@Nullable Object o, JSObjectType type) { @@ -206,35 +197,6 @@ public static String toMappedTypeString(Type type) { throw new IllegalArgumentException("Expected a Class, ParameterizedType, GenericArrayType, TypeVariable or WildcardType, but <" + type + "> is of type " + className); } - public static EntitySelector entitySelector(@Nullable Object o) { - if (o == null) { - return ALL_ENTITIES_SELECTOR; - } else if (o instanceof EntitySelector s) { - return s; - } - - String s = o.toString(); - - if (s.isBlank()) { - return ALL_ENTITIES_SELECTOR; - } - - var sel = ENTITY_SELECTOR_CACHE.get(s); - - if (sel == null) { - sel = ALL_ENTITIES_SELECTOR; - - try { - sel = new EntitySelectorParser(new StringReader(s), true).parse(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - ENTITY_SELECTOR_CACHE.put(s, sel); - return sel; - } - @Nullable public static CreativeModeTab findCreativeTab(ResourceLocation id) { return BuiltInRegistries.CREATIVE_MODE_TAB.get(id);