9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +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 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());
}
}
}

View File

@@ -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()) {

View File

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

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_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());

View File

@@ -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()) {

View File

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

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 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);

View File

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

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.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;

View File

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

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.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;

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.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<Object> superMethod) throws Exception {
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
ObjectHolder<BlockBehavior> 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());
}
}
}

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.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<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();
List<SectionPos> 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<SectionPos> pos = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, 15);
world.sectionLightUpdated(pos);

View File

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

View File

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

View File

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

View File

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

View File

@@ -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");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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");

View File

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

View File

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

View File

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

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.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<I> extends AbstractModelGenerator impl
List<String> data = MiscUtils.getAsStringList(obj);
return new RemoveComponentModifier<>(data);
}, "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()) {
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 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");
}

View File

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

View File

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

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.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 <I> List<ItemDataModifier<I>> modifiers() {
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()));
// 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<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) {

View File

@@ -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<I> implements ItemDataModifier<I> {
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 Set<Key> dataPackRecipes = new HashSet<>();
protected final Set<Key> customRecipes = new HashSet<>();
private final RecipeParser recipeParser;
protected final RecipeParser recipeParser;
protected boolean isReloading;
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;

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.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;

View File

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

View File

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

View File

@@ -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() {

View File

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