diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index e41b66b9..906bc971 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -305,6 +305,9 @@ public class CarpetSettings @Rule(desc = "fill/clone/setblock and structure blocks cause block updates", category = CREATIVE) public static boolean fillUpdates = true; + @Rule(desc = "placing blocks cause block updates", category = CREATIVE) + public static boolean interactionUpdates = true; + @Rule(desc = "smooth client animations with low tps settings", extra = "works only in SP, and will slow down players", category = CREATIVE) public static boolean smoothClientAnimations; diff --git a/src/main/java/carpet/mixins/ServerPlayNetworkHandler_interactionUpdatesMixin.java b/src/main/java/carpet/mixins/ServerPlayNetworkHandler_interactionUpdatesMixin.java new file mode 100644 index 00000000..5967b45f --- /dev/null +++ b/src/main/java/carpet/mixins/ServerPlayNetworkHandler_interactionUpdatesMixin.java @@ -0,0 +1,81 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.packet.PlayerActionC2SPacket; +import net.minecraft.server.network.packet.PlayerInteractBlockC2SPacket; +import net.minecraft.server.network.packet.PlayerInteractItemC2SPacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerPlayNetworkHandler.class) +public class ServerPlayNetworkHandler_interactionUpdatesMixin +{ + @Inject(method = "onPlayerInteractBlock", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;interactBlock(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Lnet/minecraft/util/ActionResult;", + shift = At.Shift.BEFORE + )) + private void beforeBlockInteracted(PlayerInteractBlockC2SPacket playerInteractBlockC2SPacket_1, CallbackInfo ci) + { + if (!CarpetSettings.interactionUpdates) + CarpetSettings.impendingFillSkipUpdates = true; + } + + @Inject(method = "onPlayerInteractBlock", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;interactBlock(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Lnet/minecraft/util/ActionResult;", + shift = At.Shift.AFTER + )) + private void afterBlockInteracted(PlayerInteractBlockC2SPacket playerInteractBlockC2SPacket_1, CallbackInfo ci) + { + if (!CarpetSettings.interactionUpdates) + CarpetSettings.impendingFillSkipUpdates = false; + } + + @Inject(method = "onPlayerInteractItem", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;interactItem(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;)Lnet/minecraft/util/ActionResult;", + shift = At.Shift.BEFORE + )) + private void beforeItemInteracted(PlayerInteractItemC2SPacket packet, CallbackInfo ci) + { + if (!CarpetSettings.interactionUpdates) + CarpetSettings.impendingFillSkipUpdates = true; + } + + @Inject(method = "onPlayerInteractItem", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;interactItem(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;)Lnet/minecraft/util/ActionResult;", + shift = At.Shift.AFTER + )) + private void afterItemInteracted(PlayerInteractItemC2SPacket packet, CallbackInfo ci) + { + if (!CarpetSettings.interactionUpdates) + CarpetSettings.impendingFillSkipUpdates = false; + } + @Inject(method = "onPlayerAction", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;method_14263(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/server/network/packet/PlayerActionC2SPacket$Action;Lnet/minecraft/util/math/Direction;I)V", + shift = At.Shift.BEFORE + )) + private void beforeBlockBroken(PlayerActionC2SPacket packet, CallbackInfo ci) + { + if (!CarpetSettings.interactionUpdates) + CarpetSettings.impendingFillSkipUpdates = true; + } + + @Inject(method = "onPlayerAction", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;method_14263(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/server/network/packet/PlayerActionC2SPacket$Action;Lnet/minecraft/util/math/Direction;I)V", + shift = At.Shift.AFTER + )) + private void afterBlockBroken(PlayerActionC2SPacket packet, CallbackInfo ci) + { + if (!CarpetSettings.interactionUpdates) + CarpetSettings.impendingFillSkipUpdates = false; + } + +} diff --git a/src/main/java/carpet/mixins/World_fillUpdatesMixin.java b/src/main/java/carpet/mixins/World_fillUpdatesMixin.java index 8c80014a..4459e3e1 100644 --- a/src/main/java/carpet/mixins/World_fillUpdatesMixin.java +++ b/src/main/java/carpet/mixins/World_fillUpdatesMixin.java @@ -1,10 +1,14 @@ package carpet.mixins; import carpet.CarpetSettings; +import net.minecraft.block.Block; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(World.class) public abstract class World_fillUpdatesMixin @@ -16,4 +20,14 @@ public abstract class World_fillUpdatesMixin return -1; return original; } + + @Redirect(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/World;updateNeighbors(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/Block;)V" + )) + private void updateNeighborsMaybe(World world, BlockPos blockPos, Block block) + { + if (!CarpetSettings.impendingFillSkipUpdates) world.updateNeighbors(blockPos, block); + } + } diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 4741d425..efe96e4e 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -2292,7 +2292,9 @@ public class CarpetExpression boolean hasTag = false; if (lv.size() > position.offset) { - NBTSerializableValue v = NBTSerializableValue.parseString(lv.get(position.offset).evalValue(c).getString()); + Value nbt = lv.get(position.offset).evalValue(c); + NBTSerializableValue v = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt + : NBTSerializableValue.parseString(nbt.getString()); if (v != null) { hasTag = true; diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 6f294724..26935e54 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -14,6 +14,7 @@ "WorldChunk_fillUpdatesMixin", "StructureBlockBlockEntity_fillUpdatesMixin", "Structure_fillUpdatesMixin", + "ServerPlayNetworkHandler_interactionUpdatesMixin", "ServerMetadata_motdMixin",