diff --git a/gradle.properties b/gradle.properties index 0eca5ea4..e6434070 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+v190627 + mod_version = 1.0.0+v190707 maven_group = carpet archives_base_name = fabric-carpet diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index 94027a8d..5c411f08 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -48,13 +48,9 @@ public class CarpetServer // static for now - easier to handle all around the co extensions.forEach(CarpetExtension::onGameStarted); } - public static void init(MinecraftServer server) //aka constructor of this static singleton class - { - // no sure we really need this here, needs testing and moving to onServerLoaded - CarpetServer.minecraft_server = server; - } public static void onServerLoaded(MinecraftServer server) { + CarpetServer.minecraft_server = server; settingsManager.attachServer(server); extensions.forEach(e -> { SettingsManager sm = e.customSettingsManager(); @@ -69,8 +65,12 @@ public class CarpetServer // static for now - easier to handle all around the co TickSpeed.tick(server); HUDController.update_hud(server); scriptServer.events.tick(); + //in case something happens CarpetSettings.impendingFillSkipUpdates = false; + CarpetSettings.currentTelepotingEntityBox = null; + CarpetSettings.fixedPosition = null; + extensions.forEach(e -> e.onTick(server)); } diff --git a/src/main/java/carpet/fakes/MinecraftServer_motdInterface.java b/src/main/java/carpet/fakes/MinecraftServer_motdInterface.java deleted file mode 100644 index 6cb05284..00000000 --- a/src/main/java/carpet/fakes/MinecraftServer_motdInterface.java +++ /dev/null @@ -1,6 +0,0 @@ -package carpet.fakes; - -public interface MinecraftServer_motdInterface -{ - String checkMOTD(); -} diff --git a/src/main/java/carpet/mixins/Entity_portalSuffocationMixin.java b/src/main/java/carpet/mixins/Entity_portalSuffocationMixin.java new file mode 100644 index 00000000..d5de13d0 --- /dev/null +++ b/src/main/java/carpet/mixins/Entity_portalSuffocationMixin.java @@ -0,0 +1,51 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.world.dimension.DimensionType; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Entity.class) +public abstract class Entity_portalSuffocationMixin +{ + @Shadow public abstract Box getBoundingBox(); + + @Inject(method = "changeDimension", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/Entity;getLastPortalDirection()Lnet/minecraft/util/math/Direction;" + )) + private void registerEntityDimensionChange(DimensionType dimensionType_1, CallbackInfoReturnable cir) + { + if (CarpetSettings.portalSuffocationFix) + { + CarpetSettings.currentTelepotingEntityBox = getBoundingBox(); + CarpetSettings.fixedPosition = null; + } + } + + @Redirect(method = "changeDimension", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/Entity;setPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V" + )) + private void alternativeSetPositionAndAngles(Entity entity, BlockPos blockPos_1, float float_1, float float_2) + { + if (CarpetSettings.portalSuffocationFix && CarpetSettings.fixedPosition != null) + entity.setPositionAndAngles(CarpetSettings.fixedPosition.x, CarpetSettings.fixedPosition.y, CarpetSettings.fixedPosition.z, float_1, float_2); + else + entity.setPositionAndAngles(blockPos_1, float_1, float_2); + } + + @Inject(method = "changeDimension", at = @At("RETURN")) + private void removeEntity(DimensionType dimensionType_1, CallbackInfoReturnable cir) + { + CarpetSettings.currentTelepotingEntityBox = null; + CarpetSettings.fixedPosition = null; + } +} diff --git a/src/main/java/carpet/mixins/IntegratedServerMixin.java b/src/main/java/carpet/mixins/IntegratedServerMixin.java index a5149af5..c81dbf84 100644 --- a/src/main/java/carpet/mixins/IntegratedServerMixin.java +++ b/src/main/java/carpet/mixins/IntegratedServerMixin.java @@ -1,17 +1,19 @@ package carpet.mixins; import carpet.CarpetServer; +import com.google.gson.JsonElement; import net.minecraft.server.integrated.IntegratedServer; +import net.minecraft.world.level.LevelGeneratorType; 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.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(IntegratedServer.class) public class IntegratedServerMixin { - @Inject(method = "setupServer", at = @At("TAIL")) - private void onSetupServerIntegrated(CallbackInfoReturnable cir) { + @Inject(method = "loadWorld", at = @At("HEAD")) + private void onSetupServerIntegrated(String string_1, String string_2, long long_1, LevelGeneratorType levelGeneratorType_1, JsonElement jsonElement_1, CallbackInfo ci) { CarpetServer.onServerLoaded((IntegratedServer) (Object) this); } } diff --git a/src/main/java/carpet/mixins/MinecraftDedicatedServerMixin.java b/src/main/java/carpet/mixins/MinecraftDedicatedServerMixin.java index 9b23c940..a9cf010a 100644 --- a/src/main/java/carpet/mixins/MinecraftDedicatedServerMixin.java +++ b/src/main/java/carpet/mixins/MinecraftDedicatedServerMixin.java @@ -12,11 +12,14 @@ public class MinecraftDedicatedServerMixin { //to inject right before // this.tickWorlds(booleanSupplier_1); - @Inject(method = "setupServer", at = @At("TAIL")) + @Inject(method = "setupServer", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/dedicated/MinecraftDedicatedServer;loadWorld(Ljava/lang/String;Ljava/lang/String;JLnet/minecraft/world/level/LevelGeneratorType;Lcom/google/gson/JsonElement;)V", + shift = At.Shift.BEFORE + )) private void onSetupServer(CallbackInfoReturnable cir) { - //CM init - all stuff loaded from the server, just before worlds loading - CarpetServer.onServerLoaded((MinecraftDedicatedServer) (Object) this); //CM start game hook CarpetServer.onGameStarted(); + } } diff --git a/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java b/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java index 11107bbf..4061db16 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java @@ -1,37 +1,19 @@ package carpet.mixins; import carpet.CarpetServer; -import com.mojang.authlib.GameProfileRepository; -import com.mojang.authlib.minecraft.MinecraftSessionService; -import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; -import com.mojang.datafixers.DataFixer; +import com.google.gson.JsonElement; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.WorldGenerationProgressListenerFactory; -import net.minecraft.server.command.CommandManager; -import net.minecraft.util.UserCache; +import net.minecraft.world.level.LevelGeneratorType; 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.io.File; -import java.net.Proxy; import java.util.function.BooleanSupplier; @Mixin(MinecraftServer.class) public abstract class MinecraftServer_coreMixin { - @Inject(method = "", at = @At(value = "RETURN")) - private void onMinecraftServerCTOR(File file_1, Proxy proxy_1, DataFixer dataFixer_1, - CommandManager serverCommandManager_1, YggdrasilAuthenticationService yggdrasilAuthenticationService_1, - MinecraftSessionService minecraftSessionService_1, GameProfileRepository gameProfileRepository_1, - UserCache userCache_1, WorldGenerationProgressListenerFactory worldGenerationProgressListenerFactory_1, - String string_1, CallbackInfo ci) - { - // Called during game start - CarpetServer.init((MinecraftServer) (Object) this); - } - //to inject right before // this.tickWorlds(booleanSupplier_1); @Inject( @@ -46,4 +28,11 @@ public abstract class MinecraftServer_coreMixin private void onTick(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { CarpetServer.tick((MinecraftServer) (Object) this); } + + // Dedicated server only + @Inject(method = "loadWorld", at = @At("HEAD")) + private void serverLoaded(String string_1, String string_2, long long_1, LevelGeneratorType levelGeneratorType_1, JsonElement jsonElement_1, CallbackInfo ci) + { + CarpetServer.onServerLoaded((MinecraftServer) (Object) this); + } } diff --git a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java deleted file mode 100644 index 187018ab..00000000 --- a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package carpet.mixins; - -import carpet.settings.CarpetSettings; -import carpet.fakes.MinecraftServer_motdInterface; -import net.minecraft.server.MinecraftServer; -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.Redirect; - -@Mixin(MinecraftServer.class) -public abstract class MinecraftServer_motdMixin implements MinecraftServer_motdInterface -{ - @Shadow private String motd; - - @Shadow public abstract void setMotd(String string_1); - - @Redirect(method = "run", at = @At( - value = "FIELD", - target = "Lnet/minecraft/server/MinecraftServer;motd:Ljava/lang/String;") - ) - private String setCustomMotd(MinecraftServer server) - { - return checkMOTD(); - } - - @Override - public String checkMOTD() - { - if ("_".equals(CarpetSettings.customMOTD)) - { - setMotd(motd); - return motd; - } - else - { - setMotd(CarpetSettings.customMOTD); - return CarpetSettings.customMOTD; - } - } -} diff --git a/src/main/java/carpet/mixins/MobEntity_leashMixin.java b/src/main/java/carpet/mixins/MobEntity_leashMixin.java new file mode 100644 index 00000000..f39d0b88 --- /dev/null +++ b/src/main/java/carpet/mixins/MobEntity_leashMixin.java @@ -0,0 +1,28 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.entity.Entity; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.nbt.CompoundTag; +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; + +@Mixin(MobEntity.class) +public abstract class MobEntity_leashMixin +{ + @Shadow /*@Nullable*/ private Entity holdingEntity; + + @Shadow /*@Nullable*/ private CompoundTag leashTag; + + @Inject(method = "writeCustomDataToTag", at = @At("TAIL")) + private void addLeashData(CompoundTag compoundTag_1, CallbackInfo ci) + { + if (holdingEntity == null && CarpetSettings.leadFix && leashTag != null) + { + compoundTag_1.put("Leash", leashTag); + } + } +} diff --git a/src/main/java/carpet/mixins/PickaxeItem_missingToolsMixin.java b/src/main/java/carpet/mixins/PickaxeItem_missingToolsMixin.java new file mode 100644 index 00000000..ea683c45 --- /dev/null +++ b/src/main/java/carpet/mixins/PickaxeItem_missingToolsMixin.java @@ -0,0 +1,25 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.block.BlockState; +import net.minecraft.block.Material; +import net.minecraft.item.PickaxeItem; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(PickaxeItem.class) +public class PickaxeItem_missingToolsMixin +{ + @Redirect(method = "getMiningSpeed", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/BlockState;getMaterial()Lnet/minecraft/block/Material;" + )) + private Material getCustomMaterial(BlockState blockState) + { + Material material = blockState.getMaterial(); + if (CarpetSettings.missingTools && (material == Material.PISTON || material == Material.GLASS)) + material = Material.STONE; + return material; + } +} diff --git a/src/main/java/carpet/mixins/PortalForcer_portalSuffocationMixin.java b/src/main/java/carpet/mixins/PortalForcer_portalSuffocationMixin.java new file mode 100644 index 00000000..ea18d73a --- /dev/null +++ b/src/main/java/carpet/mixins/PortalForcer_portalSuffocationMixin.java @@ -0,0 +1,100 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.block.pattern.BlockPattern; +import net.minecraft.entity.Entity; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.PortalForcer; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(PortalForcer.class) +public class PortalForcer_portalSuffocationMixin +{ + @Inject(method = "usePortal", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/Entity;getLastPortalDirectionVector()Lnet/minecraft/util/math/Vec3d;" + )) + private void registerEntityDimensionChange(Entity entity_1, float float_1, CallbackInfoReturnable cir) + { + if (CarpetSettings.portalSuffocationFix) + { + CarpetSettings.currentTelepotingEntityBox = entity_1.getBoundingBox(); + CarpetSettings.fixedPosition = null; + } + } + + @Redirect(method = "usePortal", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/Entity;setPositionAndAngles(DDDFF)V" + )) + private void alternativeSetPositionAndAngles(Entity entity, double double_1, double double_2, double double_3, float float_1, float float_2) + { + if (CarpetSettings.portalSuffocationFix && CarpetSettings.fixedPosition != null) + entity.setPositionAndAngles(CarpetSettings.fixedPosition.x, CarpetSettings.fixedPosition.y, CarpetSettings.fixedPosition.z, float_1, float_2); + else + entity.setPositionAndAngles(double_1, double_2, double_3, float_1, float_2); + + } + + @Redirect(method = "usePortal", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;requestTeleport(DDDFF)V" + )) + private void alternativeSetPositionAndAngles(ServerPlayNetworkHandler serverPlayNetworkHandler, double double_1, double double_2, double double_3, float float_1, float float_2) + { + if (CarpetSettings.portalSuffocationFix && CarpetSettings.fixedPosition != null) + serverPlayNetworkHandler.requestTeleport(CarpetSettings.fixedPosition.x, CarpetSettings.fixedPosition.y, CarpetSettings.fixedPosition.z, float_1, float_2); + else + serverPlayNetworkHandler.requestTeleport(double_1, double_2, double_3, float_1, float_2); + + } + + @Inject(method = "usePortal", at = @At("RETURN")) + private void removeEntity(Entity entity_1, float float_1, CallbackInfoReturnable cir) + { + CarpetSettings.currentTelepotingEntityBox = null; + CarpetSettings.fixedPosition = null; + } + + + @Redirect(method = "getPortal",at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/pattern/BlockPattern$Result;method_18478(Lnet/minecraft/util/math/Direction;Lnet/minecraft/util/math/BlockPos;DLnet/minecraft/util/math/Vec3d;D)Lnet/minecraft/block/pattern/BlockPattern$TeleportTarget;" + )) + private BlockPattern.TeleportTarget newResult(BlockPattern.Result portal, Direction direction_1, BlockPos blockPos_1, double height_position_from_top, Vec3d vec3d_1, double width_position) + { + if (CarpetSettings.portalSuffocationFix && CarpetSettings.currentTelepotingEntityBox != null) + { + double entityWidth = CarpetSettings.currentTelepotingEntityBox.getXSize(); + double entityHeight = CarpetSettings.currentTelepotingEntityBox.getYSize(); + if (entityWidth >= portal.getWidth()) + { + width_position = 0.5; // will suffocate anyways, placing in the middle + } + else + { + width_position = MathHelper.clamp(width_position, entityWidth/(2*portal.getWidth()), 1.0-entityWidth/(2*portal.getWidth())); + } + if (entityHeight >= portal.getHeight()) + { + height_position_from_top = 1.0; + } + else + { + height_position_from_top = MathHelper.clamp(height_position_from_top, entityHeight/portal.getHeight(),1.0); + } + + } + BlockPattern.TeleportTarget target = portal.method_18478(direction_1, blockPos_1, height_position_from_top, vec3d_1, width_position); + CarpetSettings.fixedPosition = target.pos; + return target; + } +} diff --git a/src/main/java/carpet/mixins/ServerMetadata_motdMixin.java b/src/main/java/carpet/mixins/ServerMetadata_motdMixin.java new file mode 100644 index 00000000..f6116d2d --- /dev/null +++ b/src/main/java/carpet/mixins/ServerMetadata_motdMixin.java @@ -0,0 +1,24 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.server.ServerMetadata; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +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.CallbackInfoReturnable; + +@Mixin(ServerMetadata.class) +public class ServerMetadata_motdMixin +{ + @Inject(method = "getDescription", at = @At("HEAD"), cancellable = true) + private void getDescriptionAlternative(CallbackInfoReturnable cir) + { + if (!CarpetSettings.customMOTD.equals("_")) + { + cir.setReturnValue(new LiteralText(CarpetSettings.customMOTD)); + cir.cancel(); + } + } +} diff --git a/src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java b/src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java index 779e7619..ea11e749 100644 --- a/src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java @@ -1,6 +1,5 @@ package carpet.mixins; -import carpet.settings.CarpetSettings; import carpet.helpers.TickSpeed; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; @@ -10,7 +9,6 @@ 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ServerPlayNetworkHandler.class) @@ -43,13 +41,4 @@ public class ServerPlayNetworkHandlerMixin TickSpeed.reset_player_active_timeout(); } } - - @Redirect(method = "onPlayerMove", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/network/ServerPlayerEntity;isInTeleportationState()Z")) - private boolean relaxMoveRestrictions(ServerPlayerEntity serverPlayerEntity) - { - return serverPlayerEntity.isInTeleportationState() || CarpetSettings.antiCheatSpeed; - } - } diff --git a/src/main/java/carpet/mixins/ServerPlayNetworkHandler_antiCheatDisabledMixin.java b/src/main/java/carpet/mixins/ServerPlayNetworkHandler_antiCheatDisabledMixin.java new file mode 100644 index 00000000..f3650563 --- /dev/null +++ b/src/main/java/carpet/mixins/ServerPlayNetworkHandler_antiCheatDisabledMixin.java @@ -0,0 +1,52 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerPlayNetworkHandler.class) +public abstract class ServerPlayNetworkHandler_antiCheatDisabledMixin +{ + @Shadow private int floatingTicks; + + @Shadow private int vehicleFloatingTicks; + + @Shadow protected abstract boolean isServerOwner(); + + @Inject(method = "tick", at = @At("HEAD")) + private void restrictFloatingBits(CallbackInfo ci) + { + if (CarpetSettings.antiCheatDisabled) + { + if (floatingTicks > 70) floatingTicks--; + if (vehicleFloatingTicks > 70) vehicleFloatingTicks--; + } + + } + + @Redirect(method = "onVehicleMove", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;isServerOwner()Z" + )) + private boolean isServerTrusting(ServerPlayNetworkHandler serverPlayNetworkHandler) + { + return isServerOwner() || CarpetSettings.antiCheatDisabled; + } + + @Redirect(method = "onPlayerMove", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerEntity;isInTeleportationState()Z")) + private boolean relaxMoveRestrictions(ServerPlayerEntity serverPlayerEntity) + { + return CarpetSettings.antiCheatDisabled || serverPlayerEntity.isInTeleportationState(); + } + + + +} diff --git a/src/main/java/carpet/mixins/ServerWorld_fakePlayersMixin.java b/src/main/java/carpet/mixins/ServerWorld_fakePlayersMixin.java new file mode 100644 index 00000000..73b2bdab --- /dev/null +++ b/src/main/java/carpet/mixins/ServerWorld_fakePlayersMixin.java @@ -0,0 +1,37 @@ +package carpet.mixins; + +import carpet.patches.EntityPlayerMPFake; +import net.minecraft.entity.Entity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.ServerTask; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +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.Redirect; + +@Mixin(ServerWorld.class) +public abstract class ServerWorld_fakePlayersMixin +{ + @Shadow private boolean ticking; + + @Shadow /*@Nonnull*/ public abstract MinecraftServer getServer(); + + @Redirect( method = "removePlayer", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/world/ServerWorld;removeEntity(Lnet/minecraft/entity/Entity;)V" + )) + private void crashRemovePlayer(ServerWorld serverWorld, Entity entity_1, ServerPlayerEntity serverPlayerEntity_1) + { + if ( !(ticking && serverPlayerEntity_1 instanceof EntityPlayerMPFake) ) + serverWorld.removeEntity(entity_1); + else + getServer().method_18858(new ServerTask(getServer().getTicks(), () -> + { + serverWorld.removeEntity(serverPlayerEntity_1); + serverPlayerEntity_1.onTeleportationDone(); + })); + + } +} diff --git a/src/main/java/carpet/mixins/ServerWorld_unloadedEntityMixin.java b/src/main/java/carpet/mixins/ServerWorld_unloadedEntityMixin.java new file mode 100644 index 00000000..77f12cef --- /dev/null +++ b/src/main/java/carpet/mixins/ServerWorld_unloadedEntityMixin.java @@ -0,0 +1,21 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.entity.Entity; +import net.minecraft.server.world.ServerWorld; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ServerWorld.class) +public class ServerWorld_unloadedEntityMixin +{ + @Redirect(method = "checkChunk", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/Entity;teleportRequested()Z" + )) + private boolean addFastEntityCheck(Entity entity) + { + return CarpetSettings.unloadedEntityFix || entity.teleportRequested(); + } +} diff --git a/src/main/java/carpet/mixins/ShearsItem_missingToolsMixin.java b/src/main/java/carpet/mixins/ShearsItem_missingToolsMixin.java new file mode 100644 index 00000000..96f4b59f --- /dev/null +++ b/src/main/java/carpet/mixins/ShearsItem_missingToolsMixin.java @@ -0,0 +1,26 @@ +package carpet.mixins; + +import carpet.settings.CarpetSettings; +import net.minecraft.block.BlockState; +import net.minecraft.block.Material; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ShearsItem; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ShearsItem.class) +public class ShearsItem_missingToolsMixin +{ + @Inject(method = "getMiningSpeed", at = @At("HEAD"), cancellable = true) + private void getCustomMaterial(ItemStack itemStack_1, BlockState blockState_1, CallbackInfoReturnable cir) + { + if (CarpetSettings.missingTools && (blockState_1.getMaterial() == Material.SPONGE)) + { + cir.setReturnValue(15.0F); + cir.cancel(); + } + } +} diff --git a/src/main/java/carpet/mixins/SpawnHelperMixin.java b/src/main/java/carpet/mixins/SpawnHelperMixin.java index 7e8854e0..dba85845 100644 --- a/src/main/java/carpet/mixins/SpawnHelperMixin.java +++ b/src/main/java/carpet/mixins/SpawnHelperMixin.java @@ -5,17 +5,22 @@ import carpet.fakes.WorldInterface; import carpet.utils.SpawnReporter; import net.minecraft.block.Block; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCategory; import net.minecraft.entity.EntityType; 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.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.SpawnHelper; import net.minecraft.world.World; +import net.minecraft.world.chunk.WorldChunk; 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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Map; @@ -96,4 +101,17 @@ public class SpawnHelperMixin return world.spawnEntity(entity_1); return false; } + + @Redirect(method = "spawnEntitiesInChunk", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/player/PlayerEntity;squaredDistanceTo(DDD)D" + )) + private static double getSqDistanceTo(PlayerEntity playerEntity, double double_1, double double_2, double double_3, + EntityCategory entityCategory_1, World world_1, WorldChunk worldChunk_1, BlockPos blockPos_1) + { + double distanceTo = playerEntity.squaredDistanceTo(double_1, double_2, double_3); + if (CarpetSettings.lagFreeSpawning && distanceTo > 16384.0D && entityCategory_1 != EntityCategory.CREATURE) + return 0.0; + return distanceTo; + } } diff --git a/src/main/java/carpet/mixins/Structure_fillUpdatesMixin.java b/src/main/java/carpet/mixins/Structure_fillUpdatesMixin.java index 61e12b77..30e89b62 100644 --- a/src/main/java/carpet/mixins/Structure_fillUpdatesMixin.java +++ b/src/main/java/carpet/mixins/Structure_fillUpdatesMixin.java @@ -3,6 +3,7 @@ package carpet.mixins; import carpet.settings.CarpetSettings; import net.minecraft.block.Block; import net.minecraft.structure.Structure; +import net.minecraft.structure.StructurePlacementData; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; import org.spongepowered.asm.mixin.Mixin; @@ -21,4 +22,13 @@ public class Structure_fillUpdatesMixin if (!CarpetSettings.impendingFillSkipUpdates) iWorld.updateNeighbors(var1, var2); } + + @Redirect(method = "method_15172", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/structure/StructurePlacementData;method_16444()Z" + )) + private boolean skipPostprocess(StructurePlacementData structurePlacementData) + { + return structurePlacementData.method_16444() || CarpetSettings.impendingFillSkipUpdates; + } } diff --git a/src/main/java/carpet/patches/EntityPlayerMPFake.java b/src/main/java/carpet/patches/EntityPlayerMPFake.java index 464c0219..09419095 100644 --- a/src/main/java/carpet/patches/EntityPlayerMPFake.java +++ b/src/main/java/carpet/patches/EntityPlayerMPFake.java @@ -59,6 +59,7 @@ public class EntityPlayerMPFake extends ServerPlayerEntity server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(instance, (byte) (instance.headYaw * 256 / 360)), instance.dimension); server.getPlayerManager().sendToDimension(new EntityPositionS2CPacket(instance), instance.dimension); instance.getServerWorld().method_14178().updateCameraPosition(instance); + instance.dataTracker.set(PLAYER_MODEL_BIT_MASK, (byte) 0x7f); // show all model layers (incl. capes) return instance; } diff --git a/src/main/java/carpet/settings/CarpetSettings.java b/src/main/java/carpet/settings/CarpetSettings.java index 0fc5db9b..02942790 100644 --- a/src/main/java/carpet/settings/CarpetSettings.java +++ b/src/main/java/carpet/settings/CarpetSettings.java @@ -1,7 +1,6 @@ package carpet.settings; import carpet.CarpetServer; -import carpet.fakes.MinecraftServer_motdInterface; import carpet.utils.Messenger; import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ServerCommandSource; @@ -10,7 +9,9 @@ import net.minecraft.server.world.ChunkTicketType; import net.minecraft.server.world.ServerChunkManager; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Unit; +import net.minecraft.util.math.Box; import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.dimension.DimensionType; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -25,16 +26,17 @@ import static carpet.settings.RuleCategory.SURVIVAL; public class CarpetSettings { - public static final String carpetVersion = "v190704"; + public static final String carpetVersion = "v190707"; public static final Logger LOG = LogManager.getLogger(); public static boolean skipGenerationChecks = false; public static boolean impendingFillSkipUpdates = false; + public static Box currentTelepotingEntityBox = null; + public static Vec3d fixedPosition = null; @Rule( desc = "Nether portals correctly place entities going through", extra = "Entities shouldn't suffocate in obsidian", - category = BUGFIX, - validate = Validator.WIP.class + category = BUGFIX ) public static boolean portalSuffocationFix = false; @@ -102,7 +104,7 @@ public class CarpetSettings @Rule( desc = "Shulkers will respawn in end cities", category = FEATURE ) public static boolean shulkerSpawningInEndCities = false; - @Rule(desc = "Entities pushed or moved into unloaded chunks no longer disappear", category = {EXPERIMENTAL, BUGFIX}, validate = Validator.WIP.class) + @Rule(desc = "Entities pushed or moved into unloaded chunks no longer disappear", category = {EXPERIMENTAL, BUGFIX}) public static boolean unloadedEntityFix = false; @Rule( desc = "TNT doesn't update when placed against a power source", category = CREATIVE ) @@ -110,11 +112,10 @@ public class CarpetSettings @Rule( desc = "Prevents players from rubberbanding when moving too fast", - extra = "Puts more trust in clients positioning", - category = {CREATIVE, SURVIVAL}, - validate = Validator.WIP.class + extra = {"... or being kicked out for 'flying'","Puts more trust in clients positioning"}, + category = {CREATIVE, SURVIVAL} ) - public static boolean antiCheatSpeed = false; + public static boolean antiCheatDisabled = false; @Rule(desc = "Pistons, droppers and dispensers react if block above them is powered", category = CREATIVE) public static boolean quasiConnectivity = true; @@ -163,7 +164,11 @@ public class CarpetSettings @Rule(desc = "Enables /tick command to control game clocks", category = COMMAND) public static boolean commandTick = true; - @Rule(desc = "Enables /log command to monitor events in the game via chat and overlays", category = COMMAND) + @Rule( + desc = "Enables /log command to monitor events in the game via chat and overlays", + category = COMMAND, + validate = Validator.WIP.class + ) public static boolean commandLog = true; @Rule( @@ -209,11 +214,7 @@ public class CarpetSettings @Rule(desc = "Placing carpets may issue carpet commands for non-op players", category = SURVIVAL) public static boolean carpets = false; - @Rule( - desc = "Pistons, Glass and Sponge can be broken faster with their appropriate tools", - category = SURVIVAL, - validate = Validator.WIP.class - ) + @Rule(desc = "Pistons, Glass and Sponge can be broken faster with their appropriate tools", category = SURVIVAL) public static boolean missingTools = false; @Rule(desc = "Alternative, persistent caching strategy for nether portals", category = {SURVIVAL, CREATIVE}) @@ -287,19 +288,11 @@ public class CarpetSettings @Rule(desc = "One player is required on the server to cause night to pass", category = SURVIVAL) public static boolean onePlayerSleeping = false; - private static class SetMotd extends Validator { - @Override public String validate(ServerCommandSource source, ParsedRule currentRule, String newValue, String string) { - customMOTD = newValue; // accelerate a smidge - ((MinecraftServer_motdInterface) CarpetServer.minecraft_server).checkMOTD(); - return newValue; - } - } @Rule( desc = "Sets a different motd message on client trying to connect to the server", extra = "use '_' to use the startup setting from server.properties", options = "_", - category = CREATIVE, - validate = {SetMotd.class, Validator.WIP.class} // for some reason doesn't yet work + category = CREATIVE ) public static String customMOTD = "_"; @@ -399,8 +392,7 @@ public class CarpetSettings @Rule( desc = "Fixes leads breaking/becoming invisible in unloaded chunks", extra = "You may still get visibly broken leash links on the client side, but server side the link is still there.", - category = BUGFIX, - validate = Validator.WIP.class + category = BUGFIX ) public static boolean leadFix = false; diff --git a/src/main/java/carpet/settings/Validator.java b/src/main/java/carpet/settings/Validator.java index 66ca79cf..706147d7 100644 --- a/src/main/java/carpet/settings/Validator.java +++ b/src/main/java/carpet/settings/Validator.java @@ -47,13 +47,13 @@ public abstract class Validator if (source != null) try { - Messenger.m(source, "r "+currentRule.name+" is not yet fully implemented - we are still working on it."); + Messenger.m(source, "r "+currentRule.name+" is missing a few bits - we are still working on it."); } catch (NullPointerException ignored) { } return newValue; } @Override - public String description() { return "Its not yet fully implemented - we are working on it";} + public String description() { return "A few bits still needs implementing - we are working on it";} } public static class _STRICT extends Validator { diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 7c322d6c..a715a07c 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -13,6 +13,8 @@ "StructureBlockBlockEntity_fillUpdatesMixin", "Structure_fillUpdatesMixin", + "ServerMetadata_motdMixin", + "MinecraftServer_coreMixin", "MinecraftServer_tickspeedMixin", @@ -22,8 +24,11 @@ "ThreadedAnvilChunkStorage_tickMixin", "MobEntityMixin", + "ServerWorld_unloadedEntityMixin", + "MobEntity_leashMixin", + + "ServerWorld_fakePlayersMixin", - "MinecraftServer_motdMixin", "ServerPlayNetworkHandlerMixin", "MinecraftServer_scarpetMixin", "PlayerListHeaderS2CPacketMixin", @@ -68,9 +73,14 @@ "ItemUsageContext_cactusMixin", "DispenserBehaviour_cactusMixin", + "ServerPlayNetworkHandler_antiCheatDisabledMixin", + "PortalForcer_portalCachingMixin", "PortalBlock_portalCachingMixin", + "Entity_portalSuffocationMixin", + "PortalForcer_portalSuffocationMixin", + "HopperBlockEntityMixin", "ContainerMixin", "ClientConnectionMixin", @@ -93,6 +103,10 @@ "PistonBlock_qcMixin", "DispenserBlock_qcMixin", + "PickaxeItem_missingToolsMixin", + "ShearsItem_missingToolsMixin", + + "PistonBlock_movableTEMixin", "PistonBlockEntity_movableTEMixin", "World_movableTEMixin",