1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00
This commit is contained in:
TheBusyBiscuit 2020-08-18 14:18:44 +02:00
parent 85b0c80e3f
commit 6be0709aea
3 changed files with 109 additions and 46 deletions

View File

@ -43,6 +43,7 @@
* Crafting a Rag now yields two items
* Small performance improvements for Slimefun guides
* Small performance improvements for Cargo networks
* Small performance improvements for Miner Androids
#### Fixes
* Fixed Programmable Androids rotating in the wrong direction
@ -68,6 +69,7 @@
* Fixed #2207
* Fixed ChestTerminal timings showing up as cargo nodes
* Fixed timings reports never arriving sometimes
* Fixed #2138
## Release Candidate 15 (01 Aug 2020)

View File

@ -6,6 +6,7 @@ import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack;
@ -39,24 +40,28 @@ public abstract class MinerAndroid extends ProgrammableAndroid {
protected void dig(Block b, BlockMenu menu, Block block) {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty() && SlimefunPlugin.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))), block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) {
OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")));
AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b));
Bukkit.getPluginManager().callEvent(event);
if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
if (event.isCancelled()) {
return;
}
// We only want to break non-Slimefun blocks
String blockId = BlockStorage.checkID(block);
if (blockId == null) {
for (ItemStack drop : drops) {
if (menu.fits(drop, getOutputSlots())) {
menu.pushItem(drop, getOutputSlots());
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
block.setType(Material.AIR);
// We only want to break non-Slimefun blocks
String blockId = BlockStorage.checkID(block);
if (blockId == null) {
for (ItemStack drop : drops) {
if (menu.fits(drop, getOutputSlots())) {
menu.pushItem(drop, getOutputSlots());
}
}
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
block.setType(Material.AIR);
}
}
}
@ -66,30 +71,34 @@ public abstract class MinerAndroid extends ProgrammableAndroid {
protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty() && SlimefunPlugin.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))), block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) {
OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")));
AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b));
Bukkit.getPluginManager().callEvent(event);
if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
// We only want to break non-Slimefun blocks
SlimefunItem blockId = BlockStorage.check(block);
if (blockId == null) {
for (ItemStack drop : drops) {
if (menu.fits(drop, getOutputSlots())) {
menu.pushItem(drop, getOutputSlots());
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
block.setType(Material.AIR);
move(b, face, block);
b.setType(Material.AIR);
BlockStorage.moveBlockInfo(b.getLocation(), block.getLocation());
}
if (event.isCancelled()) {
return;
}
// We only want to break non-Slimefun blocks
SlimefunItem blockId = BlockStorage.check(block);
if (blockId == null) {
for (ItemStack drop : drops) {
if (menu.fits(drop, getOutputSlots())) {
menu.pushItem(drop, getOutputSlots());
}
}
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
block.setType(Material.AIR);
move(b, face, block);
}
}
else {
move(b, face, block);
}
}
else {

View File

@ -1,26 +1,33 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Nameable;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Dispenser;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.papermc.lib.PaperLib;
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -39,7 +46,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see BlockPlacerPlaceEvent
*
*/
public class BlockPlacer extends SimpleSlimefunItem<BlockDispenseHandler> {
public class BlockPlacer extends SlimefunItem {
private final ItemSetting<List<String>> blacklist = new ItemSetting<>("unplaceable-blocks", MaterialCollections.getAllUnbreakableBlocks().stream().map(Material::name).collect(Collectors.toList()));
@ -47,11 +54,28 @@ public class BlockPlacer extends SimpleSlimefunItem<BlockDispenseHandler> {
super(category, item, recipeType, recipe);
addItemSetting(blacklist);
addItemHandler(onPlace(), onBlockDispense());
}
@Override
public BlockDispenseHandler getItemHandler() {
private BlockPlaceHandler onPlace() {
return new BlockPlaceHandler(false) {
@Override
public void onPlayerPlace(BlockPlaceEvent e) {
Player p = e.getPlayer();
Block b = e.getBlock();
BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString());
}
};
}
private BlockDispenseHandler onBlockDispense() {
return (e, dispenser, facedBlock, machine) -> {
if (!hasPermission(dispenser, facedBlock)) {
return;
}
if (isShulkerBox(e.getItem().getType())) {
// Since vanilla Dispensers can already place Shulker boxes, we
// simply fallback to the vanilla behaviour.
@ -76,6 +100,31 @@ public class BlockPlacer extends SimpleSlimefunItem<BlockDispenseHandler> {
};
}
/**
* This checks whether the {@link Player} who placed down this {@link BlockPlacer} has
* building permissions at that {@link Location}.
*
* @param dispenser
* The {@link Dispenser} who represents our {@link BlockPlacer}
* @param target
* The {@link Block} where it should be placed
*
* @return Whether this action is permitted or not
*/
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.
return true;
}
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(owner));
return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK);
}
private boolean isShulkerBox(Material type) {
return type == Material.SHULKER_BOX || type.name().endsWith("_SHULKER_BOX");
}
@ -139,14 +188,17 @@ public class BlockPlacer extends SimpleSlimefunItem<BlockDispenseHandler> {
ItemMeta meta = item.getItemMeta();
if (meta.hasDisplayName()) {
BlockState blockState = facedBlock.getState();
BlockStateSnapshotResult blockState = PaperLib.getBlockState(facedBlock, false);
if ((blockState instanceof Nameable)) {
((Nameable) blockState).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);
}
}
// Update block state after changing name
blockState.update();
}
}