diff --git a/gradle.properties b/gradle.properties index 17fa2a32..9b00f21b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.4.8+build.155 # Mod Properties - mod_version = 1.0.0+v190721 + mod_version = 1.0.1+v190726 maven_group = carpet archives_base_name = fabric-carpet diff --git a/src/main/java/carpet/fakes/EntityInterface.java b/src/main/java/carpet/fakes/EntityInterface.java index deb9a033..723e5425 100644 --- a/src/main/java/carpet/fakes/EntityInterface.java +++ b/src/main/java/carpet/fakes/EntityInterface.java @@ -1,6 +1,20 @@ package carpet.fakes; +import carpet.script.CarpetContext; +import carpet.script.CarpetEventServer; +import carpet.script.ScriptHost; +import carpet.script.value.Value; + +import java.util.List; + public interface EntityInterface { float getMainYaw(float partialTicks); + //scarpet part + void onDeathCallback(String reason); + void setDeathCallback(CarpetContext cc, String function, List extraArgs); + void onDamageCallback(); + void setDamageCallback(CarpetContext cc, String function, List extraArgs); + void onRemovedCallback(); + void setRemovedCallback(CarpetContext cc, String function, List extraArgs); } diff --git a/src/main/java/carpet/mixins/Entity_scarpetEventsMixin.java b/src/main/java/carpet/mixins/Entity_scarpetEventsMixin.java new file mode 100644 index 00000000..bb798e6c --- /dev/null +++ b/src/main/java/carpet/mixins/Entity_scarpetEventsMixin.java @@ -0,0 +1,58 @@ +package carpet.mixins; + +import carpet.CarpetServer; +import carpet.fakes.EntityInterface; +import carpet.script.CarpetContext; +import carpet.script.CarpetEventServer; +import carpet.script.ScriptHost; +import carpet.script.value.Value; +import carpet.settings.CarpetSettings; +import net.minecraft.entity.Entity; +import org.lwjgl.system.CallbackI; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +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.List; + +@Mixin(Entity.class) +public abstract class Entity_scarpetEventsMixin implements EntityInterface +{ + @Shadow public boolean removed; + private CarpetEventServer.ScheduledCall deathCall; + private CarpetEventServer.ScheduledCall removeCall; + + + @Override + public void onDeathCallback(String reason) + { + if (deathCall != null) + { + CarpetServer.scriptServer.events.onEntityDeath(deathCall, (Entity)(Object)this, reason); + } + } + + @Override + public void setDeathCallback(CarpetContext cc, String function, List extraArgs) + { + deathCall = CarpetServer.scriptServer.events.makeDeathCall(cc, function, extraArgs); + } + + @Override + public void setRemovedCallback(CarpetContext cc, String function, List extraArgs) + { + removeCall = CarpetServer.scriptServer.events.makeRemovedCall(cc, function, extraArgs); + } + + + @Inject(method = "remove", at = @At("HEAD")) + private void onRemove(CallbackInfo ci) + { + if (!removed && removeCall != null) + { + CarpetServer.scriptServer.events.onEntityRemoved(removeCall, (Entity)(Object)this); + } + } +} diff --git a/src/main/java/carpet/mixins/LivingEntity_scarpetEventsMixin.java b/src/main/java/carpet/mixins/LivingEntity_scarpetEventsMixin.java new file mode 100644 index 00000000..ee51d29e --- /dev/null +++ b/src/main/java/carpet/mixins/LivingEntity_scarpetEventsMixin.java @@ -0,0 +1,23 @@ +package carpet.mixins; + +import carpet.fakes.EntityInterface; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.world.World; +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(LivingEntity.class) +public abstract class LivingEntity_scarpetEventsMixin +{ + + @Inject(method = "onDeath", at = @At("HEAD")) + private void onDeathCall(DamageSource damageSource_1, CallbackInfo ci) + { + ((EntityInterface)this).onDeathCallback(damageSource_1.name); + } +} diff --git a/src/main/java/carpet/mixins/ServerPlayerInteractionManager_ghostBlocksMixin.java b/src/main/java/carpet/mixins/ServerPlayerInteractionManager_ghostBlocksMixin.java new file mode 100644 index 00000000..09552f0c --- /dev/null +++ b/src/main/java/carpet/mixins/ServerPlayerInteractionManager_ghostBlocksMixin.java @@ -0,0 +1,43 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerInteractionManager; +import net.minecraft.server.network.packet.PlayerActionC2SPacket; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.Redirect; + +//needs tests, WIP +@Mixin(ServerPlayerInteractionManager.class) +public class ServerPlayerInteractionManager_ghostBlocksMixin +{ + @Redirect(method = "method_14263", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/BlockState;calcBlockBreakingDelta(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;)F") + + ) + private float noCheatBlockBreakSpeed(BlockState blockState, PlayerEntity playerEntity_1, BlockView blockView_1, BlockPos blockPos_1, + // main args + BlockPos blockPos_1a, PlayerActionC2SPacket.Action playerActionC2SPacket$Action_1, Direction direction_1, int int_1) + { + if (CarpetSettings.miningGhostBlockFix && playerActionC2SPacket$Action_1 == PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK) + return 1.0f; + return blockState.calcBlockBreakingDelta(playerEntity_1, blockView_1, blockPos_1); + } + + + @ModifyConstant(method = "method_14263", + constant = @Constant(doubleValue = 36D)) + private double addDistance(double original) { + if (CarpetSettings.miningGhostBlockFix) + return 1024D; + return original; + } +} diff --git a/src/main/java/carpet/mixins/SpawnHelperMixin.java b/src/main/java/carpet/mixins/SpawnHelperMixin.java index dba85845..af352d57 100644 --- a/src/main/java/carpet/mixins/SpawnHelperMixin.java +++ b/src/main/java/carpet/mixins/SpawnHelperMixin.java @@ -11,6 +11,7 @@ import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.SpawnHelper; @@ -43,9 +44,15 @@ public class SpawnHelperMixin if (CarpetSettings.lagFreeSpawning) { BlockPos.Mutable blockpos = new BlockPos.Mutable(); - for (int y = (int)bb.minY, maxy = (int)Math.ceil(bb.maxY); y < maxy; y++) - for (int x = (int)bb.minX, maxx = (int)Math.ceil(bb.maxX); x < maxx; x++) - for (int z = (int)bb.minZ, maxz = (int)Math.ceil(bb.maxZ); z < maxz; z++) + int minX = MathHelper.floor(bb.minX); + int maxX = MathHelper.ceil(bb.maxX); + int minY = MathHelper.floor(bb.minY); + int maxY = MathHelper.ceil(bb.maxY); + int minZ = MathHelper.floor(bb.minZ); + int maxZ = MathHelper.ceil(bb.maxZ); + for (int y = minY; y < maxY; y++) + for (int x = minX; x < maxX; x++) + for (int z = minZ; z < maxZ; z++) { blockpos.set(x, y, z); VoxelShape box = world.getBlockState(blockpos).getCollisionShape(world, blockpos); diff --git a/src/main/java/carpet/mixins/TntEntityMixin.java b/src/main/java/carpet/mixins/TntEntityMixin.java index 8818cc8d..fb120b2b 100644 --- a/src/main/java/carpet/mixins/TntEntityMixin.java +++ b/src/main/java/carpet/mixins/TntEntityMixin.java @@ -17,7 +17,7 @@ import carpet.logging.logHelpers.TNTLogHelper; @Mixin(TntEntity.class) public abstract class TntEntityMixin extends Entity { - private TNTLogHelper logHelper = null; + private TNTLogHelper logHelper; public TntEntityMixin(EntityType entityType_1, World world_1) { diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java index 4fcf43d4..507b2a48 100644 --- a/src/main/java/carpet/script/CarpetEventServer.java +++ b/src/main/java/carpet/script/CarpetEventServer.java @@ -6,6 +6,8 @@ import carpet.script.value.EntityValue; import carpet.script.value.ListValue; import carpet.script.value.NumericValue; import carpet.script.value.StringValue; +import carpet.script.value.Value; +import carpet.settings.CarpetSettings; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.command.ServerCommandSource; @@ -33,6 +35,7 @@ import java.util.Map; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class CarpetEventServer { @@ -74,6 +77,19 @@ public class CarpetEventServer { CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, args); } + + public void execute(List args) + { + if (this.args == null) + CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, args); + else + { + List combinedArgs = new ArrayList<>(); + combinedArgs.addAll(args); + combinedArgs.addAll(this.args); + CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, combinedArgs); + } + } } public static class CallbackList @@ -215,6 +231,24 @@ public class CarpetEventServer return new Callback(null, funName); } + private ScheduledCall makeEventCall(CarpetContext cc, String function, List extraArgs, int argCount) + { + UserDefinedFunction udf = cc.host.globalFunctions.get(function); + if (udf == null || (udf.getArguments().size()-extraArgs.size()) != argCount) + { + // call won't match arguments + return null; + } + List lazyArgs = null; + if (extraArgs != null) + { + lazyArgs = new ArrayList<>(); + for (Value v : extraArgs) + lazyArgs.add( (c, t) -> v); + } + return new ScheduledCall(cc, function, lazyArgs, 0); + } + public void onTick() { eventHandlers.get("tick").call(Collections::emptyList, CarpetServer.minecraft_server::getCommandSource); @@ -347,4 +381,24 @@ public class CarpetEventServer { eventHandlers.get("player_stops_sprinting").call( () -> Arrays.asList(((c, t) -> new EntityValue(player))), player::getCommandSource); } + + public ScheduledCall makeDeathCall(CarpetContext cc, String function, List extraArgs) + { + return makeEventCall(cc, function, extraArgs, 2); + } + public ScheduledCall makeRemovedCall(CarpetContext cc, String function, List extraArgs) + { + return makeEventCall(cc, function, extraArgs, 1); + } + + + public void onEntityDeath(ScheduledCall call, Entity e, String reason) + { + call.execute( Arrays.asList( (c, t)-> new EntityValue(e), (c, t)-> new StringValue(reason))); + } + public void onEntityRemoved(ScheduledCall removeCall, Entity entity) + { + removeCall.execute(Collections.singletonList((c, t) -> new EntityValue(entity))); + } + } diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 2fc5dad7..d6e9c534 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -3,7 +3,6 @@ package carpet.script; import carpet.CarpetServer; import carpet.fakes.MinecraftServerInterface; import carpet.helpers.FeatureGenerator; -import carpet.helpers.Tracer; import carpet.script.Fluff.TriFunction; import carpet.script.exception.CarpetExpressionException; import carpet.script.exception.ExpressionException; @@ -50,7 +49,6 @@ import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; import net.minecraft.particle.ParticleEffect; import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.server.MinecraftServer; @@ -65,9 +63,6 @@ import net.minecraft.text.LiteralText; import net.minecraft.text.TranslatableText; import net.minecraft.util.Clearable; import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.EulerAngle; @@ -84,7 +79,7 @@ import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -1804,6 +1799,32 @@ public class CarpetExpression ((EntityValue) v).set(what, ListValue.wrap(lv.subList(2, lv.size()).stream().map((vv) -> vv.evalValue(c)).collect(Collectors.toList()))); return lv.get(0); }); + + // or update + this.expr.addLazyFunction("entity_event", -1, (c, t, lv) -> + { + if (lv.size()<3) + throw new InternalExpressionException("entity_event requires at least 3 arguments, entity, event to be handled, and function name, with optional arguments"); + Value v = lv.get(0).evalValue(c); + if (!(v instanceof EntityValue)) + throw new InternalExpressionException("First argument to get should be an entity"); + String what = lv.get(1).evalValue(c).getString(); + Value functionValue = lv.get(2).evalValue(c); + String function = null; + if (!(functionValue instanceof NullValue)) + function = functionValue.getString(); + List args = null; + if (lv.size()==4) + args = Collections.singletonList(lv.get(3).evalValue(c)); + else if (lv.size()>4) + { + args = new ArrayList<>(lv.subList(3, lv.size()).stream().map((vv) -> vv.evalValue(c)).collect(Collectors.toList())); + } + + ((EntityValue) v).setEvent((CarpetContext)c, what, function, args); + + return LazyValue.NULL; + }); } /** diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 469d65fe..128f89ff 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -2527,6 +2527,20 @@ public class Expression implements Cloneable return (cc, tt) -> time; }); + addLazyFunction("profile_expr", 1, (c, t, lv) -> + { + LazyValue lazy = lv.get(0); + long end = System.nanoTime()+50000000L; + long it = 0; + while (System.nanoTime() res; + }); + addLazyFunction("var", 1, (c, t, lv) -> { String varname = lv.get(0).evalValue(c).getString(); if (!c.isAVariable(varname)) diff --git a/src/main/java/carpet/script/Fluff.java b/src/main/java/carpet/script/Fluff.java index 5cd29ad4..77dc72b1 100644 --- a/src/main/java/carpet/script/Fluff.java +++ b/src/main/java/carpet/script/Fluff.java @@ -12,6 +12,12 @@ public abstract class Fluff @FunctionalInterface public interface TriFunction { R apply(A a, B b, C c); } + @FunctionalInterface + public interface TriConsumer { void accept(A a, B b, C c); } + + @FunctionalInterface + public interface QuadConsumer { void accept(A a, B b, C c, D d); } + @FunctionalInterface public interface QuadFunction { R apply(A a, B b, C c, D d);} diff --git a/src/main/java/carpet/script/value/BlockValue.java b/src/main/java/carpet/script/value/BlockValue.java index 11073e6b..a6277555 100644 --- a/src/main/java/carpet/script/value/BlockValue.java +++ b/src/main/java/carpet/script/value/BlockValue.java @@ -208,7 +208,7 @@ public class BlockValue extends Value data = be.toTag(tag); return data; } - throw new InternalExpressionException("Attemted to fetch block data without world or stored block data"); + return null; } diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index 0b5dab95..48cf3ef1 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -1,8 +1,12 @@ package carpet.script.value; +import carpet.fakes.EntityInterface; import carpet.fakes.MobEntityInterface; import carpet.helpers.Tracer; +import carpet.script.CarpetContext; +import carpet.script.Fluff; import carpet.script.exception.InternalExpressionException; +import carpet.settings.CarpetSettings; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.client.network.packet.EntityPositionS2CPacket; @@ -427,7 +431,8 @@ public class EntityValue extends Value private static void updateVelocity(Entity e) { - ((ServerWorld)e.getEntityWorld()).method_14178().sendToNearbyPlayers(e, new EntityVelocityUpdateS2CPacket(e)); + e.velocityModified = true; + //((ServerWorld)e.getEntityWorld()).method_14178().sendToNearbyPlayers(e, new EntityVelocityUpdateS2CPacket(e)); } @@ -680,6 +685,7 @@ public class EntityValue extends Value } }); //requires mixing + // gamemode // spectate // "fire" @@ -697,4 +703,16 @@ public class EntityValue extends Value // "jump" // "nbt" <-big one, for now use run('data merge entity ... }}; + + public void setEvent(CarpetContext cc, String event, String fun, List args) + { + if (!(events.containsKey(event))) + throw new InternalExpressionException("unknown entity event: " + event); + events.get(event).accept(cc, entity, fun, args); + } + + private static Map>> events = new HashMap>>() {{ + put("on_death", (c, e, f, l) -> ((EntityInterface)e).setDeathCallback(c, f, l)); + put("on_removed", (c, e, f, l) -> ((EntityInterface)e).setRemovedCallback(c, f, l)); + }}; } diff --git a/src/main/java/carpet/settings/CarpetSettings.java b/src/main/java/carpet/settings/CarpetSettings.java index 96767a49..7fe5cfaa 100644 --- a/src/main/java/carpet/settings/CarpetSettings.java +++ b/src/main/java/carpet/settings/CarpetSettings.java @@ -26,7 +26,7 @@ import static carpet.settings.RuleCategory.SURVIVAL; public class CarpetSettings { - public static final String carpetVersion = "1.0.0-v190721"; + public static final String carpetVersion = "1.0.1-v190726"; public static final Logger LOG = LogManager.getLogger(); public static boolean skipGenerationChecks = false; public static boolean impendingFillSkipUpdates = false; @@ -229,6 +229,9 @@ public class CarpetSettings @Rule(desc = "smooth client animations with low tps settings", extra = "works only in SP, and will slow down players", category = CREATIVE) public static boolean smoothClientAnimations; + //@Rule(desc="Fixes mining ghost blocks by allowing ANY mining speed from clients", category = SURVIVAL) + public static boolean miningGhostBlockFix; + private static class PushLimitLimits extends Validator { @Override public Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { return (newValue>0 && newValue <= 1024) ? newValue : null; diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index e137da04..e3c56c81 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -112,6 +112,9 @@ "PickaxeItem_missingToolsMixin", "ShearsItem_missingToolsMixin", + "Entity_scarpetEventsMixin", + "LivingEntity_scarpetEventsMixin", + "PistonBlock_movableTEMixin", "PistonBlockEntity_movableTEMixin", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 535fb707..4617f22d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "carpet", - "version": "1.0.0", + "version": "1.0.1", "name": "Carpet Mod in Fabric", "description": "Carpet made out of fabric",