diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index f20cdcca1..3cefc336a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -28,7 +28,6 @@ import net.momirealms.craftengine.core.world.Vec3d; import net.momirealms.craftengine.core.world.WorldPosition; import org.bukkit.*; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -371,19 +370,18 @@ public class BlockEventListener implements Listener { // for vanilla blocks if (event.getChangedType() == Material.NOTE_BLOCK) { Block block = event.getBlock(); - World world = block.getWorld(); - Location location = block.getLocation(); Block sourceBlock = event.getSourceBlock(); - BlockFace direction = sourceBlock.getFace(block); - if (direction == BlockFace.UP || direction == BlockFace.DOWN) { + if (block.getX() == sourceBlock.getX() && block.getX() == sourceBlock.getZ()) { + World world = block.getWorld(); + Location location = block.getLocation(); Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world); Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); Object blockPos = LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); - if (direction == BlockFace.UP) { - NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, 0); + if (block.getY() > sourceBlock.getY()) { + NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, Config.maxNoteBlockChainUpdate()); } else { - NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, 0); + NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, Config.maxNoteBlockChainUpdate()); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java index 93469a576..b2da03528 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java @@ -129,13 +129,12 @@ public class BukkitCustomBlock extends AbstractCustomBlock { // init cache CoreReflections.method$BlockStateBase$initCache.invoke(mcBlockState); // set block light - if (settings.blockLight() != -1) { - if (VersionHelper.isOrAbove1_21_2()) { - CoreReflections.field$BlockStateBase$lightBlock.set(mcBlockState, settings.blockLight()); - } else { - Object cache = CoreReflections.field$BlockStateBase$cache.get(mcBlockState); - CoreReflections.field$BlockStateBase$Cache$lightBlock.set(cache, settings.blockLight()); - } + int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(state.vanillaBlockState().handle()); + if (VersionHelper.isOrAbove1_21_2()) { + CoreReflections.field$BlockStateBase$lightBlock.set(mcBlockState, blockLight); + } else { + Object cache = CoreReflections.field$BlockStateBase$cache.get(mcBlockState); + CoreReflections.field$BlockStateBase$Cache$lightBlock.set(cache, blockLight); } // set fluid later if (settings.fluidState()) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureElement.java index 6b5c0097b..55f574ac7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureElement.java @@ -49,7 +49,7 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement { Vector3f offset = conjugated.transform(new Vector3f(position())); packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityId, UUID.randomUUID(), position.x() + offset.x, position.y() + offset.y, position.z() - offset.z, 0, position.xRot(), - MEntityTypes.instance$EntityType$ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 )); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, getCachedValues(dyedColor))); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index f4ed4f698..8df61266c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -40,7 +40,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { public static final NamespacedKey FURNITURE_SEAT_VECTOR_3F_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_SEAT_VECTOR_3F_KEY); public static final NamespacedKey FURNITURE_COLLISION = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_COLLISION); public static Class COLLISION_ENTITY_CLASS = Interaction.class; - public static Object NMS_COLLISION_ENTITY_TYPE = MEntityTypes.instance$EntityType$INTERACTION; + public static Object NMS_COLLISION_ENTITY_TYPE = MEntityTypes.INTERACTION; public static ColliderType COLLISION_ENTITY_TYPE = ColliderType.INTERACTION; private static BukkitFurnitureManager instance; private final BukkitCraftEngine plugin; @@ -93,7 +93,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { @Override public void delayedInit() { COLLISION_ENTITY_CLASS = Config.colliderType() == ColliderType.INTERACTION ? Interaction.class : Boat.class; - NMS_COLLISION_ENTITY_TYPE = Config.colliderType() == ColliderType.INTERACTION ? MEntityTypes.instance$EntityType$INTERACTION : MEntityTypes.instance$EntityType$OAK_BOAT; + NMS_COLLISION_ENTITY_TYPE = Config.colliderType() == ColliderType.INTERACTION ? MEntityTypes.INTERACTION : MEntityTypes.OAK_BOAT; COLLISION_ENTITY_TYPE = Config.colliderType(); Bukkit.getPluginManager().registerEvents(this.dismountListener, this.plugin.javaPlugin()); Bukkit.getPluginManager().registerEvents(this.furnitureEventListener, this.plugin.javaPlugin()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java index 9cb6ab155..1ab038efe 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java @@ -62,7 +62,7 @@ public class InteractionHitBox extends AbstractHitBox { float yaw = position.xRot(); packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityId[0], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw, - MEntityTypes.instance$EntityType$INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 ), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId[0], List.copyOf(this.cachedValues)), true); if (canUseItemOn()) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java index 18928102a..fdf1db0c3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java @@ -61,7 +61,7 @@ public class ShulkerHitBox extends AbstractHitBox { if (interactionEntity) { packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f, z - offset.z, 0, yaw, - MEntityTypes.instance$EntityType$INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 ), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true); if (canUseOn) { @@ -80,7 +80,7 @@ public class ShulkerHitBox extends AbstractHitBox { if (interactionEntity) { packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f - shulkerHeight + scale, z - offset.z, 0, yaw, - MEntityTypes.instance$EntityType$INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 ), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true); if (canUseOn) { @@ -102,14 +102,14 @@ public class ShulkerHitBox extends AbstractHitBox { // first interaction packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f, z - offset.z, 0, yaw, - MEntityTypes.instance$EntityType$INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 ), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true); // second interaction double distance = shulkerHeight - scale; packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityIds[3], UUID.randomUUID(), x + offset.x + shulkerDirection.stepX() * distance, y + offset.y - 0.005f, z - offset.z + shulkerDirection.stepZ() * distance, 0, yaw, - MEntityTypes.instance$EntityType$INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 ), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[3], List.copyOf(cachedInteractionValues)), true); if (canUseOn) { @@ -213,11 +213,11 @@ public class ShulkerHitBox extends AbstractHitBox { double processedY = (fractionalPart >= 0.5) ? integerPart + 1 : originalY; packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityIds[0], UUID.randomUUID(), x + offset.x, originalY, z - offset.z, 0, yaw, - MEntityTypes.instance$EntityType$ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 ), false); packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityIds[1], UUID.randomUUID(), x + offset.x, processedY, z - offset.z, 0, yaw, - MEntityTypes.instance$EntityType$SHULKER, 0, CoreReflections.instance$Vec3$Zero, 0 + MEntityTypes.SHULKER, 0, CoreReflections.instance$Vec3$Zero, 0 ), false); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[1], List.copyOf(this.cachedShulkerValues)), false); // add passengers diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java index 91dc42d40..f8081572b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java @@ -10,7 +10,6 @@ public class BukkitItemBehaviors extends ItemBehaviors { public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item"); public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item"); public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item"); - public static final Key HAT_ITEM = Key.from("craftengine:hat_item"); public static void init() { register(EMPTY, EmptyItemBehavior.FACTORY); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java index f840d2cb7..ebb1e5c30 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java @@ -4,10 +4,10 @@ import com.google.gson.JsonElement; import com.saicone.rtag.item.ItemTagStream; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.util.ItemTags; -import net.momirealms.craftengine.core.item.EquipmentData; import net.momirealms.craftengine.core.item.ItemFactory; import net.momirealms.craftengine.core.item.ItemWrapper; import net.momirealms.craftengine.core.item.JukeboxPlayable; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Key; import net.momirealms.sparrow.nbt.Tag; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java index 13f9be33f..b5e17b8fd 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java @@ -2,7 +2,7 @@ package net.momirealms.craftengine.bukkit.item.factory; import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.item.ComponentTypes; -import net.momirealms.craftengine.core.item.EquipmentData; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.plugin.CraftEngine; import java.util.Optional; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index e67c1239c..21436d077 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -318,16 +318,15 @@ public class ItemEventListener implements Listener { if (optionalCustomItem.isEmpty()) { return; } - Cancellable dummy = Cancellable.dummy(); + Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled); CustomItem customItem = optionalCustomItem.get(); PlayerOptionalContext context = PlayerOptionalContext.of(this.plugin.adapt(event.getPlayer()), ContextHolder.builder() .withParameter(DirectContextParameters.ITEM_IN_HAND, wrapped) - .withParameter(DirectContextParameters.EVENT, dummy) + .withParameter(DirectContextParameters.EVENT, cancellable) .withParameter(DirectContextParameters.HAND, event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND) ); customItem.execute(context, EventTrigger.CONSUME); - if (dummy.isCancelled()) { - event.setCancelled(true); + if (event.isCancelled()) { return; } } 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 91a6938b7..b1ab779fc 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 @@ -20,6 +20,7 @@ import net.momirealms.craftengine.core.item.recipe.Recipe; import net.momirealms.craftengine.core.item.recipe.input.CraftingInput; import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput; import net.momirealms.craftengine.core.item.recipe.input.SmithingInput; +import net.momirealms.craftengine.core.item.setting.AnvilRepairItem; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.registry.BuiltInRegistries; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java index ffe67dcb5..0b349fca0 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java @@ -19,6 +19,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; import net.momirealms.craftengine.bukkit.util.NoteBlockChainUpdateUtils; import net.momirealms.craftengine.core.block.*; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ObjectHolder; import net.momirealms.craftengine.core.util.VersionHelper; @@ -36,6 +37,7 @@ public final class BlockGenerator { private static Field field$CraftEngineBlock$behavior; private static Field field$CraftEngineBlock$shape; private static Field field$CraftEngineBlock$isNoteBlock; + private static Field field$CraftEngineBlock$isTripwire; public static void init() throws ReflectiveOperationException { ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17); @@ -48,6 +50,7 @@ public final class BlockGenerator { .defineField("behaviorHolder", ObjectHolder.class, Visibility.PUBLIC) .defineField("shapeHolder", ObjectHolder.class, Visibility.PUBLIC) .defineField("isClientSideNoteBlock", boolean.class, Visibility.PUBLIC) + .defineField("isClientSideTripwire", boolean.class, Visibility.PUBLIC) // should always implement this interface .implement(CoreReflections.clazz$Fallable) .implement(CoreReflections.clazz$BonemealableBlock) @@ -55,13 +58,15 @@ public final class BlockGenerator { // internal interfaces .implement(BehaviorHolder.class) .implement(ShapeHolder.class) - .implement(NoteBlockIndicator.class) + .implement(ChainUpdateBlockIndicator.class) .method(ElementMatchers.named("getBehaviorHolder")) .intercept(FieldAccessor.ofField("behaviorHolder")) .method(ElementMatchers.named("getShapeHolder")) .intercept(FieldAccessor.ofField("shapeHolder")) .method(ElementMatchers.named("isNoteBlock")) .intercept(FieldAccessor.ofField("isClientSideNoteBlock")) + .method(ElementMatchers.named("isTripwire")) + .intercept(FieldAccessor.ofField("isClientSideTripwire")) // getShape .method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$getShape)) .intercept(MethodDelegation.to(GetShapeInterceptor.INSTANCE)) @@ -142,6 +147,7 @@ public final class BlockGenerator { field$CraftEngineBlock$behavior = clazz$CraftEngineBlock.getField("behaviorHolder"); field$CraftEngineBlock$shape = clazz$CraftEngineBlock.getField("shapeHolder"); field$CraftEngineBlock$isNoteBlock = clazz$CraftEngineBlock.getField("isClientSideNoteBlock"); + field$CraftEngineBlock$isTripwire = clazz$CraftEngineBlock.getField("isClientSideTripwire"); } public static Object generateBlock(Key replacedBlock, Object ownerBlock, Object properties) throws Throwable { @@ -155,18 +161,24 @@ public final class BlockGenerator { field$CraftEngineBlock$behavior.set(newBlockInstance, behaviorHolder); field$CraftEngineBlock$shape.set(newBlockInstance, shapeHolder); field$CraftEngineBlock$isNoteBlock.set(newBlockInstance, replacedBlock.equals(BlockKeys.NOTE_BLOCK)); + field$CraftEngineBlock$isTripwire.set(newBlockInstance, replacedBlock.equals(BlockKeys.TRIPWIRE)); return newBlockInstance; } public static class UpdateShapeInterceptor { public static final UpdateShapeInterceptor INSTANCE = new UpdateShapeInterceptor(); public static final int levelIndex = VersionHelper.isOrAbove1_21_2() ? 1 : 3; + public static final int directionIndex = VersionHelper.isOrAbove1_21_2() ? 4 : 1; + public static final int posIndex = VersionHelper.isOrAbove1_21_2() ? 3 : 4; @RuntimeType - public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) throws Exception { + public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) { ObjectHolder holder = ((BehaviorHolder) thisObj).getBehaviorHolder(); - if (((NoteBlockIndicator) thisObj).isNoteBlock() && CoreReflections.clazz$ServerLevel.isInstance(args[levelIndex])) { - startNoteBlockChain(args); + ChainUpdateBlockIndicator indicator = (ChainUpdateBlockIndicator) thisObj; + if (indicator.isNoteBlock()) { + if (CoreReflections.clazz$ServerLevel.isInstance(args[levelIndex])) { + startNoteBlockChain(args); + } } try { return holder.value().updateShape(thisObj, args, superMethod); @@ -175,30 +187,20 @@ public final class BlockGenerator { return args[0]; } } - } - private static void startNoteBlockChain(Object[] args) throws ReflectiveOperationException { - Object direction; - Object serverLevel; - Object blockPos; - if (VersionHelper.isOrAbove1_21_2()) { - direction = args[4]; - serverLevel = args[1]; - blockPos = args[3]; - } else { - direction = args[1]; - serverLevel = args[3]; - blockPos = args[4]; - } - int id = (int) CoreReflections.field$Direction$data3d.get(direction); - // Y axis - if (id == 0 || id == 1) { - Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); - FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); - if (id == 1) { - NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, 0); - } else { - NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, 0); + private static void startNoteBlockChain(Object[] args) { + Object direction = args[directionIndex]; + Object serverLevel = args[levelIndex]; + Object blockPos = args[posIndex]; + // Y axis + if (direction == CoreReflections.instance$Direction$DOWN) { + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); + FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); + NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, Config.maxNoteBlockChainUpdate()); + } else if (direction == CoreReflections.instance$Direction$UP) { + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); + FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); + NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, Config.maxNoteBlockChainUpdate()); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java index 02a99e042..285d026c8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java @@ -17,6 +17,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; +import net.momirealms.craftengine.core.block.BlockStateWrapper; import net.momirealms.craftengine.core.block.EmptyBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.plugin.CraftEngine; @@ -220,23 +221,36 @@ public class WorldStorageInjector { CESection section = holder.ceSection(); // 如果是原版方块 if (BlockStateUtils.isVanillaBlock(stateId)) { - // 那么应该情况自定义块 + // 那么应该清空自定义块 ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE); - // 如果先前不是空气则标记 + // 处理 自定义块 -> 原版块 if (!previous.isEmpty()) { holder.ceChunk().setDirty(true); if (Config.enableLightSystem()) { - updateLightIfChanged(holder, previousState, newState, newState, x, y, z); + // 自定义块到原版块,只需要判断旧块是否和客户端一直 + BlockStateWrapper wrapper = previous.vanillaBlockState(); + if (wrapper != null) { + updateLight(holder, wrapper.handle(), previousState, x, y, z); + } } } } else { ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState); if (previousImmutableBlockState == immutableBlockState) return; + // 处理 自定义块到自定义块或原版块到自定义块 holder.ceChunk().setDirty(true); + // 不可能!绝对不可能! + if (immutableBlockState.isEmpty()) return; // 如果新方块的光照属性和客户端认为的不同 - if (Config.enableLightSystem() && !immutableBlockState.isEmpty()) { - updateLightIfChanged(holder, previousState, immutableBlockState.vanillaBlockState().handle(), newState, x, y, z); + if (Config.enableLightSystem()) { + if (previousImmutableBlockState.isEmpty()) { + // 原版块到自定义块,只需要判断新块是否和客户端视觉一致 + updateLight(holder, immutableBlockState.vanillaBlockState().handle(), newState, x, y, z); + } else { + // 自定义块到自定义块 + updateLight$complex(holder, immutableBlockState.vanillaBlockState().handle(), newState, previousState, x, y, z); + } } } } catch (Exception e) { @@ -244,17 +258,31 @@ public class WorldStorageInjector { } } - protected static void updateLightIfChanged(@This InjectedHolder thisObj, Object oldServerSideState, Object clientSideState, Object serverSideState, int x, int y, int z) { + @SuppressWarnings("DuplicatedCode") + protected static void updateLight(@This InjectedHolder thisObj, Object clientState, Object serverState, int x, int y, int z) { CEWorld world = thisObj.ceChunk().world(); Object blockPos = LocationUtils.toBlockPos(x, y, z); Object serverWorld = world.world().serverWorld(); - if (clientSideState != serverSideState && FastNMS.INSTANCE.method$LightEngine$hasDifferentLightProperties(clientSideState, serverSideState, serverWorld, blockPos)) { + if (FastNMS.INSTANCE.method$LightEngine$hasDifferentLightProperties(serverState, clientState, serverWorld, blockPos)) { + SectionPos sectionPos = thisObj.cePos(); + List pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15); + world.sectionLightUpdated(pos); + } + } + + @SuppressWarnings("DuplicatedCode") + protected static void updateLight$complex(@This InjectedHolder thisObj, Object newClientState, Object newServerState, Object oldServerState, int x, int y, int z) { + CEWorld world = thisObj.ceChunk().world(); + Object blockPos = LocationUtils.toBlockPos(x, y, z); + Object serverWorld = world.world().serverWorld(); + // 如果客户端新状态和服务端新状态光照属性不同 + if (FastNMS.INSTANCE.method$LightEngine$hasDifferentLightProperties(newClientState, newServerState, serverWorld, blockPos)) { SectionPos sectionPos = thisObj.cePos(); List pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15); world.sectionLightUpdated(pos); return; } - if (FastNMS.INSTANCE.method$LightEngine$hasDifferentLightProperties(oldServerSideState, serverSideState, serverWorld, blockPos)) { + if (FastNMS.INSTANCE.method$LightEngine$hasDifferentLightProperties(newServerState, oldServerState, serverWorld, blockPos)) { SectionPos sectionPos = thisObj.cePos(); List pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15); world.sectionLightUpdated(pos); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index a34aa1c44..3d9758014 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -84,7 +84,7 @@ public class PacketConsumers { public static void initEntities(int registrySize) { ADD_ENTITY_HANDLERS = new BukkitNetworkManager.Handlers[registrySize]; Arrays.fill(ADD_ENTITY_HANDLERS, BukkitNetworkManager.Handlers.DO_NOTHING); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$FALLING_BLOCK$registryId] = (user, event) -> { + ADD_ENTITY_HANDLERS[MEntityTypes.FALLING_BLOCK$registryId] = (user, event) -> { FriendlyByteBuf buf = event.getBuffer(); int id = buf.readVarInt(); UUID uuid = buf.readUUID(); @@ -121,28 +121,28 @@ public class PacketConsumers { } }; - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$BLOCK_DISPLAY$registryId] = simpleAddEntityHandler(BlockDisplayPacketHandler.INSTANCE); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$TEXT_DISPLAY$registryId] = simpleAddEntityHandler(TextDisplayPacketHandler.INSTANCE); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ARMOR_STAND$registryId] = simpleAddEntityHandler(ArmorStandPacketHandler.INSTANCE); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ITEM_DISPLAY$registryId] = simpleAddEntityHandler(ItemDisplayPacketHandler.INSTANCE); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ITEM$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$GLOW_ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$EYE_OF_ENDER$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$FIREWORK_ROCKET$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$SMALL_FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$EGG$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ENDER_PEARL$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$EXPERIENCE_BOTTLE$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$SNOWBALL$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$POTION$registryId] = createOptionalCustomProjectileEntityHandler(); - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$TRIDENT$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.BLOCK_DISPLAY$registryId] = simpleAddEntityHandler(BlockDisplayPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.TEXT_DISPLAY$registryId] = simpleAddEntityHandler(TextDisplayPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.ARMOR_STAND$registryId] = simpleAddEntityHandler(ArmorStandPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.ITEM_DISPLAY$registryId] = simpleAddEntityHandler(ItemDisplayPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.ITEM$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.GLOW_ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.EYE_OF_ENDER$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.FIREWORK_ROCKET$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.SMALL_FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.EGG$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.ENDER_PEARL$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.EXPERIENCE_BOTTLE$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.SNOWBALL$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.POTION$registryId] = createOptionalCustomProjectileEntityHandler(); + ADD_ENTITY_HANDLERS[MEntityTypes.TRIDENT$registryId] = createOptionalCustomProjectileEntityHandler(); if (VersionHelper.isOrAbove1_20_5()) { - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$OMINOUS_ITEM_SPAWNER$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[MEntityTypes.OMINOUS_ITEM_SPAWNER$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); } - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ITEM_DISPLAY$registryId] = (user, event) -> { + ADD_ENTITY_HANDLERS[MEntityTypes.ITEM_DISPLAY$registryId] = (user, event) -> { FriendlyByteBuf buf = event.getBuffer(); int id = buf.readVarInt(); BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id); @@ -154,8 +154,8 @@ public class PacketConsumers { } } }; - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$INTERACTION$registryId] = (user, event) -> { - if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.instance$EntityType$INTERACTION) return; + ADD_ENTITY_HANDLERS[MEntityTypes.INTERACTION$registryId] = (user, event) -> { + if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.INTERACTION) return; FriendlyByteBuf buf = event.getBuffer(); int id = buf.readVarInt(); // Cancel collider entity packet @@ -164,8 +164,8 @@ public class PacketConsumers { event.setCancelled(true); } }; - ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$OAK_BOAT$registryId] = (user, event) -> { - if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.instance$EntityType$OAK_BOAT) return; + ADD_ENTITY_HANDLERS[MEntityTypes.OAK_BOAT$registryId] = (user, event) -> { + if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.OAK_BOAT) return; FriendlyByteBuf buf = event.getBuffer(); int id = buf.readVarInt(); // Cancel collider entity packet @@ -2295,5 +2295,4 @@ public class PacketConsumers { CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e); } }; - } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java index 00d588a66..41679b5a6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java @@ -52,6 +52,8 @@ public interface PacketIds { int clientboundSetPlayerInventoryPacket(); + int clientboundBlockEventPacket(); + int serverboundContainerClickPacket(); int serverboundSetCreativeModeSlotPacket(); 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 c936562f8..3d671ff0a 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 @@ -81,7 +81,7 @@ public class ProjectilePacketHandler implements EntityPacketHandler { buf.writeVarInt(event.packetID()); buf.writeVarInt(this.entityId); buf.writeUUID(uuid); - buf.writeVarInt(MEntityTypes.instance$EntityType$ITEM_DISPLAY$registryId); + buf.writeVarInt(MEntityTypes.ITEM_DISPLAY$registryId); buf.writeDouble(x); buf.writeDouble(y); buf.writeDouble(z); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java index 97271778a..c106da9f2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java @@ -139,4 +139,9 @@ public class PacketIds1_20 implements PacketIds { public int serverboundSetCreativeModeSlotPacket() { return PacketIdFinder.serverboundByClazz(NetworkReflections.clazz$ServerboundSetCreativeModeSlotPacket); } + + @Override + public int clientboundBlockEventPacket() { + return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundBlockEventPacket); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java index bb29be78b..afefc4407 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java @@ -129,6 +129,11 @@ public class PacketIds1_20_5 implements PacketIds { return PacketIdFinder.clientboundByName("minecraft:set_player_inventory"); } + @Override + public int clientboundBlockEventPacket() { + return PacketIdFinder.clientboundByName("minecraft:block_event"); + } + @Override public int serverboundContainerClickPacket() { return PacketIdFinder.serverboundByName("minecraft:container_click"); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java index 6687be290..615e57d14 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java @@ -16,6 +16,7 @@ public final class MBlocks { public static final Object ICE; public static final Object SHORT_GRASS; public static final Object SHORT_GRASS$defaultState; + public static final Object SHULKER_BOX; private static Object getById(String id) throws ReflectiveOperationException { Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); @@ -33,6 +34,7 @@ public final class MBlocks { ICE = getById("ice"); SHORT_GRASS = getById(VersionHelper.isOrAbove1_20_3() ? "short_grass" : "grass"); SHORT_GRASS$defaultState = CoreReflections.method$Block$defaultBlockState.invoke(SHORT_GRASS); + SHULKER_BOX = getById("shulker_box"); } catch (ReflectiveOperationException e) { throw new ReflectionInitException("Failed to init Blocks", e); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntityTypes.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntityTypes.java index ba09983a0..d28c6581b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntityTypes.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntityTypes.java @@ -7,50 +7,50 @@ import net.momirealms.craftengine.core.util.VersionHelper; public final class MEntityTypes { private MEntityTypes() {} - public static final Object instance$EntityType$TEXT_DISPLAY; - public static final int instance$EntityType$TEXT_DISPLAY$registryId; - public static final Object instance$EntityType$ITEM_DISPLAY; - public static final int instance$EntityType$ITEM_DISPLAY$registryId; - public static final Object instance$EntityType$BLOCK_DISPLAY; - public static final int instance$EntityType$BLOCK_DISPLAY$registryId; - public static final Object instance$EntityType$ARMOR_STAND; - public static final int instance$EntityType$ARMOR_STAND$registryId; - public static final Object instance$EntityType$FALLING_BLOCK; - public static final int instance$EntityType$FALLING_BLOCK$registryId; - public static final Object instance$EntityType$INTERACTION; - public static final int instance$EntityType$INTERACTION$registryId; - public static final Object instance$EntityType$SHULKER; - public static final int instance$EntityType$SHULKER$registryId; - public static final Object instance$EntityType$OAK_BOAT; - public static final int instance$EntityType$OAK_BOAT$registryId; - public static final Object instance$EntityType$TRIDENT; - public static final int instance$EntityType$TRIDENT$registryId; - public static final Object instance$EntityType$SNOWBALL; - public static final int instance$EntityType$SNOWBALL$registryId; - public static final Object instance$EntityType$FIREBALL; - public static final int instance$EntityType$FIREBALL$registryId; - public static final Object instance$EntityType$EYE_OF_ENDER; - public static final int instance$EntityType$EYE_OF_ENDER$registryId; - public static final Object instance$EntityType$FIREWORK_ROCKET; - public static final int instance$EntityType$FIREWORK_ROCKET$registryId; - public static final Object instance$EntityType$ITEM; - public static final int instance$EntityType$ITEM$registryId; - public static final Object instance$EntityType$ITEM_FRAME; - public static final int instance$EntityType$ITEM_FRAME$registryId; - public static final Object instance$EntityType$GLOW_ITEM_FRAME; - public static final int instance$EntityType$GLOW_ITEM_FRAME$registryId; - public static final Object instance$EntityType$OMINOUS_ITEM_SPAWNER; - public static final int instance$EntityType$OMINOUS_ITEM_SPAWNER$registryId; - public static final Object instance$EntityType$SMALL_FIREBALL; - public static final int instance$EntityType$SMALL_FIREBALL$registryId; - public static final Object instance$EntityType$EGG; - public static final int instance$EntityType$EGG$registryId; - public static final Object instance$EntityType$ENDER_PEARL; - public static final int instance$EntityType$ENDER_PEARL$registryId; - public static final Object instance$EntityType$EXPERIENCE_BOTTLE; - public static final int instance$EntityType$EXPERIENCE_BOTTLE$registryId; - public static final Object instance$EntityType$POTION; - public static final int instance$EntityType$POTION$registryId; + public static final Object TEXT_DISPLAY; + public static final int TEXT_DISPLAY$registryId; + public static final Object ITEM_DISPLAY; + public static final int ITEM_DISPLAY$registryId; + public static final Object BLOCK_DISPLAY; + public static final int BLOCK_DISPLAY$registryId; + public static final Object ARMOR_STAND; + public static final int ARMOR_STAND$registryId; + public static final Object FALLING_BLOCK; + public static final int FALLING_BLOCK$registryId; + public static final Object INTERACTION; + public static final int INTERACTION$registryId; + public static final Object SHULKER; + public static final int SHULKER$registryId; + public static final Object OAK_BOAT; + public static final int OAK_BOAT$registryId; + public static final Object TRIDENT; + public static final int TRIDENT$registryId; + public static final Object SNOWBALL; + public static final int SNOWBALL$registryId; + public static final Object FIREBALL; + public static final int FIREBALL$registryId; + public static final Object EYE_OF_ENDER; + public static final int EYE_OF_ENDER$registryId; + public static final Object FIREWORK_ROCKET; + public static final int FIREWORK_ROCKET$registryId; + public static final Object ITEM; + public static final int ITEM$registryId; + public static final Object ITEM_FRAME; + public static final int ITEM_FRAME$registryId; + public static final Object GLOW_ITEM_FRAME; + public static final int GLOW_ITEM_FRAME$registryId; + public static final Object OMINOUS_ITEM_SPAWNER; + public static final int OMINOUS_ITEM_SPAWNER$registryId; + public static final Object SMALL_FIREBALL; + public static final int SMALL_FIREBALL$registryId; + public static final Object EGG; + public static final int EGG$registryId; + public static final Object ENDER_PEARL; + public static final int ENDER_PEARL$registryId; + public static final Object EXPERIENCE_BOTTLE; + public static final int EXPERIENCE_BOTTLE$registryId; + public static final Object POTION; + public static final int POTION$registryId; private static Object getById(String id) throws ReflectiveOperationException { Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); @@ -64,50 +64,50 @@ public final class MEntityTypes { static { try { - instance$EntityType$TEXT_DISPLAY = getById("text_display"); - instance$EntityType$TEXT_DISPLAY$registryId = getRegistryId(instance$EntityType$TEXT_DISPLAY); - instance$EntityType$ITEM_DISPLAY = getById("item_display"); - instance$EntityType$ITEM_DISPLAY$registryId = getRegistryId(instance$EntityType$ITEM_DISPLAY); - instance$EntityType$BLOCK_DISPLAY = getById("block_display"); - instance$EntityType$BLOCK_DISPLAY$registryId = getRegistryId(instance$EntityType$BLOCK_DISPLAY); - instance$EntityType$FALLING_BLOCK = getById("falling_block"); - instance$EntityType$FALLING_BLOCK$registryId = getRegistryId(instance$EntityType$FALLING_BLOCK); - instance$EntityType$INTERACTION = getById("interaction"); - instance$EntityType$INTERACTION$registryId = getRegistryId(instance$EntityType$INTERACTION); - instance$EntityType$SHULKER = getById("shulker"); - instance$EntityType$SHULKER$registryId = getRegistryId(instance$EntityType$SHULKER); - instance$EntityType$ARMOR_STAND = getById("armor_stand"); - instance$EntityType$ARMOR_STAND$registryId = getRegistryId(instance$EntityType$ARMOR_STAND); - instance$EntityType$OAK_BOAT = getById(VersionHelper.isOrAbove1_21_2() ? "oak_boat" : "boat"); - instance$EntityType$OAK_BOAT$registryId = getRegistryId(instance$EntityType$OAK_BOAT); - instance$EntityType$TRIDENT = getById("trident"); - instance$EntityType$TRIDENT$registryId = getRegistryId(instance$EntityType$TRIDENT); - instance$EntityType$SNOWBALL = getById("snowball"); - instance$EntityType$SNOWBALL$registryId = getRegistryId(instance$EntityType$SNOWBALL); - instance$EntityType$FIREBALL = getById("fireball"); - instance$EntityType$FIREBALL$registryId = getRegistryId(instance$EntityType$FIREBALL); - instance$EntityType$EYE_OF_ENDER = getById("eye_of_ender"); - instance$EntityType$EYE_OF_ENDER$registryId = getRegistryId(instance$EntityType$EYE_OF_ENDER); - instance$EntityType$FIREWORK_ROCKET = getById("firework_rocket"); - instance$EntityType$FIREWORK_ROCKET$registryId = getRegistryId(instance$EntityType$FIREWORK_ROCKET); - instance$EntityType$ITEM = getById("item"); - instance$EntityType$ITEM$registryId = getRegistryId(instance$EntityType$ITEM); - instance$EntityType$ITEM_FRAME = getById("item_frame"); - instance$EntityType$ITEM_FRAME$registryId = getRegistryId(instance$EntityType$ITEM_FRAME); - instance$EntityType$GLOW_ITEM_FRAME = getById("glow_item_frame"); - instance$EntityType$GLOW_ITEM_FRAME$registryId = getRegistryId(instance$EntityType$GLOW_ITEM_FRAME); - instance$EntityType$SMALL_FIREBALL = getById("small_fireball"); - instance$EntityType$SMALL_FIREBALL$registryId = getRegistryId(instance$EntityType$SMALL_FIREBALL); - instance$EntityType$EGG = getById("egg"); - instance$EntityType$EGG$registryId = getRegistryId(instance$EntityType$EGG); - instance$EntityType$ENDER_PEARL = getById("ender_pearl"); - instance$EntityType$ENDER_PEARL$registryId = getRegistryId(instance$EntityType$ENDER_PEARL); - instance$EntityType$EXPERIENCE_BOTTLE = getById("experience_bottle"); - instance$EntityType$EXPERIENCE_BOTTLE$registryId = getRegistryId(instance$EntityType$EXPERIENCE_BOTTLE); - instance$EntityType$POTION = getById("potion"); - instance$EntityType$POTION$registryId = getRegistryId(instance$EntityType$POTION); - instance$EntityType$OMINOUS_ITEM_SPAWNER = VersionHelper.isOrAbove1_20_5() ? getById("ominous_item_spawner") : null; - instance$EntityType$OMINOUS_ITEM_SPAWNER$registryId = getRegistryId(instance$EntityType$OMINOUS_ITEM_SPAWNER); + TEXT_DISPLAY = getById("text_display"); + TEXT_DISPLAY$registryId = getRegistryId(TEXT_DISPLAY); + ITEM_DISPLAY = getById("item_display"); + ITEM_DISPLAY$registryId = getRegistryId(ITEM_DISPLAY); + BLOCK_DISPLAY = getById("block_display"); + BLOCK_DISPLAY$registryId = getRegistryId(BLOCK_DISPLAY); + FALLING_BLOCK = getById("falling_block"); + FALLING_BLOCK$registryId = getRegistryId(FALLING_BLOCK); + INTERACTION = getById("interaction"); + INTERACTION$registryId = getRegistryId(INTERACTION); + SHULKER = getById("shulker"); + SHULKER$registryId = getRegistryId(SHULKER); + ARMOR_STAND = getById("armor_stand"); + ARMOR_STAND$registryId = getRegistryId(ARMOR_STAND); + OAK_BOAT = getById(VersionHelper.isOrAbove1_21_2() ? "oak_boat" : "boat"); + OAK_BOAT$registryId = getRegistryId(OAK_BOAT); + TRIDENT = getById("trident"); + TRIDENT$registryId = getRegistryId(TRIDENT); + SNOWBALL = getById("snowball"); + SNOWBALL$registryId = getRegistryId(SNOWBALL); + FIREBALL = getById("fireball"); + FIREBALL$registryId = getRegistryId(FIREBALL); + EYE_OF_ENDER = getById("eye_of_ender"); + EYE_OF_ENDER$registryId = getRegistryId(EYE_OF_ENDER); + FIREWORK_ROCKET = getById("firework_rocket"); + FIREWORK_ROCKET$registryId = getRegistryId(FIREWORK_ROCKET); + ITEM = getById("item"); + ITEM$registryId = getRegistryId(ITEM); + ITEM_FRAME = getById("item_frame"); + ITEM_FRAME$registryId = getRegistryId(ITEM_FRAME); + GLOW_ITEM_FRAME = getById("glow_item_frame"); + GLOW_ITEM_FRAME$registryId = getRegistryId(GLOW_ITEM_FRAME); + SMALL_FIREBALL = getById("small_fireball"); + SMALL_FIREBALL$registryId = getRegistryId(SMALL_FIREBALL); + EGG = getById("egg"); + EGG$registryId = getRegistryId(EGG); + ENDER_PEARL = getById("ender_pearl"); + ENDER_PEARL$registryId = getRegistryId(ENDER_PEARL); + EXPERIENCE_BOTTLE = getById("experience_bottle"); + EXPERIENCE_BOTTLE$registryId = getRegistryId(EXPERIENCE_BOTTLE); + POTION = getById("potion"); + POTION$registryId = getRegistryId(POTION); + OMINOUS_ITEM_SPAWNER = VersionHelper.isOrAbove1_20_5() ? getById("ominous_item_spawner") : null; + OMINOUS_ITEM_SPAWNER$registryId = getRegistryId(OMINOUS_ITEM_SPAWNER); } catch (ReflectiveOperationException e) { throw new ReflectionInitException("Failed to init EntityTypes", e); } 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 27ceab131..156a91c0a 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 @@ -1297,6 +1297,13 @@ public final class NetworkReflections { .map(it -> ReflectionUtils.getConstructor(it, float.class, boolean.class)) .orElse(null); + public static final Class clazz$ClientboundBlockEventPacket = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutBlockAction", + "network.protocol.game.ClientboundBlockEventPacket" + ) + ); + public static final MethodHandle handle$ServerboundRenameItemPacket$nameGetter; public static final MethodHandle handle$ServerboundRenameItemPacket$nameSetter; public static final MethodHandle handle$ServerboundHelloPacket$nameGetter; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java index 39d85f954..3cb195fa0 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java @@ -1,19 +1,19 @@ package net.momirealms.craftengine.bukkit.util; import net.momirealms.craftengine.bukkit.nms.FastNMS; -import net.momirealms.craftengine.core.plugin.config.Config; public class NoteBlockChainUpdateUtils { private NoteBlockChainUpdateUtils() {} + // TODO 都在一个区块内,应该优化到区块内的方块getter public static void noteBlockChainUpdate(Object level, Object chunkSource, Object direction, Object blockPos, int times) { - if (times >= Config.maxChainUpdate()) return; + if (times-- < 0) return; Object relativePos = FastNMS.INSTANCE.method$BlockPos$relative(blockPos, direction); Object state = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, relativePos); if (BlockStateUtils.isClientSideNoteBlock(state)) { FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, relativePos); - noteBlockChainUpdate(level, chunkSource, direction, relativePos, times+1); + noteBlockChainUpdate(level, chunkSource, direction, relativePos, times); } } } diff --git a/common-files/src/main/resources/config.yml b/common-files/src/main/resources/config.yml index b01304628..0291b026e 100644 --- a/common-files/src/main/resources/config.yml +++ b/common-files/src/main/resources/config.yml @@ -336,7 +336,7 @@ gui: performance: # Maximum chain update depth when fixing client visuals - max-block-chain-update-limit: 64 + max-note-block-chain-update-limit: 48 # Prevent lag or oversized packet when processing emoji-heavy content max-emojis-per-parse: 16 diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java index 4192b74c6..26e86bc98 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java @@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.util.Key; public class BlockKeys { public static final Key NOTE_BLOCK = Key.of("minecraft:note_block"); + public static final Key TRIPWIRE = Key.of("minecraft:tripwire"); public static final Key CRAFTING_TABLE = Key.of("minecraft:crafting_table"); public static final Key STONECUTTER = Key.of("minecraft:stonecutter"); public static final Key BELL = Key.of("minecraft:bell"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java index 72cb6de1c..1b273d9e2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java @@ -17,4 +17,8 @@ public class BlockRegistryMirror { public static int size() { return customBlockStates.length; } + + public static BlockStateWrapper stoneState() { + return stoneState; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/NoteBlockIndicator.java b/core/src/main/java/net/momirealms/craftengine/core/block/ChainUpdateBlockIndicator.java similarity index 52% rename from core/src/main/java/net/momirealms/craftengine/core/block/NoteBlockIndicator.java rename to core/src/main/java/net/momirealms/craftengine/core/block/ChainUpdateBlockIndicator.java index f78f10785..156028f94 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/NoteBlockIndicator.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/ChainUpdateBlockIndicator.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.block; -public interface NoteBlockIndicator { +public interface ChainUpdateBlockIndicator { boolean isNoteBlock(); + + boolean isTripwire(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java index 48e4b70af..6cd95e248 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.util.Key; import net.momirealms.sparrow.nbt.Tag; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java index 729fd56b8..3e413ffc0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.behavior.ItemBehaviors; import net.momirealms.craftengine.core.item.modifier.*; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.pack.ResourceLocation; @@ -491,6 +492,12 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl List data = MiscUtils.getAsStringList(obj); return new RemoveComponentModifier<>(data); }, "remove-components", "remove-component"); + registerDataFunction((obj) -> { + Map data = MiscUtils.castToMap(obj, false); + int nutrition = ResourceConfigUtils.getAsInt(data.get("nutrition"), "nutrition"); + float saturation = ResourceConfigUtils.getAsFloat(data.get("saturation"), "saturation"); + return new FoodModifier<>(nutrition, saturation, (boolean) data.getOrDefault("can-always-eat", false)); + }, "food"); } if (VersionHelper.isOrAbove1_21()) { registerDataFunction((obj) -> { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java index 813ac6486..40e402bff 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java @@ -26,4 +26,5 @@ public final class ComponentKeys { public static final Key PROFILE = Key.of("minecraft", "profile"); public static final Key DYED_COLOR = Key.of("minecraft", "dyed_color"); public static final Key DEATH_PROTECTION = Key.of("minecraft", "death_protection"); + public static final Key FOOD = Key.of("minecraft", "food"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java index 26f3f39e8..3943a7e5a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.util.Key; import net.momirealms.sparrow.nbt.Tag; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java index b27853e93..51384810d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.Key; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index a9f93ebb5..d8cae1654 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -3,7 +3,12 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.entity.ItemDisplayContext; import net.momirealms.craftengine.core.entity.projectile.ProjectileMeta; import net.momirealms.craftengine.core.item.modifier.EquippableModifier; +import net.momirealms.craftengine.core.item.modifier.FoodModifier; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; +import net.momirealms.craftengine.core.item.setting.AnvilRepairItem; +import net.momirealms.craftengine.core.item.setting.EquipmentData; +import net.momirealms.craftengine.core.item.setting.FoodData; +import net.momirealms.craftengine.core.item.setting.Helmet; import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.sound.SoundData; @@ -30,13 +35,18 @@ public class ItemSettings { ProjectileMeta projectileMeta; boolean dyeable = true; Helmet helmet = null; + FoodData foodData = null; private ItemSettings() {} public List> modifiers() { ArrayList> modifiers = new ArrayList<>(); - if (VersionHelper.isOrAbove1_21_2() && this.equipment != null && this.equipment.modernData() != null) modifiers.add(new EquippableModifier<>(this.equipment.modernData())); - // TODO 1.20 leather armor + if (VersionHelper.isOrAbove1_21_2() && this.equipment != null && this.equipment.modernData() != null) { + modifiers.add(new EquippableModifier<>(this.equipment.modernData())); + } + if (VersionHelper.isOrAbove1_20_5() && this.foodData != null) { + modifiers.add(new FoodModifier<>(this.foodData.nutrition(), this.foodData.saturation(), false)); + } return modifiers; } @@ -60,6 +70,8 @@ public class ItemSettings { newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock; newSettings.projectileMeta = settings.projectileMeta; newSettings.dyeable = settings.dyeable; + newSettings.helmet = settings.helmet; + newSettings.foodData = settings.foodData; return newSettings; } @@ -107,6 +119,11 @@ public class ItemSettings { return anvilRepairItems; } + @Nullable + public FoodData foodData() { + return foodData; + } + @Nullable public Helmet helmet() { return helmet; @@ -152,6 +169,11 @@ public class ItemSettings { return this; } + public ItemSettings foodData(FoodData foodData) { + this.foodData = foodData; + return this; + } + public ItemSettings equipment(EquipmentGeneration equipment) { this.equipment = equipment; return this; @@ -249,6 +271,14 @@ public class ItemSettings { boolean bool = (boolean) value; return settings -> settings.dyeable(bool); })); + registerFactory("food", (value -> { + Map args = MiscUtils.castToMap(value, false); + FoodData data = new FoodData( + ResourceConfigUtils.getAsInt(args.get("nutrition"), "nutrition"), + ResourceConfigUtils.getAsFloat(args.get("saturation"), "saturation") + ); + return settings -> settings.foodData(data); + })); } private static void registerFactory(String id, ItemSettings.Modifier.Factory factory) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java index 52845cb07..fd989e090 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java @@ -1,8 +1,8 @@ package net.momirealms.craftengine.core.item.modifier; -import net.momirealms.craftengine.core.item.EquipmentData; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.setting.EquipmentData; public class EquippableModifier implements ItemDataModifier { private final EquipmentData data; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/FoodModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/FoodModifier.java new file mode 100644 index 000000000..7f862f1cb --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/FoodModifier.java @@ -0,0 +1,46 @@ +package net.momirealms.craftengine.core.item.modifier; + +import net.momirealms.craftengine.core.item.ComponentKeys; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.sparrow.nbt.CompoundTag; +import net.momirealms.sparrow.nbt.Tag; + +import java.util.Map; + +public class FoodModifier implements ItemDataModifier { + private final int nutrition; + private final float saturation; + private final boolean canAlwaysEat; + + public FoodModifier(int nutrition, float saturation, boolean canAlwaysEat) { + this.canAlwaysEat = canAlwaysEat; + this.nutrition = nutrition; + this.saturation = saturation; + } + + @Override + public String name() { + return "food"; + } + + @Override + public void apply(Item item, ItemBuildContext context) { + item.setJavaComponent(ComponentKeys.FOOD, Map.of( + "nutrition", this.nutrition, + "saturation", this.saturation, + "can_always_eat", this.canAlwaysEat + )); + } + + @Override + public void prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { + Tag previous = item.getNBTComponent(ComponentKeys.FOOD); + if (previous != null) { + networkData.put(ComponentKeys.FOOD.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); + } else { + networkData.put(ComponentKeys.FOOD.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java index 5b4a9d4ed..280e6b7e3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java @@ -27,7 +27,7 @@ public abstract class AbstractRecipeManager implements RecipeManager { protected final Map>> byIngredient = new HashMap<>(); protected final Set dataPackRecipes = new HashSet<>(); protected final Set customRecipes = new HashSet<>(); - private final RecipeParser recipeParser; + protected final RecipeParser recipeParser; protected boolean isReloading; public AbstractRecipeManager() { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AnvilRepairItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/setting/AnvilRepairItem.java similarity index 66% rename from core/src/main/java/net/momirealms/craftengine/core/item/AnvilRepairItem.java rename to core/src/main/java/net/momirealms/craftengine/core/item/setting/AnvilRepairItem.java index 8ea18261d..650624de3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AnvilRepairItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/setting/AnvilRepairItem.java @@ -1,4 +1,4 @@ -package net.momirealms.craftengine.core.item; +package net.momirealms.craftengine.core.item.setting; import java.util.List; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/EquipmentData.java b/core/src/main/java/net/momirealms/craftengine/core/item/setting/EquipmentData.java similarity index 98% rename from core/src/main/java/net/momirealms/craftengine/core/item/EquipmentData.java rename to core/src/main/java/net/momirealms/craftengine/core/item/setting/EquipmentData.java index 2a33f07df..aa371660c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/EquipmentData.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/setting/EquipmentData.java @@ -1,4 +1,4 @@ -package net.momirealms.craftengine.core.item; +package net.momirealms.craftengine.core.item.setting; import net.momirealms.craftengine.core.entity.EquipmentSlot; import net.momirealms.craftengine.core.util.Key; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/setting/FoodData.java b/core/src/main/java/net/momirealms/craftengine/core/item/setting/FoodData.java new file mode 100644 index 000000000..bf69775dc --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/setting/FoodData.java @@ -0,0 +1,19 @@ +package net.momirealms.craftengine.core.item.setting; + +public class FoodData { + private final int nutrition; + private final float saturation; + + public FoodData(int nutrition, float saturation) { + this.nutrition = nutrition; + this.saturation = saturation; + } + + public int nutrition() { + return nutrition; + } + + public float saturation() { + return saturation; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/Helmet.java b/core/src/main/java/net/momirealms/craftengine/core/item/setting/Helmet.java similarity index 83% rename from core/src/main/java/net/momirealms/craftengine/core/item/Helmet.java rename to core/src/main/java/net/momirealms/craftengine/core/item/setting/Helmet.java index 0235c411e..231839c1b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/Helmet.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/setting/Helmet.java @@ -1,4 +1,4 @@ -package net.momirealms.craftengine.core.item; +package net.momirealms.craftengine.core.item.setting; import net.momirealms.craftengine.core.sound.SoundData; 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 c2abd2c50..819a3cbf7 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 @@ -8,7 +8,7 @@ import dev.dejvokep.boostedyaml.block.implementation.Section; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.momirealms.craftengine.core.font.BitmapImage; import net.momirealms.craftengine.core.font.Font; -import net.momirealms.craftengine.core.item.EquipmentData; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.pack.conflict.PathContext; import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionConditional; import net.momirealms.craftengine.core.pack.host.ResourcePackHost; diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/misc/EquipmentGeneration.java b/core/src/main/java/net/momirealms/craftengine/core/pack/misc/EquipmentGeneration.java index d3622cb72..47430f516 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/misc/EquipmentGeneration.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/misc/EquipmentGeneration.java @@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.pack.misc; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import net.momirealms.craftengine.core.item.EquipmentData; +import net.momirealms.craftengine.core.item.setting.EquipmentData; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index 6db94681c..b40b7538a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -87,7 +87,8 @@ public class Config { protected Path resource_pack$delivery$file_to_upload; protected Component resource_pack$send$prompt; - protected int performance$max_block_chain_update_limit; + protected int performance$max_note_block_chain_update_limit; + protected int performance$max_tripwire_chain_update_limit; protected int performance$max_emojis_per_parse; protected boolean light_system$force_update_light; @@ -276,7 +277,8 @@ public class Config { item$non_italic_tag = config.getBoolean("item.non-italic-tag", false); // performance - performance$max_block_chain_update_limit = config.getInt("performance.max-block-chain-update-limit", 64); + performance$max_note_block_chain_update_limit = config.getInt("performance.max-note-block-chain-update-limit", 64); + performance$max_tripwire_chain_update_limit = config.getInt("performance.max-tripwire-chain-update-limit", 128); performance$max_emojis_per_parse = config.getInt("performance.max-emojis-per-parse", 32); // light @@ -391,8 +393,8 @@ public class Config { return instance.resource_pack$override_uniform_font; } - public static int maxChainUpdate() { - return instance.performance$max_block_chain_update_limit; + public static int maxNoteBlockChainUpdate() { + return instance.performance$max_note_block_chain_update_limit; } public static int maxEmojisPerParse() { diff --git a/gradle.properties b/gradle.properties index e9c2a415d..77c08d973 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.17 -nms_helper_version=0.66.15 +nms_helper_version=0.66.16 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23