From e00734d9abe443c25b4d4ab75a999dd7b3d3f88d Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 12 Sep 2025 04:15:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mythicmobs/MythicItemDrop.java | 2 +- .../skript/expression/ExprCustomItem.java | 3 +- .../advancement/BukkitAdvancementManager.java | 76 ++++++- .../behavior/ConcretePowderBlockBehavior.java | 2 +- .../block/behavior/LeavesBlockBehavior.java | 2 +- .../ItemDisplayBlockEntityElement.java | 19 +- .../ItemDisplayBlockEntityElementConfig.java | 28 +-- .../bukkit/item/BukkitItemManager.java | 3 +- .../item/recipe/BukkitRecipeManager.java | 4 +- .../item/recipe/RecipeEventListener.java | 11 +- .../bukkit/pack/BukkitPackManager.java | 2 +- .../feature/TotemAnimationCommand.java | 2 +- .../handler/ProjectilePacketHandler.java | 2 +- .../reflection/minecraft/CoreReflections.java | 188 +++++++++++++++++- .../minecraft/NetworkReflections.java | 6 + .../plugin/user/BukkitServerPlayer.java | 6 + .../src/main/resources/translations/en.yml | 12 +- .../AbstractAdvancementManager.java | 2 + .../core/advancement/AdvancementManager.java | 5 + .../element/BlockEntityElementConfigs.java | 3 +- .../core/entity/player/Player.java | 4 +- .../craftengine/core/item/BuildableItem.java | 9 +- .../core/item/ItemBuildContext.java | 16 +- .../core/loot/AbstractVanillaLootManager.java | 2 +- .../core/pack/AbstractPackManager.java | 2 +- .../core/pack/conflict/PathContext.java | 2 +- .../craftengine/core/plugin/CraftEngine.java | 1 - .../core/plugin/context/ContextHolder.java | 28 ++- .../plugin/context/PlayerOptionalContext.java | 14 +- .../plugin/context/event/EventFunctions.java | 2 + .../context/function/ActionBarFunction.java | 2 +- .../context/function/CommandFunction.java | 2 +- .../context/function/CommonFunctions.java | 1 + .../context/function/LevelerExpFunction.java | 2 +- .../context/function/MessageFunction.java | 2 +- .../context/function/OpenWindowFunction.java | 2 +- .../function/PotionEffectFunction.java | 2 +- .../context/function/SetCooldownFunction.java | 2 +- .../context/function/SetFoodFunction.java | 2 +- .../function/SetSaturationFunction.java | 2 +- .../context/function/SetVariableFunction.java | 72 +++++++ .../context/function/TeleportFunction.java | 27 +-- .../context/function/TitleFunction.java | 2 +- .../context/function/ToastFunction.java | 87 ++++++++ .../gui/category/ItemBrowserManagerImpl.java | 12 +- .../core/util/ReflectionUtils.java | 16 ++ gradle.properties | 4 +- 47 files changed, 590 insertions(+), 107 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetVariableFunction.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ToastFunction.java diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/mythicmobs/MythicItemDrop.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/mythicmobs/MythicItemDrop.java index 634f341c2..dbb2f00db 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/mythicmobs/MythicItemDrop.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/mythicmobs/MythicItemDrop.java @@ -33,7 +33,7 @@ public class MythicItemDrop extends ItemDrop implements IItemDrop { @Override public AbstractItemStack getDrop(DropMetadata dropMetadata, double amount) { - ItemBuildContext context = ItemBuildContext.EMPTY; + ItemBuildContext context = ItemBuildContext.empty(); SkillCaster caster = dropMetadata.getCaster(); if (caster != null && caster.getEntity() instanceof AbstractPlayer abstractPlayer) { Entity bukkitEntity = abstractPlayer.getBukkitEntity(); diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprCustomItem.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprCustomItem.java index 6ad45ad4c..ff22863b6 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprCustomItem.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprCustomItem.java @@ -33,7 +33,6 @@ public class ExprCustomItem extends SimpleExpression { private Expression itemIds; @Override - @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { itemIds = exprs[0]; return true; @@ -49,7 +48,7 @@ public class ExprCustomItem extends SimpleExpression { if (object instanceof String string) { CustomItem customItem = CraftEngineItems.byId(Key.of(string)); if (customItem != null) { - ItemType itemType = new ItemType(customItem.buildItemStack(ItemBuildContext.EMPTY)); + ItemType itemType = new ItemType(customItem.buildItemStack(ItemBuildContext.empty())); items.add(itemType); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java index 38ead6b3f..c037f46c3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java @@ -1,17 +1,25 @@ package net.momirealms.craftengine.bukkit.advancement; import com.google.gson.JsonElement; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; +import net.momirealms.craftengine.bukkit.util.ComponentUtils; +import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.advancement.AbstractAdvancementManager; +import net.momirealms.craftengine.core.advancement.AdvancementType; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.VersionHelper; import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public class BukkitAdvancementManager extends AbstractAdvancementManager { private final BukkitCraftEngine plugin; @@ -33,6 +41,70 @@ public class BukkitAdvancementManager extends AbstractAdvancementManager { return this.advancementParser; } + @Override + public void sendToast(Player player, Item icon, Component message, AdvancementType type) { + try { + Object displayInfo = CoreReflections.constructor$DisplayInfo.newInstance( + icon.getLiteralObject(), + ComponentUtils.adventureToMinecraft(message), // title + CoreReflections.instance$Component$empty, // description + VersionHelper.isOrAbove1_20_3() ? Optional.empty() : null, // background + CoreReflections.instance$AdvancementType$values[type.ordinal()], + true, // show toast + false, // announce to chat + true // hidden + ); + if (VersionHelper.isOrAbove1_20_2()) { + displayInfo = Optional.of(displayInfo); + } + Object resourceLocation = KeyUtils.toResourceLocation(Key.of("craftengine", "toast")); + Object criterion = VersionHelper.isOrAbove1_20_2() ? + CoreReflections.constructor$Criterion.newInstance(CoreReflections.constructor$ImpossibleTrigger.newInstance(), CoreReflections.constructor$ImpossibleTrigger$TriggerInstance.newInstance()) : + CoreReflections.constructor$Criterion.newInstance(CoreReflections.constructor$ImpossibleTrigger$TriggerInstance.newInstance()); + Map criteria = Map.of("impossible", criterion); + Object advancementProgress = CoreReflections.constructor$AdvancementProgress.newInstance(); + Object advancement; + if (VersionHelper.isOrAbove1_20_2()) { + Object advancementRequirements = VersionHelper.isOrAbove1_20_3() ? + CoreReflections.constructor$AdvancementRequirements.newInstance(List.of(List.of("impossible"))) : + CoreReflections.constructor$AdvancementRequirements.newInstance((Object) new String[][] {{"impossible"}}); + advancement = CoreReflections.constructor$Advancement.newInstance( + Optional.empty(), + displayInfo, + CoreReflections.instance$AdvancementRewards$EMPTY, + criteria, + advancementRequirements, + false + ); + CoreReflections.method$AdvancementProgress$update.invoke(advancementProgress, advancementRequirements); + advancement = CoreReflections.constructor$AdvancementHolder.newInstance(resourceLocation, advancement); + } else { + advancement = CoreReflections.constructor$Advancement.newInstance( + resourceLocation, + null, // parent + displayInfo, + CoreReflections.instance$AdvancementRewards$EMPTY, + criteria, + new String[][] {{"impossible"}}, + false + ); + CoreReflections.method$AdvancementProgress$update.invoke(advancementProgress, criteria, new String[][] {{"impossible"}}); + } + CoreReflections.method$AdvancementProgress$grantProgress.invoke(advancementProgress, "impossible"); + Map advancementsToGrant = new HashMap<>(); + advancementsToGrant.put(resourceLocation, advancementProgress); + Object grantPacket = VersionHelper.isOrAbove1_21_5() ? + NetworkReflections.constructor$ClientboundUpdateAdvancementsPacket.newInstance(false, Arrays.asList(advancement), new HashSet<>(), advancementsToGrant, true) : + NetworkReflections.constructor$ClientboundUpdateAdvancementsPacket.newInstance(false, Arrays.asList(advancement), new HashSet<>(), advancementsToGrant); + Object removePacket = VersionHelper.isOrAbove1_21_5() ? + NetworkReflections.constructor$ClientboundUpdateAdvancementsPacket.newInstance(false, new ArrayList<>(), new HashSet<>() {{add(resourceLocation);}}, new HashMap<>(), true) : + NetworkReflections.constructor$ClientboundUpdateAdvancementsPacket.newInstance(false, new ArrayList<>(), new HashSet<>() {{add(resourceLocation);}}, new HashMap<>()); + player.sendPackets(List.of(grantPacket, removePacket), false); + } catch (ReflectiveOperationException e) { + this.plugin.logger().warn("Failed to send toast for player " + player.name(), e); + } + } + public class AdvancementParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"advancements", "advancement"}; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java index aa872018e..d932532cf 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java @@ -129,7 +129,7 @@ public class ConcretePowderBlockBehavior extends BukkitBlockBehavior { Object mutablePos = CoreReflections.method$BlockPos$mutable.invoke(pos); int j = Direction.values().length; for (int k = 0; k < j; k++) { - Object direction = CoreReflections.instance$Directions[k]; + Object direction = CoreReflections.instance$Direction$values[k]; Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, mutablePos); if (direction != CoreReflections.instance$Direction$DOWN || canSolidify(blockState)) { CoreReflections.method$MutableBlockPos$setWithOffset.invoke(mutablePos, pos, direction); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java index c863c19a6..85924d053 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java @@ -132,7 +132,7 @@ public class LeavesBlockBehavior extends BukkitBlockBehavior { Object mutablePos = CoreReflections.constructor$MutableBlockPos.newInstance(); int j = Direction.values().length; for (int k = 0; k < j; ++k) { - Object direction = CoreReflections.instance$Directions[k]; + Object direction = CoreReflections.instance$Direction$values[k]; CoreReflections.method$MutableBlockPos$setWithOffset.invoke(mutablePos, blockPos, direction); Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(world, mutablePos); i = Math.min(i, getDistanceAt(blockState) + 1); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java index b195e328d..f60666842 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java @@ -13,22 +13,21 @@ import java.util.List; import java.util.UUID; public class ItemDisplayBlockEntityElement implements BlockEntityElement { + private final ItemDisplayBlockEntityElementConfig config; private final Object cachedSpawnPacket; private final Object cachedDespawnPacket; + private final int entityId; public ItemDisplayBlockEntityElement(ItemDisplayBlockEntityElementConfig config, BlockPos pos) { int entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(); Vector3f position = config.position(); - this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(List.of( - FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( - entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, - config.xRot(), config.yRot(), MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 - ), - FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket( - entityId, config.metadataValues().get() - ) - )); + this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( + entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, + config.xRot(), config.yRot(), MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 + ); + this.config = config; this.cachedDespawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(IntList.of(entityId)); + this.entityId = entityId; } @Override @@ -38,7 +37,7 @@ public class ItemDisplayBlockEntityElement implements BlockEntityElement { @Override public void spawn(Player player) { - player.sendPacket(this.cachedSpawnPacket, true); + player.sendPackets(List.of(this.cachedSpawnPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), true); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java index 35d53f551..b70d1136a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java @@ -7,9 +7,9 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfigFactory; import net.momirealms.craftengine.core.entity.Billboard; import net.momirealms.craftengine.core.entity.ItemDisplayContext; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.LazyReference; import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.world.BlockPos; import org.joml.Quaternionf; @@ -19,11 +19,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.function.Function; public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementConfig { public static final Factory FACTORY = new Factory(); - private final LazyReference> lazyMetadataPacket; - private final LazyReference> item; + private final Function> lazyMetadataPacket; + private final Function> item; private final Vector3f scale; private final Vector3f position; private final Vector3f translation; @@ -33,7 +34,7 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo private final ItemDisplayContext displayContext; private final Billboard billboard; - public ItemDisplayBlockEntityElementConfig(LazyReference> item, + public ItemDisplayBlockEntityElementConfig(Function> item, Vector3f scale, Vector3f position, Vector3f translation, @@ -51,16 +52,16 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo this.rotation = rotation; this.displayContext = displayContext; this.billboard = billboard; - this.lazyMetadataPacket = LazyReference.lazyReference(() -> { + this.lazyMetadataPacket = player -> { List dataValues = new ArrayList<>(); - ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.get().getLiteralObject(), dataValues); + ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.apply(player).getLiteralObject(), dataValues); ItemDisplayEntityData.Scale.addEntityDataIfNotDefaultValue(this.scale, dataValues); ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(this.rotation, dataValues); ItemDisplayEntityData.BillboardConstraints.addEntityDataIfNotDefaultValue(this.billboard.id(), dataValues); ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(this.translation, dataValues); ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(this.displayContext.id(), dataValues); return dataValues; - }); + }; } @Override @@ -68,8 +69,8 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo return new ItemDisplayBlockEntityElement(this, pos); } - public Item item() { - return this.item.get(); + public Item item(Player player) { + return this.item.apply(player); } public Vector3f scale() { @@ -104,8 +105,8 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo return rotation; } - public LazyReference> metadataValues() { - return this.lazyMetadataPacket; + public List metadataValues(Player player) { + return this.lazyMetadataPacket.apply(player); } public static class Factory implements BlockEntityElementConfigFactory { @@ -113,10 +114,9 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo @SuppressWarnings("unchecked") @Override public BlockEntityElementConfig create(Map arguments) { - // todo item should not be null - Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("item"), "")); + Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("item"), "warning.config.block.state.entity_renderer.item_display.missing_item")); return (BlockEntityElementConfig) new ItemDisplayBlockEntityElementConfig( - LazyReference.lazyReference(() -> BukkitItemManager.instance().createWrappedItem(itemId, null)), + player -> BukkitItemManager.instance().createWrappedItem(itemId, player), ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("scale", 1f), "scale"), ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0.5f), "position"), ResourceConfigUtils.getAsVector3f(arguments.get("translation"), "translation"), diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index c21500bb8..2318e20a9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -21,7 +21,6 @@ import net.momirealms.craftengine.core.item.recipe.DatapackRecipeResult; import net.momirealms.craftengine.core.item.recipe.UniqueIdItem; import net.momirealms.craftengine.core.pack.AbstractPackManager; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.plugin.logger.Debugger; import net.momirealms.craftengine.core.util.*; @@ -335,7 +334,7 @@ public class BukkitItemManager extends AbstractItemManager { @Override public ItemStack buildCustomItemStack(Key id, Player player) { - return Optional.ofNullable(this.customItemsById.get(id)).map(it -> it.buildItemStack(new ItemBuildContext(player, ContextHolder.EMPTY), 1)).orElse(null); + return Optional.ofNullable(this.customItemsById.get(id)).map(it -> it.buildItemStack(ItemBuildContext.of(player), 1)).orElse(null); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java index 11cd5b5a1..b738734a3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java @@ -200,7 +200,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { for (UniqueKey holder : holders) { Optional> buildableItem = BukkitItemManager.instance().getBuildableItem(holder.key()); if (buildableItem.isPresent()) { - ItemStack itemStack = buildableItem.get().buildItemStack(ItemBuildContext.EMPTY, 1); + ItemStack itemStack = buildableItem.get().buildItemStack(ItemBuildContext.empty(), 1); Object nmsStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack); itemStacks.add(nmsStack); } else { @@ -336,7 +336,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { if (recipe instanceof CustomBrewingRecipe brewingRecipe) { if (!VersionHelper.isOrAbove1_20_2()) return; PotionMix potionMix = new PotionMix(new NamespacedKey(id.namespace(), id.value()), - brewingRecipe.result(ItemBuildContext.EMPTY), + brewingRecipe.result(ItemBuildContext.empty()), PotionMix.createPredicateChoice(container -> { Item wrapped = this.plugin.itemManager().wrap(container); return brewingRecipe.container().test(UniqueIdItem.of(wrapped)); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java index ef458eacb..59894f3e4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java @@ -23,7 +23,6 @@ import net.momirealms.craftengine.core.item.recipe.input.SmithingInput; import net.momirealms.craftengine.core.item.setting.AnvilRepairItem; import net.momirealms.craftengine.core.item.setting.ItemEquipment; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.util.*; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -614,9 +613,9 @@ public class RecipeEventListener implements Listener { Player player = InventoryUtils.getPlayerFromInventoryEvent(event); BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player); if (craftingTableRecipe.hasVisualResult()) { - inventory.setResult(craftingTableRecipe.assembleVisual(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY))); + inventory.setResult(craftingTableRecipe.assembleVisual(input, ItemBuildContext.of(serverPlayer))); } else { - inventory.setResult(craftingTableRecipe.assemble(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY))); + inventory.setResult(craftingTableRecipe.assemble(input, ItemBuildContext.of(serverPlayer))); } } @@ -642,7 +641,7 @@ public class RecipeEventListener implements Listener { if (input == null) return; Player player = InventoryUtils.getPlayerFromInventoryEvent(event); BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player); - inventory.setResult(craftingTableRecipe.assemble(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY))); + inventory.setResult(craftingTableRecipe.assemble(input, ItemBuildContext.of(serverPlayer))); } private CraftingInput getCraftingInput(CraftingInventory inventory) { @@ -694,7 +693,7 @@ public class RecipeEventListener implements Listener { SmithingInput input = getSmithingInput(inventory); if (smithingTrimRecipe.matches(input)) { Player player = InventoryUtils.getPlayerFromInventoryEvent(event); - ItemStack result = smithingTrimRecipe.assemble(getSmithingInput(inventory), new ItemBuildContext(BukkitAdaptors.adapt(player), ContextHolder.EMPTY)); + ItemStack result = smithingTrimRecipe.assemble(getSmithingInput(inventory), ItemBuildContext.of(BukkitAdaptors.adapt(player))); event.setResult(result); } else { event.setResult(null); @@ -718,7 +717,7 @@ public class RecipeEventListener implements Listener { SmithingInput input = getSmithingInput(inventory); if (smithingTransformRecipe.matches(input)) { Player player = InventoryUtils.getPlayerFromInventoryEvent(event); - ItemStack processed = smithingTransformRecipe.assemble(input, new ItemBuildContext(BukkitAdaptors.adapt(player), ContextHolder.EMPTY)); + ItemStack processed = smithingTransformRecipe.assemble(input, ItemBuildContext.of(BukkitAdaptors.adapt(player))); event.setResult(processed); } else { event.setResult(null); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java index 6acebe428..a8513327a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java @@ -90,7 +90,7 @@ public class BukkitPackManager extends AbstractPackManager implements Listener { return; } if (!Config.sendPackOnUpload()) return; - CraftEngine.instance().logger().info("Complete uploading resource pack"); + CraftEngine.instance().logger().info("Completed uploading resource pack"); for (BukkitServerPlayer player : this.plugin.networkManager().onlineUsers()) { sendResourcePack(player); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemAnimationCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemAnimationCommand.java index 9584a7fd1..7001785f0 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemAnimationCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemAnimationCommand.java @@ -61,7 +61,7 @@ public class TotemAnimationCommand extends BukkitCommandFeature { handleFeedback(context, MessageConstants.COMMAND_TOTEM_NOT_TOTEM, Component.text(key.toString())); return; } - Item item = customItem.buildItem(ItemBuildContext.EMPTY); + Item item = customItem.buildItem(ItemBuildContext.empty()); if (VersionHelper.isOrAbove1_21_2()) { if (context.flags().contains("sound_location")) { String soundResourceLocation = context.flags().getValue("sound_location").get().toString(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java index 5c7d29b86..6e697af25 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java @@ -112,7 +112,7 @@ public class ProjectilePacketHandler implements EntityPacketHandler { Optional> customItem = BukkitItemManager.instance().getCustomItem(this.projectile.metadata().item()); if (customItem.isEmpty()) return itemDisplayValues; ProjectileMeta meta = this.projectile.metadata(); - Item displayedItem = customItem.get().buildItem(ItemBuildContext.EMPTY); + Item displayedItem = customItem.get().buildItem(ItemBuildContext.empty()); // 我们应当使用新的展示物品的组件覆盖原物品的组件,以完成附魔,附魔光效等组件的继承 displayedItem = this.projectile.item().mergeCopy(displayedItem); ItemDisplayEntityData.InterpolationDelay.addEntityDataIfNotDefaultValue(-1, itemDisplayValues); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java index 79cd15c2d..48eb0072e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java @@ -469,17 +469,17 @@ public final class CoreReflections { public static final Object instance$Direction$SOUTH; public static final Object instance$Direction$WEST; public static final Object instance$Direction$EAST; - public static final Object[] instance$Directions; + public static final Object[] instance$Direction$values; static { try { - instance$Directions = (Object[]) method$Direction$values.invoke(null); - instance$Direction$DOWN = instance$Directions[0]; - instance$Direction$UP = instance$Directions[1]; - instance$Direction$NORTH = instance$Directions[2]; - instance$Direction$SOUTH = instance$Directions[3]; - instance$Direction$WEST = instance$Directions[4]; - instance$Direction$EAST = instance$Directions[5]; + instance$Direction$values = (Object[]) method$Direction$values.invoke(null); + instance$Direction$DOWN = instance$Direction$values[0]; + instance$Direction$UP = instance$Direction$values[1]; + instance$Direction$NORTH = instance$Direction$values[2]; + instance$Direction$SOUTH = instance$Direction$values[3]; + instance$Direction$WEST = instance$Direction$values[4]; + instance$Direction$EAST = instance$Direction$values[5]; } catch (ReflectiveOperationException e) { throw new ReflectionInitException("Failed to init Direction", e); } @@ -4217,4 +4217,176 @@ public final class CoreReflections { public static final Method method$Block$updateEntityMovementAfterFallOn = requireNonNull( ReflectionUtils.getDeclaredMethod(clazz$Block, void.class, clazz$BlockGetter, clazz$Entity) ); + + public static final Class clazz$AdvancementRewards = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.AdvancementRewards", + "advancements.AdvancementRewards" + ) + ); + + public static final Field field$AdvancementRewards$EMPTY = requireNonNull( + ReflectionUtils.getStaticDeclaredField(clazz$AdvancementRewards, clazz$AdvancementRewards, 0) + ); + + public static final Object instance$AdvancementRewards$EMPTY; + + static { + try { + instance$AdvancementRewards$EMPTY = field$AdvancementRewards$EMPTY.get(null); + } catch (ReflectiveOperationException e) { + throw new ReflectionInitException("Failed to initialize AdvancementRewards$EMPTY", e); + } + } + + public static final Class clazz$AdvancementRequirements = MiscUtils.requireNonNullIf( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.AdvancementRequirements", + "advancements.AdvancementRequirements" + ), VersionHelper.isOrAbove1_20_2() + ); + + public static final Constructor constructor$AdvancementRequirements = Optional.ofNullable(clazz$AdvancementRequirements) + .map(it -> { + if (VersionHelper.isOrAbove1_20_3()) { + return ReflectionUtils.getConstructor(it, List.class); + } else { + return ReflectionUtils.getConstructor(it, String[][].class); + } + }).orElse(null); + + public static final Class clazz$AdvancementProgress = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.AdvancementProgress", + "advancements.AdvancementProgress" + ) + ); + + public static final Constructor constructor$AdvancementProgress = requireNonNull( + ReflectionUtils.getConstructor(clazz$AdvancementProgress) + ); + + public static final Method method$AdvancementProgress$update = requireNonNull( + VersionHelper.isOrAbove1_20_2() ? + ReflectionUtils.getMethod(clazz$AdvancementProgress, void.class, clazz$AdvancementRequirements) : + ReflectionUtils.getMethod(clazz$AdvancementProgress, void.class, Map.class, String[][].class) + ); + + public static final Class clazz$AdvancementType = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.AdvancementFrameType", + VersionHelper.isOrAbove1_20_3() ? "advancements.AdvancementType" : "advancements.FrameType" + ) + ); + + public static final Method method$AdvancementType$values = requireNonNull( + ReflectionUtils.getStaticMethod(clazz$AdvancementType, clazz$AdvancementType.arrayType()) + ); + + public static final Object[] instance$AdvancementType$values; + + static { + try { + instance$AdvancementType$values = (Object[]) method$AdvancementType$values.invoke(null); + } catch (ReflectiveOperationException e) { + throw new ReflectionInitException("Failed to initialize AdvancementTypes", e); + } + } + + public static final Class clazz$DisplayInfo = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.AdvancementDisplay", + "advancements.DisplayInfo" + ) + ); + + public static final Constructor constructor$DisplayInfo = requireNonNull( + VersionHelper.isOrAbove1_20_3() ? + ReflectionUtils.getConstructor(clazz$DisplayInfo, clazz$ItemStack, clazz$Component, clazz$Component, Optional.class, clazz$AdvancementType, boolean.class, boolean.class, boolean.class) : + ReflectionUtils.getConstructor(clazz$DisplayInfo, clazz$ItemStack, clazz$Component, clazz$Component, clazz$ResourceLocation, clazz$AdvancementType, boolean.class, boolean.class, boolean.class) + ); + + public static final Class clazz$Criterion = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.Criterion", + "advancements.Criterion" + ) + ); + + public static final Class clazz$CriterionTrigger = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.CriterionTrigger", + "advancements.CriterionTrigger" + ) + ); + + public static final Class clazz$CriterionTriggerInstance = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.CriterionInstance", + "advancements.CriterionTriggerInstance" + ) + ); + + public static final Class clazz$ImpossibleTrigger = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.critereon.CriterionTriggerImpossible", + "advancements.critereon.ImpossibleTrigger" + ) + ); + + public static final Constructor constructor$ImpossibleTrigger = requireNonNull( + ReflectionUtils.getConstructor(clazz$ImpossibleTrigger) + ); + + public static final Class clazz$ImpossibleTrigger$TriggerInstance = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.critereon.CriterionTriggerImpossible$a", + "advancements.critereon.ImpossibleTrigger$TriggerInstance" + ) + ); + + public static final Constructor constructor$Criterion = requireNonNull( + VersionHelper.isOrAbove1_20_2() ? + ReflectionUtils.getConstructor(clazz$Criterion, clazz$CriterionTrigger, clazz$CriterionTriggerInstance) : + ReflectionUtils.getConstructor(clazz$Criterion, clazz$CriterionTriggerInstance) + ); + + public static final Constructor constructor$ImpossibleTrigger$TriggerInstance = requireNonNull( + ReflectionUtils.getConstructor(clazz$ImpossibleTrigger$TriggerInstance) + ); + + public static final Class clazz$Advancement = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.Advancement", + "advancements.Advancement" + ) + ); + + public static final Constructor constructor$Advancement = requireNonNull( + VersionHelper.isOrAbove1_20_2() ? + ReflectionUtils.getConstructor(clazz$Advancement, Optional.class, Optional.class, clazz$AdvancementRewards, Map.class, clazz$AdvancementRequirements, boolean.class) : + ReflectionUtils.getConstructor(clazz$Advancement, clazz$ResourceLocation, clazz$Advancement, clazz$DisplayInfo, clazz$AdvancementRewards, Map.class, String[][].class, boolean.class) + ); + + public static final Class clazz$CriterionProgress = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.CriterionProgress", + "advancements.CriterionProgress" + ) + ); + + public static final Method method$AdvancementProgress$grantProgress = requireNonNull( + ReflectionUtils.getMethod(clazz$AdvancementProgress, boolean.class, new String[]{"grantProgress", "a"}, String.class) + ); + + public static final Class clazz$AdvancementHolder = MiscUtils.requireNonNullIf( + BukkitReflectionUtils.findReobfOrMojmapClass( + "advancements.AdvancementHolder", + "advancements.AdvancementHolder" + ), VersionHelper.isOrAbove1_20_2() + ); + + public static final Constructor constructor$AdvancementHolder = Optional.ofNullable(clazz$AdvancementHolder) + .map(it -> ReflectionUtils.getConstructor(it, clazz$ResourceLocation, clazz$Advancement)) + .orElse(null); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java index f97ae5164..efbcc589d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java @@ -1671,4 +1671,10 @@ public final class NetworkReflections { "network.protocol.game.ClientboundForgetLevelChunkPacket" ) ); + + public static final Constructor constructor$ClientboundUpdateAdvancementsPacket = requireNonNull( + VersionHelper.isOrAbove1_21_5() ? + ReflectionUtils.getConstructor(clazz$ClientboundUpdateAdvancementsPacket, boolean.class, Collection.class, Set.class, Map.class, boolean.class) : + ReflectionUtils.getConstructor(clazz$ClientboundUpdateAdvancementsPacket, boolean.class, Collection.class, Set.class, Map.class) + ); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 5b9512f15..dbdbebfeb 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -20,6 +20,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MMobEffects import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; import net.momirealms.craftengine.bukkit.util.*; import net.momirealms.craftengine.bukkit.world.BukkitWorld; +import net.momirealms.craftengine.core.advancement.AdvancementType; import net.momirealms.craftengine.core.block.BlockStateWrapper; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.entity.BlockEntity; @@ -235,6 +236,11 @@ public class BukkitServerPlayer extends Player { return AdventureModeUtils.canPlace(platformPlayer().getInventory().getItemInMainHand(), new Location(platformPlayer().getWorld(), pos.x(), pos.y(), pos.z()), state); } + @Override + public void sendToast(Component text, Item icon, AdvancementType type) { + this.plugin.advancementManager().sendToast(this, icon, text, type); + } + @Override public void sendActionBar(Component text) { Object packet = FastNMS.INSTANCE.constructor$ClientboundActionBarPacket(ComponentUtils.adventureToMinecraft(text)); diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 2b6d0705d..42e20d0f1 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -261,6 +261,8 @@ warning.config.block.state.missing_state: "Issue found in file - warning.config.block.state.missing_properties: "Issue found in file - The block '' is missing the required 'properties' section for 'states'." warning.config.block.state.missing_appearances: "Issue found in file - The block '' is missing the required 'appearances' section for 'states'." warning.config.block.state.missing_variants: "Issue found in file - The block '' is missing the required 'variants' section for 'states'." +warning.config.block.state.entity_renderer.invalid_type: "Issue found in file - The block '' is using an invalid entity renderer type ''." +warning.config.block.state.entity_renderer.item_display.missing_item: "Issue found in file - The block '' is missing the required 'item' argument for 'item_display' entity renderer." warning.config.block.state.variant.missing_appearance: "Issue found in file - The block '' is missing the required 'appearance' argument for variant ''." warning.config.block.state.variant.invalid_appearance: "Issue found in file - The block '' has an error that the variant '' is using a non-existing appearance ''." warning.config.block.state.invalid_vanilla: "Issue found in file - The block '' is using an invalid vanilla block state ''." @@ -392,7 +394,7 @@ warning.config.function.command.missing_command: "Issue found in file Issue found in file - The config '' is missing the required 'actionbar' argument for 'actionbar' function." warning.config.function.message.missing_message: "Issue found in file - The config '' is missing the required 'message' argument for 'message' function." warning.config.function.open_window.missing_gui_type: "Issue found in file - The config '' is missing the required 'gui-type' argument for 'open_window' function." -warning.config.function.open_window.invalid_gui_type: "Issue found in file - The config '' is using an invalid gui type for 'open_window' function. Allowed types: []." +warning.config.function.open_window.invalid_gui_type: "Issue found in file - The config '' is using an invalid gui type '' for 'open_window' function. Allowed types: []." warning.config.function.run.missing_functions: "Issue found in file - The config '' is missing the required 'functions' argument for 'run' function." warning.config.function.place_block.missing_block_state: "Issue found in file - The config '' is missing the required 'block-state' argument for 'place_block' function." warning.config.function.set_food.missing_food: "Issue found in file - The config '' is missing the required 'food' argument for 'set_food' function." @@ -415,6 +417,14 @@ warning.config.function.remove_cooldown.missing_id: "Issue found in file warning.config.function.mythic_mobs_skill.missing_skill: "Issue found in file - The config '' is missing the required 'skill' argument for 'mythic_mobs_skill' function." warning.config.function.spawn_furniture.missing_furniture_id: "Issue found in file - The config '' is missing the required 'furniture-id' argument for 'spawn_furniture' function." warning.config.function.replace_furniture.missing_furniture_id: "Issue found in file - The config '' is missing the required 'furniture-id' argument for 'replace_furniture' function." +warning.config.function.teleport.missing_x: "Issue found in file - The config '' is missing the required 'x' argument for 'teleport' function." +warning.config.function.teleport.missing_y: "Issue found in file - The config '' is missing the required 'y' argument for 'teleport' function." +warning.config.function.teleport.missing_z: "Issue found in file - The config '' is missing the required 'z' argument for 'teleport' function." +warning.config.function.set_variable.missing_name: "Issue found in file - The config '' is missing the required 'name' argument for 'set_variable' function." +warning.config.function.set_variable.missing_value: "Issue found in file - The config '' is missing the required 'number' or 'text' argument for 'set_variable' function." +warning.config.function.toast.missing_toast: "Issue found in file - The config '' is missing the required 'toast' argument for 'toast' function." +warning.config.function.toast.missing_icon: "Issue found in file - The config '' is missing the required 'icon' argument for 'toast' function." +warning.config.function.toast.invalid_advancement_type: "Issue found in file - The config '' is using an invalid advancement type '' for 'toast' function. Allowed types: []." warning.config.selector.missing_type: "Issue found in file - The config '' is missing the required 'type' argument for selector." warning.config.selector.invalid_type: "Issue found in file - The config '' is using an invalid selector type ''." warning.config.selector.invalid_target: "Issue found in file - The config '' is using an invalid selector target ''." diff --git a/core/src/main/java/net/momirealms/craftengine/core/advancement/AbstractAdvancementManager.java b/core/src/main/java/net/momirealms/craftengine/core/advancement/AbstractAdvancementManager.java index 8af17d774..43711d2f9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/advancement/AbstractAdvancementManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/advancement/AbstractAdvancementManager.java @@ -8,4 +8,6 @@ public abstract class AbstractAdvancementManager implements AdvancementManager { public AbstractAdvancementManager(CraftEngine plugin) { this.plugin = plugin; } + + } diff --git a/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java b/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java index b4a13703b..f7d664bdf 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java @@ -1,9 +1,14 @@ package net.momirealms.craftengine.core.advancement; +import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.Manageable; import net.momirealms.craftengine.core.plugin.config.ConfigParser; public interface AdvancementManager extends Manageable { ConfigParser parser(); + + void sendToast(Player player, Item icon, Component message, AdvancementType type); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java index 6ea5d16ad..70338ebee 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java @@ -23,8 +23,7 @@ public class BlockEntityElementConfigs { Key type = Optional.ofNullable(arguments.get("type")).map(String::valueOf).map(Key::of).orElse(ITEM_DISPLAY); BlockEntityElementConfigFactory factory = BuiltInRegistries.BLOCK_ENTITY_ELEMENT_TYPE.getValue(type); if (factory == null) { - // todo 发送消息 - throw new LocalizedResourceConfigException("", type.toString()); + throw new LocalizedResourceConfigException("warning.config.block.state.entity_renderer.invalid_type", type.toString()); } return factory.create(arguments); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java index 3ed4302fc..9a33c2dbc 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.entity.player; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.advancement.AdvancementType; import net.momirealms.craftengine.core.entity.AbstractEntity; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.context.CooldownData; @@ -8,7 +9,6 @@ import net.momirealms.craftengine.core.plugin.network.NetWorkUser; import net.momirealms.craftengine.core.sound.SoundSource; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.world.BlockPos; -import net.momirealms.craftengine.core.world.Position; import net.momirealms.craftengine.core.world.WorldPosition; import org.jetbrains.annotations.NotNull; @@ -64,6 +64,8 @@ public abstract class Player extends AbstractEntity implements NetWorkUser { public abstract boolean canPlace(BlockPos pos, Object state); + public abstract void sendToast(Component text, Item icon, AdvancementType type); + public abstract void sendActionBar(Component text); public abstract void sendMessage(Component text, boolean overlay); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java index 4e996c007..3b2798539 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.entity.player.Player; -import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.util.Key; public interface BuildableItem { @@ -27,18 +26,18 @@ public interface BuildableItem { } default I buildItemStack() { - return buildItemStack(ItemBuildContext.EMPTY, 1); + return buildItemStack(ItemBuildContext.empty(), 1); } default I buildItemStack(int count) { - return buildItemStack(ItemBuildContext.EMPTY, count); + return buildItemStack(ItemBuildContext.empty(), count); } default I buildItemStack(Player player) { - return this.buildItemStack(new ItemBuildContext(player, ContextHolder.EMPTY), 1); + return this.buildItemStack(ItemBuildContext.of(player), 1); } default I buildItemStack(Player player, int count) { - return this.buildItemStack(new ItemBuildContext(player, ContextHolder.EMPTY), count); + return this.buildItemStack(ItemBuildContext.of(player), count); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemBuildContext.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemBuildContext.java index a8b7dd219..1a9009dd6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemBuildContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemBuildContext.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.item; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; @@ -10,12 +11,23 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; public class ItemBuildContext extends PlayerOptionalContext { - public static final ItemBuildContext EMPTY = new ItemBuildContext(null, ContextHolder.EMPTY); + + /** + * Use {@link #empty()} instead + */ + @Deprecated(since = "0.0.63", forRemoval = true) + public static final ItemBuildContext EMPTY = new ItemBuildContext(null, ContextHolder.empty()); + public static final TagResolver[] EMPTY_RESOLVERS = empty().tagResolvers(); public ItemBuildContext(@Nullable Player player, @NotNull ContextHolder contexts) { super(player, contexts); } + @NotNull + public static ItemBuildContext empty() { + return new ItemBuildContext(null, ContextHolder.empty()); + } + @NotNull public static ItemBuildContext of(@Nullable Player player, @NotNull ContextHolder contexts) { return new ItemBuildContext(player, contexts); @@ -29,7 +41,7 @@ public class ItemBuildContext extends PlayerOptionalContext { @NotNull public static ItemBuildContext of(@Nullable Player player) { - if (player == null) return new ItemBuildContext(null, ContextHolder.EMPTY); + if (player == null) return new ItemBuildContext(null, ContextHolder.empty()); return new ItemBuildContext(player, new ContextHolder(Map.of(DirectContextParameters.PLAYER, () -> player))); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java b/core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java index fbacf55cb..80b937630 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java @@ -8,7 +8,7 @@ import java.util.Optional; public abstract class AbstractVanillaLootManager implements VanillaLootManager { protected final Map blockLoots = new HashMap<>(); - // TODO More entity NBT + // TODO 实现一个基于entity data的生物战利品系统 protected final Map entityLoots = new HashMap<>(); public AbstractVanillaLootManager() { diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 2ce619894..ece216966 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -467,7 +467,7 @@ public abstract class AbstractPackManager implements PackManager { plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/pebble_1.json"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/pebble_2.json"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/pebble_3.json"); - plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/item/custom/sofa_straight.json"); + plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/item/custom/sleeper_sofa.json"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/item/custom/sofa_inner.json"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/item/custom/sofa.json"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/sofa.png"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/PathContext.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/PathContext.java index 55bdce4db..d8aaefc24 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/PathContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/PathContext.java @@ -18,6 +18,6 @@ public class PathContext extends AbstractCommonContext { } public static PathContext of(Path path) { - return new PathContext(ContextHolder.EMPTY, path); + return new PathContext(ContextHolder.empty(), path); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index b2759fd4b..276dc3ee8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -35,7 +35,6 @@ import net.momirealms.craftengine.core.plugin.logger.filter.LogFilter; import net.momirealms.craftengine.core.plugin.network.NetworkManager; import net.momirealms.craftengine.core.plugin.scheduler.SchedulerAdapter; import net.momirealms.craftengine.core.sound.SoundManager; -import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.Logger; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ContextHolder.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ContextHolder.java index 5e54f2ea8..59d678797 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ContextHolder.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ContextHolder.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.plugin.context; import com.google.common.collect.ImmutableMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -10,11 +11,32 @@ import java.util.Optional; import java.util.function.Supplier; public class ContextHolder { + /** + * Use {@link #empty()} instead + */ + @Deprecated(forRemoval = true, since = "0.0.63") public static final ContextHolder EMPTY = ContextHolder.builder().immutable(true).build(); + protected final Map, Supplier> params; + private final boolean immutable; + + public ContextHolder(Map, Supplier> params, boolean immutable) { + this.params = immutable ? ImmutableMap.copyOf(params) : new HashMap<>(params); + this.immutable = immutable; + } public ContextHolder(Map, Supplier> params) { - this.params = params; + this.params = new HashMap<>(params); + this.immutable = true; + } + + @NotNull + public static ContextHolder empty() { + return ContextHolder.builder().build(); + } + + public boolean immutable() { + return this.immutable; } public boolean has(ContextKey key) { @@ -67,7 +89,7 @@ public class ContextHolder { } public static class Builder { - private final Map, Supplier> params = new HashMap<>(); + private final Map, Supplier> params = new HashMap<>(8); private boolean immutable = false; public Builder() {} @@ -113,7 +135,7 @@ public class ContextHolder { } public ContextHolder build() { - return new ContextHolder(this.immutable ? ImmutableMap.copyOf(this.params) : this.params); + return new ContextHolder(this.params, this.immutable); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java index f2a39186c..e38a1668d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java @@ -11,7 +11,12 @@ import java.util.List; import java.util.Map; public class PlayerOptionalContext extends AbstractChainParameterContext implements PlayerContext { - public static final PlayerOptionalContext EMPTY = new PlayerOptionalContext(null, ContextHolder.EMPTY); + /** + * Use {@link #empty()} instead + */ + @Deprecated(forRemoval = true) + public static final PlayerOptionalContext EMPTY = new PlayerOptionalContext(null, ContextHolder.empty()); + protected final Player player; public PlayerOptionalContext(@Nullable Player player, @@ -40,10 +45,15 @@ public class PlayerOptionalContext extends AbstractChainParameterContext impleme @NotNull public static PlayerOptionalContext of(@Nullable Player player) { - if (player == null) return EMPTY; + if (player == null) return empty(); return new PlayerOptionalContext(player, new ContextHolder(Map.of(DirectContextParameters.PLAYER, () -> player))); } + @NotNull + public static PlayerOptionalContext empty() { + return new PlayerOptionalContext(null, ContextHolder.empty()); + } + @Override @Nullable public Player player() { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java index bfde55253..8c36f5af6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java @@ -43,6 +43,8 @@ public class EventFunctions { register(CommonFunctions.REPLACE_FURNITURE, new ReplaceFurnitureFunction.FactoryImpl<>(EventConditions::fromMap)); register(CommonFunctions.MYTHIC_MOBS_SKILL, new MythicMobsSkillFunction.FactoryImpl<>(EventConditions::fromMap)); register(CommonFunctions.TELEPORT, new TeleportFunction.FactoryImpl<>(EventConditions::fromMap)); + register(CommonFunctions.SET_VARIABLE, new SetVariableFunction.FactoryImpl<>(EventConditions::fromMap)); + register(CommonFunctions.TOAST, new ToastFunction.FactoryImpl<>(EventConditions::fromMap)); } public static void register(Key key, FunctionFactory factory) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ActionBarFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ActionBarFunction.java index 9f3781528..86aeebfa5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ActionBarFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ActionBarFunction.java @@ -33,7 +33,7 @@ public class ActionBarFunction extends AbstractConditionalF }); } else { for (Player viewer : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer)); viewer.sendActionBar(AdventureHelper.miniMessage().deserialize(this.message.get(relationalContext), relationalContext.tagResolvers())); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommandFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommandFunction.java index 2447d64ff..fc6c360fa 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommandFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommandFunction.java @@ -45,7 +45,7 @@ public class CommandFunction extends AbstractConditionalFun )); } else { for (Player viewer : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer)); executeCommands(relationalContext, this.asEvent ? viewer::performCommandAsEvent : command1 -> viewer.performCommand(command1, this.asOp)); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java index 5f1d6d787..143b02f1d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java @@ -33,4 +33,5 @@ public final class CommonFunctions { public static final Key MYTHIC_MOBS_SKILL = Key.of("craftengine:mythic_mobs_skill"); public static final Key TELEPORT = Key.of("craftengine:teleport"); public static final Key TOAST = Key.of("craftengine:toast"); + public static final Key SET_VARIABLE = Key.of("craftengine:set_variable"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/LevelerExpFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/LevelerExpFunction.java index dd369f792..51316f239 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/LevelerExpFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/LevelerExpFunction.java @@ -36,7 +36,7 @@ public class LevelerExpFunction extends AbstractConditional }); } else { for (Player target : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target)); CraftEngine.instance().compatibilityManager().addLevelerExp(target, this.plugin, this.leveler, this.count.getDouble(relationalContext)); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/MessageFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/MessageFunction.java index 640d26b41..ffedc3333 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/MessageFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/MessageFunction.java @@ -38,7 +38,7 @@ public class MessageFunction extends AbstractConditionalFun }); } else { for (Player viewer : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer)); for (TextProvider c : this.messages) { viewer.sendMessage(AdventureHelper.miniMessage().deserialize(c.get(relationalContext), relationalContext.tagResolvers()), this.overlay); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/OpenWindowFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/OpenWindowFunction.java index 9799f63e2..3cda10b9b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/OpenWindowFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/OpenWindowFunction.java @@ -46,7 +46,7 @@ public class OpenWindowFunction extends AbstractConditional for (Player viewer : this.selector.get(ctx)) { CraftEngine.instance().guiManager().openInventory(viewer, this.guiType); if (this.optionalTitle != null) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer)); CraftEngine.instance().guiManager().updateInventoryTitle(viewer, AdventureHelper.miniMessage().deserialize(this.optionalTitle.get(relationalContext), relationalContext.tagResolvers())); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/PotionEffectFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/PotionEffectFunction.java index 0b91844ee..fa25af75f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/PotionEffectFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/PotionEffectFunction.java @@ -39,7 +39,7 @@ public class PotionEffectFunction extends AbstractCondition }); } else { for (Player target : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target)); target.addPotionEffect(this.potionEffectType, this.duration.getInt(relationalContext), this.amplifier.getInt(relationalContext), this.ambient, this.particles); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetCooldownFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetCooldownFunction.java index 8019f8717..5634d5f19 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetCooldownFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetCooldownFunction.java @@ -41,7 +41,7 @@ public class SetCooldownFunction extends AbstractConditiona }); } else { for (Player target : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target)); long millis = TimeUtils.parseToMillis(this.time.get(relationalContext)); CooldownData data = target.cooldown(); if (this.add) data.addCooldown(this.id, millis); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetFoodFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetFoodFunction.java index 70a1e3f6e..544a2a147 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetFoodFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetFoodFunction.java @@ -33,7 +33,7 @@ public class SetFoodFunction extends AbstractConditionalFun optionalPlayer.ifPresent(player -> player.setFoodLevel(this.add ? player.foodLevel() + this.count.getInt(ctx) : this.count.getInt(ctx))); } else { for (Player target : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target)); target.setFoodLevel(this.add ? target.foodLevel() + this.count.getInt(relationalContext) : this.count.getInt(relationalContext)); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetSaturationFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetSaturationFunction.java index 6b002aedd..9c6d24e98 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetSaturationFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetSaturationFunction.java @@ -33,7 +33,7 @@ public class SetSaturationFunction extends AbstractConditio optionalPlayer.ifPresent(player -> player.setSaturation(this.add ? player.saturation() + this.count.getFloat(ctx) : this.count.getFloat(ctx))); } else { for (Player target : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(target)); target.setSaturation(this.add ? target.saturation() + this.count.getFloat(relationalContext) : this.count.getFloat(relationalContext)); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetVariableFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetVariableFunction.java new file mode 100644 index 000000000..4d8c47419 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SetVariableFunction.java @@ -0,0 +1,72 @@ +package net.momirealms.craftengine.core.plugin.context.function; + +import com.mojang.datafixers.util.Either; +import net.momirealms.craftengine.core.plugin.context.Condition; +import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.plugin.context.ContextHolder; +import net.momirealms.craftengine.core.plugin.context.ContextKey; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; +import net.momirealms.craftengine.core.plugin.context.text.TextProvider; +import net.momirealms.craftengine.core.plugin.context.text.TextProviders; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; + +import java.util.List; +import java.util.Map; + +public class SetVariableFunction extends AbstractConditionalFunction { + private final Either either; + private final String variableName; + private final boolean asInt; + + public SetVariableFunction(List> predicates, String variableName, Either either, boolean asInt) { + super(predicates); + this.either = either; + this.variableName = variableName; + this.asInt = asInt; + } + + @Override + public void runInternal(CTX ctx) { + ContextHolder contexts = ctx.contexts(); + if (contexts.immutable()) return; + this.either.ifLeft(text -> contexts.withParameter(ContextKey.direct("var_" + this.variableName), text.get(ctx))) + .ifRight(number -> contexts.withParameter(ContextKey.direct("var_" + this.variableName), asInt ? number.getInt(ctx) : number.getDouble(ctx))); + } + + @Override + public Key type() { + return CommonFunctions.SET_VARIABLE; + } + + public static class FactoryImpl extends AbstractFactory { + + public FactoryImpl(java.util.function.Function, Condition> factory) { + super(factory); + } + + @Override + public Function create(Map arguments) { + String variableName = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("name"), "warning.config.function.set_variable.missing_name"); + if (arguments.containsKey("number")) { + return new SetVariableFunction<>( + getPredicates(arguments), + variableName, + Either.right(NumberProviders.fromObject(arguments.get("number"))), + ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("as-int", false), "as-int") + ); + } else if (arguments.containsKey("text")) { + return new SetVariableFunction<>( + getPredicates(arguments), + variableName, + Either.left(TextProviders.fromString(arguments.get("text").toString())), + false + ); + } else { + throw new LocalizedResourceConfigException("warning.config.function.set_variable.missing_value"); + } + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TeleportFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TeleportFunction.java index 1455c93ab..f207afed2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TeleportFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TeleportFunction.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.plugin.context.function; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.plugin.Platform; import net.momirealms.craftengine.core.plugin.context.*; import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; @@ -11,19 +10,14 @@ import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelector; import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectors; import net.momirealms.craftengine.core.plugin.context.text.TextProvider; import net.momirealms.craftengine.core.plugin.context.text.TextProviders; -import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.ResourceConfigUtils; -import net.momirealms.craftengine.core.world.Vec3d; import net.momirealms.craftengine.core.world.WorldPosition; import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Text; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.Consumer; public class TeleportFunction extends AbstractConditionalFunction { private final PlayerSelector selector; @@ -47,22 +41,21 @@ public class TeleportFunction extends AbstractConditionalFu this.yaw = yaw; } + @SuppressWarnings("DuplicatedCode") @Override public void runInternal(CTX ctx) { if (this.selector == null) { - ctx.getOptionalParameter(DirectContextParameters.PLAYER).ifPresent(it -> { - it.teleport(new WorldPosition( - Optional.ofNullable(this.world).map(w -> w.get(ctx)).map(w -> CraftEngine.instance().platform().getWorld(w)).orElse(it.world()), - this.x.getDouble(ctx), - this.y.getDouble(ctx), - this.z.getDouble(ctx), - this.pitch.getFloat(ctx), - this.yaw.getFloat(ctx)) - ); - }); + ctx.getOptionalParameter(DirectContextParameters.PLAYER).ifPresent(it -> it.teleport(new WorldPosition( + Optional.ofNullable(this.world).map(w -> w.get(ctx)).map(w -> CraftEngine.instance().platform().getWorld(w)).orElse(it.world()), + this.x.getDouble(ctx), + this.y.getDouble(ctx), + this.z.getDouble(ctx), + this.pitch.getFloat(ctx), + this.yaw.getFloat(ctx)) + )); } else { for (Player viewer : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer)); viewer.teleport(new WorldPosition( Optional.ofNullable(this.world).map(w -> w.get(relationalContext)).map(w -> CraftEngine.instance().platform().getWorld(w)).orElse(viewer.world()), this.x.getDouble(relationalContext), diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TitleFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TitleFunction.java index 43eb8d195..cbae62005 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TitleFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TitleFunction.java @@ -45,7 +45,7 @@ public class TitleFunction extends AbstractConditionalFunct )); } else { for (Player viewer : this.selector.get(ctx)) { - RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY)); + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer)); viewer.sendTitle( AdventureHelper.miniMessage().deserialize(this.main.get(relationalContext), relationalContext.tagResolvers()), AdventureHelper.miniMessage().deserialize(this.sub.get(relationalContext), relationalContext.tagResolvers()), diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ToastFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ToastFunction.java new file mode 100644 index 000000000..eadb1609e --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ToastFunction.java @@ -0,0 +1,87 @@ +package net.momirealms.craftengine.core.plugin.context.function; + +import net.momirealms.craftengine.core.advancement.AdvancementType; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemKeys; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.context.*; +import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelector; +import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectors; +import net.momirealms.craftengine.core.plugin.context.text.TextProvider; +import net.momirealms.craftengine.core.plugin.context.text.TextProviders; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.util.AdventureHelper; +import net.momirealms.craftengine.core.util.EnumUtils; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +public class ToastFunction extends AbstractConditionalFunction { + private final PlayerSelector selector; + private final TextProvider toast; + private final java.util.function.Function> icon; + private final AdvancementType advancementType; + + public ToastFunction(List> predicates, + @Nullable PlayerSelector selector, + TextProvider toast, + java.util.function.Function> icon, + AdvancementType advancementType) { + super(predicates); + this.selector = selector; + this.toast = toast; + this.icon = icon; + this.advancementType = advancementType; + } + + @Override + public void runInternal(CTX ctx) { + if (this.selector == null) { + ctx.getOptionalParameter(DirectContextParameters.PLAYER).ifPresent(it -> it.sendToast(AdventureHelper.miniMessage().deserialize(this.toast.get(ctx), ctx.tagResolvers()), this.icon.apply(it), this.advancementType)); + } else { + for (Player viewer : this.selector.get(ctx)) { + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer)); + viewer.sendToast(AdventureHelper.miniMessage().deserialize(this.toast.get(relationalContext), relationalContext.tagResolvers()), this.icon.apply(viewer), this.advancementType); + } + } + } + + @Override + public Key type() { + return CommonFunctions.TOAST; + } + + public static class FactoryImpl extends AbstractFactory { + + public FactoryImpl(java.util.function.Function, Condition> factory) { + super(factory); + } + + @Override + public Function create(Map arguments) { + AdvancementType advancementType; + String advancementName = arguments.getOrDefault("advancement-type", "goal").toString(); + try { + advancementType = AdvancementType.valueOf(advancementName.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + throw new LocalizedResourceConfigException("warning.config.function.toast.invalid_advancement_type", advancementName, EnumUtils.toString(AdvancementType.values())); + } + String toast = ResourceConfigUtils.requireNonEmptyStringOrThrow(ResourceConfigUtils.get(arguments, "toast", "message"), "warning.config.function.toast.missing_toast"); + Key item = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(ResourceConfigUtils.get(arguments, "item", "icon"), "warning.config.function.toast.missing_icon")); + return new ToastFunction<>( + getPredicates(arguments), + PlayerSelectors.fromObject(arguments.get("target"), conditionFactory()), + TextProviders.fromString(toast), + player -> CraftEngine.instance().itemManager().createWrappedItem(item, player), + advancementType + ); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java index 5556a9d6c..b4f530ae8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java @@ -161,8 +161,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { this.plugin.logger().warn("Can't not find item " + it.icon() + " for category icon"); return null; } - item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(it.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); - item.loreJson(it.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); + item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(it.displayName(), ItemBuildContext.EMPTY_RESOLVERS))); + item.loreJson(it.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY_RESOLVERS))).toList()); return new ItemWithAction(item, (element, click) -> { click.cancel(); player.playSound(Constants.SOUND_CLICK_BUTTON); @@ -245,12 +245,12 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (ItemUtils.isEmpty(item)) { if (!subCategory.icon().equals(ItemKeys.AIR)) { item = this.plugin.itemManager().createWrappedItem(ItemKeys.BARRIER, player); - item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); - item.loreJson(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); + item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY_RESOLVERS))); + item.loreJson(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY_RESOLVERS))).toList()); } } else { - item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); - item.loreJson(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); + item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY_RESOLVERS))); + item.loreJson(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY_RESOLVERS))).toList()); } return new ItemWithAction(item, (element, click) -> { click.cancel(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java index fa7b61ce5..703571af4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java @@ -111,6 +111,22 @@ public class ReflectionUtils { return null; } + @Nullable + public static Field getStaticDeclaredField(final Class clazz, final Class type, final int index) { + int i = 0; + for (final Field field : clazz.getDeclaredFields()) { + if (field.getType() == type) { + if (Modifier.isStatic(field.getModifiers())) { + if (index == i) { + return setAccessible(field); + } + i++; + } + } + } + return null; + } + @Nullable public static Field getDeclaredField(final Class clazz, final Class type, int index) { int i = 0; diff --git a/gradle.properties b/gradle.properties index 63049c23f..b366a9595 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.62.17 +project_version=0.0.62.18 config_version=45 -lang_version=26 +lang_version=27 project_group=net.momirealms latest_supported_version=1.21.8