diff --git a/README.md b/README.md index 7eecfbd..904f782 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,25 @@ Toggles no message mode, which hides non-command messages like automatic protect Permission node: `htm.command.quiet` +### Config +`canTrustedPlayersBreakChests`: Toggles whether players trusted to a locked container can break the container + + (set to false by default meaning only the owner can break a locked container). + + + +`defaultFlags`: + + - `hoppers`: Toggles whether hoppers can pull from locked containers by default + + (true by default meaning hoppers can pull from locked containers). + + + +`autolockingContainers`: List of containers which will be set to PRIVATE by default + + (remove items in the list to make them set to public by default). + ### Additional permissions -`htm.admin`: Allows unrestricted access to containers and other managerial permissions \ No newline at end of file +`htm.admin`: Allows unrestricted access to containers and other managerial permissions diff --git a/src/main/java/com/github/fabricservertools/htm/config/HTMConfig.java b/src/main/java/com/github/fabricservertools/htm/config/HTMConfig.java index aec906d..e39d3dc 100644 --- a/src/main/java/com/github/fabricservertools/htm/config/HTMConfig.java +++ b/src/main/java/com/github/fabricservertools/htm/config/HTMConfig.java @@ -22,6 +22,8 @@ public class HTMConfig { .setPrettyPrinting() .create(); + public boolean canTrustedPlayersBreakChests = false; + public final Map defaultFlags = new HashMap<>(); public final ArrayList autolockingContainers = new ArrayList<>(Arrays.asList( @@ -56,7 +58,6 @@ public HTMConfig() { defaultFlags.put("hoppers", true); } - public static HTMConfig loadConfig(File file) { HTMConfig config; diff --git a/src/main/java/com/github/fabricservertools/htm/listeners/PlayerEventListener.java b/src/main/java/com/github/fabricservertools/htm/listeners/PlayerEventListener.java index a1fd073..d67731c 100644 --- a/src/main/java/com/github/fabricservertools/htm/listeners/PlayerEventListener.java +++ b/src/main/java/com/github/fabricservertools/htm/listeners/PlayerEventListener.java @@ -55,7 +55,7 @@ private static boolean onBeforeBreak(World world, PlayerEntity player, BlockPos if (!lock.isLocked()) return true; - if (lock.isOwner((ServerPlayerEntity) player)) { + if (lock.isOwner((ServerPlayerEntity) player) || (HTM.config.canTrustedPlayersBreakChests && lock.getTrusted().contains(player.getUuid()))) { if (state.getBlock() instanceof LockableChestBlock) { Optional unlocked = ((LockableChestBlock) state.getBlock()).getUnlockedPart(state, world, pos); if (unlocked.isPresent()) { @@ -65,7 +65,6 @@ private static boolean onBeforeBreak(World world, PlayerEntity player, BlockPos } } - Utility.sendMessage(playerEntity, Text.translatable("text.htm.unlocked")); return true; diff --git a/src/main/java/com/github/fabricservertools/htm/mixin/HopperBlockEntityMixin.java b/src/main/java/com/github/fabricservertools/htm/mixin/HopperBlockEntityMixin.java index 6440417..5389dca 100644 --- a/src/main/java/com/github/fabricservertools/htm/mixin/HopperBlockEntityMixin.java +++ b/src/main/java/com/github/fabricservertools/htm/mixin/HopperBlockEntityMixin.java @@ -3,36 +3,36 @@ import com.github.fabricservertools.htm.HTMContainerLock; import com.github.fabricservertools.htm.interactions.InteractionManager; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.Hopper; import net.minecraft.block.entity.HopperBlockEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.Objects; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(HopperBlockEntity.class) public abstract class HopperBlockEntityMixin { - @Redirect(method = "getInventoryAt(Lnet/minecraft/world/World;DDD)Lnet/minecraft/inventory/Inventory;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getBlockEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/entity/BlockEntity;")) - private static BlockEntity getProtectedInventory(World world, BlockPos pos) { - BlockEntity blockEntity = Objects.requireNonNull(world.getBlockEntity(pos)); - if (world.isClient) return blockEntity; - - HTMContainerLock lock = InteractionManager.getLock((ServerWorld) world, blockEntity); - if (lock == null) { - return blockEntity; - } + @Inject(method = "extract(Lnet/minecraft/world/World;Lnet/minecraft/block/entity/Hopper;)Z", at = @At(value = "FIELD", target = "Lnet/minecraft/util/math/Direction;DOWN:Lnet/minecraft/util/math/Direction;", shift = At.Shift.AFTER), cancellable = true) + private static void extractHTMCheck(World world, Hopper hopper, CallbackInfoReturnable cir) { + // only checks extraction, so only needs to check block above hopper + if (!isBlockContainerHopperable(world, new BlockPos(hopper.getHopperX(), hopper.getHopperY(), hopper.getHopperZ()).offset(Direction.UP))) + cir.setReturnValue(true); // if block is not hopperable, cancel the extract method call + // otherwise continue the extract method as normal + } - if (!lock.isLocked()) { - return blockEntity; - } + //TODO optimize better + private static boolean isBlockContainerHopperable(World world, BlockPos pos) { + if (world.isClient) return true; - if (lock.getFlags().get("hoppers")) { - return blockEntity; - } + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity == null) // no block entity above + return true; - return null; - } + HTMContainerLock lock = InteractionManager.getLock((ServerWorld) world, blockEntity); + return lock == null || !lock.isLocked() || lock.getFlags().get("hoppers"); + } }