Skip to content

Commit

Permalink
Fix #500
Browse files Browse the repository at this point in the history
  • Loading branch information
NichtStudioCode committed Nov 16, 2024
1 parent cac7baa commit 2238161
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 15 deletions.
3 changes: 2 additions & 1 deletion nova/src/main/kotlin/xyz/xenondevs/nova/patch/Patcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import xyz.xenondevs.nova.patch.impl.FieldFilterPatch
import xyz.xenondevs.nova.patch.impl.block.BlockBehaviorPatches
import xyz.xenondevs.nova.patch.impl.block.BlockMigrationPatches
import xyz.xenondevs.nova.patch.impl.block.DisableBackingStateLogicPatch
import xyz.xenondevs.nova.patch.impl.block.EarlyBlockPlaceEventPatch
import xyz.xenondevs.nova.patch.impl.block.FluidFlowPatch
import xyz.xenondevs.nova.patch.impl.block.TripwireLogicPatch
import xyz.xenondevs.nova.patch.impl.bossbar.BossBarOriginPatch
Expand Down Expand Up @@ -64,7 +65,7 @@ internal object Patcher {
BroadcastPacketPatch, EventPreventionPatch, WearablePatch, BossBarOriginPatch,
FakePlayerLastHurtPatch, BlockBehaviorPatches, ChunkSchedulingPatch, DisableBackingStateLogicPatch,
ItemStackDataComponentsPatch, EnchantmentPatches, TagsPatch, RepairPatches, BlockMigrationPatches,
TripwireLogicPatch, FluidFlowPatch
TripwireLogicPatch, FluidFlowPatch, EarlyBlockPlaceEventPatch
).filter(Transformer::shouldTransform).toSet()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package xyz.xenondevs.nova.patch.impl.block

import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.block.state.BlockState
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.MethodInsnNode
import xyz.xenondevs.bytebase.jvm.VirtualClassPath
import xyz.xenondevs.bytebase.util.calls
import xyz.xenondevs.bytebase.util.replaceEvery
import xyz.xenondevs.nova.LOGGER
import xyz.xenondevs.nova.patch.MultiTransformer
import xyz.xenondevs.nova.util.reflection.ReflectionUtils
import xyz.xenondevs.nova.util.toNovaPos
import xyz.xenondevs.nova.world.block.logic.place.BlockPlacing
import java.util.logging.Level

private val BLOCK_ITEM_PLACE_BLOCK = ReflectionUtils.getMethod(BlockItem::class, "placeBlock", BlockPlaceContext::class, BlockState::class)

internal object EarlyBlockPlaceEventPatch : MultiTransformer(BlockItem::class) {

override fun transform() {
VirtualClassPath[BlockItem::place].replaceEvery(
0, 0,
{ invokeStatic(::placeBlock) }
) { it.opcode == Opcodes.INVOKEVIRTUAL && (it as MethodInsnNode).calls(BLOCK_ITEM_PLACE_BLOCK) }
dumpAll()
}

@JvmStatic
fun placeBlock(blockItem: BlockItem, context: BlockPlaceContext, state: BlockState): Boolean {
try {
val pos = context.clickedPos.toNovaPos(context.level.world)
if (!BlockPlacing.handleBlockPlace(pos)) {
context.player?.containerMenu?.sendAllDataToRemote()
return false
}
} catch(t: Throwable) {
LOGGER.log(Level.SEVERE, "An exception occurred while handling early block place event", t)
}

return BLOCK_ITEM_PLACE_BLOCK.invoke(blockItem, context, state) as Boolean
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener
import org.bukkit.event.block.Action
import org.bukkit.event.block.BlockMultiPlaceEvent
import org.bukkit.event.block.BlockPlaceEvent
import org.bukkit.event.player.PlayerBucketEmptyEvent
import org.bukkit.event.player.PlayerBucketFillEvent
import org.bukkit.event.player.PlayerInteractEvent
Expand Down Expand Up @@ -63,18 +61,10 @@ internal object BlockPlacing : Listener {
// However, we want to permit this for built-in custom blocks, as those might have their
// WorldDataManager entry set before this event is called (block migration patch)

@EventHandler(ignoreCancelled = true)
private fun handleBlockPlace(event: BlockPlaceEvent) {
val blockState = WorldDataManager.getBlockState(event.block.pos)
event.isCancelled = blockState != null && blockState.block.id.namespace != "nova"
}

@EventHandler(ignoreCancelled = true)
private fun handleBlockPlace(event: BlockMultiPlaceEvent) {
event.isCancelled = event.replacedBlockStates.any {
val blockState = WorldDataManager.getBlockState(it.location.pos)
blockState != null && blockState.block.id.namespace != "nova"
}
// requires earlier block place event because BlockMigrator has already removed WorldDataManager entry already otherwise
fun handleBlockPlace(pos: BlockPos): Boolean {
val blockState = WorldDataManager.getBlockState(pos)
return blockState == null || blockState.block.id.namespace == "nova"
}

@EventHandler(ignoreCancelled = true)
Expand Down

0 comments on commit 2238161

Please sign in to comment.