From 60844cea9f3f86818d080676f29cec4451d3a6e2 Mon Sep 17 00:00:00 2001 From: gnembon Date: Fri, 17 May 2019 12:16:16 -0300 Subject: [PATCH 1/6] ctrlQCraftingFix --- .../java/carpet/helpers/CtrlQCrafting.javax | 48 ---------- .../java/carpet/mixins/ContainerMixin.java | 90 +++++++++++++++++++ src/main/resources/carpet.mixins.json | 1 + 3 files changed, 91 insertions(+), 48 deletions(-) delete mode 100644 src/main/java/carpet/helpers/CtrlQCrafting.javax create mode 100644 src/main/java/carpet/mixins/ContainerMixin.java diff --git a/src/main/java/carpet/helpers/CtrlQCrafting.javax b/src/main/java/carpet/helpers/CtrlQCrafting.javax deleted file mode 100644 index 6b5d06bc..00000000 --- a/src/main/java/carpet/helpers/CtrlQCrafting.javax +++ /dev/null @@ -1,48 +0,0 @@ -package carpet.helpers; - -import net.minecraft.entity.LivingEntity LivingEntity; -import net.minecraft.entity.player.PlayerEntity PlayerEntity; -import net.minecraft.inventory. EntityEquipmentSlot; -import net.minecraft.inventory.Slot; -import net.minecraft.item.ItemStack; - -import java.util.List; - -public class CtrlQCrafting { - - public static ItemStack dropAllCrafting(PlayerEntity playerIn, int index, List invSlotParam) - { - ItemStack itemstack = ItemStack.EMPTY; - Slot slot = invSlotParam.get(index); - - if (slot != null && slot.getHasStack()) - { - ItemStack itemstack1 = slot.getStack(); - itemstack = itemstack1.copy(); - EntityEquipmentSlot entityequipmentslot = LivingEntity.getSlotForItemStack(itemstack); - - if (index == 0) - { - playerIn.dropItem(itemstack, true); - - itemstack1.setCount(0); - - slot.onSlotChange(itemstack1, itemstack); - } - - if (itemstack.getCount() == itemstack1.getCount()) - { - return ItemStack.EMPTY; - } - - ItemStack itemstack2 = slot.onTake(playerIn, itemstack1); - - if (index == 0) - { - playerIn.dropItem(itemstack2, false); - } - } - - return itemstack; - } -} diff --git a/src/main/java/carpet/mixins/ContainerMixin.java b/src/main/java/carpet/mixins/ContainerMixin.java new file mode 100644 index 00000000..5f8d5f61 --- /dev/null +++ b/src/main/java/carpet/mixins/ContainerMixin.java @@ -0,0 +1,90 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.container.Container; +import net.minecraft.container.Slot; +import net.minecraft.container.SlotActionType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Final; +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.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(Container.class) +public class ContainerMixin +{ + @Shadow @Final public List slotList; + + @Inject( method = "onSlotClick", at = @At(value = "HEAD"), cancellable = true) + private void onThrowClick( + int int_1, + int int_2, + SlotActionType slotActionType_1, + PlayerEntity playerEntity_1, + CallbackInfoReturnable cir + ) + { + if (slotActionType_1 == SlotActionType.THROW && CarpetSettings.getBool("ctrlQCraftingFix") && playerEntity_1.inventory.getCursorStack().isEmpty() && int_1 >= 0) + { + ItemStack itemStack_1 = ItemStack.EMPTY; + Slot slot_4 = slotList.get(int_1); + if (slot_4 != null && slot_4.canTakeItems(playerEntity_1)) + { + if(int_1 == 0 && int_2 == 1) + { + ItemStack itemStackDropAll = dropAllCrafting(playerEntity_1, int_1, slotList); + while (!itemStackDropAll.isEmpty() && ItemStack.areEqual(slot_4.getStack(), itemStackDropAll)) + { + itemStack_1 = itemStackDropAll.copy(); + itemStackDropAll = dropAllCrafting(playerEntity_1, int_1, slotList); + } + cir.setReturnValue(itemStack_1); + cir.cancel(); + } + } + } + } + + private ItemStack dropAllCrafting(PlayerEntity playerIn, int index, List invSlotParam) + { + + ItemStack itemstack = ItemStack.EMPTY; + Slot slot = invSlotParam.get(index); + + if (slot != null && slot.hasStack()) + { + ItemStack itemstack1 = slot.getStack(); + itemstack = itemstack1.copy(); + + if (index == 0) + { + playerIn.dropItem(itemstack, true); + + itemstack1.setAmount(0); + + slot.onStackChanged(itemstack1, itemstack); + } + + if (itemstack.getAmount() == itemstack1.getAmount()) + { + return ItemStack.EMPTY; + } + + ItemStack itemstack2 = slot.onTakeItem(playerIn, itemstack1); + + if (index == 0) + { + playerIn.dropItem(itemstack2, false); + } + } + + return itemstack; + } + + +} diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index d4e29dd4..3d3d8f20 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -14,6 +14,7 @@ "ServerPlayerEntityMixin", "ServerChunkManagerMixin", "HopperBlockEntityMixin", + "ContainerMixin", "ClientConnectionMixin", "ItemEntityMixin" ], From 514317326b2b40d8e92dfc0f2050ab828bfd5323 Mon Sep 17 00:00:00 2001 From: gnembon Date: Fri, 17 May 2019 12:27:40 -0300 Subject: [PATCH 2/6] ctrlQCraftingFix --- src/main/java/carpet/mixins/ContainerMixin.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/carpet/mixins/ContainerMixin.java b/src/main/java/carpet/mixins/ContainerMixin.java index 5f8d5f61..bda4c3cf 100644 --- a/src/main/java/carpet/mixins/ContainerMixin.java +++ b/src/main/java/carpet/mixins/ContainerMixin.java @@ -52,39 +52,28 @@ public class ContainerMixin private ItemStack dropAllCrafting(PlayerEntity playerIn, int index, List invSlotParam) { - ItemStack itemstack = ItemStack.EMPTY; Slot slot = invSlotParam.get(index); - if (slot != null && slot.hasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); - if (index == 0) { playerIn.dropItem(itemstack, true); - itemstack1.setAmount(0); - slot.onStackChanged(itemstack1, itemstack); } - if (itemstack.getAmount() == itemstack1.getAmount()) { return ItemStack.EMPTY; } - ItemStack itemstack2 = slot.onTakeItem(playerIn, itemstack1); - if (index == 0) { playerIn.dropItem(itemstack2, false); } } - return itemstack; } - - } From 59914856fba5d1ac9966c2296da6195f5f6054f1 Mon Sep 17 00:00:00 2001 From: gnembon Date: Fri, 17 May 2019 17:27:30 -0300 Subject: [PATCH 3/6] ctrlQCraftingFix --- .../mixins/MinecraftServer_motdMixin.java | 29 ++++++++ .../MinecraftServer_tickspeedMixin.java | 67 +++++++++++++++++++ .../mixins/ServerPlayNetworkHandlerMixin.java | 57 ++++++++++++++++ .../carpet/mixins/ServerWorld_tickMixin.java | 32 +++++++++ .../java/carpet/mixins/World_tickMixin.java | 54 +++++++++++++++ .../java/carpet/utils/CarpetProfiler.java | 21 +++--- src/main/resources/carpet.mixins.json | 3 + 7 files changed, 253 insertions(+), 10 deletions(-) create mode 100644 src/main/java/carpet/mixins/MinecraftServer_motdMixin.java create mode 100644 src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java create mode 100644 src/main/java/carpet/mixins/ServerWorld_tickMixin.java create mode 100644 src/main/java/carpet/mixins/World_tickMixin.java diff --git a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java new file mode 100644 index 00000000..c65e2dc7 --- /dev/null +++ b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java @@ -0,0 +1,29 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +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; + +import javax.annotation.Nullable; + +@Mixin(MinecraftServer.class) +public class MinecraftServer_motdMixin +{ + @Shadow @Nullable private String motd; + + @Redirect(method = "run", at = @At( + value = "FIELD", + target = "Lnet/minecraft/server/MinecraftServer;motd:Ljava/lang/String;") + ) + private String setMotd(MinecraftServer server) + { + if ("_".equals(CarpetSettings.getString("customMOTD"))) + return motd; + else + return CarpetSettings.getString("customMOTD"); + } + +} diff --git a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java index 77b0fdb2..11ee4a39 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java @@ -1,6 +1,7 @@ package carpet.mixins; import carpet.helpers.TickSpeed; +import carpet.utils.CarpetProfiler; import net.minecraft.server.MinecraftServer; import net.minecraft.util.SystemUtil; import net.minecraft.util.profiler.DisableableProfiler; @@ -102,4 +103,70 @@ public abstract class MinecraftServer_tickspeedMixin } } + + @Inject(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/MinecraftServer;tickWorlds(Ljava/util/function/BooleanSupplier;)V", + shift = At.Shift.BEFORE + )) + private void startProfilerTick(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (CarpetProfiler.tick_health_requested != 0L) + { + CarpetProfiler.start_tick_profiling(); + } + } + + @Inject( + method = "tick", + at = @At("TAIL") + ) + private void endTick(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { + if (CarpetProfiler.tick_health_requested != 0L) + { + CarpetProfiler.end_tick_profiling((MinecraftServer) (Object)this); + } + } + + @Inject(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/PlayerManager;saveAllPlayerData()V", + shift = At.Shift.BEFORE + )) + private void startAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + CarpetProfiler.start_section(null, "Autosave"); + } + + @Inject(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/MinecraftServer;save(ZZZ)Z", + shift = At.Shift.AFTER + )) + private void finishAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + CarpetProfiler.end_current_section(); + } + + @Inject(method = "tickWorlds", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/MinecraftServer;getNetworkIo()Lnet/minecraft/server/ServerNetworkIo;", + shift = At.Shift.BEFORE + )) + private void startNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + CarpetProfiler.start_section(null, "Network"); + } + + @Inject(method = "tickWorlds", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/PlayerManager;updatePlayerLatency()V", + shift = At.Shift.AFTER + )) + private void finishNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + CarpetProfiler.end_current_section(); + } + + } diff --git a/src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java b/src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java new file mode 100644 index 00000000..cb07ae50 --- /dev/null +++ b/src/main/java/carpet/mixins/ServerPlayNetworkHandlerMixin.java @@ -0,0 +1,57 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import carpet.helpers.TickSpeed; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.network.packet.PlayerInputC2SPacket; +import net.minecraft.server.network.packet.PlayerMoveC2SPacket; +import net.minecraft.server.network.packet.VehicleMoveC2SPacket; +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; + +@Mixin(ServerPlayNetworkHandler.class) +public class ServerPlayNetworkHandlerMixin +{ + @Shadow public ServerPlayerEntity player; + + @Shadow private double lastTickX; + + @Shadow private double lastTickY; + + @Inject(method = "onPlayerInput", at = @At(value = "RETURN")) + private void checkMoves(PlayerInputC2SPacket p, CallbackInfo ci) + { + if (p.getSideways() != 0.0F || p.getForward() != 0.0F || p.isJumping() || p.isSneaking()) + { + TickSpeed.reset_player_active_timeout(); + } + } + + @Inject(method = "onPlayerMove", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerEntity;isSleeping()Z", + shift = At.Shift.BEFORE + )) + private void checkMove(PlayerMoveC2SPacket p, CallbackInfo ci) + { + if (p.getX(player.x) - lastTickX > 0.0001D || p.getY(player.y) - lastTickY > 0.0001D || p.getY(player.y) - lastTickY > 0.0001D) + { + 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.getBool("antiCheatSpeed"); + } + +} diff --git a/src/main/java/carpet/mixins/ServerWorld_tickMixin.java b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java new file mode 100644 index 00000000..ab3ec193 --- /dev/null +++ b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java @@ -0,0 +1,32 @@ +package carpet.mixins; + +import carpet.utils.CarpetProfiler; +import net.minecraft.server.world.ServerWorld; +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; + +import java.util.function.BooleanSupplier; + +@Mixin(ServerWorld.class) +public class ServerWorld_tickMixin +{ + CarpetProfiler.ProfilerToken entityToken; + + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=entities" + )) + private void startEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + CarpetProfiler.start_section((World)(Object)this, "Entities"); + } + + @Inject(method = "tick", at = @At("TAIL")) + private void endEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + CarpetProfiler.end_current_section(); + } +} diff --git a/src/main/java/carpet/mixins/World_tickMixin.java b/src/main/java/carpet/mixins/World_tickMixin.java new file mode 100644 index 00000000..3285f7cf --- /dev/null +++ b/src/main/java/carpet/mixins/World_tickMixin.java @@ -0,0 +1,54 @@ +package carpet.mixins; + +import carpet.utils.CarpetProfiler; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.util.profiler.Profiler; +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; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.Iterator; + +@Mixin(World.class) +public abstract class World_tickMixin +{ + CarpetProfiler.ProfilerToken beToken; + + @Inject(method = "tickBlockEntities", at = @At("HEAD")) + private void startBlockEntities(CallbackInfo ci) { + CarpetProfiler.start_section((World) (Object) this, "Tile Entities"); + } + + @Inject(method = "tickBlockEntities", at = @At("TAIL")) + private void endBlockEntities(CallbackInfo ci) { + CarpetProfiler.end_current_section(); + } + + @Inject(method = "tickBlockEntities", locals = LocalCapture.CAPTURE_FAILHARD, at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/entity/BlockEntity;isInvalid()Z", + shift = At.Shift.BEFORE, + ordinal = 0 + )) + private void startTileEntitySection(CallbackInfo ci, Profiler profiler_1, int int_1, BlockEntity blockEntity_2) + { + beToken = CarpetProfiler.start_tileentity_section((World)(Object)this, blockEntity_2); + } + + @Inject(method = "tickBlockEntities", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/entity/BlockEntity;isInvalid()Z", + shift = At.Shift.BEFORE, + ordinal = 1 + )) + private void endTileEntitySection(CallbackInfo ci) + { + CarpetProfiler.end_current_entity_section(beToken); + beToken = null; + } + + +} diff --git a/src/main/java/carpet/utils/CarpetProfiler.java b/src/main/java/carpet/utils/CarpetProfiler.java index 59f4aa18..97c14584 100644 --- a/src/main/java/carpet/utils/CarpetProfiler.java +++ b/src/main/java/carpet/utils/CarpetProfiler.java @@ -6,6 +6,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.registry.Registry; +import net.minecraft.world.World; import java.util.Comparator; import java.util.HashMap; @@ -53,7 +54,7 @@ public class CarpetProfiler } - public static void start_section(String dimension, String name) + public static void start_section(World world, String name) { if (tick_health_requested == 0L || test_type != 1) { @@ -68,9 +69,9 @@ public class CarpetProfiler end_current_section(); } String key = name; - if (dimension != null) + if (world != null) { - key = dimension+"."+name; + key = world.getDimension().getType().getSuffix()+"."+name; } current_section = key; current_section_start = System.nanoTime(); @@ -88,7 +89,7 @@ public class CarpetProfiler } } - public static ProfilerToken start_section_concurrent(String dimension, String name, boolean isRemote) + public static ProfilerToken start_section_concurrent(World world, String name, boolean isRemote) { if (tick_health_requested == 0L || test_type != 1) { @@ -100,16 +101,16 @@ public class CarpetProfiler } String key = name; - if (dimension != null) + if (world != null) { - key = dimension+"."+name; + key = world.getDimension().getType().getSuffix()+"."+name; } if (isRemote) key += "(client)"; long time = System.nanoTime(); return new ProfilerToken(key, time); } - public static ProfilerToken start_entity_section(String dimension, Entity e) + public static ProfilerToken start_entity_section(World world, Entity e) { if (tick_health_requested == 0L || test_type != 2) { @@ -119,14 +120,14 @@ public class CarpetProfiler { return null; } - String section = dimension+"."+ Registry.ENTITY_TYPE.getId(e.getType()).toString().replaceFirst("minecraft:",""); + String section = world.getDimension().getType().getSuffix()+"."+ Registry.ENTITY_TYPE.getId(e.getType()).toString().replaceFirst("minecraft:",""); if (e.getEntityWorld().isClient) section += "(client)"; long section_start = System.nanoTime(); return new ProfilerToken(section, section_start); } - public static ProfilerToken start_tileentity_section(String dimension, BlockEntity e) + public static ProfilerToken start_tileentity_section(World world, BlockEntity e) { if (tick_health_requested == 0L || test_type != 2) { @@ -136,7 +137,7 @@ public class CarpetProfiler { return null; } - String section = dimension+"."+ BlockEntityType.getId(e.getType()).toString().replaceFirst("minecraft:",""); + String section = world.getDimension().getType().getSuffix()+"."+ BlockEntityType.getId(e.getType()).toString().replaceFirst("minecraft:",""); if (e.getWorld() == null) section += "??"; else if (e.getWorld().isClient) diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 3d3d8f20..e1dc2d76 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -6,6 +6,9 @@ "CommandManagerMixin", "MinecraftServer_coreMixin", "MinecraftServer_tickspeedMixin", + "World_tickMixin", + "MinecraftServer_motdMixin", + "ServerPlayNetworkHandlerMixin", "MinecraftServer_scarpetMixin", "PlayerListHeaderS2CPacketMixin", "WeightedPickerEntryMixin", From 03b78b52c12f9a31029d38fb63b4f1db01e6a2c7 Mon Sep 17 00:00:00 2001 From: gnembon Date: Fri, 17 May 2019 23:58:33 -0300 Subject: [PATCH 4/6] tick complete --- .../java/carpet/commands/TickCommand.java | 4 +- .../mixins/MinecraftServer_motdMixin.java | 4 +- .../MinecraftServer_tickspeedMixin.java | 56 +-- .../mixins/ServerChunkManager_tickMixin.java | 64 +++ .../carpet/mixins/ServerWorld_tickMixin.java | 71 +++- .../java/carpet/mixins/World_tickMixin.java | 27 +- .../java/carpet/utils/CarpetProfiler.java | 369 ++++++++---------- src/main/resources/carpet.mixins.json | 4 + 8 files changed, 338 insertions(+), 261 deletions(-) create mode 100644 src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java diff --git a/src/main/java/carpet/commands/TickCommand.java b/src/main/java/carpet/commands/TickCommand.java index dbe9759d..5f2dcf8d 100644 --- a/src/main/java/carpet/commands/TickCommand.java +++ b/src/main/java/carpet/commands/TickCommand.java @@ -130,13 +130,13 @@ public class TickCommand private static int healthReport(ServerCommandSource source, int ticks) { - CarpetProfiler.prepare_tick_report(ticks); + CarpetProfiler.prepare_tick_report(source.getMinecraftServer(), ticks); return 1; } private static int healthEntities(ServerCommandSource source, int ticks) { - CarpetProfiler.prepare_entity_report(ticks); + CarpetProfiler.prepare_entity_report(source.getMinecraftServer(), ticks); return 1; } diff --git a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java index c65e2dc7..35fd5fe5 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java @@ -7,12 +7,10 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import javax.annotation.Nullable; - @Mixin(MinecraftServer.class) public class MinecraftServer_motdMixin { - @Shadow @Nullable private String motd; + @Shadow private String motd; @Redirect(method = "run", at = @At( value = "FIELD", diff --git a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java index 11ee4a39..ab54cb4c 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java @@ -43,6 +43,8 @@ public abstract class MinecraftServer_tickspeedMixin @Shadow private volatile boolean loading; + CarpetProfiler.ProfilerToken currentSection; + // Cancel a while statement @Redirect(method = "run", at = @At(value = "FIELD", target = "Lnet/minecraft/server/MinecraftServer;running:Z")) private boolean cancelRunLoop(MinecraftServer server) @@ -61,6 +63,10 @@ public abstract class MinecraftServer_tickspeedMixin { //long long_1 = SystemUtil.getMeasuringTimeMs() - this.timeReference; //CM deciding on tick speed + if (CarpetProfiler.tick_health_requested != 0L) + { + CarpetProfiler.start_tick_profiling(); + } long mspt = 0L; long long_1 = 0L; if (TickSpeed.time_warp_start_time != 0 && TickSpeed.continueWarp()) @@ -104,30 +110,6 @@ public abstract class MinecraftServer_tickspeedMixin } - @Inject(method = "tick", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/MinecraftServer;tickWorlds(Ljava/util/function/BooleanSupplier;)V", - shift = At.Shift.BEFORE - )) - private void startProfilerTick(BooleanSupplier booleanSupplier_1, CallbackInfo ci) - { - if (CarpetProfiler.tick_health_requested != 0L) - { - CarpetProfiler.start_tick_profiling(); - } - } - - @Inject( - method = "tick", - at = @At("TAIL") - ) - private void endTick(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - if (CarpetProfiler.tick_health_requested != 0L) - { - CarpetProfiler.end_tick_profiling((MinecraftServer) (Object)this); - } - } - @Inject(method = "tick", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;saveAllPlayerData()V", @@ -135,7 +117,7 @@ public abstract class MinecraftServer_tickspeedMixin )) private void startAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.start_section(null, "Autosave"); + currentSection = CarpetProfiler.start_section(null, "Autosave", CarpetProfiler.TYPE.GENERAL); } @Inject(method = "tick", at = @At( @@ -145,7 +127,7 @@ public abstract class MinecraftServer_tickspeedMixin )) private void finishAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); } @Inject(method = "tickWorlds", at = @At( @@ -155,7 +137,7 @@ public abstract class MinecraftServer_tickspeedMixin )) private void startNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.start_section(null, "Network"); + currentSection = CarpetProfiler.start_section(null, "Network", CarpetProfiler.TYPE.GENERAL); } @Inject(method = "tickWorlds", at = @At( @@ -165,7 +147,25 @@ public abstract class MinecraftServer_tickspeedMixin )) private void finishNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); + } + + @Inject(method = "method_16208", at = @At("HEAD")) + private void startAsync(CallbackInfo ci) + { + currentSection = CarpetProfiler.start_section(null, "Async Tasks", CarpetProfiler.TYPE.GENERAL); + } + @Inject(method = "method_16208", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/MinecraftServer;waitFor(Ljava/util/function/BooleanSupplier;)V", + shift = At.Shift.BEFORE + )) + private void stopAsync(CallbackInfo ci) + { + if (CarpetProfiler.tick_health_requested != 0L) + { + CarpetProfiler.end_tick_profiling((MinecraftServer) (Object)this, currentSection); + } } diff --git a/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java b/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java new file mode 100644 index 00000000..e8987d3e --- /dev/null +++ b/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java @@ -0,0 +1,64 @@ +package carpet.mixins; + +import carpet.utils.CarpetProfiler; +import net.minecraft.server.world.ServerChunkManager; +import net.minecraft.server.world.ServerWorld; +import org.spongepowered.asm.mixin.Final; +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.function.BooleanSupplier; + +@Mixin(ServerChunkManager.class) +public abstract class ServerChunkManager_tickMixin +{ + @Shadow @Final private ServerWorld world; + CarpetProfiler.ProfilerToken currentSection; + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At( + value = "CONSTANT", + args = "stringValue=purge" + )) + private void startTicketSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + currentSection = CarpetProfiler.start_section(world, "Ticket Manager", CarpetProfiler.TYPE.GENERAL); + } + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At( + value = "CONSTANT", + args = "stringValue=chunks" + )) + private void stopTicketStartSpawningSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section(world, "Spawning and Random Ticks", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At( + value = "CONSTANT", + args = "stringValue=unload" + )) + private void stopSpawningStartUnloadSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section(world, "Unloading", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At("TAIL")) + private void stopUnloadSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + } + } +} diff --git a/src/main/java/carpet/mixins/ServerWorld_tickMixin.java b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java index ab3ec193..8aadaacf 100644 --- a/src/main/java/carpet/mixins/ServerWorld_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java @@ -13,20 +13,83 @@ import java.util.function.BooleanSupplier; @Mixin(ServerWorld.class) public class ServerWorld_tickMixin { - CarpetProfiler.ProfilerToken entityToken; + CarpetProfiler.ProfilerToken currentSection; + + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=world border" + )) + private void startWeatherSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + currentSection = CarpetProfiler.start_section((World)(Object)this, "Environment", CarpetProfiler.TYPE.GENERAL); + } + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=world border" + )) + private void stopWeatherStartChunkSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + // we go deeper here + } + } + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=tickPending" + )) + private void stopChunkStartBlockSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + // out of chunk + currentSection = CarpetProfiler.start_section((World) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=village" + )) + private void stopBlockStartVillageSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Village", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=tickPending" + )) + private void stopVillageStartBlockAgainSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL); + } + } @Inject(method = "tick", at = @At( value = "CONSTANT", args = "stringValue=entities" )) - private void startEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + private void stopBlockAgainStartEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.start_section((World)(Object)this, "Entities"); + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Entities", CarpetProfiler.TYPE.GENERAL); + } } @Inject(method = "tick", at = @At("TAIL")) private void endEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); } } diff --git a/src/main/java/carpet/mixins/World_tickMixin.java b/src/main/java/carpet/mixins/World_tickMixin.java index 3285f7cf..ea22dfce 100644 --- a/src/main/java/carpet/mixins/World_tickMixin.java +++ b/src/main/java/carpet/mixins/World_tickMixin.java @@ -2,6 +2,7 @@ package carpet.mixins; import carpet.utils.CarpetProfiler; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.Entity; import net.minecraft.util.profiler.Profiler; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; @@ -11,20 +12,22 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.Iterator; +import java.util.function.Consumer; @Mixin(World.class) public abstract class World_tickMixin { - CarpetProfiler.ProfilerToken beToken; + CarpetProfiler.ProfilerToken currentSection; + CarpetProfiler.ProfilerToken entitySection; @Inject(method = "tickBlockEntities", at = @At("HEAD")) private void startBlockEntities(CallbackInfo ci) { - CarpetProfiler.start_section((World) (Object) this, "Tile Entities"); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Tile Entities", CarpetProfiler.TYPE.GENERAL); } @Inject(method = "tickBlockEntities", at = @At("TAIL")) private void endBlockEntities(CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); } @Inject(method = "tickBlockEntities", locals = LocalCapture.CAPTURE_FAILHARD, at = @At( @@ -33,9 +36,9 @@ public abstract class World_tickMixin shift = At.Shift.BEFORE, ordinal = 0 )) - private void startTileEntitySection(CallbackInfo ci, Profiler profiler_1, int int_1, BlockEntity blockEntity_2) + private void startTileEntitySection(CallbackInfo ci, Profiler profiler_1, Iterator i, BlockEntity blockEntity_2) { - beToken = CarpetProfiler.start_tileentity_section((World)(Object)this, blockEntity_2); + entitySection = CarpetProfiler.start_entity_section((World)(Object)this, blockEntity_2, CarpetProfiler.TYPE.TILEENTITY); } @Inject(method = "tickBlockEntities", at = @At( @@ -46,8 +49,18 @@ public abstract class World_tickMixin )) private void endTileEntitySection(CallbackInfo ci) { - CarpetProfiler.end_current_entity_section(beToken); - beToken = null; + CarpetProfiler.end_current_entity_section(entitySection); + } + + @Inject(method = "tickEntity", at = @At("HEAD")) + private void startEntity(Consumer call, Entity e, CallbackInfo ci) + { + entitySection = CarpetProfiler.start_entity_section((World) (Object) this, e, CarpetProfiler.TYPE.ENTITY); + } + + @Inject(method = "tickEntity", at = @At("TAIL")) + private void endEntity(Consumer call, Entity e, CallbackInfo ci) { + CarpetProfiler.end_current_entity_section(entitySection); } diff --git a/src/main/java/carpet/utils/CarpetProfiler.java b/src/main/java/carpet/utils/CarpetProfiler.java index 97c14584..fd1e3ac9 100644 --- a/src/main/java/carpet/utils/CarpetProfiler.java +++ b/src/main/java/carpet/utils/CarpetProfiler.java @@ -4,7 +4,6 @@ import carpet.CarpetSettings; import net.minecraft.entity.Entity; import net.minecraft.server.MinecraftServer; import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; @@ -18,196 +17,153 @@ public class CarpetProfiler private static final HashMap time_repo = new HashMap<>(); public static int tick_health_requested = 0; private static int tick_health_elapsed = 0; - private static int test_type = 0; //1 for ticks, 2 for entities; - private static String current_section = null; - private static long current_section_start = 0; + private static TYPE test_type = TYPE.NONE; //1 for ticks, 2 for entities; private static long current_tick_start = 0; - private static String [] GENERAL_SECTIONS = {"Network", "Autosave"}; - private static String [] DIMENSIONS = {"Overworld","The End","The Nether"}; - private static String [] SECTIONS = {"Spawning","Blocks","Entities","Tile Entities","Entities(client)","Tile Entities(client)","Villages"}; + private static String[] GENERAL_SECTIONS = {"Network", "Autosave", "Async Tasks"}; + private static String[] DIMENSIONS = {"overworld", "the_end", "the_nether"}; + private static String[] SECTIONS = { + "Spawning and Random Ticks", "Ticket Manager","Unloading", + "Blocks", "Entities", "Tile Entities", + "Entities (Client)", "Tile Entities (Client)", + "Village", "Environment"}; - public static void prepare_tick_report(int ticks) + public enum TYPE + { + NONE, + GENERAL, + ENTITY, + TILEENTITY + } + + public static class ProfilerToken + { + public TYPE type; + public Object section; + public long start; + public World world; + + public ProfilerToken(TYPE type, Object section, World world, long start) + { + this.type = type; + this.section = section; + this.start = start; + this.world = world; + } + } + + private static String getWorldString(World world) + { + return world.getDimension().getType().toString().replaceFirst("minecraft:", "") + (world.isClient ? "(Client)" : ""); + } + + private static String getSectionString(World world, String section) + { + return String.format("%s.%s%s", + world.getDimension().getType().toString().replaceFirst("minecraft:", ""), + section, + world.isClient ? " (Client)" : ""); + } + + private static String getEntityString(World world, Entity e) + { + return String.format("%s.%s%s", + world.getDimension().getType().toString().replaceFirst("minecraft:", ""), + Registry.ENTITY_TYPE.getId(e.getType()).toString().replaceFirst("minecraft:", ""), + world.isClient ? " (Client)" : ""); + } + + private static String getTEntityString(World world, BlockEntity be) + { + return String.format("%s.%s%s", + world.getDimension().getType().toString().replaceFirst("minecraft:", ""), + Registry.BLOCK_ENTITY.getId(be.getType()).toString().replaceFirst("minecraft:", ""), + world.isClient ? " (Client)" : ""); + } + + public static void prepare_tick_report(MinecraftServer server, int ticks) { //maybe add so it only spams the sending player, but honestly - all may want to see it time_repo.clear(); - test_type = 1; - time_repo.put("tick",0L); - time_repo.put("Network",0L); - time_repo.put("Autosave",0L); - for (String section: GENERAL_SECTIONS) + test_type = TYPE.GENERAL; + time_repo.put("tick", 0L); + time_repo.put("Network", 0L); + time_repo.put("Autosave", 0L); + for (String section : GENERAL_SECTIONS) { - time_repo.put(section,0L); + time_repo.put(section, 0L); } - for (String level: DIMENSIONS) + for (String level : DIMENSIONS) { - for (String section: SECTIONS) + for (String section : SECTIONS) { - time_repo.put(level+"."+section,0L); + time_repo.put(level + "." + section, 0L); } } tick_health_elapsed = ticks; tick_health_requested = ticks; current_tick_start = 0L; - current_section_start = 0L; - current_section = null; - } - public static void start_section(World world, String name) + public static void prepare_entity_report(MinecraftServer server, int ticks) { - if (tick_health_requested == 0L || test_type != 1) - { + //maybe add so it only spams the sending player, but honestly - all may want to see it + time_repo.clear(); + time_repo.put("tick", 0L); + test_type = TYPE.ENTITY; + tick_health_elapsed = ticks; + tick_health_requested = ticks; + current_tick_start = 0L; + } + + public static ProfilerToken start_section(World world, String name, TYPE type) + { + if (tick_health_requested == 0L || test_type != TYPE.GENERAL || current_tick_start == 0) + return null; + return new ProfilerToken(type, name, world, System.nanoTime()); + } + + public static ProfilerToken start_entity_section(World world, Object e, TYPE type) + { + if (tick_health_requested == 0L || test_type != TYPE.ENTITY || current_tick_start == 0) + return null; + return new ProfilerToken(type, e, world, System.nanoTime()); + } + + public static void end_current_section(ProfilerToken tok) + { + if (tick_health_requested == 0L || test_type != TYPE.GENERAL || current_tick_start == 0) return; - } - if (current_tick_start == 0L) - { - return; - } - if (current_section != null) - { - end_current_section(); - } - String key = name; - if (world != null) - { - key = world.getDimension().getType().getSuffix()+"."+name; - } - current_section = key; - current_section_start = System.nanoTime(); - } - - - public static class ProfilerToken - { - public String section; - public long start; - public ProfilerToken(String name, long start) - { - this.section = name; - this.start = start; - } - } - - public static ProfilerToken start_section_concurrent(World world, String name, boolean isRemote) - { - if (tick_health_requested == 0L || test_type != 1) - { - return null; - } - if (current_tick_start == 0L) - { - return null; - } - - String key = name; - if (world != null) - { - key = world.getDimension().getType().getSuffix()+"."+name; - } - if (isRemote) key += "(client)"; - long time = System.nanoTime(); - return new ProfilerToken(key, time); - } - - public static ProfilerToken start_entity_section(World world, Entity e) - { - if (tick_health_requested == 0L || test_type != 2) - { - return null; - } - if (current_tick_start == 0L) - { - return null; - } - String section = world.getDimension().getType().getSuffix()+"."+ Registry.ENTITY_TYPE.getId(e.getType()).toString().replaceFirst("minecraft:",""); - if (e.getEntityWorld().isClient) - section += "(client)"; - long section_start = System.nanoTime(); - return new ProfilerToken(section, section_start); - } - - public static ProfilerToken start_tileentity_section(World world, BlockEntity e) - { - if (tick_health_requested == 0L || test_type != 2) - { - return null; - } - if (current_tick_start == 0L) - { - return null; - } - String section = world.getDimension().getType().getSuffix()+"."+ BlockEntityType.getId(e.getType()).toString().replaceFirst("minecraft:",""); - if (e.getWorld() == null) - section += "??"; - else if (e.getWorld().isClient) - section += "(client)"; - long section_start = System.nanoTime(); - return new ProfilerToken(section, section_start); - } - - public static void end_current_section() - { - if (tick_health_requested == 0L || test_type != 1) - { - return; - } long end_time = System.nanoTime(); - if (current_tick_start == 0L) + if (tok.type == TYPE.GENERAL) { - return; + String current_section = (tok.world == null) ? (String) tok.section : + getSectionString(tok.world, (String)tok.section); + if (time_repo.get(current_section) == null) + { + CarpetSettings.LOG.error("Current section: "+current_section); + } + else + time_repo.put(current_section, time_repo.get(current_section) + end_time - tok.start); } - if (current_section == null) - { - CarpetSettings.LOG.error("finishing section that hasn't started"); - return; - } - //CarpetSettings.LOG.error("finishing section "+current_section); - time_repo.put(current_section,time_repo.get(current_section)+end_time-current_section_start); - current_section = null; - current_section_start = 0; - } - - public static void end_current_section_concurrent(ProfilerToken tok) - { - if (tick_health_requested == 0L || test_type != 1) - { - return; - } - long end_time = System.nanoTime(); - if (current_tick_start == 0L) - { - return; - } - if (tok == null) - { - CarpetSettings.LOG.error("finishing section that hasn't started"); - return; - } - //CarpetSettings.LOG.error("finishing section "+current_section); - time_repo.put(tok.section,time_repo.get(tok.section)+end_time-tok.start); } public static void end_current_entity_section(ProfilerToken tok) { - if (tick_health_requested == 0L || test_type != 2) - { + if (tick_health_requested == 0L || test_type != TYPE.ENTITY || current_tick_start == 0) return; - } long end_time = System.nanoTime(); - if (current_tick_start == 0L) - { + String section; + if (tok.type == TYPE.ENTITY) + section = getEntityString(tok.world, (Entity) tok.section); + else if (tok.type == TYPE.TILEENTITY) + section = getTEntityString(tok.world, (BlockEntity) tok.section); + else return; - } - if (tok == null) - { - CarpetSettings.LOG.error("finishing entity/TE section that hasn't started"); - return; - } - String time_section = "t."+tok.section; - String count_section = "c."+tok.section; - time_repo.put(time_section,time_repo.getOrDefault(time_section,0L)+end_time-tok.start); - time_repo.put(count_section,time_repo.getOrDefault(count_section,0L)+1); + String time_section = "t." + section; + String count_section = "c." + section; + time_repo.put(time_section, time_repo.getOrDefault(time_section, 0L) + end_time - tok.start); + time_repo.put(count_section, time_repo.getOrDefault(count_section, 0L) + 1); } public static void start_tick_profiling() @@ -215,15 +171,14 @@ public class CarpetProfiler current_tick_start = System.nanoTime(); } - public static void end_tick_profiling(MinecraftServer server) + public static void end_tick_profiling(MinecraftServer server, ProfilerToken postTasks) { if (current_tick_start == 0L) - { return; - } - time_repo.put("tick",time_repo.get("tick")+System.nanoTime()-current_tick_start); - tick_health_elapsed --; - //CarpetSettings.LOG.error("tick count current at "+time_repo.get("tick")); + if (postTasks != null) + end_current_section(postTasks); + time_repo.put("tick", time_repo.get("tick") + System.nanoTime() - current_tick_start); + tick_health_elapsed--; if (tick_health_elapsed <= 0) { finalize_tick_report(server); @@ -232,41 +187,35 @@ public class CarpetProfiler public static void finalize_tick_report(MinecraftServer server) { - if (test_type == 1) - { + if (test_type == TYPE.GENERAL) finalize_tick_report_for_time(server); - } - if (test_type == 2) - { + if (test_type == TYPE.ENTITY) finalize_tick_report_for_entities(server); - } cleanup_tick_report(); } public static void cleanup_tick_report() { time_repo.clear(); - time_repo.put("tick",0L); - test_type = 0; + time_repo.put("tick", 0L); + test_type = TYPE.NONE; tick_health_elapsed = 0; tick_health_requested = 0; current_tick_start = 0L; - current_section_start = 0L; - current_section = null; - } public static void finalize_tick_report_for_time(MinecraftServer server) { //print stats long total_tick_time = time_repo.get("tick"); - double divider = 1.0D/tick_health_requested/1000000; - Messenger.print_server_message(server, String.format("Average tick time: %.3fms",divider*total_tick_time)); + double divider = 1.0D / tick_health_requested / 1000000; + Messenger.print_server_message(server, ""); + Messenger.print_server_message(server, String.format("Average tick time: %.3fms", divider * total_tick_time)); long accumulated = 0L; - for (String section: GENERAL_SECTIONS) + for (String section : GENERAL_SECTIONS) { - double amount = divider*time_repo.get(section); + double amount = divider * time_repo.get(section); if (amount > 0.01) { accumulated += time_repo.get(section); @@ -274,12 +223,12 @@ public class CarpetProfiler } } - for (String dimension: DIMENSIONS) + for (String dimension : DIMENSIONS) { boolean hasSomethin = false; - for (String section: SECTIONS) + for (String section : SECTIONS) { - double amount = divider*time_repo.get(dimension+"."+section); + double amount = divider * time_repo.get(dimension + "." + section); if (amount > 0.01) { hasSomethin = true; @@ -290,35 +239,36 @@ public class CarpetProfiler { continue; } - Messenger.print_server_message(server, dimension+":"); - for (String section: SECTIONS) + Messenger.print_server_message(server, dimension + ":"); + for (String section : SECTIONS) { - double amount = divider*time_repo.get(dimension+"."+section); + double amount = divider * time_repo.get(dimension + "." + section); if (amount > 0.01) { if (!(section.endsWith("(client)"))) - accumulated += time_repo.get(dimension+"."+section); + accumulated += time_repo.get(dimension + "." + section); Messenger.print_server_message(server, String.format(" - %s: %.3fms", section, amount)); } } } - long rest = total_tick_time-accumulated; + long rest = total_tick_time - accumulated; - Messenger.print_server_message(server, String.format("The Rest, whatever that might be: %.3fms",divider*rest)); + Messenger.print_server_message(server, String.format("The Rest, whatever that might be: %.3fms", divider * rest)); } public static void finalize_tick_report_for_entities(MinecraftServer server) { //print stats long total_tick_time = time_repo.get("tick"); - double divider = 1.0D/tick_health_requested/1000000; - double divider_1 = 1.0D/(tick_health_requested-1)/1000000; - Messenger.print_server_message(server, String.format("Average tick time: %.3fms",divider*total_tick_time)); + double divider = 1.0D / tick_health_requested / 1000000; + double divider_1 = 1.0D / (tick_health_requested - 1) / 1000000; + Messenger.print_server_message(server, ""); + Messenger.print_server_message(server, String.format("Average tick time: %.3fms", divider * total_tick_time)); time_repo.remove("tick"); Messenger.print_server_message(server, "Top 10 counts:"); int total = 0; - for ( Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()) ) + for (Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList())) { if (entry.getKey().startsWith("t.")) { @@ -332,12 +282,12 @@ public class CarpetProfiler String[] parts = entry.getKey().split("\\."); String dim = parts[1]; String name = parts[2]; - int penalty = name.endsWith("(client)") ? 1 :0; - Messenger.print_server_message(server, String.format(" - %s in %s: %.3f",name, dim, 1.0D*entry.getValue()/(tick_health_requested-penalty))); + int penalty = name.endsWith("(client)") ? 1 : 0; + Messenger.print_server_message(server, String.format(" - %s in %s: %.3f", name, dim, 1.0D * entry.getValue() / (tick_health_requested - penalty))); } Messenger.print_server_message(server, "Top 10 grossing:"); total = 0; - for ( Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()) ) + for (Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList())) { if (entry.getKey().startsWith("c.")) { @@ -351,23 +301,8 @@ public class CarpetProfiler String[] parts = entry.getKey().split("\\."); String dim = parts[1]; String name = parts[2]; - double applicableDivider = name.endsWith("(client)") ? divider :divider_1; - Messenger.print_server_message(server, String.format(" - %s in %s: %.3fms",name, dim, applicableDivider*entry.getValue())); + double applicableDivider = name.endsWith("(client)") ? divider : divider_1; + Messenger.print_server_message(server, String.format(" - %s in %s: %.3fms", name, dim, applicableDivider * entry.getValue())); } - } - - public static void prepare_entity_report(int ticks) - { - //maybe add so it only spams the sending player, but honestly - all may want to see it - time_repo.clear(); - time_repo.put("tick",0L); - test_type = 2; - tick_health_elapsed = ticks; - tick_health_requested = ticks; - current_tick_start = 0L; - current_section_start = 0L; - current_section = null; - - } -} +} \ No newline at end of file diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index e1dc2d76..571fc132 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -5,8 +5,12 @@ "mixins": [ "CommandManagerMixin", "MinecraftServer_coreMixin", + "MinecraftServer_tickspeedMixin", "World_tickMixin", + "ServerWorld_tickMixin", + "ServerChunkManager_tickMixin", + "MinecraftServer_motdMixin", "ServerPlayNetworkHandlerMixin", "MinecraftServer_scarpetMixin", From 3330e6f9229c5d5f6f48516b22ae0babaee521fc Mon Sep 17 00:00:00 2001 From: gnembon Date: Sat, 18 May 2019 00:45:36 -0300 Subject: [PATCH 5/6] rework motd and 14.2 pre 2 --- gradle.properties | 4 +-- src/main/java/carpet/CarpetSettings.java | 4 ++- .../fakes/MinecraftServer_motdInterface.java | 6 +++++ .../mixins/MinecraftServer_motdMixin.java | 26 ++++++++++++++----- 4 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 src/main/java/carpet/fakes/MinecraftServer_motdInterface.java diff --git a/gradle.properties b/gradle.properties index 86ded629..2c9e0c6a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,8 +4,8 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use # or better: https://modmuss50.me/fabric.html - minecraft_version=1.14.2 Pre-Release 1 - yarn_mappings=1.14.2 Pre-Release 1+build.1 + minecraft_version=1.14.2 Pre-Release 2 + yarn_mappings=1.14.2 Pre-Release 2+build.2 loader_version=0.4.7+build.147 # Mod Properties diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index fb3f625d..be0958d0 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.FileNotFoundException; //import carpet.helpers.SpawnChunks; +import carpet.fakes.MinecraftServer_motdInterface; import carpet.utils.Messenger; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.dedicated.DedicatedServer; @@ -152,7 +153,8 @@ public class CarpetSettings .choices("100","0 10 50 100").setNotStrict(), rule("customMOTD", "creative","Sets a different motd message on client trying to connect to the server") .extraInfo("use '_' to use the startup setting from server.properties") - .choices("_","_").setNotStrict(), + .choices("_","_").setNotStrict().validate((s) -> + ((MinecraftServer_motdInterface)CarpetServer.minecraft_server).checkMOTD()), rule("rotatorBlock", "experimental", "Cactus in dispensers rotates blocks.") .extraInfo("Cactus in a dispenser gives the dispenser the ability to rotate the blocks " + "that are in front of it anti-clockwise if possible."), diff --git a/src/main/java/carpet/fakes/MinecraftServer_motdInterface.java b/src/main/java/carpet/fakes/MinecraftServer_motdInterface.java new file mode 100644 index 00000000..6cb05284 --- /dev/null +++ b/src/main/java/carpet/fakes/MinecraftServer_motdInterface.java @@ -0,0 +1,6 @@ +package carpet.fakes; + +public interface MinecraftServer_motdInterface +{ + String checkMOTD(); +} diff --git a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java index 35fd5fe5..c177d465 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java @@ -1,6 +1,7 @@ package carpet.mixins; import carpet.CarpetSettings; +import carpet.fakes.MinecraftServer_motdInterface; import net.minecraft.server.MinecraftServer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -8,20 +9,33 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(MinecraftServer.class) -public class MinecraftServer_motdMixin +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 setMotd(MinecraftServer server) + private String setCustomMotd(MinecraftServer server) { - if ("_".equals(CarpetSettings.getString("customMOTD"))) - return motd; - else - return CarpetSettings.getString("customMOTD"); + return checkMOTD(); } + @Override + public String checkMOTD() + { + if ("_".equals(CarpetSettings.getString("customMOTD"))) + { + setMotd(motd); + return motd; + } + else + { + setMotd(CarpetSettings.getString("customMOTD")); + return CarpetSettings.getString("customMOTD"); + } + } } From 109dd4d013f19b37f43c93b6a32cadc3fee4f4fe Mon Sep 17 00:00:00 2001 From: gnembon Date: Sat, 18 May 2019 02:15:00 -0300 Subject: [PATCH 6/6] tick freeze --- .../mixins/ServerChunkManager_tickMixin.java | 16 +++ .../carpet/mixins/ServerWorld_tickMixin.java | 100 +++++++++++++++++- .../java/carpet/mixins/World_tickMixin.java | 18 +++- 3 files changed, 131 insertions(+), 3 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java b/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java index e8987d3e..9d38df9e 100644 --- a/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java @@ -1,13 +1,17 @@ package carpet.mixins; +import carpet.helpers.TickSpeed; import carpet.utils.CarpetProfiler; import net.minecraft.server.world.ServerChunkManager; import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.level.LevelGeneratorType; +import net.minecraft.world.level.LevelProperties; import org.spongepowered.asm.mixin.Final; 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 java.util.function.BooleanSupplier; @@ -61,4 +65,16 @@ public abstract class ServerChunkManager_tickMixin CarpetProfiler.end_current_section(currentSection); } } + + //// Tick freeze + @Redirect(method = "tickChunks", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/LevelProperties;getGeneratorType()Lnet/minecraft/world/level/LevelGeneratorType;" + )) + private LevelGeneratorType skipChunkTicking(LevelProperties levelProperties) + { + if (!TickSpeed.process_entities) return LevelGeneratorType.DEBUG_ALL_BLOCK_STATES; + return levelProperties.getGeneratorType(); + } + } diff --git a/src/main/java/carpet/mixins/ServerWorld_tickMixin.java b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java index 8aadaacf..73c96434 100644 --- a/src/main/java/carpet/mixins/ServerWorld_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java @@ -1,20 +1,41 @@ package carpet.mixins; +import carpet.helpers.TickSpeed; import carpet.utils.CarpetProfiler; +import net.minecraft.entity.raid.RaidManager; import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.profiler.Profiler; +import net.minecraft.village.ZombieSiegeManager; +import net.minecraft.world.WanderingTraderManager; import net.minecraft.world.World; +import net.minecraft.world.border.WorldBorder; +import net.minecraft.world.chunk.ChunkManager; +import net.minecraft.world.dimension.Dimension; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.level.LevelGeneratorType; +import net.minecraft.world.level.LevelProperties; 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 java.util.function.BiFunction; import java.util.function.BooleanSupplier; @Mixin(ServerWorld.class) -public class ServerWorld_tickMixin +public abstract class ServerWorld_tickMixin extends World { + @Shadow protected abstract void sendBlockActions(); + CarpetProfiler.ProfilerToken currentSection; + protected ServerWorld_tickMixin(LevelProperties levelProperties_1, DimensionType dimensionType_1, BiFunction biFunction_1, Profiler profiler_1, boolean boolean_1) + { + super(levelProperties_1, dimensionType_1, biFunction_1, profiler_1, boolean_1); + } + @Inject(method = "tick", at = @At( value = "CONSTANT", args = "stringValue=world border" @@ -92,4 +113,81 @@ public class ServerWorld_tickMixin { CarpetProfiler.end_current_section(currentSection); } + + //// freeze + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/border/WorldBorder;tick()V" + )) + private void tickWorldBorder(WorldBorder worldBorder) + { + if (TickSpeed.process_entities) worldBorder.tick(); + } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/dimension/Dimension;hasSkyLight()Z" + )) + private boolean tickWorldBorder(Dimension dimension) + { + return TickSpeed.process_entities && dimension.hasSkyLight(); + } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/world/ServerWorld;tickTime()V" + )) + private void tickTimeConditionally(ServerWorld serverWorld) + { + if (TickSpeed.process_entities) this.tickTime(); + } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/LevelProperties;getGeneratorType()Lnet/minecraft/world/level/LevelGeneratorType;" + )) + private LevelGeneratorType tickPendingBlocks(LevelProperties levelProperties) + { + if (TickSpeed.process_entities) return levelProperties.getGeneratorType(); + return LevelGeneratorType.DEBUG_ALL_BLOCK_STATES; + } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/village/ZombieSiegeManager;tick()V" + )) + private void tickConditionally(ZombieSiegeManager zombieSiegeManager) + { + if (TickSpeed.process_entities) zombieSiegeManager.tick(); + } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/raid/RaidManager;tick()V" + )) + private void tickConditionally(RaidManager raidManager) + { + if (TickSpeed.process_entities) raidManager.tick(); + } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/WanderingTraderManager;tick()V" + )) + private void tickConditionally(WanderingTraderManager wanderingTraderManager) + { + if (TickSpeed.process_entities) wanderingTraderManager.tick(); + } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/world/ServerWorld;sendBlockActions()V" + )) + private void tickConditionally(ServerWorld serverWorld) + { + if (TickSpeed.process_entities) sendBlockActions(); + } + + } diff --git a/src/main/java/carpet/mixins/World_tickMixin.java b/src/main/java/carpet/mixins/World_tickMixin.java index ea22dfce..c299c293 100644 --- a/src/main/java/carpet/mixins/World_tickMixin.java +++ b/src/main/java/carpet/mixins/World_tickMixin.java @@ -1,13 +1,16 @@ package carpet.mixins; +import carpet.helpers.TickSpeed; import carpet.utils.CarpetProfiler; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.profiler.Profiler; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -41,6 +44,15 @@ public abstract class World_tickMixin entitySection = CarpetProfiler.start_entity_section((World)(Object)this, blockEntity_2, CarpetProfiler.TYPE.TILEENTITY); } + @Redirect(method = "tickBlockEntities", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/entity/BlockEntity;hasWorld()Z" + )) + private boolean checkProcessTEs(BlockEntity blockEntity) + { + return blockEntity.hasWorld() && TickSpeed.process_entities; + } + @Inject(method = "tickBlockEntities", at = @At( value = "INVOKE", target = "Lnet/minecraft/block/entity/BlockEntity;isInvalid()Z", @@ -52,9 +64,11 @@ public abstract class World_tickMixin CarpetProfiler.end_current_entity_section(entitySection); } - @Inject(method = "tickEntity", at = @At("HEAD")) - private void startEntity(Consumer call, Entity e, CallbackInfo ci) + @Inject(method = "tickEntity", at = @At("HEAD"), cancellable = true) + private void startEntity(Consumer consumer_1, Entity e, CallbackInfo ci) { + if (!TickSpeed.process_entities && !(e instanceof PlayerEntity)) + ci.cancel(); entitySection = CarpetProfiler.start_entity_section((World) (Object) this, e, CarpetProfiler.TYPE.ENTITY); }