From 8c95aab2c62fc645847d9c8cc0da8a1ead2c67b2 Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 19 Dec 2019 18:11:13 -0400 Subject: [PATCH] scarpet thread safe pt1 --- .../java/carpet/script/CarpetExpression.java | 4 +- .../java/carpet/script/value/BlockValue.java | 12 ++++- .../java/carpet/script/value/EntityValue.java | 16 ++++++ .../script/value/NBTSerializableValue.java | 51 +++++++++++++++++-- 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index a66a9911..c5cbe225 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -127,7 +127,7 @@ import static java.lang.Math.sqrt; * players using player('*'), which only returns players in current dimension, or use * in_dimension(expr) function.

*/ -public class CarpetExpression +public class CarpetExpression { private ServerCommandSource source; @@ -771,7 +771,7 @@ public class CarpetExpression booleanStateTest(c, "liquid", lv, (s, p) -> !s.getFluidState().isEmpty())); this.expr.addLazyFunction("flammable", -1, (c, t, lv) -> - booleanStateTest(c, "flammable", lv, (s, p) -> !s.getMaterial().isBurnable())); + booleanStateTest(c, "flammable", lv, (s, p) -> s.getMaterial().isBurnable())); this.expr.addLazyFunction("transparent", -1, (c, t, lv) -> booleanStateTest(c, "transparent", lv, (s, p) -> !s.getMaterial().isSolid())); diff --git a/src/main/java/carpet/script/value/BlockValue.java b/src/main/java/carpet/script/value/BlockValue.java index 485aa5e8..9a460338 100644 --- a/src/main/java/carpet/script/value/BlockValue.java +++ b/src/main/java/carpet/script/value/BlockValue.java @@ -21,6 +21,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; +import net.minecraft.world.chunk.WorldChunk; import java.util.Arrays; import java.util.HashMap; @@ -192,6 +193,15 @@ public class BlockValue extends Value throw new InternalExpressionException("Attempted to fetch block state without world or stored block state"); } + public static BlockEntity getBlockEntity(ServerWorld world, BlockPos pos) + { + if (world.getServer().isOnThread()) + return world.getBlockEntity(pos); + else + return world.getWorldChunk(pos).getBlockEntity(pos, WorldChunk.CreationType.IMMEDIATE); + } + + public CompoundTag getData() { if (data != null) @@ -202,7 +212,7 @@ public class BlockValue extends Value } if (world != null && pos != null) { - BlockEntity be = world.getBlockEntity(pos); + BlockEntity be = getBlockEntity(world, pos); CompoundTag tag = new CompoundTag(); if (be == null) { diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index e1aacde9..61760579 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -273,6 +273,22 @@ public class EntityValue extends Value } return Value.NULL; }); + + put("permission_level", (e, a) -> { + if (e instanceof ServerPlayerEntity) + { + ServerPlayerEntity spe = (ServerPlayerEntity) e; + for (int i=4; i>=0; i--) + { + if (spe.allowsPermissionLevel(i)) + return new NumericValue(i); + + } + return new NumericValue(0); + } + return Value.NULL; + }); + //spectating_entity // isGlowing put("effect", (e, a) -> diff --git a/src/main/java/carpet/script/value/NBTSerializableValue.java b/src/main/java/carpet/script/value/NBTSerializableValue.java index 40b058ea..7cbeaec9 100644 --- a/src/main/java/carpet/script/value/NBTSerializableValue.java +++ b/src/main/java/carpet/script/value/NBTSerializableValue.java @@ -5,6 +5,12 @@ import carpet.script.LazyValue; import carpet.script.exception.InternalExpressionException; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ChestBlock; +import net.minecraft.block.InventoryProvider; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.ChestBlockEntity; import net.minecraft.block.entity.HopperBlockEntity; import net.minecraft.command.arguments.ItemStackArgument; import net.minecraft.command.arguments.ItemStringReader; @@ -21,8 +27,12 @@ import net.minecraft.nbt.ListTag; import net.minecraft.nbt.StringNbtReader; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; +import net.minecraft.predicate.entity.EntityPredicates; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.world.World; import java.util.Collection; import java.util.HashMap; @@ -116,6 +126,41 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa return copy; } + // stolen from HopperBlockEntity, adjusted for threaded operation + public static Inventory getInventoryAt(ServerWorld world, BlockPos blockPos) + { + Inventory inventory = null; + BlockState blockState = world.getBlockState(blockPos); + Block block = blockState.getBlock(); + if (block instanceof InventoryProvider) { + inventory = ((InventoryProvider)block).getInventory(blockState, world, blockPos); + } else if (block.hasBlockEntity()) { + BlockEntity blockEntity = BlockValue.getBlockEntity(world, blockPos); + if (blockEntity instanceof Inventory) { + inventory = (Inventory)blockEntity; + if (inventory instanceof ChestBlockEntity && block instanceof ChestBlock) { + inventory = ChestBlock.getInventory(blockState, world, blockPos, true); + } + } + } + + if (inventory == null) { + List list = world.getEntities( + (Entity)null, + new Box( + blockPos.getX() - 0.5D, blockPos.getY() - 0.5D, blockPos.getZ() - 0.5D, + blockPos.getX() + 0.5D, blockPos.getY() + 0.5D, blockPos.getZ() + 0.5D), + EntityPredicates.VALID_INVENTORIES + ); + if (!list.isEmpty()) { + inventory = (Inventory)list.get(world.random.nextInt(list.size())); + } + } + + return inventory; + } + + public static InventoryLocator locateInventory(CarpetContext c, List params, int offset) { try @@ -139,7 +184,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa BlockPos pos = ((BlockValue) v1).getPos(); if (pos == null) throw new InternalExpressionException("Block to access inventory needs to be positioned in the world"); - inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos); + inv = getInventoryAt(c.s.getWorld(), pos); if (inv == null) return null; return new InventoryLocator(pos, pos, inv, offset + 1); @@ -151,7 +196,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa NumericValue.asNumber(args.get(0)).getDouble(), NumericValue.asNumber(args.get(1)).getDouble(), NumericValue.asNumber(args.get(2)).getDouble()); - inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos); + inv = getInventoryAt(c.s.getWorld(), pos); if (inv == null) return null; return new InventoryLocator(pos, pos, inv, offset + 1); @@ -160,7 +205,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa NumericValue.asNumber(v1).getDouble(), NumericValue.asNumber(params.get(1 + offset).evalValue(c)).getDouble(), NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble()); - inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos); + inv = getInventoryAt(c.s.getWorld(), pos); if (inv == null) return null; return new InventoryLocator(pos, pos, inv, offset + 3);