Last active
November 23, 2023 09:27
-
-
Save Jikoo/c0126ce4ad9cc0f5ef3862180e413d80 to your computer and use it in GitHub Desktop.
Block bed placement duplicating crops
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.jikoo.blockbedcropdupe; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import org.bukkit.Material; | |
import org.bukkit.block.Block; | |
import org.bukkit.block.BlockFace; | |
import org.bukkit.block.BlockState; | |
import org.bukkit.block.data.Ageable; | |
import org.bukkit.entity.Player; | |
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.player.PlayerInteractEvent; | |
import org.bukkit.plugin.java.JavaPlugin; | |
import org.jetbrains.annotations.NotNull; | |
public class BlockBedCropDupe extends JavaPlugin implements Listener { | |
private final BlockFace[] adjacents = { | |
BlockFace.NORTH, | |
BlockFace.SOUTH, | |
BlockFace.EAST, | |
BlockFace.WEST | |
}; | |
private final Map<Material, MultiBlockShape> multiBlocks = new HashMap<>(); | |
@Override | |
public void onEnable() { | |
MultiBlockShape bedShape = (block, player) -> Arrays.asList( | |
block.getState(), | |
block.getRelative(player.getFacing()).getState() | |
); | |
for (Material material : Material.values()) { | |
if (material.name().endsWith("_BED")) { | |
multiBlocks.put(material, bedShape); | |
} | |
} | |
getServer().getPluginManager().registerEvents(this, this); | |
} | |
@Override | |
public void onDisable() { | |
multiBlocks.clear(); | |
} | |
public void addMultiBlockMat(@NotNull Material material, @NotNull MultiBlockShape shape) { | |
multiBlocks.put(material, shape); | |
} | |
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) | |
private void preBlockMultiPlace(@NotNull PlayerInteractEvent event) { | |
if (event.getAction() != Action.RIGHT_CLICK_BLOCK | |
|| event.getClickedBlock() == null | |
|| event.getItem() == null) { | |
// Non-placement. | |
return; | |
} | |
MultiBlockShape shape = multiBlocks.get(event.getItem().getType()); | |
if (shape == null) { | |
// Non-multiblock placement. | |
return; | |
} | |
// Fast-placing client sends placement packets on ghost blocks. Since the ghost block is air, | |
// the block is placed inside it instead. | |
Block placeLocation; | |
if (event.getClickedBlock().getType() == Material.AIR) { | |
placeLocation = event.getClickedBlock(); | |
} else { | |
placeLocation = event.getClickedBlock().getRelative(event.getBlockFace()); | |
} | |
// Server only erroneously updates blocks adjacent to the origin block, i.e. the bed foot. | |
boolean adjacentCrop = false; | |
for (BlockFace adjacentFace : adjacents) { | |
if (placeLocation.getRelative(adjacentFace).getBlockData() instanceof Ageable) { | |
// There's an adjacent crop, this is a potential dupe. | |
adjacentCrop = true; | |
break; | |
} | |
} | |
if (!adjacentCrop) { | |
// No adjacent crops, no dupe risk. | |
return; | |
} | |
BlockMultiPlaceEvent fakeEvent = new BlockMultiPlaceEvent( | |
shape.getBlocks(placeLocation, event.getPlayer()), | |
placeLocation, | |
event.getItem(), | |
event.getPlayer(), | |
true); | |
getServer().getPluginManager().callEvent(fakeEvent); | |
if (fakeEvent.isCancelled()) { | |
// Protection plugin cancelled our pre-fire event. | |
event.setCancelled(true); | |
} | |
} | |
public interface MultiBlockShape { | |
@NotNull List<BlockState> getBlocks(@NotNull Block start, @NotNull Player player); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main: com.github.jikoo.blockbedcropdupe.BlockBedCropDupe | |
name: BlockBedCropDupe | |
version: ${project.version} | |
api-version: 1.13 | |
author: Jikoo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment