mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Fixes #2817
This commit is contained in:
parent
45a48288b2
commit
e2f3944d66
@ -37,6 +37,7 @@
|
||||
* Fixed #2809
|
||||
* Fixed #2810
|
||||
* Fixed #2804
|
||||
* Fixed #2817
|
||||
* Fixed a small exception which gets thrown when Slimefun is disabled due to an invalid environment
|
||||
|
||||
## Release Candidate 20 (30 Jan 2021)
|
||||
|
@ -3,6 +3,9 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
@ -13,10 +16,10 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Dispenser;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||
@ -47,15 +50,17 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||
*/
|
||||
public class BlockPlacer extends SlimefunItem {
|
||||
|
||||
private final ItemSetting<List<String>> blacklist = new MaterialTagSetting("unplaceable-blocks", SlimefunTag.UNBREAKABLE_MATERIALS);
|
||||
private final ItemSetting<List<String>> unplaceableBlocks = new MaterialTagSetting("unplaceable-blocks", SlimefunTag.UNBREAKABLE_MATERIALS);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(category, item, recipeType, recipe);
|
||||
|
||||
addItemSetting(blacklist);
|
||||
addItemSetting(unplaceableBlocks);
|
||||
addItemHandler(onPlace(), onBlockDispense());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private BlockPlaceHandler onPlace() {
|
||||
return new BlockPlaceHandler(false) {
|
||||
|
||||
@ -69,6 +74,7 @@ public class BlockPlacer extends SlimefunItem {
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private BlockDispenseHandler onBlockDispense() {
|
||||
return (e, dispenser, facedBlock, machine) -> {
|
||||
if (!hasPermission(dispenser, facedBlock)) {
|
||||
@ -79,7 +85,7 @@ public class BlockPlacer extends SlimefunItem {
|
||||
Material material = e.getItem().getType();
|
||||
|
||||
if (SlimefunTag.SHULKER_BOXES.isTagged(material)) {
|
||||
/**
|
||||
/*
|
||||
* Since vanilla Dispensers can already place Shulker boxes,
|
||||
* we simply fallback to the vanilla behaviour.
|
||||
*/
|
||||
@ -89,7 +95,7 @@ public class BlockPlacer extends SlimefunItem {
|
||||
e.setCancelled(true);
|
||||
|
||||
if (!material.isBlock() || SlimefunTag.BLOCK_PLACER_IGNORED_MATERIALS.isTagged(material)) {
|
||||
/**
|
||||
/*
|
||||
* Some materials cannot be reliably placed, like beds,
|
||||
* it would look kinda wonky, so we just ignore these altogether.
|
||||
* The event has already been cancelled too, so they won't drop.
|
||||
@ -97,7 +103,7 @@ public class BlockPlacer extends SlimefunItem {
|
||||
return;
|
||||
}
|
||||
|
||||
if (facedBlock.isEmpty() && !isBlacklisted(material) && dispenser.getInventory().getViewers().isEmpty()) {
|
||||
if (facedBlock.isEmpty() && isAllowed(material) && dispenser.getInventory().getViewers().isEmpty()) {
|
||||
SlimefunItem item = SlimefunItem.getByItem(e.getItem());
|
||||
|
||||
if (item != null) {
|
||||
@ -123,11 +129,12 @@ public class BlockPlacer extends SlimefunItem {
|
||||
*
|
||||
* @return Whether this action is permitted or not
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
private boolean hasPermission(Dispenser dispenser, Block target) {
|
||||
String owner = BlockStorage.getLocationInfo(dispenser.getLocation(), "owner");
|
||||
|
||||
if (owner == null) {
|
||||
/**
|
||||
/*
|
||||
* If no owner was set, then we will fallback to the previous behaviour:
|
||||
* Allowing block placers to bypass protection, newly placed Block placers
|
||||
* will respect protection plugins.
|
||||
@ -135,20 +142,30 @@ public class BlockPlacer extends SlimefunItem {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the corresponding OfflinePlayer
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(owner));
|
||||
return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK);
|
||||
}
|
||||
|
||||
private boolean isBlacklisted(Material type) {
|
||||
for (String blockType : blacklist.getValue()) {
|
||||
/**
|
||||
* This checks if the given {@link Material} is allowed to be placed.
|
||||
*
|
||||
* @param type
|
||||
* The {@link Material} to check
|
||||
*
|
||||
* @return Whether placing this {@link Material} is allowed
|
||||
*/
|
||||
private boolean isAllowed(@Nonnull Material type) {
|
||||
for (String blockType : unplaceableBlocks.getValue()) {
|
||||
if (type.toString().equals(blockType)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void placeSlimefunBlock(SlimefunItem sfItem, ItemStack item, Block block, Dispenser dispenser) {
|
||||
BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, block);
|
||||
Bukkit.getPluginManager().callEvent(e);
|
||||
@ -156,68 +173,78 @@ public class BlockPlacer extends SlimefunItem {
|
||||
if (!e.isCancelled()) {
|
||||
boolean hasItemHandler = sfItem.callItemHandler(BlockPlaceHandler.class, handler -> {
|
||||
if (handler.isBlockPlacerAllowed()) {
|
||||
block.setType(item.getType());
|
||||
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType());
|
||||
schedulePlacement(block, dispenser.getInventory(), item, () -> {
|
||||
block.setType(item.getType());
|
||||
BlockStorage.store(block, sfItem.getId());
|
||||
|
||||
BlockStorage.store(block, sfItem.getId());
|
||||
handler.onBlockPlacerPlace(e);
|
||||
|
||||
if (dispenser.getInventory().containsAtLeast(item, 2)) {
|
||||
dispenser.getInventory().removeItem(new CustomItem(item, 1));
|
||||
} else {
|
||||
SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
|
||||
}
|
||||
handler.onBlockPlacerPlace(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasItemHandler) {
|
||||
block.setType(item.getType());
|
||||
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType());
|
||||
|
||||
BlockStorage.store(block, sfItem.getId());
|
||||
|
||||
if (dispenser.getInventory().containsAtLeast(item, 2)) {
|
||||
dispenser.getInventory().removeItem(new CustomItem(item, 1));
|
||||
} else {
|
||||
SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
|
||||
}
|
||||
schedulePlacement(block, dispenser.getInventory(), item, () -> {
|
||||
block.setType(item.getType());
|
||||
BlockStorage.store(block, sfItem.getId());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void placeBlock(ItemStack item, Block facedBlock, Dispenser dispenser) {
|
||||
BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, facedBlock);
|
||||
Bukkit.getPluginManager().callEvent(e);
|
||||
|
||||
if (!e.isCancelled()) {
|
||||
facedBlock.setType(item.getType());
|
||||
schedulePlacement(facedBlock, dispenser.getInventory(), item, () -> {
|
||||
facedBlock.setType(item.getType());
|
||||
|
||||
if (item.hasItemMeta()) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (item.hasItemMeta()) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta.hasDisplayName()) {
|
||||
BlockStateSnapshotResult blockState = PaperLib.getBlockState(facedBlock, false);
|
||||
if (meta.hasDisplayName()) {
|
||||
BlockStateSnapshotResult blockState = PaperLib.getBlockState(facedBlock, false);
|
||||
|
||||
if ((blockState.getState() instanceof Nameable)) {
|
||||
Nameable nameable = ((Nameable) blockState.getState());
|
||||
nameable.setCustomName(meta.getDisplayName());
|
||||
if ((blockState.getState() instanceof Nameable)) {
|
||||
Nameable nameable = ((Nameable) blockState.getState());
|
||||
nameable.setCustomName(meta.getDisplayName());
|
||||
|
||||
if (blockState.isSnapshot()) {
|
||||
// Update block state after changing name
|
||||
blockState.getState().update(true, false);
|
||||
if (blockState.isSnapshot()) {
|
||||
// Update block state after changing name
|
||||
blockState.getState().update(true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
facedBlock.getWorld().playEffect(facedBlock.getLocation(), Effect.STEP_SOUND, item.getType());
|
||||
|
||||
if (dispenser.getInventory().containsAtLeast(item, 2)) {
|
||||
dispenser.getInventory().removeItem(new CustomItem(item, 1));
|
||||
} else {
|
||||
SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void schedulePlacement(Block b, Inventory inv, ItemStack item, Runnable runnable) {
|
||||
// We need to delay this due to Dispenser-Inventory synchronization issues in Spigot.
|
||||
SlimefunPlugin.runSync(() -> {
|
||||
// Make sure the Block has not been occupied yet
|
||||
if (b.isEmpty()) {
|
||||
// Only remove 1 item.
|
||||
ItemStack removedItem = item.clone();
|
||||
removedItem.setAmount(1);
|
||||
|
||||
// Play particles
|
||||
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, item.getType());
|
||||
|
||||
// Make sure the item was actually removed (fixes #2817)
|
||||
|
||||
try {
|
||||
if (inv.removeItem(removedItem).isEmpty()) {
|
||||
runnable.run();
|
||||
}
|
||||
} catch (Exception x) {
|
||||
error("An Exception was thrown while a BlockPlacer was performing its action", x);
|
||||
}
|
||||
}
|
||||
}, 2L);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user