add generic block interact permission for blocks not covered by opencontainer #69

This commit is contained in:
Flemmli97 2021-06-29 16:01:03 +02:00
parent 4cf3d7f7be
commit b9c7426eb5
4 changed files with 62 additions and 40 deletions

View File

@ -33,6 +33,7 @@ public class PermissionRegistry {
public static ClaimPermission BREAK = register(new ClaimPermission("BREAK", () -> new ItemStack(Items.DIAMOND_PICKAXE), "Permission to break blocks in the claim"));
public static ClaimPermission PLACE = register(new ClaimPermission("PLACE", () -> new ItemStack(Items.GRASS_BLOCK), "Permission to place blocks in the claim"));
public static ClaimPermission OPENCONTAINER = register(new ClaimPermission("OPENCONTAINER", () -> new ItemStack(Items.CHEST), "Permission to open containers", "(chest, furnace etc.)"));
public static ClaimPermission INTERACTBLOCK = register(new ClaimPermission("INTERACTBLOCK", () -> new ItemStack(Items.CHEST), "Generic permission for block interaction.", "Fallback to OPENCONTAINER", "Gets used for all blocks OPENCONTAINER doesn't check for"));
public static ClaimPermission ANVIL = register(new ClaimPermission("ANVIL", () -> new ItemStack(Items.ANVIL), "Permission to use anvils"));
public static ClaimPermission BED = register(new ClaimPermission("BED", () -> new ItemStack(Items.RED_BED), "Permission to use beds"));
public static ClaimPermission BEACON = register(new ClaimPermission("BEACON", () -> new ItemStack(Items.BEACON), "Permission to use beacons"));

View File

@ -39,6 +39,9 @@ import java.util.Map;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Assign items/blocks to a certain permission
*/
public class ObjectToPermissionMap {
private static final Map<Block, ClaimPermission> blockToPermission = new HashMap<>();

View File

@ -35,6 +35,8 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import java.util.function.Function;
public class BlockInteractEvents {
public static ActionResult startBreakBlocks(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
@ -59,8 +61,12 @@ public class BlockInteractEvents {
return true;
}
//Right click block
public static ActionResult useBlocks(PlayerEntity p, World world, Hand hand, BlockHitResult hitResult) {
return useBlocks(p, world, hand, hitResult, BlockInteractEvents::isContainer);
}
//Right click block
public static ActionResult useBlocks(PlayerEntity p, World world, Hand hand, BlockHitResult hitResult, Function<BlockEntity, Boolean> isInventory) {
if (world.isClient)
return ActionResult.PASS;
ServerPlayerEntity player = (ServerPlayerEntity) p;
@ -76,54 +82,58 @@ public class BlockInteractEvents {
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
IPermissionContainer claim = storage.getForPermissionCheck(hitResult.getBlockPos());
if (claim != null) {
boolean emptyHand = !player.getMainHandStack().isEmpty() || !player.getOffHandStack().isEmpty();
boolean cancelBlockInteract = player.shouldCancelInteraction() && emptyHand;
if (!cancelBlockInteract) {
BlockState state = world.getBlockState(hitResult.getBlockPos());
Identifier id = CrossPlatformStuff.registryBlocks().getIDFrom(state.getBlock());
BlockEntity blockEntity = world.getBlockEntity(hitResult.getBlockPos());
if (alwaysAllowBlock(id, blockEntity))
BlockState state = world.getBlockState(hitResult.getBlockPos());
Identifier id = CrossPlatformStuff.registryBlocks().getIDFrom(state.getBlock());
BlockEntity blockEntity = world.getBlockEntity(hitResult.getBlockPos());
if (alwaysAllowBlock(id, blockEntity))
return ActionResult.PASS;
ClaimPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
if (perm == PermissionRegistry.PROJECTILES)
perm = PermissionRegistry.OPENCONTAINER;
//Pressureplate handled elsewhere
if (perm != null && perm != PermissionRegistry.PRESSUREPLATE) {
if (claim.canInteract(player, perm, hitResult.getBlockPos(), true))
return ActionResult.PASS;
ClaimPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
if (perm == PermissionRegistry.PROJECTILES)
perm = PermissionRegistry.OPENCONTAINER;
//Pressureplate handled elsewhere
if (perm != null && perm != PermissionRegistry.PRESSUREPLATE) {
if (claim.canInteract(player, perm, hitResult.getBlockPos(), true))
return ActionResult.PASS;
if (state.getBlock() instanceof DoorBlock) {
DoubleBlockHalf half = state.get(DoorBlock.HALF);
if (half == DoubleBlockHalf.LOWER) {
BlockState other = world.getBlockState(hitResult.getBlockPos().up());
player.networkHandler.sendPacket(new BlockUpdateS2CPacket(hitResult.getBlockPos().up(), other));
} else {
BlockState other = world.getBlockState(hitResult.getBlockPos().down());
player.networkHandler.sendPacket(new BlockUpdateS2CPacket(hitResult.getBlockPos().down(), other));
}
if (state.getBlock() instanceof DoorBlock) {
DoubleBlockHalf half = state.get(DoorBlock.HALF);
if (half == DoubleBlockHalf.LOWER) {
BlockState other = world.getBlockState(hitResult.getBlockPos().up());
player.networkHandler.sendPacket(new BlockUpdateS2CPacket(hitResult.getBlockPos().up(), other));
} else {
BlockState other = world.getBlockState(hitResult.getBlockPos().down());
player.networkHandler.sendPacket(new BlockUpdateS2CPacket(hitResult.getBlockPos().down(), other));
}
}
PlayerClaimData.get(player).addDisplayClaim(claim, EnumDisplayType.MAIN, player.getBlockPos().getY());
return ActionResult.FAIL;
}
if (blockEntity != null) {
if (blockEntity instanceof LecternBlockEntity) {
if (claim.canInteract(player, PermissionRegistry.LECTERNTAKE, hitResult.getBlockPos(), false))
return ActionResult.PASS;
if (state.get(LecternBlock.HAS_BOOK))
LockedLecternScreenHandler.create(player, (LecternBlockEntity) blockEntity);
return ActionResult.FAIL;
}
if (!ConfigHandler.config.lenientBlockEntityCheck || isInventory.apply(blockEntity)) {
if (claim.canInteract(player, PermissionRegistry.OPENCONTAINER, hitResult.getBlockPos(), true))
return ActionResult.PASS;
PlayerClaimData.get(player).addDisplayClaim(claim, EnumDisplayType.MAIN, player.getBlockPos().getY());
return ActionResult.FAIL;
}
if (blockEntity != null) {
if (blockEntity instanceof LecternBlockEntity) {
if (claim.canInteract(player, PermissionRegistry.LECTERNTAKE, hitResult.getBlockPos(), false))
return ActionResult.PASS;
if (state.get(LecternBlock.HAS_BOOK))
LockedLecternScreenHandler.create(player, (LecternBlockEntity) blockEntity);
return ActionResult.FAIL;
}
if (!ConfigHandler.config.lenientBlockEntityCheck || blockEntity instanceof Inventory || blockEntity instanceof InventoryProvider) {
if (claim.canInteract(player, PermissionRegistry.OPENCONTAINER, hitResult.getBlockPos(), true))
return ActionResult.PASS;
PlayerClaimData.get(player).addDisplayClaim(claim, EnumDisplayType.MAIN, player.getBlockPos().getY());
return ActionResult.FAIL;
}
}
}
if (claim.canInteract(player, PermissionRegistry.INTERACTBLOCK, hitResult.getBlockPos(), true))
return ActionResult.PASS;
PlayerClaimData.get(player).addDisplayClaim(claim, EnumDisplayType.MAIN, player.getBlockPos().getY());
return ActionResult.FAIL;
}
return ActionResult.PASS;
}
private static boolean isContainer(BlockEntity blockEntity) {
return blockEntity instanceof Inventory || blockEntity instanceof InventoryProvider;
}
public static boolean alwaysAllowBlock(Identifier id, BlockEntity blockEntity) {
return ConfigHandler.config.ignoredBlocks.contains(id.toString())
|| (blockEntity != null

View File

@ -1,11 +1,15 @@
package io.github.flemmli97.flan.forgeevent;
import io.github.flemmli97.flan.event.BlockInteractEvents;
import net.minecraft.block.InventoryProvider;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.items.CapabilityItemHandler;
public class BlockInteractEventsForge {
@ -25,10 +29,14 @@ public class BlockInteractEventsForge {
//Right click block
public static void useBlocks(PlayerInteractEvent.RightClickBlock event) {
ActionResult result = BlockInteractEvents.useBlocks(event.getPlayer(), event.getWorld(), event.getHand(), event.getHitVec());
ActionResult result = BlockInteractEvents.useBlocks(event.getPlayer(), event.getWorld(), event.getHand(), event.getHitVec(), BlockInteractEventsForge::isContainer);
if (result != ActionResult.PASS) {
event.setCancellationResult(result);
event.setCanceled(true);
}
}
private static boolean isContainer(BlockEntity blockEntity) {
return blockEntity instanceof Inventory || blockEntity instanceof InventoryProvider || blockEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).isPresent();
}
}