diff --git a/common/src/main/java/io/github/flemmli97/flan/api/permission/PermissionRegistry.java b/common/src/main/java/io/github/flemmli97/flan/api/permission/PermissionRegistry.java index 398e661..1774e40 100644 --- a/common/src/main/java/io/github/flemmli97/flan/api/permission/PermissionRegistry.java +++ b/common/src/main/java/io/github/flemmli97/flan/api/permission/PermissionRegistry.java @@ -74,6 +74,8 @@ public class PermissionRegistry { public static ClaimPermission TELEPORT = register(new ClaimPermission("TELEPORT", () -> new ItemStack(Items.END_PORTAL_FRAME), false, "Allow player to teleport to your claim home position")); public static ClaimPermission NOHUNGER = register(new ClaimPermission("NOHUNGER", () -> new ItemStack(Items.COOKED_BEEF), false, "Disable hunger")); public static ClaimPermission CLAIMMESSAGE = register(new ClaimPermission("CLAIMMESSAGE", () -> new ItemStack(Items.OAK_SIGN), false, "Permission to edit the enter/leave message")); + public static ClaimPermission PLAYERMOBSPAWN = register(new ClaimPermission("PLAYERMOBSPAWN", () -> new ItemStack(Items.WARDEN_SPAWN_EGG), false, "Permission for affected players to spawn mobs with interactions", "E.g. wardens, or endermites with enderpearls")); + public static ClaimPermission SCULK = register(new ClaimPermission("SCULK", () -> new ItemStack(Items.SCULK_SENSOR), false, "Permission for sculk sensors.", "Shriekers are handled under PLAYERMOBSPAWN")); public static ClaimPermission HURTPLAYER = global(new ClaimPermission("HURTPLAYER", () -> new ItemStack(Items.DIAMOND_SWORD), "Permission to hurt other players")); public static ClaimPermission EXPLOSIONS = global(new ClaimPermission("EXPLOSIONS", () -> new ItemStack(Items.TNT), "Toggle explosions in claim")); diff --git a/common/src/main/java/io/github/flemmli97/flan/event/PlayerEvents.java b/common/src/main/java/io/github/flemmli97/flan/event/PlayerEvents.java index a937a14..66a8a1a 100644 --- a/common/src/main/java/io/github/flemmli97/flan/event/PlayerEvents.java +++ b/common/src/main/java/io/github/flemmli97/flan/event/PlayerEvents.java @@ -2,6 +2,7 @@ package io.github.flemmli97.flan.event; import io.github.flemmli97.flan.api.permission.ClaimPermission; import io.github.flemmli97.flan.api.permission.ObjectToPermissionMap; +import io.github.flemmli97.flan.api.permission.PermissionRegistry; import io.github.flemmli97.flan.claim.ClaimStorage; import io.github.flemmli97.flan.claim.PermHelper; import io.github.flemmli97.flan.config.ConfigHandler; @@ -12,6 +13,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.data.worldgen.features.CaveFeatures; import net.minecraft.data.worldgen.features.NetherFeatures; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.block.Blocks; @@ -76,4 +78,20 @@ public class PlayerEvents { } return false; } + + public static float canSpawnFromPlayer(Entity entity, float old) { + BlockPos pos; + if (entity instanceof ServerPlayer player && + !ClaimStorage.get(player.getLevel()).getForPermissionCheck(pos = player.blockPosition()).canInteract(player, PermissionRegistry.PLAYERMOBSPAWN, pos, false)) + return -1; + return old; + } + + public static boolean canWardenSpawnTrigger(BlockPos pos, ServerPlayer player) { + return ClaimStorage.get(player.getLevel()).getForPermissionCheck(pos).canInteract(player, PermissionRegistry.PLAYERMOBSPAWN, pos, false); + } + + public static boolean canSculkTrigger(BlockPos pos, ServerPlayer player) { + return ClaimStorage.get(player.getLevel()).getForPermissionCheck(pos).canInteract(player, PermissionRegistry.SCULK, pos, false); + } } diff --git a/common/src/main/java/io/github/flemmli97/flan/mixin/EnderMitePearlCheck.java b/common/src/main/java/io/github/flemmli97/flan/mixin/EnderMitePearlCheck.java new file mode 100644 index 0000000..7234876 --- /dev/null +++ b/common/src/main/java/io/github/flemmli97/flan/mixin/EnderMitePearlCheck.java @@ -0,0 +1,24 @@ +package io.github.flemmli97.flan.mixin; + +import io.github.flemmli97.flan.event.PlayerEvents; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.projectile.ThrowableItemProjectile; +import net.minecraft.world.entity.projectile.ThrownEnderpearl; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(ThrownEnderpearl.class) +public abstract class EnderMitePearlCheck extends ThrowableItemProjectile { + + private EnderMitePearlCheck(EntityType entityType, Level level) { + super(entityType, level); + } + + @ModifyConstant(method = "onHit", constant = @Constant(floatValue = 0.05f)) + private float newChance(float old) { + return PlayerEvents.canSpawnFromPlayer(this.getOwner(), old); + } + +} diff --git a/common/src/main/java/io/github/flemmli97/flan/mixin/SculkSensorMixin.java b/common/src/main/java/io/github/flemmli97/flan/mixin/SculkSensorMixin.java new file mode 100644 index 0000000..bd87387 --- /dev/null +++ b/common/src/main/java/io/github/flemmli97/flan/mixin/SculkSensorMixin.java @@ -0,0 +1,31 @@ +package io.github.flemmli97.flan.mixin; + +import io.github.flemmli97.flan.event.PlayerEvents; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.SculkSensorBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import javax.annotation.Nullable; + +@Mixin(SculkSensorBlock.class) +public abstract class SculkSensorMixin { + + @Inject(method = "activate", at = @At("HEAD"), cancellable = true) + private static void playerPermCheck(@Nullable Entity entity, Level level, BlockPos pos, BlockState state, int strength, CallbackInfo info) { + ServerPlayer player = null; + if (entity instanceof ServerPlayer p) + player = p; + else if (entity instanceof Projectile proj && proj.getOwner() instanceof ServerPlayer p) + player = p; + if (player != null && !PlayerEvents.canSculkTrigger(pos, player)) + info.cancel(); + } +} diff --git a/common/src/main/java/io/github/flemmli97/flan/mixin/SculkShriekerMixin.java b/common/src/main/java/io/github/flemmli97/flan/mixin/SculkShriekerMixin.java new file mode 100644 index 0000000..c750533 --- /dev/null +++ b/common/src/main/java/io/github/flemmli97/flan/mixin/SculkShriekerMixin.java @@ -0,0 +1,29 @@ +package io.github.flemmli97.flan.mixin; + +import io.github.flemmli97.flan.event.PlayerEvents; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.entity.SculkShriekerBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(SculkShriekerBlockEntity.class) +public abstract class SculkShriekerMixin extends BlockEntity { + + private SculkShriekerMixin(BlockEntityType blockEntityType, BlockPos blockPos, BlockState blockState) { + super(blockEntityType, blockPos, blockState); + } + + @Inject(method = "tryShriek", at = @At("HEAD"), cancellable = true) + private void playerCheck(ServerLevel serverLevel, @Nullable ServerPlayer serverPlayer, CallbackInfo info) { + if (serverPlayer != null && !PlayerEvents.canWardenSpawnTrigger(this.getBlockPos(), serverPlayer)) + info.cancel(); + } +} diff --git a/common/src/main/resources/flan.mixins.json b/common/src/main/resources/flan.mixins.json index 9531245..059761a 100644 --- a/common/src/main/resources/flan.mixins.json +++ b/common/src/main/resources/flan.mixins.json @@ -26,7 +26,10 @@ "MinecraftServerMixin", "AbstractContainerAccessor", "PistonMixin", - "MossBlockCheckMixin" + "MossBlockCheckMixin", + "EnderMitePearlCheck", + "SculkSensorMixin", + "SculkShriekerMixin" ], "server": [ ],