diff --git a/src/main/java/carpet/mixins/ArmorStandEntity_scarpetMarkerMixin.java b/src/main/java/carpet/mixins/ArmorStandEntity_scarpetMarkerMixin.java new file mode 100644 index 00000000..b1943e26 --- /dev/null +++ b/src/main/java/carpet/mixins/ArmorStandEntity_scarpetMarkerMixin.java @@ -0,0 +1,55 @@ +package carpet.mixins; + +import carpet.CarpetServer; +import carpet.script.ExpressionInspector; +import carpet.settings.CarpetSettings; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.decoration.ArmorStandEntity; +import net.minecraft.world.World; +import org.apache.commons.lang3.StringUtils; +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 java.util.Optional; + +@Mixin(ArmorStandEntity.class) +public abstract class ArmorStandEntity_scarpetMarkerMixin extends LivingEntity +{ + protected ArmorStandEntity_scarpetMarkerMixin(EntityType entityType_1, World world_1) + { + super(entityType_1, world_1); + } + + /** + * Remove all markers that do not belong to any script host and not part of the global one when loaded + * @param ci + */ + @Inject(method = "readCustomDataFromTag", at = @At("HEAD")) + private void checkScarpetMarkerUnloaded(CallbackInfo ci) + { + if ((CarpetSettings.scriptsAutoload || CarpetSettings.commandScript) && !world.isClient) + { + if (getScoreboardTags().contains(ExpressionInspector.MARKER_STRING)) + { + String prefix = ExpressionInspector.MARKER_STRING+"_"; + Optional owner = getScoreboardTags().stream().filter(s -> s.startsWith(prefix)).findFirst(); + if (owner.isPresent()) + { + String hostName = StringUtils.removeStart(owner.get(),prefix); + if (!hostName.isEmpty() && CarpetServer.scriptServer.getHostByName(hostName) == null) + { + remove(); + } + + } + else + { + remove(); + } + } + } + } +} diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index f3abbba6..8036af3b 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -2737,7 +2737,8 @@ public class CarpetExpression (float)pointLocator.yaw, (float) pointLocator.pitch ); - armorstand.addScoreboardTag("__scarpet_marker"); + armorstand.addScoreboardTag(ExpressionInspector.MARKER_STRING+"_"+((cc.host.getName()==null)?"":cc.host.getName())); + armorstand.addScoreboardTag(ExpressionInspector.MARKER_STRING); if (targetBlock != null) armorstand.setEquippedStack(EquipmentSlot.HEAD, new ItemStack(targetBlock.getBlock().asItem())); if (!name.isEmpty()) @@ -2757,7 +2758,8 @@ public class CarpetExpression this.expr.addLazyFunction("remove_all_markers", 0, (c, t, lv) -> { CarpetContext cc = (CarpetContext)c; int total = 0; - for (Entity e : cc.s.getWorld().getEntities(EntityType.ARMOR_STAND, (as) -> as.getScoreboardTags().contains("__scarpet_marker"))) + String markerName = ExpressionInspector.MARKER_STRING+"_"+((cc.host.getName()==null)?"":cc.host.getName()); + for (Entity e : cc.s.getWorld().getEntities(EntityType.ARMOR_STAND, (as) -> as.getScoreboardTags().contains(markerName))) { total ++; e.remove(); diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 906dbe68..c879cbb6 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -358,6 +358,7 @@ public class CarpetScriptServer } // stop all events associated with name events.removeAllHostEvents(name); + modules.get(name).onClose(); modules.remove(name); CarpetServer.settingsManager.notifyPlayersCommandsChanged(); Messenger.m(source, "gi Removed "+name+" app"); diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 89994ce3..370c2fa8 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -2824,6 +2824,8 @@ public class Expression implements Cloneable addUnaryFunction("title", v -> new StringValue(WordUtils.capitalizeFully(v.getString()))); + // TODO: split, replace, replace_first, escape_special (to make nbt to string) + addUnaryFunction("type", v -> new StringValue(v.getTypeString())); diff --git a/src/main/java/carpet/script/ExpressionInspector.java b/src/main/java/carpet/script/ExpressionInspector.java index 56d602c5..dd762c32 100644 --- a/src/main/java/carpet/script/ExpressionInspector.java +++ b/src/main/java/carpet/script/ExpressionInspector.java @@ -15,6 +15,7 @@ import java.util.stream.Collectors; */ public class ExpressionInspector { + public static final String MARKER_STRING = "__scarpet_marker"; public static List Expression_getExpressionSnippet(Tokenizer.Token token, Expression expr) { return Expression.getExpressionSnippet(token, expr); diff --git a/src/main/java/carpet/script/ScriptHost.java b/src/main/java/carpet/script/ScriptHost.java index 059774db..f8f0b4be 100644 --- a/src/main/java/carpet/script/ScriptHost.java +++ b/src/main/java/carpet/script/ScriptHost.java @@ -9,9 +9,12 @@ import carpet.script.value.NumericValue; import carpet.script.value.StringValue; import carpet.script.value.Value; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; import net.minecraft.nbt.Tag; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import java.math.BigInteger; @@ -288,6 +291,14 @@ public class ScriptHost { if (this.saveTimeout > 0) dumpState(); + String markerName = ExpressionInspector.MARKER_STRING+"_"+((getName()==null)?"":getName()); + for (ServerWorld world : CarpetServer.minecraft_server.getWorlds()) + { + for (Entity e : world.getEntities(EntityType.ARMOR_STAND, (as) -> as.getScoreboardTags().contains(markerName))) + { + e.remove(); + } + } } public void setPerPlayer(boolean isPerUser) diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index d43db955..39d33280 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -13,7 +13,6 @@ import net.minecraft.client.network.packet.EntityPassengersSetS2CPacket; import net.minecraft.client.network.packet.EntityPositionS2CPacket; import net.minecraft.command.EntitySelector; import net.minecraft.command.EntitySelectorReader; -import net.minecraft.command.arguments.NbtPathArgumentType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityType; @@ -28,7 +27,6 @@ import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntityWithAi; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; @@ -423,6 +421,7 @@ public class EntityValue extends Value private static void updatePosition(Entity e) { if (e instanceof ServerPlayerEntity) + // TODO next - figure out proper way of informting client about pos changes ((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch); else ((ServerWorld)e.getEntityWorld()).method_14178().sendToNearbyPlayers(e,new EntityPositionS2CPacket(e)); diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 901905a0..758169c4 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -122,6 +122,7 @@ "PickaxeItem_missingToolsMixin", "ShearsItem_missingToolsMixin", + "ArmorStandEntity_scarpetMarkerMixin", "Entity_scarpetEventsMixin", "LivingEntity_scarpetEventsMixin", "DamageTracker_scarpetEventMixin",