fix various entity bypassing claim #48. sync failed block placing. refactor block checks

This commit is contained in:
Flemmli97 2021-04-11 23:34:45 +02:00
parent b5a560e11f
commit 035ec2adfb
11 changed files with 164 additions and 123 deletions

View File

@ -1,3 +1,9 @@
Flan 1.2.5
======================
- Fix inventory desync after closing gui
- Sync itemstack when failing to place blocks
- Fix various thrown entitys to not abide by claim protection
Flan 1.2.4
======================
- Fix crash in void worlds #39

View File

@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx2G
loader_version=0.9.1+build.205
# Mod Properties
mod_version = 1.2.4
mod_version = 1.2.5
maven_group = com.flemmli97.flan
archives_base_name = flan

View File

@ -1,7 +1,7 @@
package com.flemmli97.flan;
import com.flemmli97.flan.api.PermissionRegistry;
import com.flemmli97.flan.claim.BlockToPermissionMap;
import com.flemmli97.flan.claim.ObjectToPermissionMap;
import com.flemmli97.flan.commands.CommandClaim;
import com.flemmli97.flan.config.ConfigHandler;
import com.flemmli97.flan.event.BlockInteractEvents;
@ -34,7 +34,7 @@ public class Flan implements ModInitializer {
AttackEntityCallback.EVENT.register(EntityInteractEvents::attackEntity);
UseItemCallback.EVENT.register(ItemInteractEvents::useItem);
ServerLifecycleEvents.SERVER_STARTING.register(ConfigHandler::serverLoad);
ServerLifecycleEvents.SERVER_STARTING.register(BlockToPermissionMap::reload);
ServerLifecycleEvents.SERVER_STARTING.register(ObjectToPermissionMap::reload);
ServerLifecycleEvents.SERVER_STARTING.register(this::lockRegistry);
CommandRegistrationCallback.EVENT.register(CommandClaim::register);

View File

@ -1,84 +0,0 @@
package com.flemmli97.flan.claim;
import com.flemmli97.flan.api.ClaimPermission;
import com.flemmli97.flan.api.PermissionRegistry;
import com.google.common.collect.Maps;
import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.AbstractPressurePlateBlock;
import net.minecraft.block.AbstractRedstoneGateBlock;
import net.minecraft.block.AnvilBlock;
import net.minecraft.block.BeaconBlock;
import net.minecraft.block.BedBlock;
import net.minecraft.block.BellBlock;
import net.minecraft.block.Block;
import net.minecraft.block.CampfireBlock;
import net.minecraft.block.ChorusFlowerBlock;
import net.minecraft.block.DaylightDetectorBlock;
import net.minecraft.block.DoorBlock;
import net.minecraft.block.EnchantingTableBlock;
import net.minecraft.block.EnderChestBlock;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.block.FenceGateBlock;
import net.minecraft.block.JukeboxBlock;
import net.minecraft.block.LeverBlock;
import net.minecraft.block.NetherPortalBlock;
import net.minecraft.block.NoteBlock;
import net.minecraft.block.RedstoneWireBlock;
import net.minecraft.block.TargetBlock;
import net.minecraft.block.TntBlock;
import net.minecraft.block.TrapdoorBlock;
import net.minecraft.block.TurtleEggBlock;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.registry.Registry;
import java.util.Map;
public class BlockToPermissionMap {
private static final Map<Block, ClaimPermission> blockToPermission = Maps.newHashMap();
public static void reload(MinecraftServer server) {
blockToPermission.clear();
for (Block block : Registry.BLOCK) {
if (block instanceof AnvilBlock)
blockToPermission.put(block, PermissionRegistry.ANVIL);
if (block instanceof BedBlock)
blockToPermission.put(block, PermissionRegistry.BED);
if (block instanceof BeaconBlock)
blockToPermission.put(block, PermissionRegistry.BEACON);
if (block instanceof DoorBlock)
blockToPermission.put(block, PermissionRegistry.DOOR);
if (block instanceof FenceGateBlock)
blockToPermission.put(block, PermissionRegistry.FENCEGATE);
if (block instanceof TrapdoorBlock)
blockToPermission.put(block, PermissionRegistry.TRAPDOOR);
if (block instanceof LeverBlock || block instanceof AbstractButtonBlock)
blockToPermission.put(block, PermissionRegistry.BUTTONLEVER);
if (block instanceof NoteBlock)
blockToPermission.put(block, PermissionRegistry.NOTEBLOCK);
if (block instanceof AbstractRedstoneGateBlock || block instanceof RedstoneWireBlock || block instanceof DaylightDetectorBlock)
blockToPermission.put(block, PermissionRegistry.REDSTONE);
if (block instanceof JukeboxBlock)
blockToPermission.put(block, PermissionRegistry.JUKEBOX);
if (block instanceof AbstractPressurePlateBlock)
blockToPermission.put(block, PermissionRegistry.PRESSUREPLATE);
if (block instanceof NetherPortalBlock)
blockToPermission.put(block, PermissionRegistry.PORTAL);
if (block instanceof TurtleEggBlock || block instanceof FarmlandBlock)
blockToPermission.put(block, PermissionRegistry.TRAMPLE);
if (block instanceof TargetBlock)
blockToPermission.put(block, PermissionRegistry.TARGETBLOCK);
if (block instanceof BellBlock || block instanceof CampfireBlock
|| block instanceof TntBlock || block instanceof ChorusFlowerBlock)
blockToPermission.put(block, PermissionRegistry.PROJECTILES);
if (block instanceof EnderChestBlock)
blockToPermission.put(block, PermissionRegistry.ENDERCHEST);
if (block instanceof EnchantingTableBlock)
blockToPermission.put(block, PermissionRegistry.ENCHANTMENTTABLE);
}
}
public static ClaimPermission getFromBlock(Block block) {
return blockToPermission.get(block);
}
}

View File

@ -0,0 +1,115 @@
package com.flemmli97.flan.claim;
import com.flemmli97.flan.api.ClaimPermission;
import com.flemmli97.flan.api.PermissionRegistry;
import com.google.common.collect.Maps;
import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.AbstractPressurePlateBlock;
import net.minecraft.block.AbstractRedstoneGateBlock;
import net.minecraft.block.AnvilBlock;
import net.minecraft.block.BeaconBlock;
import net.minecraft.block.BedBlock;
import net.minecraft.block.BellBlock;
import net.minecraft.block.Block;
import net.minecraft.block.CampfireBlock;
import net.minecraft.block.ChorusFlowerBlock;
import net.minecraft.block.DaylightDetectorBlock;
import net.minecraft.block.DoorBlock;
import net.minecraft.block.EnchantingTableBlock;
import net.minecraft.block.EnderChestBlock;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.block.FenceGateBlock;
import net.minecraft.block.JukeboxBlock;
import net.minecraft.block.LeverBlock;
import net.minecraft.block.NetherPortalBlock;
import net.minecraft.block.NoteBlock;
import net.minecraft.block.RedstoneWireBlock;
import net.minecraft.block.TargetBlock;
import net.minecraft.block.TntBlock;
import net.minecraft.block.TrapdoorBlock;
import net.minecraft.block.TurtleEggBlock;
import net.minecraft.item.BucketItem;
import net.minecraft.item.EnderPearlItem;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.registry.Registry;
import java.util.Map;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class ObjectToPermissionMap {
private static final Map<Block, ClaimPermission> blockToPermission = Maps.newHashMap();
private static final Map<Predicate<Block>, Supplier<ClaimPermission>> blockPermissionBuilder = Maps.newHashMap();
private static final Map<Item, ClaimPermission> itemToPermission = Maps.newHashMap();
private static final Map<Predicate<Item>, Supplier<ClaimPermission>> itemPermissionBuilder = Maps.newHashMap();
public static void reload(MinecraftServer server) {
blockToPermission.clear();
itemToPermission.clear();
for (Block block : Registry.BLOCK) {
blockPermissionBuilder.entrySet().stream().filter(e -> e.getKey().test(block)).map(Map.Entry::getValue).findFirst().ifPresent(sub -> blockToPermission.put(block, sub.get()));
}
for (Item item : Registry.ITEM) {
itemPermissionBuilder.entrySet().stream().filter(e -> e.getKey().test(item)).map(Map.Entry::getValue).findFirst().ifPresent(sub -> itemToPermission.put(item, sub.get()));
}
}
public static ClaimPermission getFromBlock(Block block) {
return blockToPermission.get(block);
}
public static ClaimPermission getFromItem(Item block) {
return itemToPermission.get(block);
}
/**
* Register a custom permission to check for the given blocks. Used when trying to interact with blocks
* Register before ServerLifecycleEvents.SERVER_STARTING
*
* @param pred Predicate for blocks that should return the given permission
* @param perm The given permission
*/
public static void registerBlockPredicateMap(Predicate<Block> pred, Supplier<ClaimPermission> perm) {
blockPermissionBuilder.put(pred, perm);
}
/**
* Register a custom permission to check for the given items. Used when trying to use items.
* Register before ServerLifecycleEvents.SERVER_STARTING
*
* @param pred Predicate for items that should return the given permission
* @param perm The given permission
*/
public static void registerItemPredicateMap(Predicate<Item> pred, Supplier<ClaimPermission> perm) {
itemPermissionBuilder.put(pred, perm);
}
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 AbstractButtonBlock, () -> PermissionRegistry.BUTTONLEVER);
registerBlockPredicateMap((block) -> block instanceof NoteBlock, () -> PermissionRegistry.NOTEBLOCK);
registerBlockPredicateMap((block) -> block instanceof AbstractRedstoneGateBlock || block instanceof RedstoneWireBlock || block instanceof DaylightDetectorBlock, () -> PermissionRegistry.REDSTONE);
registerBlockPredicateMap((block) -> block instanceof JukeboxBlock, () -> PermissionRegistry.JUKEBOX);
registerBlockPredicateMap((block) -> block instanceof AbstractPressurePlateBlock, () -> PermissionRegistry.PRESSUREPLATE);
registerBlockPredicateMap((block) -> block instanceof NetherPortalBlock, () -> PermissionRegistry.PORTAL);
registerBlockPredicateMap((block) -> block instanceof TurtleEggBlock || block instanceof FarmlandBlock, () -> 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 EnchantingTableBlock, () -> PermissionRegistry.ENCHANTMENTTABLE);
registerItemPredicateMap(item -> item instanceof EnderPearlItem, () -> PermissionRegistry.ENDERPEARL);
registerItemPredicateMap(item -> item instanceof BucketItem, () -> PermissionRegistry.BUCKET);
registerItemPredicateMap(item -> item == Items.END_CRYSTAL, () -> PermissionRegistry.ENDCRYSTALPLACE);
}
}

View File

@ -2,9 +2,9 @@ package com.flemmli97.flan.event;
import com.flemmli97.flan.api.ClaimPermission;
import com.flemmli97.flan.api.PermissionRegistry;
import com.flemmli97.flan.claim.BlockToPermissionMap;
import com.flemmli97.flan.claim.ClaimStorage;
import com.flemmli97.flan.claim.IPermissionContainer;
import com.flemmli97.flan.claim.ObjectToPermissionMap;
import com.flemmli97.flan.config.ConfigHandler;
import com.flemmli97.flan.gui.LockedLecternScreenHandler;
import com.flemmli97.flan.player.EnumDisplayType;
@ -77,7 +77,7 @@ public class BlockInteractEvents {
Identifier id = Registry.BLOCK.getId(state.getBlock());
if (ConfigHandler.config.ignoredBlocks.contains(id.toString()))
return ActionResult.PASS;
ClaimPermission perm = BlockToPermissionMap.getFromBlock(state.getBlock());
ClaimPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
//Pressureplate handled elsewhere
if (perm != null && perm != PermissionRegistry.PRESSUREPLATE) {
if (claim.canInteract(player, perm, hitResult.getBlockPos(), true))
@ -133,7 +133,7 @@ public class BlockInteractEvents {
}
if (player == null)
return false;
ClaimPermission perm = BlockToPermissionMap.getFromBlock(state.getBlock());
ClaimPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
if (perm == null)
return false;
if (perm != PermissionRegistry.PRESSUREPLATE && perm != PermissionRegistry.PORTAL)
@ -149,7 +149,7 @@ public class BlockInteractEvents {
if (entity.world.isClient)
return false;
if (entity instanceof ServerPlayerEntity) {
ClaimPermission perm = BlockToPermissionMap.getFromBlock(landedState.getBlock());
ClaimPermission perm = ObjectToPermissionMap.getFromBlock(landedState.getBlock());
if (perm != PermissionRegistry.TRAMPLE)
return false;
ClaimStorage storage = ClaimStorage.get((ServerWorld) entity.world);
@ -160,7 +160,7 @@ public class BlockInteractEvents {
} else if (entity instanceof ProjectileEntity) {
Entity owner = ((ProjectileEntity) entity).getOwner();
if (owner instanceof ServerPlayerEntity) {
ClaimPermission perm = BlockToPermissionMap.getFromBlock(landedState.getBlock());
ClaimPermission perm = ObjectToPermissionMap.getFromBlock(landedState.getBlock());
if (perm != PermissionRegistry.TRAMPLE)
return false;
ClaimStorage storage = ClaimStorage.get((ServerWorld) entity.world);

View File

@ -2,9 +2,9 @@ package com.flemmli97.flan.event;
import com.flemmli97.flan.api.ClaimPermission;
import com.flemmli97.flan.api.PermissionRegistry;
import com.flemmli97.flan.claim.BlockToPermissionMap;
import com.flemmli97.flan.claim.ClaimStorage;
import com.flemmli97.flan.claim.IPermissionContainer;
import com.flemmli97.flan.claim.ObjectToPermissionMap;
import com.flemmli97.flan.mixin.IPersistentProjectileVars;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import net.minecraft.block.BlockState;
@ -20,7 +20,9 @@ import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.projectile.thrown.EggEntity;
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
import net.minecraft.entity.projectile.thrown.PotionEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.entity.vehicle.MinecartEntity;
@ -97,9 +99,13 @@ public class EntityInteractEvents {
BlockHitResult blockRes = (BlockHitResult) res;
BlockPos pos = blockRes.getBlockPos();
BlockState state = proj.world.getBlockState(pos);
ClaimPermission perm = BlockToPermissionMap.getFromBlock(state.getBlock());
ClaimPermission perm;
if (proj instanceof EnderPearlEntity)
perm = PermissionRegistry.ENDERPEARL;
else if (proj instanceof EggEntity || proj instanceof PotionEntity)
perm = PermissionRegistry.PROJECTILES;
else
perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
if (perm != PermissionRegistry.ENDERPEARL && perm != PermissionRegistry.TARGETBLOCK && perm != PermissionRegistry.PROJECTILES)
return false;
ClaimStorage storage = ClaimStorage.get((ServerWorld) proj.world);

View File

@ -1,9 +1,11 @@
package com.flemmli97.flan.event;
import com.flemmli97.flan.api.ClaimPermission;
import com.flemmli97.flan.api.PermissionRegistry;
import com.flemmli97.flan.claim.Claim;
import com.flemmli97.flan.claim.ClaimStorage;
import com.flemmli97.flan.claim.IPermissionContainer;
import com.flemmli97.flan.claim.ObjectToPermissionMap;
import com.flemmli97.flan.claim.PermHelper;
import com.flemmli97.flan.commands.CommandPermission;
import com.flemmli97.flan.config.ConfigHandler;
@ -15,13 +17,13 @@ import com.mojang.authlib.GameProfile;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BucketItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
@ -59,15 +61,15 @@ public class ItemInteractEvents {
}
return TypedActionResult.pass(stack);
}
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
BlockPos pos = player.getBlockPos();
IPermissionContainer claim = storage.getForPermissionCheck(pos);
if (claim == null)
return TypedActionResult.pass(stack);
if (stack.getItem() == Items.ENDER_PEARL)
return claim.canInteract(player, PermissionRegistry.ENDERPEARL, pos, true) ? TypedActionResult.pass(stack) : TypedActionResult.fail(stack);
if (stack.getItem() instanceof BucketItem)
return claim.canInteract(player, PermissionRegistry.BUCKET, pos, true) ? TypedActionResult.pass(stack) : TypedActionResult.fail(stack);
ClaimPermission perm = ObjectToPermissionMap.getFromItem(stack.getItem());
if (perm != null)
return claim.canInteract(player, perm, pos, true) ? TypedActionResult.pass(stack) : TypedActionResult.fail(stack);
return TypedActionResult.pass(stack);
}
@ -86,8 +88,9 @@ public class ItemInteractEvents {
return ActionResult.PASS;
boolean actualInClaim = !(claim instanceof Claim) || placePos.getY() >= ((Claim) claim).getDimensions()[4];
ServerPlayerEntity player = (ServerPlayerEntity) context.getPlayer();
if (context.getStack().getItem() == Items.END_CRYSTAL) {
if (claim.canInteract(player, PermissionRegistry.ENDCRYSTALPLACE, placePos, false))
ClaimPermission perm = ObjectToPermissionMap.getFromItem(context.getStack().getItem());
if (perm != null) {
if (claim.canInteract(player, perm, placePos, false))
return ActionResult.PASS;
else if (actualInClaim) {
player.sendMessage(PermHelper.simpleColoredText(ConfigHandler.lang.noPermissionSimple, Formatting.DARK_RED), true);
@ -104,11 +107,20 @@ public class ItemInteractEvents {
BlockState other = context.getWorld().getBlockState(placePos.up());
player.networkHandler.sendPacket(new BlockUpdateS2CPacket(placePos.up(), other));
PlayerClaimData.get(player).addDisplayClaim(claim, EnumDisplayType.MAIN, player.getBlockPos().getY());
updateHeldItem(player);
return ActionResult.FAIL;
}
return ActionResult.PASS;
}
/**
* -2 == Main inventory update
*/
private static void updateHeldItem(ServerPlayerEntity player) {
player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-2, player.inventory.selectedSlot, player.inventory.getMainHandStack()));
player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-2, 40, player.inventory.getStack(40)));
}
private static boolean cantClaimInWorld(ServerWorld world) {
for (String s : ConfigHandler.config.blacklistedWorlds) {
if (s.equals(world.getRegistryKey().getValue().toString())) {

View File

@ -1,20 +0,0 @@
package com.flemmli97.flan.mixin;
import com.flemmli97.flan.event.EntityInteractEvents;
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
import net.minecraft.util.hit.HitResult;
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(EnderPearlEntity.class)
public abstract class EnderPearlEntityMixin {
@Inject(method = "onCollision", at = @At(value = "HEAD"), cancellable = true)
public void collision(HitResult hitResult, CallbackInfo info) {
if (EntityInteractEvents.projectileHit((EnderPearlEntity) (Object) this, hitResult)) {
info.cancel();
}
}
}

View File

@ -1,14 +1,21 @@
package com.flemmli97.flan.mixin;
import com.flemmli97.flan.event.EntityInteractEvents;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.DragonFireballEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.projectile.thrown.EggEntity;
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
import net.minecraft.entity.projectile.thrown.ExperienceBottleEntity;
import net.minecraft.entity.projectile.thrown.PotionEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.hit.HitResult;
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(ProjectileEntity.class)
@Mixin(value = {ProjectileEntity.class, EggEntity.class, PotionEntity.class, ExperienceBottleEntity.class, DragonFireballEntity.class, EnderPearlEntity.class})
public abstract class ProjectileMixin {
@Inject(method = "onCollision", at = @At(value = "HEAD"), cancellable = true)

View File

@ -13,7 +13,6 @@
"TurtleEggMixin",
"XpEntityMixin",
"WitherMixin",
"EnderPearlEntityMixin",
"IPersistentProjectileVars",
"LivingEntityMixin",
"ItemStackMixin",