diff --git a/Changelog.md b/Changelog.md index 024e4c8..3e9db69 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,7 @@ +Flan 1.7.7 +================ +- Prevent moss bonemealing if too close to a claim without permission + Flan 1.7.6 ================ - Fix delete command using wrong permission node diff --git a/common/src/main/java/io/github/flemmli97/flan/api/permission/ObjectToPermissionMap.java b/common/src/main/java/io/github/flemmli97/flan/api/permission/ObjectToPermissionMap.java index 9b89e86..ed82c4e 100644 --- a/common/src/main/java/io/github/flemmli97/flan/api/permission/ObjectToPermissionMap.java +++ b/common/src/main/java/io/github/flemmli97/flan/api/permission/ObjectToPermissionMap.java @@ -29,6 +29,7 @@ import net.minecraft.world.level.block.FarmBlock; import net.minecraft.world.level.block.FenceGateBlock; import net.minecraft.world.level.block.JukeboxBlock; import net.minecraft.world.level.block.LeverBlock; +import net.minecraft.world.level.block.MossBlock; import net.minecraft.world.level.block.NetherPortalBlock; import net.minecraft.world.level.block.NoteBlock; import net.minecraft.world.level.block.RedStoneWireBlock; @@ -136,24 +137,25 @@ public class ObjectToPermissionMap { } static { - registerBlockPredicateMap((block) -> block instanceof AnvilBlock, () -> PermissionRegistry.ANVIL); - registerBlockPredicateMap((block) -> block instanceof BedBlock, () -> PermissionRegistry.BED); - registerBlockPredicateMap((block) -> block instanceof BeaconBlock, () -> PermissionRegistry.BEACON); - registerBlockPredicateMap((block) -> block instanceof DoorBlock, () -> PermissionRegistry.DOOR); - registerBlockPredicateMap((block) -> block instanceof FenceGateBlock, () -> PermissionRegistry.FENCEGATE); - registerBlockPredicateMap((block) -> block instanceof TrapDoorBlock, () -> PermissionRegistry.TRAPDOOR); - registerBlockPredicateMap((block) -> block instanceof LeverBlock || block instanceof ButtonBlock, () -> PermissionRegistry.BUTTONLEVER); - registerBlockPredicateMap((block) -> block instanceof NoteBlock, () -> PermissionRegistry.NOTEBLOCK); - registerBlockPredicateMap((block) -> block instanceof DiodeBlock || block instanceof RedStoneWireBlock || block instanceof DaylightDetectorBlock, () -> PermissionRegistry.REDSTONE); - registerBlockPredicateMap((block) -> block instanceof JukeboxBlock, () -> PermissionRegistry.JUKEBOX); - registerBlockPredicateMap((block) -> block instanceof BasePressurePlateBlock, () -> PermissionRegistry.PRESSUREPLATE); - registerBlockPredicateMap((block) -> block instanceof NetherPortalBlock, () -> PermissionRegistry.PORTAL); - registerBlockPredicateMap((block) -> block instanceof TurtleEggBlock || block instanceof FarmBlock, () -> PermissionRegistry.TRAMPLE); - registerBlockPredicateMap((block) -> block instanceof TargetBlock, () -> PermissionRegistry.TARGETBLOCK); - registerBlockPredicateMap((block) -> block instanceof BellBlock || block instanceof CampfireBlock + registerBlockPredicateMap(block -> block instanceof AnvilBlock, () -> PermissionRegistry.ANVIL); + registerBlockPredicateMap(block -> block instanceof BedBlock, () -> PermissionRegistry.BED); + registerBlockPredicateMap(block -> block instanceof BeaconBlock, () -> PermissionRegistry.BEACON); + registerBlockPredicateMap(block -> block instanceof DoorBlock, () -> PermissionRegistry.DOOR); + registerBlockPredicateMap(block -> block instanceof FenceGateBlock, () -> PermissionRegistry.FENCEGATE); + registerBlockPredicateMap(block -> block instanceof TrapDoorBlock, () -> PermissionRegistry.TRAPDOOR); + registerBlockPredicateMap(block -> block instanceof LeverBlock || block instanceof ButtonBlock, () -> PermissionRegistry.BUTTONLEVER); + registerBlockPredicateMap(block -> block instanceof NoteBlock, () -> PermissionRegistry.NOTEBLOCK); + registerBlockPredicateMap(block -> block instanceof DiodeBlock || block instanceof RedStoneWireBlock || block instanceof DaylightDetectorBlock, () -> PermissionRegistry.REDSTONE); + registerBlockPredicateMap(block -> block instanceof JukeboxBlock, () -> PermissionRegistry.JUKEBOX); + registerBlockPredicateMap(block -> block instanceof BasePressurePlateBlock, () -> PermissionRegistry.PRESSUREPLATE); + registerBlockPredicateMap(block -> block instanceof NetherPortalBlock, () -> PermissionRegistry.PORTAL); + registerBlockPredicateMap(block -> block instanceof TurtleEggBlock || block instanceof FarmBlock, () -> PermissionRegistry.TRAMPLE); + registerBlockPredicateMap(block -> block instanceof TargetBlock, () -> PermissionRegistry.TARGETBLOCK); + registerBlockPredicateMap(block -> block instanceof BellBlock || block instanceof CampfireBlock || block instanceof TntBlock || block instanceof ChorusFlowerBlock, () -> PermissionRegistry.PROJECTILES); - registerBlockPredicateMap((block) -> block instanceof EnderChestBlock, () -> PermissionRegistry.ENDERCHEST); - registerBlockPredicateMap((block) -> block instanceof EnchantmentTableBlock, () -> PermissionRegistry.ENCHANTMENTTABLE); + registerBlockPredicateMap(block -> block instanceof EnderChestBlock, () -> PermissionRegistry.ENDERCHEST); + registerBlockPredicateMap(block -> block instanceof EnchantmentTableBlock, () -> PermissionRegistry.ENCHANTMENTTABLE); + registerBlockPredicateMap(block -> block instanceof MossBlock, () -> PermissionRegistry.PLACE); registerItemPredicateMap(item -> item instanceof EnderpearlItem, () -> PermissionRegistry.ENDERPEARL); registerItemPredicateMap(item -> item instanceof BucketItem, () -> PermissionRegistry.BUCKET); diff --git a/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java b/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java index 8e7aca1..a02f129 100644 --- a/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java +++ b/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java @@ -25,6 +25,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.MutableComponent; @@ -225,6 +226,37 @@ public class ClaimStorage implements IPermissionStorage { return this.globalClaim; } + public boolean canInteract(BlockPos pos, int radius, ServerPlayer player, ClaimPermission perm, boolean message) { + ChunkPos c = new ChunkPos(new BlockPos(pos.getX() - radius, pos.getY(), pos.getZ() - radius)); + List affected = new ArrayList<>(); + for (int x = 0; SectionPos.sectionToBlockCoord(c.x + x) <= pos.getX() + radius; x++) { + for (int z = 0; SectionPos.sectionToBlockCoord(c.z + z) <= pos.getZ() + radius; z++) { + List list = this.claims.get(ChunkPos.asLong(c.x + x, c.z + z)); + if (list != null) + affected.addAll(this.claims.get(ChunkPos.asLong(c.x + x, c.z + z))); + } + } + Claim last = null; + for (BlockPos ipos : BlockPos.betweenClosed(pos.getX() - radius, pos.getY(), pos.getZ() - radius, + pos.getX() + radius, pos.getY(), pos.getZ() + radius)) { + if (last != null) { + if (last.insideClaim(ipos)) { + if (!last.canInteract(player, perm, ipos, message)) + return false; + continue; + } else last = null; + } + for (Claim claim : affected) { + if (claim.insideClaim(ipos)) { + last = claim; + if (!claim.canInteract(player, perm, ipos, message)) + return false; + } + } + } + return true; + } + public Claim getFromUUID(UUID uuid) { return this.claimUUIDMap.get(uuid); } diff --git a/common/src/main/java/io/github/flemmli97/flan/config/LangManager.java b/common/src/main/java/io/github/flemmli97/flan/config/LangManager.java index a17c166..d684d59 100644 --- a/common/src/main/java/io/github/flemmli97/flan/config/LangManager.java +++ b/common/src/main/java/io/github/flemmli97/flan/config/LangManager.java @@ -50,6 +50,7 @@ public class LangManager { this.defaultTranslation.put("noPermission", "You don't have the required permissions to do that here!"); this.defaultTranslation.put("noPermissionSimple", "Sorry you can't do that here!"); + this.defaultTranslation.put("tooCloseClaim", "You are too close to a protected area to do that!"); this.defaultTranslation.put("configReload", "Configs reloaded"); 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 0f77722..8ea66cb 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 @@ -1,9 +1,20 @@ 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.claim.ClaimStorage; +import io.github.flemmli97.flan.claim.PermHelper; +import io.github.flemmli97.flan.config.ConfigHandler; import io.github.flemmli97.flan.player.LogoutTracker; import io.github.flemmli97.flan.player.PlayerClaimData; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.data.worldgen.features.CaveFeatures; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.block.MossBlock; +import net.minecraft.world.level.block.state.BlockState; public class PlayerEvents { @@ -21,4 +32,21 @@ public class PlayerEvents { if (player.getServer() != null) LogoutTracker.getInstance(player.getServer()).track(player.getUUID()); } + + public static boolean mossBonemeal(UseOnContext context) { + if (context.getPlayer() instanceof ServerPlayer serverPlayer) { + BlockState state = serverPlayer.level.getBlockState(context.getClickedPos()); + if (state.getBlock() instanceof MossBlock) { + BlockPos.MutableBlockPos mutable = context.getClickedPos().mutable(); + int range = CaveFeatures.MOSS_PATCH_BONEMEAL.value().config() + .xzRadius.getMaxValue() + 1; + ClaimPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock()); + if (perm != null && !ClaimStorage.get(serverPlayer.getLevel()).canInteract(mutable, range, serverPlayer, perm, false)) { + serverPlayer.displayClientMessage(PermHelper.simpleColoredText(ConfigHandler.langManager.get("tooCloseClaim"), ChatFormatting.DARK_RED), true); + return true; + } + } + } + return false; + } } diff --git a/common/src/main/java/io/github/flemmli97/flan/mixin/MossBlockCheckMixin.java b/common/src/main/java/io/github/flemmli97/flan/mixin/MossBlockCheckMixin.java new file mode 100644 index 0000000..11c2ad5 --- /dev/null +++ b/common/src/main/java/io/github/flemmli97/flan/mixin/MossBlockCheckMixin.java @@ -0,0 +1,22 @@ +package io.github.flemmli97.flan.mixin; + +import io.github.flemmli97.flan.event.PlayerEvents; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.BoneMealItem; +import net.minecraft.world.item.context.UseOnContext; +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.CallbackInfoReturnable; + +@Mixin(BoneMealItem.class) +public class MossBlockCheckMixin { + + @Inject(method = "useOn", at = @At("HEAD"), cancellable = true) + private void check(UseOnContext context, CallbackInfoReturnable info) { + if (PlayerEvents.mossBonemeal(context)) { + info.setReturnValue(InteractionResult.PASS); + info.cancel(); + } + } +} diff --git a/common/src/main/resources/flan.mixins.json b/common/src/main/resources/flan.mixins.json index a69e7c8..9531245 100644 --- a/common/src/main/resources/flan.mixins.json +++ b/common/src/main/resources/flan.mixins.json @@ -25,7 +25,8 @@ "BannedEntryAccessor", "MinecraftServerMixin", "AbstractContainerAccessor", - "PistonMixin" + "PistonMixin", + "MossBlockCheckMixin" ], "server": [ ], diff --git a/gradle.properties b/gradle.properties index 0107f59..951d9a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ forge_version=1.18.2-40.0.3 loader_version=0.13.2 # Mod Properties -mod_version=1.7.6 +mod_version=1.7.7 maven_group=io.github.flemmli97 archives_base_name=flan