From 997dab645bf672da454a0b1297f77cca281ebb1d Mon Sep 17 00:00:00 2001 From: Dueris Date: Fri, 15 Nov 2024 22:30:45 -0800 Subject: [PATCH] make ModifyBlockRenderPowerType call on block updates and block section updates --- .../originspaper/access/BlockStateOwner.java | 9 ++++ .../access/SectionBlocksOwner.java | 12 +++++ .../ClientboundBlockUpdatePacketMixin.java | 27 +++++++++++ ...ntboundSectionBlocksUpdatePacketMixin.java | 42 ++++++++++++++++ .../ServerCommonPacketListenerImplMixin.java | 48 +++++++++++++++++++ .../type/ModifyBlockRenderPowerType.java | 9 +++- .../src/main/resources/origins.accesswidener | 1 + .../src/main/resources/origins.mixins.json | 5 +- 8 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 origins/src/main/java/io/github/dueris/originspaper/access/BlockStateOwner.java create mode 100644 origins/src/main/java/io/github/dueris/originspaper/access/SectionBlocksOwner.java create mode 100644 origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundBlockUpdatePacketMixin.java create mode 100644 origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundSectionBlocksUpdatePacketMixin.java create mode 100644 origins/src/main/java/io/github/dueris/originspaper/mixin/ServerCommonPacketListenerImplMixin.java diff --git a/origins/src/main/java/io/github/dueris/originspaper/access/BlockStateOwner.java b/origins/src/main/java/io/github/dueris/originspaper/access/BlockStateOwner.java new file mode 100644 index 00000000..364b9922 --- /dev/null +++ b/origins/src/main/java/io/github/dueris/originspaper/access/BlockStateOwner.java @@ -0,0 +1,9 @@ +package io.github.dueris.originspaper.access; + +import net.minecraft.core.SectionPos; +import net.minecraft.world.level.block.state.BlockState; + +public interface BlockStateOwner { + void apoli$setBlockState(BlockState state); + BlockState apoli$getBlockState(); +} diff --git a/origins/src/main/java/io/github/dueris/originspaper/access/SectionBlocksOwner.java b/origins/src/main/java/io/github/dueris/originspaper/access/SectionBlocksOwner.java new file mode 100644 index 00000000..a7d7c29e --- /dev/null +++ b/origins/src/main/java/io/github/dueris/originspaper/access/SectionBlocksOwner.java @@ -0,0 +1,12 @@ +package io.github.dueris.originspaper.access; + +import net.minecraft.core.SectionPos; +import net.minecraft.world.level.block.state.BlockState; + +public interface SectionBlocksOwner { + void apoli$setBlockStates(BlockState[] states); + BlockState[] apoli$getBlockStates(); + + SectionPos apoli$sectionPos(); + short[] apoli$positions(); +} diff --git a/origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundBlockUpdatePacketMixin.java b/origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundBlockUpdatePacketMixin.java new file mode 100644 index 00000000..c0ad8192 --- /dev/null +++ b/origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundBlockUpdatePacketMixin.java @@ -0,0 +1,27 @@ +package io.github.dueris.originspaper.mixin; + +import io.github.dueris.originspaper.access.BlockStateOwner; +import net.minecraft.core.SectionPos; +import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +/** + * Need to update blocks for {@link io.github.dueris.originspaper.power.type.ModifyBlockRenderPowerType}... + */ +@Mixin(ClientboundBlockUpdatePacket.class) +public class ClientboundBlockUpdatePacketMixin implements BlockStateOwner { + @Shadow + public BlockState blockState; + + @Override + public void apoli$setBlockState(BlockState state) { + this.blockState = state; + } + + @Override + public BlockState apoli$getBlockState() { + return this.blockState; + } +} diff --git a/origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundSectionBlocksUpdatePacketMixin.java b/origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundSectionBlocksUpdatePacketMixin.java new file mode 100644 index 00000000..aa69bbd5 --- /dev/null +++ b/origins/src/main/java/io/github/dueris/originspaper/mixin/ClientboundSectionBlocksUpdatePacketMixin.java @@ -0,0 +1,42 @@ +package io.github.dueris.originspaper.mixin; + +import io.github.dueris.originspaper.access.BlockStateOwner; +import io.github.dueris.originspaper.access.SectionBlocksOwner; +import net.minecraft.core.SectionPos; +import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +/** + * Primarily used to maintain compatibility with {@link io.github.dueris.originspaper.power.type.ModifyBlockRenderPowerType} and plugins + */ +@Mixin(ClientboundSectionBlocksUpdatePacket.class) +public class ClientboundSectionBlocksUpdatePacketMixin implements SectionBlocksOwner { + @Shadow @Final private BlockState[] states; + + @Shadow @Final private SectionPos sectionPos; + + @Shadow @Final private short[] positions; + + @Override + public void apoli$setBlockStates(BlockState[] states) { + System.arraycopy(states, 0, this.states, 0, states.length); + } + + @Override + public BlockState[] apoli$getBlockStates() { + return this.states; + } + + @Override + public SectionPos apoli$sectionPos() { + return this.sectionPos; + } + + @Override + public short[] apoli$positions() { + return this.positions; + } +} diff --git a/origins/src/main/java/io/github/dueris/originspaper/mixin/ServerCommonPacketListenerImplMixin.java b/origins/src/main/java/io/github/dueris/originspaper/mixin/ServerCommonPacketListenerImplMixin.java new file mode 100644 index 00000000..4ca95280 --- /dev/null +++ b/origins/src/main/java/io/github/dueris/originspaper/mixin/ServerCommonPacketListenerImplMixin.java @@ -0,0 +1,48 @@ +package io.github.dueris.originspaper.mixin; + +import io.github.dueris.originspaper.access.BlockStateOwner; +import io.github.dueris.originspaper.access.SectionBlocksOwner; +import io.github.dueris.originspaper.component.PowerHolderComponent; +import io.github.dueris.originspaper.power.type.ModifyBlockRenderPowerType; +import net.minecraft.network.PacketSendListener; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerCommonPacketListenerImpl; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerCommonPacketListenerImpl.class) +public class ServerCommonPacketListenerImplMixin { + + @Shadow @Final protected ServerPlayer player; + + @Inject(method = "send(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketSendListener;)V", at = @At("HEAD")) + public void apoli$modifyBlockRender(Packet packet, PacketSendListener callbacks, CallbackInfo ci) { + if (packet instanceof ClientboundBlockUpdatePacket blockUpdatePacket) { + for (ModifyBlockRenderPowerType powerType : PowerHolderComponent.getPowerTypes(player, ModifyBlockRenderPowerType.class)) { + if (powerType.doesPrevent(player.level(), blockUpdatePacket.getPos())) { + ((BlockStateOwner) blockUpdatePacket).apoli$setBlockState(powerType.getBlockState()); + } + } + } else if (packet instanceof ClientboundSectionBlocksUpdatePacket sectionBlocksUpdatePacket) { + SectionBlocksOwner sectionBlocksOwner = (SectionBlocksOwner) sectionBlocksUpdatePacket; + BlockState[] states = sectionBlocksOwner.apoli$getBlockStates(); + short[] positions = sectionBlocksOwner.apoli$positions(); + for (ModifyBlockRenderPowerType powerType : PowerHolderComponent.getPowerTypes(player, ModifyBlockRenderPowerType.class)) { + if (powerType.isSending()) continue; + for (int i = 0; i < states.length; i++) { + if (powerType.doesPrevent(player.level(), sectionBlocksOwner.apoli$sectionPos().relativeToBlockPos(positions[i]))) { + states[i] = powerType.getBlockState(); + } + } + } + } + } +} diff --git a/origins/src/main/java/io/github/dueris/originspaper/power/type/ModifyBlockRenderPowerType.java b/origins/src/main/java/io/github/dueris/originspaper/power/type/ModifyBlockRenderPowerType.java index b7fc9dcd..029f751e 100644 --- a/origins/src/main/java/io/github/dueris/originspaper/power/type/ModifyBlockRenderPowerType.java +++ b/origins/src/main/java/io/github/dueris/originspaper/power/type/ModifyBlockRenderPowerType.java @@ -52,6 +52,7 @@ public class ModifyBlockRenderPowerType extends PowerType { private final Optional blockCondition; private final BlockState blockState; private boolean refreshingChunks = false; + private boolean sending; public ModifyBlockRenderPowerType(Optional blockCondition, BlockState state) { this.blockCondition = blockCondition; @@ -96,18 +97,24 @@ public BlockState getBlockState() { return blockState; } + public boolean isSending() { + return this.sending; + } + public record RenderUpdate(Chunk chunk, ServerLevel level, ServerPlayer player) implements Consumer { @Override public void accept(@NotNull ModifyBlockRenderPowerType mbrpt) { - if (player.hasDisconnected() || mbrpt.refreshingChunks) return; + if (player.hasDisconnected() || mbrpt.refreshingChunks) return; // TODO - dueris - remove Map updates = new ConcurrentHashMap<>(); BlockData toSend = mbrpt.getBlockState().createCraftBlockData(); Util.runOnAllMatchingBlocks(chunk, mbrpt::doesPrevent, (pos) -> updates.put(MCUtil.toPosition(pos), toSend)); + mbrpt.sending = true; player.getBukkitEntity().sendMultiBlockChange(updates); + mbrpt.sending = false; } } } diff --git a/origins/src/main/resources/origins.accesswidener b/origins/src/main/resources/origins.accesswidener index 306a9ab1..322a9b8b 100644 --- a/origins/src/main/resources/origins.accesswidener +++ b/origins/src/main/resources/origins.accesswidener @@ -36,3 +36,4 @@ mutable field net/minecraft/world/level/storage/loot/LootTable$Builder poo accessible field net/minecraft/world/level/storage/loot/LootTable$Builder pools Lcom/google/common/collect/ImmutableList$Builder; mutable field net/minecraft/world/level/storage/loot/LootTable$Builder functions Lcom/google/common/collect/ImmutableList$Builder; accessible field net/minecraft/world/level/storage/loot/LootTable$Builder functions Lcom/google/common/collect/ImmutableList$Builder; +mutable field net/minecraft/network/protocol/game/ClientboundBlockUpdatePacket blockState Lnet/minecraft/world/level/block/state/BlockState; diff --git a/origins/src/main/resources/origins.mixins.json b/origins/src/main/resources/origins.mixins.json index c647130d..3f986fa0 100644 --- a/origins/src/main/resources/origins.mixins.json +++ b/origins/src/main/resources/origins.mixins.json @@ -61,7 +61,10 @@ "AdvancementCommandsAccessor", "ServerPlayerGameModeAccessor", "PlayerChunkSenderMixin", - "CraftEventFactoryMixin" + "CraftEventFactoryMixin", + "ClientboundBlockUpdatePacketMixin", + "ServerCommonPacketListenerImplMixin", + "ClientboundSectionBlocksUpdatePacketMixin" ], "compatibilityLevel": "JAVA_17" }