drop and pickup permission

This commit is contained in:
Flemmli97 2021-04-12 01:50:31 +02:00
parent 035ec2adfb
commit e80e8f4a62
10 changed files with 159 additions and 9 deletions

View File

@ -3,6 +3,11 @@ 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
- Add 2 new permissions:
- Item drop permission: If set to false prevents items being dropped (players only)
- Item pickup permission: If set to false prevents items from being picked up. Player thrown items
(Death included) gets a special tag so that the one who threw them can always pick it up.
- Change some permissions to default true: Enderchest, Enchanting table, Item drop, Item pickup
Flan 1.2.4
======================

View File

@ -13,16 +13,22 @@ public class ClaimPermission {
public String[] desc;
public final String id;
public final ClaimTest test;
public final boolean defaultVal;
public ClaimPermission(String id, Supplier<ItemStack> guiItem, String... defaultDescription) {
this(id, guiItem, pass, defaultDescription);
this(id, guiItem, false, pass, defaultDescription);
}
public ClaimPermission(String id, Supplier<ItemStack> guiItem, ClaimTest test, String... defaultDescription) {
public ClaimPermission(String id, Supplier<ItemStack> guiItem, boolean defaultVal, String... defaultDescription) {
this(id, guiItem, defaultVal, pass, defaultDescription);
}
public ClaimPermission(String id, Supplier<ItemStack> guiItem, boolean defaultVal, ClaimTest test, String... defaultDescription) {
this.id = id;
this.guiItem = guiItem;
this.desc = defaultDescription;
this.test = test;
this.defaultVal = defaultVal;
}
public ItemStack getItem() {

View File

@ -42,16 +42,16 @@ public class PermissionRegistry {
public static ClaimPermission NOTEBLOCK = register(new ClaimPermission("NOTEBLOCK", () -> new ItemStack(Items.NOTE_BLOCK), "Permission to change noteblocks"));
public static ClaimPermission REDSTONE = register(new ClaimPermission("REDSTONE", () -> new ItemStack(Items.REDSTONE), "Permission to change redstone components"));
public static ClaimPermission JUKEBOX = register(new ClaimPermission("JUKEBOX", () -> new ItemStack(Items.JUKEBOX), "Permission to insert/take music discs"));
public static ClaimPermission ENDERCHEST = register(new ClaimPermission("ENDERCHEST", () -> new ItemStack(Items.ENDER_CHEST), "Permission to use enderchests"));
public static ClaimPermission ENCHANTMENTTABLE = register(new ClaimPermission("ENCHANTMENT", () -> new ItemStack(Items.ENCHANTING_TABLE), "Permission to use enchanting tables"));
public static ClaimPermission ENDERCHEST = register(new ClaimPermission("ENDERCHEST", () -> new ItemStack(Items.ENDER_CHEST), true, "Permission to use enderchests"));
public static ClaimPermission ENCHANTMENTTABLE = register(new ClaimPermission("ENCHANTMENT", () -> new ItemStack(Items.ENCHANTING_TABLE), true, "Permission to use enchanting tables"));
public static ClaimPermission ITEMFRAMEROTATE = register(new ClaimPermission("ITEMFRAMEROTATE", () -> new ItemStack(Items.ITEM_FRAME), "Permission to rotate items in item frames"));
public static ClaimPermission LECTERNTAKE = register(new ClaimPermission("LECTERNTAKE", () -> new ItemStack(Items.LECTERN), "Permission to change books in a lectern"));
public static ClaimPermission ENDCRYSTALPLACE = register(new ClaimPermission("ENDCRYSTALPLACE", () -> new ItemStack(Items.END_CRYSTAL), "Permission to place end crystals"));
public static ClaimPermission TARGETBLOCK = register(new ClaimPermission("TARGETBLOCK", () -> new ItemStack(Items.TARGET), "Permission to trigger target blocks"));
public static ClaimPermission PROJECTILES = register(new ClaimPermission("PROJECTILES", () -> new ItemStack(Items.ARROW), "Permission to let shot projectiles", "interact with blocks (e.g. arrow on button)"));
public static ClaimPermission TRAMPLE = register(new ClaimPermission("TRAMPLE", () -> new ItemStack(Items.FARMLAND), "Permission to enable block trampling", "(farmland, turtle eggs)"));
public static ClaimPermission PORTAL = register(new ClaimPermission("PORTAL", () -> new ItemStack(Items.OBSIDIAN), "Permission to use nether portals"));
public static ClaimPermission RAID = register(new ClaimPermission("RAID", () -> Raid.getOminousBanner(), "Permission to trigger raids in claim.", "Wont prevent raids (just) outside"));
public static ClaimPermission PORTAL = register(new ClaimPermission("PORTAL", () -> new ItemStack(Items.OBSIDIAN), true, "Permission to use nether portals"));
public static ClaimPermission RAID = register(new ClaimPermission("RAID", Raid::getOminousBanner, "Permission to trigger raids in claim.", "Wont prevent raids (just) outside"));
public static ClaimPermission BOAT = register(new ClaimPermission("BOAT", () -> new ItemStack(Items.OAK_BOAT), "Permission to sit in boats"));
public static ClaimPermission MINECART = register(new ClaimPermission("MINECART", () -> new ItemStack(Items.MINECART), "Permission to sit in minecarts"));
public static ClaimPermission BUCKET = register(new ClaimPermission("BUCKET", () -> new ItemStack(Items.BUCKET), "Permission to take liquids with buckets"));
@ -62,6 +62,8 @@ public class PermissionRegistry {
public static ClaimPermission TRADING = register(new ClaimPermission("TRADING", () -> new ItemStack(Items.EMERALD), "Permission to trade with villagers"));
public static ClaimPermission ARMORSTAND = register(new ClaimPermission("ARMORSTAND", () -> new ItemStack(Items.ARMOR_STAND), "Permission to interact with armor stands"));
public static ClaimPermission BREAKNONLIVING = register(new ClaimPermission("BREAKNONLIVING", () -> new ItemStack(Items.COMMAND_BLOCK_MINECART), "Permission to break things like minecarts or armor stands"));
public static ClaimPermission DROP = register(new ClaimPermission("DROP", () -> new ItemStack(Items.BOWL), true, "Allow the drop of items"));
public static ClaimPermission PICKUP = register(new ClaimPermission("PICKUP", () -> new ItemStack(Items.BRICK), true, "Allow the pickup of items"));
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"));
public static ClaimPermission WITHER = global(new ClaimPermission("WITHER", () -> new ItemStack(Items.WITHER_SKELETON_SKULL), "Toggle wither breaking blocks in claim"));

View File

@ -71,6 +71,8 @@ public class Claim implements IPermissionContainer {
this.owner = creator;
this.world = world;
this.setDirty(true);
PermissionRegistry.getPerms().stream().filter(perm -> perm.defaultVal).forEach(perm -> this.globalPerm.put(perm, true));
System.out.println(this.globalPerm);
}
public static Claim fromJson(JsonObject obj, UUID owner, ServerWorld world) {

View File

@ -6,9 +6,11 @@ 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 com.flemmli97.flan.player.IOwnedItem;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.boss.WitherEntity;
import net.minecraft.entity.damage.DamageSource;
@ -27,11 +29,14 @@ import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.entity.vehicle.MinecartEntity;
import net.minecraft.entity.vehicle.StorageMinecartEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.s2c.play.InventoryS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
@ -197,6 +202,43 @@ public class EntityInteractEvents {
return false;
}
public static boolean canCollideWith(PlayerEntity player, Entity entity) {
if (player instanceof ServerPlayerEntity) {
if (entity instanceof ItemEntity) {
if (player.getUuid().equals(((IOwnedItem) entity).getPlayerOrigin()))
return true;
ClaimStorage storage = ClaimStorage.get((ServerWorld) player.world);
BlockPos pos = player.getBlockPos();
IPermissionContainer claim = storage.getForPermissionCheck(pos);
if (claim != null)
return claim.canInteract((ServerPlayerEntity) player, PermissionRegistry.PICKUP, pos, false);
}
}
return true;
}
public static boolean canDropItem(PlayerEntity player, ItemStack stack) {
if (!player.isDead() && player instanceof ServerPlayerEntity) {
ClaimStorage storage = ClaimStorage.get((ServerWorld) player.world);
BlockPos pos = player.getBlockPos();
IPermissionContainer claim = storage.getForPermissionCheck(pos);
boolean allow = true;
if (claim != null)
allow = claim.canInteract((ServerPlayerEntity) player, PermissionRegistry.DROP, pos, false);
if (!allow) {
player.inventory.insertStack(stack);
DefaultedList<ItemStack> stacks = DefaultedList.of();
for (int j = 0; j < player.currentScreenHandler.slots.size(); ++j) {
ItemStack itemStack2 = player.currentScreenHandler.slots.get(j).getStack();
stacks.add(itemStack2.isEmpty() ? ItemStack.EMPTY : itemStack2);
}
((ServerPlayerEntity) player).networkHandler.sendPacket(new InventoryS2CPacket(player.currentScreenHandler.syncId, stacks));
}
return allow;
}
return true;
}
public static boolean witherCanDestroy(WitherEntity wither) {
if (wither.world.isClient)
return true;

View File

@ -0,0 +1,40 @@
package com.flemmli97.flan.mixin;
import com.flemmli97.flan.player.IOwnedItem;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.UUID;
@Mixin(ItemEntity.class)
public class ItemEntityMixin implements IOwnedItem {
@Unique
private UUID playerOrigin;
@Inject(method = "readCustomDataFromTag", at = @At("RETURN"))
private void readData(CompoundTag tag, CallbackInfo info) {
if (tag.contains("Flan:PlayerOrigin"))
this.playerOrigin = tag.getUuid("Flan:PlayerOrigin");
}
@Inject(method = "writeCustomDataToTag", at = @At("RETURN"))
private void writeData(CompoundTag tag, CallbackInfo info) {
if (this.playerOrigin != null)
tag.putUuid("Flan:PlayerOrigin", this.playerOrigin);
}
public void setOriginPlayer(PlayerEntity player) {
this.playerOrigin = player.getUuid();
}
public UUID getPlayerOrigin() {
return this.playerOrigin;
}
}

View File

@ -0,0 +1,40 @@
package com.flemmli97.flan.mixin;
import com.flemmli97.flan.event.EntityInteractEvents;
import com.flemmli97.flan.player.IOwnedItem;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerEntity.class)
public abstract class PlayerMixin {
@Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At(value = "HEAD"), cancellable = true)
public void drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership, CallbackInfoReturnable<ItemEntity> info) {
if (!EntityInteractEvents.canDropItem((PlayerEntity) (Object) this, stack)) {
info.setReturnValue(null);
info.cancel();
}
}
@ModifyVariable(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ItemEntity;setPickupDelay(I)V"))
private ItemEntity ownerDrop(ItemEntity entity) {
((IOwnedItem) entity).setOriginPlayer(((PlayerEntity) (Object) this));
return entity;
}
@Inject(method = "collideWithEntity", at = @At(value = "HEAD"), cancellable = true)
public void entityCollide(Entity entity, CallbackInfo info) {
if (!EntityInteractEvents.canCollideWith((PlayerEntity) (Object) this, entity)) {
info.cancel();
}
}
}

View File

@ -1,14 +1,12 @@
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;

View File

@ -0,0 +1,13 @@
package com.flemmli97.flan.player;
import net.minecraft.entity.player.PlayerEntity;
import java.util.UUID;
public interface IOwnedItem {
void setOriginPlayer(PlayerEntity player);
UUID getPlayerOrigin();
}

View File

@ -21,7 +21,9 @@
"PistonMixin",
"RaidManagerMixin",
"FireBlockMixin",
"SpawnHelperMixin"
"SpawnHelperMixin",
"PlayerMixin",
"ItemEntityMixin"
],
"server": [
],