9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-21 07:59:19 +00:00

Merge remote-tracking branch 'upstream/dev' into dev

# Conflicts:
#	bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java
This commit is contained in:
jhqwqmc
2025-06-08 13:55:15 +08:00
43 changed files with 361 additions and 200 deletions

View File

@@ -28,7 +28,6 @@ import net.momirealms.craftengine.core.world.Vec3d;
import net.momirealms.craftengine.core.world.WorldPosition; import net.momirealms.craftengine.core.world.WorldPosition;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@@ -371,19 +370,18 @@ public class BlockEventListener implements Listener {
// for vanilla blocks // for vanilla blocks
if (event.getChangedType() == Material.NOTE_BLOCK) { if (event.getChangedType() == Material.NOTE_BLOCK) {
Block block = event.getBlock(); Block block = event.getBlock();
Block sourceBlock = event.getSourceBlock();
if (block.getX() == sourceBlock.getX() && block.getX() == sourceBlock.getZ()) {
World world = block.getWorld(); World world = block.getWorld();
Location location = block.getLocation(); Location location = block.getLocation();
Block sourceBlock = event.getSourceBlock();
BlockFace direction = sourceBlock.getFace(block);
if (direction == BlockFace.UP || direction == BlockFace.DOWN) {
Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world); Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world);
Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel);
Object blockPos = LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); Object blockPos = LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos);
if (direction == BlockFace.UP) { if (block.getY() > sourceBlock.getY()) {
NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, 0); NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, Config.maxNoteBlockChainUpdate());
} else { } else {
NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, 0); NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, Config.maxNoteBlockChainUpdate());
} }
} }
} }

View File

@@ -129,13 +129,12 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
// init cache // init cache
CoreReflections.method$BlockStateBase$initCache.invoke(mcBlockState); CoreReflections.method$BlockStateBase$initCache.invoke(mcBlockState);
// set block light // set block light
if (settings.blockLight() != -1) { int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(state.vanillaBlockState().handle());
if (VersionHelper.isOrAbove1_21_2()) { if (VersionHelper.isOrAbove1_21_2()) {
CoreReflections.field$BlockStateBase$lightBlock.set(mcBlockState, settings.blockLight()); CoreReflections.field$BlockStateBase$lightBlock.set(mcBlockState, blockLight);
} else { } else {
Object cache = CoreReflections.field$BlockStateBase$cache.get(mcBlockState); Object cache = CoreReflections.field$BlockStateBase$cache.get(mcBlockState);
CoreReflections.field$BlockStateBase$Cache$lightBlock.set(cache, settings.blockLight()); CoreReflections.field$BlockStateBase$Cache$lightBlock.set(cache, blockLight);
}
} }
// set fluid later // set fluid later
if (settings.fluidState()) { if (settings.fluidState()) {

View File

@@ -49,7 +49,7 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement {
Vector3f offset = conjugated.transform(new Vector3f(position())); Vector3f offset = conjugated.transform(new Vector3f(position()));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId, UUID.randomUUID(), position.x() + offset.x, position.y() + offset.y, position.z() - offset.z, 0, position.xRot(), 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))); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, getCachedValues(dyedColor)));
} }

View File

@@ -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_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 final NamespacedKey FURNITURE_COLLISION = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_COLLISION);
public static Class<?> COLLISION_ENTITY_CLASS = Interaction.class; 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; public static ColliderType COLLISION_ENTITY_TYPE = ColliderType.INTERACTION;
private static BukkitFurnitureManager instance; private static BukkitFurnitureManager instance;
private final BukkitCraftEngine plugin; private final BukkitCraftEngine plugin;
@@ -93,7 +93,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
@Override @Override
public void delayedInit() { public void delayedInit() {
COLLISION_ENTITY_CLASS = Config.colliderType() == ColliderType.INTERACTION ? Interaction.class : Boat.class; 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(); COLLISION_ENTITY_TYPE = Config.colliderType();
Bukkit.getPluginManager().registerEvents(this.dismountListener, this.plugin.javaPlugin()); Bukkit.getPluginManager().registerEvents(this.dismountListener, this.plugin.javaPlugin());
Bukkit.getPluginManager().registerEvents(this.furnitureEventListener, this.plugin.javaPlugin()); Bukkit.getPluginManager().registerEvents(this.furnitureEventListener, this.plugin.javaPlugin());

View File

@@ -62,7 +62,7 @@ public class InteractionHitBox extends AbstractHitBox {
float yaw = position.xRot(); float yaw = position.xRot();
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId[0], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw, 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); ), true);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId[0], List.copyOf(this.cachedValues)), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId[0], List.copyOf(this.cachedValues)), true);
if (canUseItemOn()) { if (canUseItemOn()) {

View File

@@ -61,7 +61,7 @@ public class ShulkerHitBox extends AbstractHitBox {
if (interactionEntity) { if (interactionEntity) {
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f, z - offset.z, 0, yaw, 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); ), true);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true);
if (canUseOn) { if (canUseOn) {
@@ -80,7 +80,7 @@ public class ShulkerHitBox extends AbstractHitBox {
if (interactionEntity) { if (interactionEntity) {
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( 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, 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); ), true);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true);
if (canUseOn) { if (canUseOn) {
@@ -102,14 +102,14 @@ public class ShulkerHitBox extends AbstractHitBox {
// first interaction // first interaction
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f, z - offset.z, 0, yaw, 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); ), true);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)), true);
// second interaction // second interaction
double distance = shulkerHeight - scale; double distance = shulkerHeight - scale;
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( 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, 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); ), true);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[3], List.copyOf(cachedInteractionValues)), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[3], List.copyOf(cachedInteractionValues)), true);
if (canUseOn) { if (canUseOn) {
@@ -213,11 +213,11 @@ public class ShulkerHitBox extends AbstractHitBox {
double processedY = (fractionalPart >= 0.5) ? integerPart + 1 : originalY; double processedY = (fractionalPart >= 0.5) ? integerPart + 1 : originalY;
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityIds[0], UUID.randomUUID(), x + offset.x, originalY, z - offset.z, 0, yaw, 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); ), false);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityIds[1], UUID.randomUUID(), x + offset.x, processedY, z - offset.z, 0, yaw, 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); ), false);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[1], List.copyOf(this.cachedShulkerValues)), false); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[1], List.copyOf(this.cachedShulkerValues)), false);
// add passengers // add passengers

View File

@@ -10,7 +10,6 @@ public class BukkitItemBehaviors extends ItemBehaviors {
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item"); 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 WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
public static final Key BUCKET_ITEM = Key.from("craftengine: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() { public static void init() {
register(EMPTY, EmptyItemBehavior.FACTORY); register(EMPTY, EmptyItemBehavior.FACTORY);

View File

@@ -4,10 +4,10 @@ import com.google.gson.JsonElement;
import com.saicone.rtag.item.ItemTagStream; import com.saicone.rtag.item.ItemTagStream;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.ItemTags; 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.ItemFactory;
import net.momirealms.craftengine.core.item.ItemWrapper; import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.item.JukeboxPlayable; 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.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
import net.momirealms.sparrow.nbt.Tag; import net.momirealms.sparrow.nbt.Tag;

View File

@@ -2,7 +2,7 @@ package net.momirealms.craftengine.bukkit.item.factory;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes; 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 net.momirealms.craftengine.core.plugin.CraftEngine;
import java.util.Optional; import java.util.Optional;

View File

@@ -318,16 +318,15 @@ public class ItemEventListener implements Listener {
if (optionalCustomItem.isEmpty()) { if (optionalCustomItem.isEmpty()) {
return; return;
} }
Cancellable dummy = Cancellable.dummy(); Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled);
CustomItem<ItemStack> customItem = optionalCustomItem.get(); CustomItem<ItemStack> customItem = optionalCustomItem.get();
PlayerOptionalContext context = PlayerOptionalContext.of(this.plugin.adapt(event.getPlayer()), ContextHolder.builder() PlayerOptionalContext context = PlayerOptionalContext.of(this.plugin.adapt(event.getPlayer()), ContextHolder.builder()
.withParameter(DirectContextParameters.ITEM_IN_HAND, wrapped) .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) .withParameter(DirectContextParameters.HAND, event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND)
); );
customItem.execute(context, EventTrigger.CONSUME); customItem.execute(context, EventTrigger.CONSUME);
if (dummy.isCancelled()) { if (event.isCancelled()) {
event.setCancelled(true);
return; return;
} }
} }

View File

@@ -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.CraftingInput;
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput; import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
import net.momirealms.craftengine.core.item.recipe.input.SmithingInput; 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.config.Config;
import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.BuiltInRegistries;

View File

@@ -19,6 +19,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
import net.momirealms.craftengine.bukkit.util.NoteBlockChainUpdateUtils; import net.momirealms.craftengine.bukkit.util.NoteBlockChainUpdateUtils;
import net.momirealms.craftengine.core.block.*; import net.momirealms.craftengine.core.block.*;
import net.momirealms.craftengine.core.plugin.CraftEngine; 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.Key;
import net.momirealms.craftengine.core.util.ObjectHolder; import net.momirealms.craftengine.core.util.ObjectHolder;
import net.momirealms.craftengine.core.util.VersionHelper; 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$behavior;
private static Field field$CraftEngineBlock$shape; private static Field field$CraftEngineBlock$shape;
private static Field field$CraftEngineBlock$isNoteBlock; private static Field field$CraftEngineBlock$isNoteBlock;
private static Field field$CraftEngineBlock$isTripwire;
public static void init() throws ReflectiveOperationException { public static void init() throws ReflectiveOperationException {
ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17); ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17);
@@ -48,6 +50,7 @@ public final class BlockGenerator {
.defineField("behaviorHolder", ObjectHolder.class, Visibility.PUBLIC) .defineField("behaviorHolder", ObjectHolder.class, Visibility.PUBLIC)
.defineField("shapeHolder", ObjectHolder.class, Visibility.PUBLIC) .defineField("shapeHolder", ObjectHolder.class, Visibility.PUBLIC)
.defineField("isClientSideNoteBlock", boolean.class, Visibility.PUBLIC) .defineField("isClientSideNoteBlock", boolean.class, Visibility.PUBLIC)
.defineField("isClientSideTripwire", boolean.class, Visibility.PUBLIC)
// should always implement this interface // should always implement this interface
.implement(CoreReflections.clazz$Fallable) .implement(CoreReflections.clazz$Fallable)
.implement(CoreReflections.clazz$BonemealableBlock) .implement(CoreReflections.clazz$BonemealableBlock)
@@ -55,13 +58,15 @@ public final class BlockGenerator {
// internal interfaces // internal interfaces
.implement(BehaviorHolder.class) .implement(BehaviorHolder.class)
.implement(ShapeHolder.class) .implement(ShapeHolder.class)
.implement(NoteBlockIndicator.class) .implement(ChainUpdateBlockIndicator.class)
.method(ElementMatchers.named("getBehaviorHolder")) .method(ElementMatchers.named("getBehaviorHolder"))
.intercept(FieldAccessor.ofField("behaviorHolder")) .intercept(FieldAccessor.ofField("behaviorHolder"))
.method(ElementMatchers.named("getShapeHolder")) .method(ElementMatchers.named("getShapeHolder"))
.intercept(FieldAccessor.ofField("shapeHolder")) .intercept(FieldAccessor.ofField("shapeHolder"))
.method(ElementMatchers.named("isNoteBlock")) .method(ElementMatchers.named("isNoteBlock"))
.intercept(FieldAccessor.ofField("isClientSideNoteBlock")) .intercept(FieldAccessor.ofField("isClientSideNoteBlock"))
.method(ElementMatchers.named("isTripwire"))
.intercept(FieldAccessor.ofField("isClientSideTripwire"))
// getShape // getShape
.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$getShape)) .method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$getShape))
.intercept(MethodDelegation.to(GetShapeInterceptor.INSTANCE)) .intercept(MethodDelegation.to(GetShapeInterceptor.INSTANCE))
@@ -142,6 +147,7 @@ public final class BlockGenerator {
field$CraftEngineBlock$behavior = clazz$CraftEngineBlock.getField("behaviorHolder"); field$CraftEngineBlock$behavior = clazz$CraftEngineBlock.getField("behaviorHolder");
field$CraftEngineBlock$shape = clazz$CraftEngineBlock.getField("shapeHolder"); field$CraftEngineBlock$shape = clazz$CraftEngineBlock.getField("shapeHolder");
field$CraftEngineBlock$isNoteBlock = clazz$CraftEngineBlock.getField("isClientSideNoteBlock"); 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 { public static Object generateBlock(Key replacedBlock, Object ownerBlock, Object properties) throws Throwable {
@@ -155,19 +161,25 @@ public final class BlockGenerator {
field$CraftEngineBlock$behavior.set(newBlockInstance, behaviorHolder); field$CraftEngineBlock$behavior.set(newBlockInstance, behaviorHolder);
field$CraftEngineBlock$shape.set(newBlockInstance, shapeHolder); field$CraftEngineBlock$shape.set(newBlockInstance, shapeHolder);
field$CraftEngineBlock$isNoteBlock.set(newBlockInstance, replacedBlock.equals(BlockKeys.NOTE_BLOCK)); field$CraftEngineBlock$isNoteBlock.set(newBlockInstance, replacedBlock.equals(BlockKeys.NOTE_BLOCK));
field$CraftEngineBlock$isTripwire.set(newBlockInstance, replacedBlock.equals(BlockKeys.TRIPWIRE));
return newBlockInstance; return newBlockInstance;
} }
public static class UpdateShapeInterceptor { public static class UpdateShapeInterceptor {
public static final UpdateShapeInterceptor INSTANCE = new UpdateShapeInterceptor(); public static final UpdateShapeInterceptor INSTANCE = new UpdateShapeInterceptor();
public static final int levelIndex = VersionHelper.isOrAbove1_21_2() ? 1 : 3; 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 @RuntimeType
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) throws Exception { public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder(); ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
if (((NoteBlockIndicator) thisObj).isNoteBlock() && CoreReflections.clazz$ServerLevel.isInstance(args[levelIndex])) { ChainUpdateBlockIndicator indicator = (ChainUpdateBlockIndicator) thisObj;
if (indicator.isNoteBlock()) {
if (CoreReflections.clazz$ServerLevel.isInstance(args[levelIndex])) {
startNoteBlockChain(args); startNoteBlockChain(args);
} }
}
try { try {
return holder.value().updateShape(thisObj, args, superMethod); return holder.value().updateShape(thisObj, args, superMethod);
} catch (Exception e) { } catch (Exception e) {
@@ -175,30 +187,20 @@ public final class BlockGenerator {
return args[0]; return args[0];
} }
} }
}
private static void startNoteBlockChain(Object[] args) throws ReflectiveOperationException { private static void startNoteBlockChain(Object[] args) {
Object direction; Object direction = args[directionIndex];
Object serverLevel; Object serverLevel = args[levelIndex];
Object blockPos; Object blockPos = args[posIndex];
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 // Y axis
if (id == 0 || id == 1) { if (direction == CoreReflections.instance$Direction$DOWN) {
Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel);
FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos);
if (id == 1) { NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, Config.maxNoteBlockChainUpdate());
NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, 0); } else if (direction == CoreReflections.instance$Direction$UP) {
} else { Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel);
NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$UP, blockPos, 0); FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos);
NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, CoreReflections.instance$Direction$DOWN, blockPos, Config.maxNoteBlockChainUpdate());
} }
} }
} }

View File

@@ -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.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils; 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.EmptyBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.CraftEngine;
@@ -220,23 +221,36 @@ public class WorldStorageInjector {
CESection section = holder.ceSection(); CESection section = holder.ceSection();
// 如果是原版方块 // 如果是原版方块
if (BlockStateUtils.isVanillaBlock(stateId)) { if (BlockStateUtils.isVanillaBlock(stateId)) {
// 那么应该情况自定义块 // 那么应该清空自定义块
ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE); ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE);
// 如果先前不是空气则标记 // 处理 自定义块 -> 原版块
if (!previous.isEmpty()) { if (!previous.isEmpty()) {
holder.ceChunk().setDirty(true); holder.ceChunk().setDirty(true);
if (Config.enableLightSystem()) { 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 { } else {
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState); ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState);
if (previousImmutableBlockState == immutableBlockState) return; if (previousImmutableBlockState == immutableBlockState) return;
// 处理 自定义块到自定义块或原版块到自定义块
holder.ceChunk().setDirty(true); holder.ceChunk().setDirty(true);
// 不可能!绝对不可能!
if (immutableBlockState.isEmpty()) return;
// 如果新方块的光照属性和客户端认为的不同 // 如果新方块的光照属性和客户端认为的不同
if (Config.enableLightSystem() && !immutableBlockState.isEmpty()) { if (Config.enableLightSystem()) {
updateLightIfChanged(holder, previousState, immutableBlockState.vanillaBlockState().handle(), newState, x, y, z); 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) { } 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(); CEWorld world = thisObj.ceChunk().world();
Object blockPos = LocationUtils.toBlockPos(x, y, z); Object blockPos = LocationUtils.toBlockPos(x, y, z);
Object serverWorld = world.world().serverWorld(); 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<SectionPos> 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(); SectionPos sectionPos = thisObj.cePos();
List<SectionPos> pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15); List<SectionPos> pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15);
world.sectionLightUpdated(pos); world.sectionLightUpdated(pos);
return; 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(); SectionPos sectionPos = thisObj.cePos();
List<SectionPos> pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15); List<SectionPos> pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15);
world.sectionLightUpdated(pos); world.sectionLightUpdated(pos);

View File

@@ -84,7 +84,7 @@ public class PacketConsumers {
public static void initEntities(int registrySize) { public static void initEntities(int registrySize) {
ADD_ENTITY_HANDLERS = new BukkitNetworkManager.Handlers[registrySize]; ADD_ENTITY_HANDLERS = new BukkitNetworkManager.Handlers[registrySize];
Arrays.fill(ADD_ENTITY_HANDLERS, BukkitNetworkManager.Handlers.DO_NOTHING); 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(); FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt(); int id = buf.readVarInt();
UUID uuid = buf.readUUID(); 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.BLOCK_DISPLAY$registryId] = simpleAddEntityHandler(BlockDisplayPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$TEXT_DISPLAY$registryId] = simpleAddEntityHandler(TextDisplayPacketHandler.INSTANCE); ADD_ENTITY_HANDLERS[MEntityTypes.TEXT_DISPLAY$registryId] = simpleAddEntityHandler(TextDisplayPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ARMOR_STAND$registryId] = simpleAddEntityHandler(ArmorStandPacketHandler.INSTANCE); ADD_ENTITY_HANDLERS[MEntityTypes.ARMOR_STAND$registryId] = simpleAddEntityHandler(ArmorStandPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ITEM_DISPLAY$registryId] = simpleAddEntityHandler(ItemDisplayPacketHandler.INSTANCE); ADD_ENTITY_HANDLERS[MEntityTypes.ITEM_DISPLAY$registryId] = simpleAddEntityHandler(ItemDisplayPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ITEM$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); ADD_ENTITY_HANDLERS[MEntityTypes.ITEM$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); ADD_ENTITY_HANDLERS[MEntityTypes.ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$GLOW_ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); ADD_ENTITY_HANDLERS[MEntityTypes.GLOW_ITEM_FRAME$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE);
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$EYE_OF_ENDER$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.EYE_OF_ENDER$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$FIREWORK_ROCKET$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.FIREWORK_ROCKET$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$SMALL_FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.SMALL_FIREBALL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$EGG$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.EGG$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$ENDER_PEARL$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.ENDER_PEARL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$EXPERIENCE_BOTTLE$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.EXPERIENCE_BOTTLE$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$SNOWBALL$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.SNOWBALL$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$POTION$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.POTION$registryId] = createOptionalCustomProjectileEntityHandler();
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$TRIDENT$registryId] = createOptionalCustomProjectileEntityHandler(); ADD_ENTITY_HANDLERS[MEntityTypes.TRIDENT$registryId] = createOptionalCustomProjectileEntityHandler();
if (VersionHelper.isOrAbove1_20_5()) { 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(); FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt(); int id = buf.readVarInt();
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id); BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
@@ -154,8 +154,8 @@ public class PacketConsumers {
} }
} }
}; };
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$INTERACTION$registryId] = (user, event) -> { ADD_ENTITY_HANDLERS[MEntityTypes.INTERACTION$registryId] = (user, event) -> {
if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.instance$EntityType$INTERACTION) return; if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.INTERACTION) return;
FriendlyByteBuf buf = event.getBuffer(); FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt(); int id = buf.readVarInt();
// Cancel collider entity packet // Cancel collider entity packet
@@ -164,8 +164,8 @@ public class PacketConsumers {
event.setCancelled(true); event.setCancelled(true);
} }
}; };
ADD_ENTITY_HANDLERS[MEntityTypes.instance$EntityType$OAK_BOAT$registryId] = (user, event) -> { ADD_ENTITY_HANDLERS[MEntityTypes.OAK_BOAT$registryId] = (user, event) -> {
if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.instance$EntityType$OAK_BOAT) return; if (BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE != MEntityTypes.OAK_BOAT) return;
FriendlyByteBuf buf = event.getBuffer(); FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt(); int id = buf.readVarInt();
// Cancel collider entity packet // Cancel collider entity packet
@@ -2295,5 +2295,4 @@ public class PacketConsumers {
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e); CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e);
} }
}; };
} }

View File

@@ -52,6 +52,8 @@ public interface PacketIds {
int clientboundSetPlayerInventoryPacket(); int clientboundSetPlayerInventoryPacket();
int clientboundBlockEventPacket();
int serverboundContainerClickPacket(); int serverboundContainerClickPacket();
int serverboundSetCreativeModeSlotPacket(); int serverboundSetCreativeModeSlotPacket();

View File

@@ -81,7 +81,7 @@ public class ProjectilePacketHandler implements EntityPacketHandler {
buf.writeVarInt(event.packetID()); buf.writeVarInt(event.packetID());
buf.writeVarInt(this.entityId); buf.writeVarInt(this.entityId);
buf.writeUUID(uuid); buf.writeUUID(uuid);
buf.writeVarInt(MEntityTypes.instance$EntityType$ITEM_DISPLAY$registryId); buf.writeVarInt(MEntityTypes.ITEM_DISPLAY$registryId);
buf.writeDouble(x); buf.writeDouble(x);
buf.writeDouble(y); buf.writeDouble(y);
buf.writeDouble(z); buf.writeDouble(z);

View File

@@ -139,4 +139,9 @@ public class PacketIds1_20 implements PacketIds {
public int serverboundSetCreativeModeSlotPacket() { public int serverboundSetCreativeModeSlotPacket() {
return PacketIdFinder.serverboundByClazz(NetworkReflections.clazz$ServerboundSetCreativeModeSlotPacket); return PacketIdFinder.serverboundByClazz(NetworkReflections.clazz$ServerboundSetCreativeModeSlotPacket);
} }
@Override
public int clientboundBlockEventPacket() {
return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundBlockEventPacket);
}
} }

View File

@@ -129,6 +129,11 @@ public class PacketIds1_20_5 implements PacketIds {
return PacketIdFinder.clientboundByName("minecraft:set_player_inventory"); return PacketIdFinder.clientboundByName("minecraft:set_player_inventory");
} }
@Override
public int clientboundBlockEventPacket() {
return PacketIdFinder.clientboundByName("minecraft:block_event");
}
@Override @Override
public int serverboundContainerClickPacket() { public int serverboundContainerClickPacket() {
return PacketIdFinder.serverboundByName("minecraft:container_click"); return PacketIdFinder.serverboundByName("minecraft:container_click");

View File

@@ -16,6 +16,7 @@ public final class MBlocks {
public static final Object ICE; public static final Object ICE;
public static final Object SHORT_GRASS; public static final Object SHORT_GRASS;
public static final Object SHORT_GRASS$defaultState; public static final Object SHORT_GRASS$defaultState;
public static final Object SHULKER_BOX;
private static Object getById(String id) throws ReflectiveOperationException { private static Object getById(String id) throws ReflectiveOperationException {
Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id);
@@ -33,6 +34,7 @@ public final class MBlocks {
ICE = getById("ice"); ICE = getById("ice");
SHORT_GRASS = getById(VersionHelper.isOrAbove1_20_3() ? "short_grass" : "grass"); SHORT_GRASS = getById(VersionHelper.isOrAbove1_20_3() ? "short_grass" : "grass");
SHORT_GRASS$defaultState = CoreReflections.method$Block$defaultBlockState.invoke(SHORT_GRASS); SHORT_GRASS$defaultState = CoreReflections.method$Block$defaultBlockState.invoke(SHORT_GRASS);
SHULKER_BOX = getById("shulker_box");
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
throw new ReflectionInitException("Failed to init Blocks", e); throw new ReflectionInitException("Failed to init Blocks", e);
} }

View File

@@ -7,50 +7,50 @@ import net.momirealms.craftengine.core.util.VersionHelper;
public final class MEntityTypes { public final class MEntityTypes {
private MEntityTypes() {} private MEntityTypes() {}
public static final Object instance$EntityType$TEXT_DISPLAY; public static final Object TEXT_DISPLAY;
public static final int instance$EntityType$TEXT_DISPLAY$registryId; public static final int TEXT_DISPLAY$registryId;
public static final Object instance$EntityType$ITEM_DISPLAY; public static final Object ITEM_DISPLAY;
public static final int instance$EntityType$ITEM_DISPLAY$registryId; public static final int ITEM_DISPLAY$registryId;
public static final Object instance$EntityType$BLOCK_DISPLAY; public static final Object BLOCK_DISPLAY;
public static final int instance$EntityType$BLOCK_DISPLAY$registryId; public static final int BLOCK_DISPLAY$registryId;
public static final Object instance$EntityType$ARMOR_STAND; public static final Object ARMOR_STAND;
public static final int instance$EntityType$ARMOR_STAND$registryId; public static final int ARMOR_STAND$registryId;
public static final Object instance$EntityType$FALLING_BLOCK; public static final Object FALLING_BLOCK;
public static final int instance$EntityType$FALLING_BLOCK$registryId; public static final int FALLING_BLOCK$registryId;
public static final Object instance$EntityType$INTERACTION; public static final Object INTERACTION;
public static final int instance$EntityType$INTERACTION$registryId; public static final int INTERACTION$registryId;
public static final Object instance$EntityType$SHULKER; public static final Object SHULKER;
public static final int instance$EntityType$SHULKER$registryId; public static final int SHULKER$registryId;
public static final Object instance$EntityType$OAK_BOAT; public static final Object OAK_BOAT;
public static final int instance$EntityType$OAK_BOAT$registryId; public static final int OAK_BOAT$registryId;
public static final Object instance$EntityType$TRIDENT; public static final Object TRIDENT;
public static final int instance$EntityType$TRIDENT$registryId; public static final int TRIDENT$registryId;
public static final Object instance$EntityType$SNOWBALL; public static final Object SNOWBALL;
public static final int instance$EntityType$SNOWBALL$registryId; public static final int SNOWBALL$registryId;
public static final Object instance$EntityType$FIREBALL; public static final Object FIREBALL;
public static final int instance$EntityType$FIREBALL$registryId; public static final int FIREBALL$registryId;
public static final Object instance$EntityType$EYE_OF_ENDER; public static final Object EYE_OF_ENDER;
public static final int instance$EntityType$EYE_OF_ENDER$registryId; public static final int EYE_OF_ENDER$registryId;
public static final Object instance$EntityType$FIREWORK_ROCKET; public static final Object FIREWORK_ROCKET;
public static final int instance$EntityType$FIREWORK_ROCKET$registryId; public static final int FIREWORK_ROCKET$registryId;
public static final Object instance$EntityType$ITEM; public static final Object ITEM;
public static final int instance$EntityType$ITEM$registryId; public static final int ITEM$registryId;
public static final Object instance$EntityType$ITEM_FRAME; public static final Object ITEM_FRAME;
public static final int instance$EntityType$ITEM_FRAME$registryId; public static final int ITEM_FRAME$registryId;
public static final Object instance$EntityType$GLOW_ITEM_FRAME; public static final Object GLOW_ITEM_FRAME;
public static final int instance$EntityType$GLOW_ITEM_FRAME$registryId; public static final int GLOW_ITEM_FRAME$registryId;
public static final Object instance$EntityType$OMINOUS_ITEM_SPAWNER; public static final Object OMINOUS_ITEM_SPAWNER;
public static final int instance$EntityType$OMINOUS_ITEM_SPAWNER$registryId; public static final int OMINOUS_ITEM_SPAWNER$registryId;
public static final Object instance$EntityType$SMALL_FIREBALL; public static final Object SMALL_FIREBALL;
public static final int instance$EntityType$SMALL_FIREBALL$registryId; public static final int SMALL_FIREBALL$registryId;
public static final Object instance$EntityType$EGG; public static final Object EGG;
public static final int instance$EntityType$EGG$registryId; public static final int EGG$registryId;
public static final Object instance$EntityType$ENDER_PEARL; public static final Object ENDER_PEARL;
public static final int instance$EntityType$ENDER_PEARL$registryId; public static final int ENDER_PEARL$registryId;
public static final Object instance$EntityType$EXPERIENCE_BOTTLE; public static final Object EXPERIENCE_BOTTLE;
public static final int instance$EntityType$EXPERIENCE_BOTTLE$registryId; public static final int EXPERIENCE_BOTTLE$registryId;
public static final Object instance$EntityType$POTION; public static final Object POTION;
public static final int instance$EntityType$POTION$registryId; public static final int POTION$registryId;
private static Object getById(String id) throws ReflectiveOperationException { private static Object getById(String id) throws ReflectiveOperationException {
Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id);
@@ -64,50 +64,50 @@ public final class MEntityTypes {
static { static {
try { try {
instance$EntityType$TEXT_DISPLAY = getById("text_display"); TEXT_DISPLAY = getById("text_display");
instance$EntityType$TEXT_DISPLAY$registryId = getRegistryId(instance$EntityType$TEXT_DISPLAY); TEXT_DISPLAY$registryId = getRegistryId(TEXT_DISPLAY);
instance$EntityType$ITEM_DISPLAY = getById("item_display"); ITEM_DISPLAY = getById("item_display");
instance$EntityType$ITEM_DISPLAY$registryId = getRegistryId(instance$EntityType$ITEM_DISPLAY); ITEM_DISPLAY$registryId = getRegistryId(ITEM_DISPLAY);
instance$EntityType$BLOCK_DISPLAY = getById("block_display"); BLOCK_DISPLAY = getById("block_display");
instance$EntityType$BLOCK_DISPLAY$registryId = getRegistryId(instance$EntityType$BLOCK_DISPLAY); BLOCK_DISPLAY$registryId = getRegistryId(BLOCK_DISPLAY);
instance$EntityType$FALLING_BLOCK = getById("falling_block"); FALLING_BLOCK = getById("falling_block");
instance$EntityType$FALLING_BLOCK$registryId = getRegistryId(instance$EntityType$FALLING_BLOCK); FALLING_BLOCK$registryId = getRegistryId(FALLING_BLOCK);
instance$EntityType$INTERACTION = getById("interaction"); INTERACTION = getById("interaction");
instance$EntityType$INTERACTION$registryId = getRegistryId(instance$EntityType$INTERACTION); INTERACTION$registryId = getRegistryId(INTERACTION);
instance$EntityType$SHULKER = getById("shulker"); SHULKER = getById("shulker");
instance$EntityType$SHULKER$registryId = getRegistryId(instance$EntityType$SHULKER); SHULKER$registryId = getRegistryId(SHULKER);
instance$EntityType$ARMOR_STAND = getById("armor_stand"); ARMOR_STAND = getById("armor_stand");
instance$EntityType$ARMOR_STAND$registryId = getRegistryId(instance$EntityType$ARMOR_STAND); ARMOR_STAND$registryId = getRegistryId(ARMOR_STAND);
instance$EntityType$OAK_BOAT = getById(VersionHelper.isOrAbove1_21_2() ? "oak_boat" : "boat"); OAK_BOAT = getById(VersionHelper.isOrAbove1_21_2() ? "oak_boat" : "boat");
instance$EntityType$OAK_BOAT$registryId = getRegistryId(instance$EntityType$OAK_BOAT); OAK_BOAT$registryId = getRegistryId(OAK_BOAT);
instance$EntityType$TRIDENT = getById("trident"); TRIDENT = getById("trident");
instance$EntityType$TRIDENT$registryId = getRegistryId(instance$EntityType$TRIDENT); TRIDENT$registryId = getRegistryId(TRIDENT);
instance$EntityType$SNOWBALL = getById("snowball"); SNOWBALL = getById("snowball");
instance$EntityType$SNOWBALL$registryId = getRegistryId(instance$EntityType$SNOWBALL); SNOWBALL$registryId = getRegistryId(SNOWBALL);
instance$EntityType$FIREBALL = getById("fireball"); FIREBALL = getById("fireball");
instance$EntityType$FIREBALL$registryId = getRegistryId(instance$EntityType$FIREBALL); FIREBALL$registryId = getRegistryId(FIREBALL);
instance$EntityType$EYE_OF_ENDER = getById("eye_of_ender"); EYE_OF_ENDER = getById("eye_of_ender");
instance$EntityType$EYE_OF_ENDER$registryId = getRegistryId(instance$EntityType$EYE_OF_ENDER); EYE_OF_ENDER$registryId = getRegistryId(EYE_OF_ENDER);
instance$EntityType$FIREWORK_ROCKET = getById("firework_rocket"); FIREWORK_ROCKET = getById("firework_rocket");
instance$EntityType$FIREWORK_ROCKET$registryId = getRegistryId(instance$EntityType$FIREWORK_ROCKET); FIREWORK_ROCKET$registryId = getRegistryId(FIREWORK_ROCKET);
instance$EntityType$ITEM = getById("item"); ITEM = getById("item");
instance$EntityType$ITEM$registryId = getRegistryId(instance$EntityType$ITEM); ITEM$registryId = getRegistryId(ITEM);
instance$EntityType$ITEM_FRAME = getById("item_frame"); ITEM_FRAME = getById("item_frame");
instance$EntityType$ITEM_FRAME$registryId = getRegistryId(instance$EntityType$ITEM_FRAME); ITEM_FRAME$registryId = getRegistryId(ITEM_FRAME);
instance$EntityType$GLOW_ITEM_FRAME = getById("glow_item_frame"); GLOW_ITEM_FRAME = getById("glow_item_frame");
instance$EntityType$GLOW_ITEM_FRAME$registryId = getRegistryId(instance$EntityType$GLOW_ITEM_FRAME); GLOW_ITEM_FRAME$registryId = getRegistryId(GLOW_ITEM_FRAME);
instance$EntityType$SMALL_FIREBALL = getById("small_fireball"); SMALL_FIREBALL = getById("small_fireball");
instance$EntityType$SMALL_FIREBALL$registryId = getRegistryId(instance$EntityType$SMALL_FIREBALL); SMALL_FIREBALL$registryId = getRegistryId(SMALL_FIREBALL);
instance$EntityType$EGG = getById("egg"); EGG = getById("egg");
instance$EntityType$EGG$registryId = getRegistryId(instance$EntityType$EGG); EGG$registryId = getRegistryId(EGG);
instance$EntityType$ENDER_PEARL = getById("ender_pearl"); ENDER_PEARL = getById("ender_pearl");
instance$EntityType$ENDER_PEARL$registryId = getRegistryId(instance$EntityType$ENDER_PEARL); ENDER_PEARL$registryId = getRegistryId(ENDER_PEARL);
instance$EntityType$EXPERIENCE_BOTTLE = getById("experience_bottle"); EXPERIENCE_BOTTLE = getById("experience_bottle");
instance$EntityType$EXPERIENCE_BOTTLE$registryId = getRegistryId(instance$EntityType$EXPERIENCE_BOTTLE); EXPERIENCE_BOTTLE$registryId = getRegistryId(EXPERIENCE_BOTTLE);
instance$EntityType$POTION = getById("potion"); POTION = getById("potion");
instance$EntityType$POTION$registryId = getRegistryId(instance$EntityType$POTION); POTION$registryId = getRegistryId(POTION);
instance$EntityType$OMINOUS_ITEM_SPAWNER = VersionHelper.isOrAbove1_20_5() ? getById("ominous_item_spawner") : null; OMINOUS_ITEM_SPAWNER = VersionHelper.isOrAbove1_20_5() ? getById("ominous_item_spawner") : null;
instance$EntityType$OMINOUS_ITEM_SPAWNER$registryId = getRegistryId(instance$EntityType$OMINOUS_ITEM_SPAWNER); OMINOUS_ITEM_SPAWNER$registryId = getRegistryId(OMINOUS_ITEM_SPAWNER);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
throw new ReflectionInitException("Failed to init EntityTypes", e); throw new ReflectionInitException("Failed to init EntityTypes", e);
} }

View File

@@ -1297,6 +1297,13 @@ public final class NetworkReflections {
.map(it -> ReflectionUtils.getConstructor(it, float.class, boolean.class)) .map(it -> ReflectionUtils.getConstructor(it, float.class, boolean.class))
.orElse(null); .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$nameGetter;
public static final MethodHandle handle$ServerboundRenameItemPacket$nameSetter; public static final MethodHandle handle$ServerboundRenameItemPacket$nameSetter;
public static final MethodHandle handle$ServerboundHelloPacket$nameGetter; public static final MethodHandle handle$ServerboundHelloPacket$nameGetter;

View File

@@ -1,19 +1,19 @@
package net.momirealms.craftengine.bukkit.util; package net.momirealms.craftengine.bukkit.util;
import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.core.plugin.config.Config;
public class NoteBlockChainUpdateUtils { public class NoteBlockChainUpdateUtils {
private NoteBlockChainUpdateUtils() {} private NoteBlockChainUpdateUtils() {}
// TODO 都在一个区块内应该优化到区块内的方块getter
public static void noteBlockChainUpdate(Object level, Object chunkSource, Object direction, Object blockPos, int times) { 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 relativePos = FastNMS.INSTANCE.method$BlockPos$relative(blockPos, direction);
Object state = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, relativePos); Object state = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, relativePos);
if (BlockStateUtils.isClientSideNoteBlock(state)) { if (BlockStateUtils.isClientSideNoteBlock(state)) {
FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, relativePos); FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, relativePos);
noteBlockChainUpdate(level, chunkSource, direction, relativePos, times+1); noteBlockChainUpdate(level, chunkSource, direction, relativePos, times);
} }
} }
} }

View File

@@ -336,7 +336,7 @@ gui:
performance: performance:
# Maximum chain update depth when fixing client visuals # 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 # Prevent lag or oversized packet when processing emoji-heavy content
max-emojis-per-parse: 16 max-emojis-per-parse: 16

View File

@@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.util.Key;
public class BlockKeys { public class BlockKeys {
public static final Key NOTE_BLOCK = Key.of("minecraft:note_block"); 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 CRAFTING_TABLE = Key.of("minecraft:crafting_table");
public static final Key STONECUTTER = Key.of("minecraft:stonecutter"); public static final Key STONECUTTER = Key.of("minecraft:stonecutter");
public static final Key BELL = Key.of("minecraft:bell"); public static final Key BELL = Key.of("minecraft:bell");

View File

@@ -17,4 +17,8 @@ public class BlockRegistryMirror {
public static int size() { public static int size() {
return customBlockStates.length; return customBlockStates.length;
} }
public static BlockStateWrapper stoneState() {
return stoneState;
}
} }

View File

@@ -1,6 +1,8 @@
package net.momirealms.craftengine.core.block; package net.momirealms.craftengine.core.block;
public interface NoteBlockIndicator { public interface ChainUpdateBlockIndicator {
boolean isNoteBlock(); boolean isNoteBlock();
boolean isTripwire();
} }

View File

@@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior; 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.craftengine.core.util.Key;
import net.momirealms.sparrow.nbt.Tag; import net.momirealms.sparrow.nbt.Tag;

View File

@@ -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.ItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehaviors; import net.momirealms.craftengine.core.item.behavior.ItemBehaviors;
import net.momirealms.craftengine.core.item.modifier.*; 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.LoadingSequence;
import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.pack.Pack;
import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.pack.ResourceLocation;
@@ -491,6 +492,12 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
List<String> data = MiscUtils.getAsStringList(obj); List<String> data = MiscUtils.getAsStringList(obj);
return new RemoveComponentModifier<>(data); return new RemoveComponentModifier<>(data);
}, "remove-components", "remove-component"); }, "remove-components", "remove-component");
registerDataFunction((obj) -> {
Map<String, Object> 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()) { if (VersionHelper.isOrAbove1_21()) {
registerDataFunction((obj) -> { registerDataFunction((obj) -> {

View File

@@ -26,4 +26,5 @@ public final class ComponentKeys {
public static final Key PROFILE = Key.of("minecraft", "profile"); public static final Key PROFILE = Key.of("minecraft", "profile");
public static final Key DYED_COLOR = Key.of("minecraft", "dyed_color"); 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 DEATH_PROTECTION = Key.of("minecraft", "death_protection");
public static final Key FOOD = Key.of("minecraft", "food");
} }

View File

@@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior; 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.craftengine.core.util.Key;
import net.momirealms.sparrow.nbt.Tag; import net.momirealms.sparrow.nbt.Tag;

View File

@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import net.kyori.adventure.text.Component; 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.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;

View File

@@ -3,7 +3,12 @@ package net.momirealms.craftengine.core.item;
import net.momirealms.craftengine.core.entity.ItemDisplayContext; import net.momirealms.craftengine.core.entity.ItemDisplayContext;
import net.momirealms.craftengine.core.entity.projectile.ProjectileMeta; import net.momirealms.craftengine.core.entity.projectile.ProjectileMeta;
import net.momirealms.craftengine.core.item.modifier.EquippableModifier; 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.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.pack.misc.EquipmentGeneration;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.sound.SoundData; import net.momirealms.craftengine.core.sound.SoundData;
@@ -30,13 +35,18 @@ public class ItemSettings {
ProjectileMeta projectileMeta; ProjectileMeta projectileMeta;
boolean dyeable = true; boolean dyeable = true;
Helmet helmet = null; Helmet helmet = null;
FoodData foodData = null;
private ItemSettings() {} private ItemSettings() {}
public <I> List<ItemDataModifier<I>> modifiers() { public <I> List<ItemDataModifier<I>> modifiers() {
ArrayList<ItemDataModifier<I>> modifiers = new ArrayList<>(); ArrayList<ItemDataModifier<I>> modifiers = new ArrayList<>();
if (VersionHelper.isOrAbove1_21_2() && this.equipment != null && this.equipment.modernData() != null) modifiers.add(new EquippableModifier<>(this.equipment.modernData())); if (VersionHelper.isOrAbove1_21_2() && this.equipment != null && this.equipment.modernData() != null) {
// TODO 1.20 leather armor 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; return modifiers;
} }
@@ -60,6 +70,8 @@ public class ItemSettings {
newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock; newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock;
newSettings.projectileMeta = settings.projectileMeta; newSettings.projectileMeta = settings.projectileMeta;
newSettings.dyeable = settings.dyeable; newSettings.dyeable = settings.dyeable;
newSettings.helmet = settings.helmet;
newSettings.foodData = settings.foodData;
return newSettings; return newSettings;
} }
@@ -107,6 +119,11 @@ public class ItemSettings {
return anvilRepairItems; return anvilRepairItems;
} }
@Nullable
public FoodData foodData() {
return foodData;
}
@Nullable @Nullable
public Helmet helmet() { public Helmet helmet() {
return helmet; return helmet;
@@ -152,6 +169,11 @@ public class ItemSettings {
return this; return this;
} }
public ItemSettings foodData(FoodData foodData) {
this.foodData = foodData;
return this;
}
public ItemSettings equipment(EquipmentGeneration equipment) { public ItemSettings equipment(EquipmentGeneration equipment) {
this.equipment = equipment; this.equipment = equipment;
return this; return this;
@@ -249,6 +271,14 @@ public class ItemSettings {
boolean bool = (boolean) value; boolean bool = (boolean) value;
return settings -> settings.dyeable(bool); return settings -> settings.dyeable(bool);
})); }));
registerFactory("food", (value -> {
Map<String, Object> 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) { private static void registerFactory(String id, ItemSettings.Modifier.Factory factory) {

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.item.modifier; 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.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.item.setting.EquipmentData;
public class EquippableModifier<I> implements ItemDataModifier<I> { public class EquippableModifier<I> implements ItemDataModifier<I> {
private final EquipmentData data; private final EquipmentData data;

View File

@@ -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<I> implements ItemDataModifier<I> {
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<I> 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<I> 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));
}
}
}

View File

@@ -27,7 +27,7 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
protected final Map<Key, List<Recipe<T>>> byIngredient = new HashMap<>(); protected final Map<Key, List<Recipe<T>>> byIngredient = new HashMap<>();
protected final Set<Key> dataPackRecipes = new HashSet<>(); protected final Set<Key> dataPackRecipes = new HashSet<>();
protected final Set<Key> customRecipes = new HashSet<>(); protected final Set<Key> customRecipes = new HashSet<>();
private final RecipeParser recipeParser; protected final RecipeParser recipeParser;
protected boolean isReloading; protected boolean isReloading;
public AbstractRecipeManager() { public AbstractRecipeManager() {

View File

@@ -1,4 +1,4 @@
package net.momirealms.craftengine.core.item; package net.momirealms.craftengine.core.item.setting;
import java.util.List; import java.util.List;

View File

@@ -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.entity.EquipmentSlot;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;

View File

@@ -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;
}
}

View File

@@ -1,4 +1,4 @@
package net.momirealms.craftengine.core.item; package net.momirealms.craftengine.core.item.setting;
import net.momirealms.craftengine.core.sound.SoundData; import net.momirealms.craftengine.core.sound.SoundData;

View File

@@ -8,7 +8,7 @@ import dev.dejvokep.boostedyaml.block.implementation.Section;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.momirealms.craftengine.core.font.BitmapImage; import net.momirealms.craftengine.core.font.BitmapImage;
import net.momirealms.craftengine.core.font.Font; 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.PathContext;
import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionConditional; import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionConditional;
import net.momirealms.craftengine.core.pack.host.ResourcePackHost; import net.momirealms.craftengine.core.pack.host.ResourcePackHost;

View File

@@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.pack.misc;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; 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 org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;

View File

@@ -87,7 +87,8 @@ public class Config {
protected Path resource_pack$delivery$file_to_upload; protected Path resource_pack$delivery$file_to_upload;
protected Component resource_pack$send$prompt; 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 int performance$max_emojis_per_parse;
protected boolean light_system$force_update_light; 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); item$non_italic_tag = config.getBoolean("item.non-italic-tag", false);
// performance // 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); performance$max_emojis_per_parse = config.getInt("performance.max-emojis-per-parse", 32);
// light // light
@@ -391,8 +393,8 @@ public class Config {
return instance.resource_pack$override_uniform_font; return instance.resource_pack$override_uniform_font;
} }
public static int maxChainUpdate() { public static int maxNoteBlockChainUpdate() {
return instance.performance$max_block_chain_update_limit; return instance.performance$max_note_block_chain_update_limit;
} }
public static int maxEmojisPerParse() { public static int maxEmojisPerParse() {

View File

@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3 ahocorasick_version=0.6.3
snake_yaml_version=2.4 snake_yaml_version=2.4
anti_grief_version=0.17 anti_grief_version=0.17
nms_helper_version=0.66.15 nms_helper_version=0.66.16
evalex_version=3.5.0 evalex_version=3.5.0
reactive_streams_version=1.0.4 reactive_streams_version=1.0.4
amazon_awssdk_version=2.31.23 amazon_awssdk_version=2.31.23