From 490db4f5d6480ace45d424b376c4248053475e91 Mon Sep 17 00:00:00 2001 From: G4me4u Date: Thu, 2 Jan 2020 21:47:28 +0100 Subject: [PATCH 1/4] Added a way to ensure tickrate compatibility with other mods --- src/main/java/carpet/helpers/TickSpeed.java | 85 +++++++++++++++---- .../MinecraftServer_tickspeedMixin.java | 29 +++++-- 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/src/main/java/carpet/helpers/TickSpeed.java b/src/main/java/carpet/helpers/TickSpeed.java index 8cf8982d..40b7c68c 100644 --- a/src/main/java/carpet/helpers/TickSpeed.java +++ b/src/main/java/carpet/helpers/TickSpeed.java @@ -1,18 +1,22 @@ package carpet.helpers; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + import carpet.CarpetServer; import carpet.utils.Messenger; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.server.command.CommandManager; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.BaseText; public class TickSpeed { public static final int PLAYER_GRACE = 2; public static float tickrate = 20.0f; - public static long mspt = 50l; + public static float mspt = 50.0f; public static long time_bias = 0; public static long time_warp_start_time = 0; public static long time_warp_scheduled_ticks = 0; @@ -24,6 +28,13 @@ public class TickSpeed public static boolean is_paused = false; public static boolean is_superHot = false; + /** + * Functional interface that listens for tickrate changes. This is + * implemented to allow tickrate compatibility with other mods etc. + */ + private static final Map> tickrateListeners = new HashMap<>(); + private static final float MIN_TICKRATE = 0.01f; + public static void reset_player_active_timeout() { if (player_active_timeout < PLAYER_GRACE) @@ -37,17 +48,6 @@ public class TickSpeed player_active_timeout = PLAYER_GRACE+ticks; } - public static void tickrate(float rate) - { - tickrate = rate; - mspt = (long)(1000.0/tickrate); - if (mspt <=0) - { - mspt = 1l; - tickrate = 1000.0f; - } - } - public static BaseText tickrate_advance(PlayerEntity player, int advance, String callback, ServerCommandSource source) { if (0 == advance) @@ -156,8 +156,61 @@ public class TickSpeed } } - - + } + + public static void tickrate(float rate) + { + tickrate = rate; + long mspt = (long)(1000.0 / tickrate); + if (mspt <= 0L) + { + mspt = 1L; + tickrate = 1000.0f; + } + + TickSpeed.mspt = (float)mspt; + + notifyTickrateListeners("carpet"); + } + + private static void tickrateChanged(String modId, float rate) + { + // Other mods might change the tickrate in a slightly + // different way. Also allow for tickrates that don't + // divide into 1000 here. + + if (rate < MIN_TICKRATE) + { + rate = MIN_TICKRATE; + } + + tickrate = rate; + mspt = 1000.0f / tickrate; + + notifyTickrateListeners(modId); + } + + private static void notifyTickrateListeners(String originModId) + { + synchronized (tickrateListeners) + { + for (Map.Entry> listenerEntry : tickrateListeners.entrySet()) + { + if (originModId == null || !originModId.equals(listenerEntry.getKey())) + { + listenerEntry.getValue().accept(originModId, Float.valueOf(tickrate)); + } + } + } + } + + public static BiConsumer establishTickrateLink(String modId, BiConsumer tickrateListener) + { + synchronized (tickrateListeners) + { + tickrateListeners.put(modId, tickrateListener); + } + return TickSpeed::tickrateChanged; } } diff --git a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java index a9d86dd0..8d120405 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java @@ -44,6 +44,12 @@ public abstract class MinecraftServer_tickspeedMixin @Shadow private volatile boolean loading; CarpetProfiler.ProfilerToken currentSection; + + private float carpetMsptAccum = 0.0f; + + /** + * To ensure compatibility with other mods we should allow milliseconds + */ // Cancel a while statement @Redirect(method = "run", at = @At(value = "FIELD", target = "Lnet/minecraft/server/MinecraftServer;running:Z")) @@ -67,29 +73,38 @@ public abstract class MinecraftServer_tickspeedMixin { CarpetProfiler.start_tick_profiling(); } - long mspt = 0L; + long msThisTick = 0L; long long_1 = 0L; if (TickSpeed.time_warp_start_time != 0 && TickSpeed.continueWarp()) { //making sure server won't flop after the warp or if the warp is interrupted this.timeReference = this.field_4557 = SystemUtil.getMeasuringTimeMs(); + carpetMsptAccum = TickSpeed.mspt; } else { - mspt = TickSpeed.mspt; // regular tick + if (Math.abs(carpetMsptAccum - TickSpeed.mspt) > 1.0f) + { + // Tickrate changed. Ensure that we use the correct value. + carpetMsptAccum = TickSpeed.mspt; + } + + msThisTick = (long)carpetMsptAccum; // regular tick + carpetMsptAccum += TickSpeed.mspt - msThisTick; + long_1 = SystemUtil.getMeasuringTimeMs() - this.timeReference; } //end tick deciding //smoothed out delay to include mcpt component. With 50L gives defaults. - if (long_1 > /*2000L*/1000L+20*mspt && this.timeReference - this.field_4557 >= /*15000L*/10000L+100*mspt) + if (long_1 > /*2000L*/1000L+20*TickSpeed.mspt && this.timeReference - this.field_4557 >= /*15000L*/10000L+100*TickSpeed.mspt) { - long long_2 = long_1 / mspt;//50L; + long long_2 = (long)(long_1 / TickSpeed.mspt);//50L; LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", long_1, long_2); - this.timeReference += long_2 * mspt;//50L; + this.timeReference += (long)(long_2 * TickSpeed.mspt);//50L; this.field_4557 = this.timeReference; } - this.timeReference += mspt;//50L; + this.timeReference += msThisTick;//50L; if (this.profilerStartQueued) { this.profilerStartQueued = false; @@ -101,7 +116,7 @@ public abstract class MinecraftServer_tickspeedMixin this.tick(TickSpeed.time_warp_start_time != 0 ? ()->true : this::shouldKeepTicking); this.profiler.swap("nextTickWait"); this.field_19249 = true; - this.field_19248 = Math.max(SystemUtil.getMeasuringTimeMs() + /*50L*/ mspt, this.timeReference); + this.field_19248 = Math.max(SystemUtil.getMeasuringTimeMs() + /*50L*/ msThisTick, this.timeReference); this.method_16208(); this.profiler.pop(); this.profiler.endTick(); From 08539da5cc70e2baa9e59ed2f84e56e7fe6fa60c Mon Sep 17 00:00:00 2001 From: G4me4u Date: Thu, 2 Jan 2020 22:23:54 +0100 Subject: [PATCH 2/4] Renamed establishTickrateLink to addTickrateListener --- src/main/java/carpet/helpers/TickSpeed.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/carpet/helpers/TickSpeed.java b/src/main/java/carpet/helpers/TickSpeed.java index 40b7c68c..79d05576 100644 --- a/src/main/java/carpet/helpers/TickSpeed.java +++ b/src/main/java/carpet/helpers/TickSpeed.java @@ -204,7 +204,7 @@ public class TickSpeed } } - public static BiConsumer establishTickrateLink(String modId, BiConsumer tickrateListener) + public static BiConsumer addTickrateListener(String modId, BiConsumer tickrateListener) { synchronized (tickrateListeners) { From f15ecd1dd2d1cc7e314217f98710e585bc7e0c2a Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 2 Jan 2020 17:30:19 -0400 Subject: [PATCH 3/4] better smooths WIP --- ...rkHandler_smoothClientAnimationsMixin.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java diff --git a/src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java b/src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java new file mode 100644 index 00000000..751fbbfa --- /dev/null +++ b/src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java @@ -0,0 +1,56 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.PistonBlockEntity; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.client.network.packet.ChunkDataS2CPacket; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.math.BlockPos; +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; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.spongepowered.asm.mixin.injection.struct.InjectionInfo; + +import java.util.Iterator; + +@Mixin(ClientPlayNetworkHandler.class) +public class ClientPlayNetworkHandler_smoothClientAnimationsMixin +{ + @Shadow private ClientWorld world; + + // as suggested by G4me4u + @Inject( method = "onChunkData", locals = LocalCapture.CAPTURE_FAILSOFT, require = 0, at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/world/ClientWorld;getBlockEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/entity/BlockEntity;", + shift = At.Shift.AFTER + )) + private void recreateMovingPistons(ChunkDataS2CPacket packet, CallbackInfo ci, + Iterator var5, CompoundTag tag, BlockPos blockPos) + { + if (CarpetSettings.smoothClientAnimations) //WIP + { + BlockEntity blockEntity = world.getBlockEntity(blockPos); + if (blockEntity == null && "minecraft:piston".equals(tag.getString("id"))) + { + BlockState blockState = world.getBlockState(blockPos); + if (blockState.getBlock() == Blocks.MOVING_PISTON) { + blockEntity = new PistonBlockEntity(); + blockEntity.fromTag(tag); + world.setBlockEntity(blockPos, blockEntity); + + // Probably not needed but it's done in + // other places so let's keep the standard. + blockEntity.resetBlock(); + } + } + } + } +} From 78ea9cd6e489b6887c3f2206b33b84295341749e Mon Sep 17 00:00:00 2001 From: gnembon Date: Fri, 3 Jan 2020 00:13:05 -0400 Subject: [PATCH 4/4] 1.3.3 --- gradle.properties | 2 +- src/main/java/carpet/CarpetSettings.java | 2 +- ...yNetworkHandler_smoothClientAnimationsMixin.java | 13 ++++--------- src/main/resources/carpet.mixins.json | 3 ++- src/main/resources/fabric.mod.json | 2 +- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/gradle.properties b/gradle.properties index cc323cd9..c5676343 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.7.2+build.174 # Mod Properties - mod_version = 1.3.2+v191230 + mod_version = 1.3.3+v200103 maven_group = carpet archives_base_name = fabric-carpet diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index 72ff6b53..87585be0 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -31,7 +31,7 @@ import static carpet.settings.RuleCategory.DISPENSER; public class CarpetSettings { - public static final String carpetVersion = "1.3.2+v191230"; + public static final String carpetVersion = "1.3.3+v200103"; public static final Logger LOG = LogManager.getLogger(); public static boolean skipGenerationChecks = false; public static boolean impendingFillSkipUpdates = false; diff --git a/src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java b/src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java index 751fbbfa..43b44256 100644 --- a/src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java +++ b/src/main/java/carpet/mixins/ClientPlayNetworkHandler_smoothClientAnimationsMixin.java @@ -14,10 +14,8 @@ 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; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import org.spongepowered.asm.mixin.injection.struct.InjectionInfo; import java.util.Iterator; @@ -25,9 +23,8 @@ import java.util.Iterator; public class ClientPlayNetworkHandler_smoothClientAnimationsMixin { @Shadow private ClientWorld world; - - // as suggested by G4me4u - @Inject( method = "onChunkData", locals = LocalCapture.CAPTURE_FAILSOFT, require = 0, at = @At( + // fix as suggested by G4me4u + @Inject( method = "onChunkData", locals = LocalCapture.CAPTURE_FAILHARD, require = 0, at = @At( value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;getBlockEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/entity/BlockEntity;", shift = At.Shift.AFTER @@ -35,19 +32,17 @@ public class ClientPlayNetworkHandler_smoothClientAnimationsMixin private void recreateMovingPistons(ChunkDataS2CPacket packet, CallbackInfo ci, Iterator var5, CompoundTag tag, BlockPos blockPos) { - if (CarpetSettings.smoothClientAnimations) //WIP + if (CarpetSettings.smoothClientAnimations) { BlockEntity blockEntity = world.getBlockEntity(blockPos); if (blockEntity == null && "minecraft:piston".equals(tag.getString("id"))) { BlockState blockState = world.getBlockState(blockPos); if (blockState.getBlock() == Blocks.MOVING_PISTON) { + tag.putFloat("progress", Math.min(tag.getFloat("progress") + 0.5F, 1.0F)); blockEntity = new PistonBlockEntity(); blockEntity.fromTag(tag); world.setBlockEntity(blockPos, blockEntity); - - // Probably not needed but it's done in - // other places so let's keep the standard. blockEntity.resetBlock(); } } diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 226622f8..53dbbe21 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -170,7 +170,8 @@ "ClientPlayerInteractionManager_ghostBlocksMixin", "BlockEntityRenderDispatcher_movableTEMixin", - "PistonBlockEntityRenderer_movableTEMixin" + "PistonBlockEntityRenderer_movableTEMixin", + "ClientPlayNetworkHandler_smoothClientAnimationsMixin" ], "server": [ "MinecraftDedicatedServerMixin" diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 8c6c93a3..efd9d097 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.3.2", + "version": "1.3.3", "name": "Carpet Mod in Fabric", "description": "Carpet made out of fabric",