From 144d3847c09bd5e1c5ac4fde3e60ce3043181799 Mon Sep 17 00:00:00 2001 From: i509VCB <git@i509.me> Date: Fri, 17 Jul 2020 06:51:05 -0700 Subject: [PATCH] Lifecycle Events: Part 2, Electric Boogaloo (#848) * Add a few new server lifecycle events Server starting, Load World, Before server resource reload, After server resource reload * Save event * Split world load into ServerWorldEvents, add failure event for data pack reload * cause * Merge fail and regular end. * Present tense lol * So we can just plainly specify the system properties * use handleAsync instead --- .../lifecycle/v1/ServerLifecycleEvents.java | 54 +++++++++++++++++++ .../event/lifecycle/v1/ServerWorldEvents.java | 44 +++++++++++++++ .../event/lifecycle/MinecraftServerMixin.java | 40 ++++++++++++++ .../ServerBlockEntityLifecycleTests.java | 27 ++++++++-- .../lifecycle/ServerEntityLifecycleTests.java | 6 ++- .../event/lifecycle/ServerLifecycleTests.java | 5 ++ .../lifecycle/ServerResourceReloadTests.java | 43 +++++++++++++++ .../ClientBlockEntityLifecycleTests.java | 22 ++++++-- .../client/ClientEntityLifecycleTests.java | 19 +++++-- .../src/testmod/resources/fabric.mod.json | 3 +- 10 files changed, 247 insertions(+), 16 deletions(-) create mode 100644 fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerWorldEvents.java create mode 100644 fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerResourceReloadTests.java diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerLifecycleEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerLifecycleEvents.java index ce5fceba8..50bf8a507 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerLifecycleEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerLifecycleEvents.java @@ -16,7 +16,9 @@ package net.fabricmc.fabric.api.event.lifecycle.v1; +import net.minecraft.resource.ServerResourceManager; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PlayerManager; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; @@ -25,6 +27,17 @@ public final class ServerLifecycleEvents { private ServerLifecycleEvents() { } + /** + * Called when a Minecraft server is starting. + * + * <p>This occurs before the {@link PlayerManager player manager} and any worlds are loaded. + */ + public static final Event<ServerStarting> SERVER_STARTING = EventFactory.createArrayBacked(ServerStarting.class, callbacks -> server -> { + for (ServerStarting callback : callbacks) { + callback.onServerStarting(server); + } + }); + /** * Called when a Minecraft server has started and is about to tick for the first time. * @@ -63,6 +76,30 @@ public final class ServerLifecycleEvents { } }); + /** + * Called before a Minecraft server reloads data packs. + */ + public static final Event<StartDataPackReload> START_DATA_PACK_RELOAD = EventFactory.createArrayBacked(StartDataPackReload.class, callbacks -> (server, serverResourceManager) -> { + for (StartDataPackReload callback : callbacks) { + callback.startDataPackReload(server, serverResourceManager); + } + }); + + /** + * Called after a Minecraft server has reloaded data packs. + * + * <p>If reloading data packs was unsuccessful, the current data packs will be kept. + */ + public static final Event<EndDataPackReload> END_DATA_PACK_RELOAD = EventFactory.createArrayBacked(EndDataPackReload.class, callbacks -> (server, serverResourceManager, success) -> { + for (EndDataPackReload callback : callbacks) { + callback.endDataPackReload(server, serverResourceManager, success); + } + }); + + public interface ServerStarting { + void onServerStarting(MinecraftServer server); + } + public interface ServerStarted { void onServerStarted(MinecraftServer server); } @@ -74,4 +111,21 @@ public final class ServerLifecycleEvents { public interface ServerStopped { void onServerStopped(MinecraftServer server); } + + public interface StartDataPackReload { + void startDataPackReload(MinecraftServer server, ServerResourceManager serverResourceManager); + } + + public interface EndDataPackReload { + /** + * Called after data packs on a Minecraft server have been reloaded. + * + * <p>If the reload was not successful, the old data packs will be kept. + * + * @param server the server + * @param serverResourceManager the server resource manager + * @param success if the reload was successful + */ + void endDataPackReload(MinecraftServer server, ServerResourceManager serverResourceManager, boolean success); + } } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerWorldEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerWorldEvents.java new file mode 100644 index 000000000..ca47bed62 --- /dev/null +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerWorldEvents.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.event.lifecycle.v1; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.PersistentState; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +public final class ServerWorldEvents { + /** + * Called when a world is loaded by a Minecraft server. + * + * <p>For example, this can be used to load world specific metadata or initialize a {@link PersistentState} on a server world. + */ + public static final Event<Load> LOAD = EventFactory.createArrayBacked(Load.class, callbacks -> (server, world) -> { + for (Load callback : callbacks) { + callback.onWorldLoad(server, world); + } + }); + + public interface Load { + void onWorldLoad(MinecraftServer server, ServerWorld world); + } + + private ServerWorldEvents() { + } +} diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/MinecraftServerMixin.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/MinecraftServerMixin.java index b67db9177..61811585b 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/MinecraftServerMixin.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/MinecraftServerMixin.java @@ -16,27 +16,43 @@ package net.fabricmc.fabric.mixin.event.lifecycle; +import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.function.BooleanSupplier; 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.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.Entity; +import net.minecraft.resource.ServerResourceManager; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; @Mixin(MinecraftServer.class) public abstract class MinecraftServerMixin { + @Shadow + private ServerResourceManager serverResourceManager; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setupServer()Z"), method = "runServer") + private void beforeSetupServer(CallbackInfo info) { + ServerLifecycleEvents.SERVER_STARTING.invoker().onServerStarting((MinecraftServer) (Object) this); + } + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setFavicon(Lnet/minecraft/server/ServerMetadata;)V", ordinal = 0), method = "runServer") private void afterSetupServer(CallbackInfo info) { ServerLifecycleEvents.SERVER_STARTED.invoker().onServerStarted((MinecraftServer) (Object) this); @@ -73,4 +89,28 @@ public abstract class MinecraftServerMixin { ServerBlockEntityEvents.BLOCK_ENTITY_UNLOAD.invoker().onUnload(blockEntity, serverWorld); } } + + // The locals you have to manage for an inject are insane. And do it twice. A redirect is much cleaner. + // Here is what it looks like with an inject: https://gist.github.com/i509VCB/f80077cc536eb4dba62b794eba5611c1 + @Redirect(method = "createWorlds", at = @At(value = "INVOKE", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")) + private <K, V> V onLoadWorld(Map<K, V> worlds, K registryKey, V serverWorld) { + final V result = worlds.put(registryKey, serverWorld); + ServerWorldEvents.LOAD.invoker().onWorldLoad((MinecraftServer) (Object) this, (ServerWorld) serverWorld); + + return result; + } + + @Inject(method = "reloadResources", at = @At("HEAD")) + private void startResourceReload(Collection<String> collection, CallbackInfoReturnable<CompletableFuture<Void>> cir) { + ServerLifecycleEvents.START_DATA_PACK_RELOAD.invoker().startDataPackReload((MinecraftServer) (Object) this, this.serverResourceManager); + } + + @Inject(method = "reloadResources", at = @At("TAIL")) + private void endResourceReload(Collection<String> collection, CallbackInfoReturnable<CompletableFuture<Void>> cir) { + cir.getReturnValue().handleAsync((value, throwable) -> { + // Hook into fail + ServerLifecycleEvents.END_DATA_PACK_RELOAD.invoker().endDataPackReload((MinecraftServer) (Object) this, this.serverResourceManager, throwable == null); + return value; + }, (MinecraftServer) (Object) this); + } } diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java index d9e0d6b5f..c3210b597 100644 --- a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java +++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java @@ -31,6 +31,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; public class ServerBlockEntityLifecycleTests implements ModInitializer { + private static boolean PRINT_SERVER_BLOCKENTITY_MESSAGES = System.getProperty("fabric-lifecycle-events-testmod.printServerBlockEntityMessages") != null; private List<BlockEntity> serverBlockEntities = new ArrayList<>(); @Override @@ -39,28 +40,44 @@ public class ServerBlockEntityLifecycleTests implements ModInitializer { ServerBlockEntityEvents.BLOCK_ENTITY_LOAD.register((blockEntity, world) -> { this.serverBlockEntities.add(blockEntity); - logger.info("[SERVER] LOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.serverBlockEntities.size()); + + if (PRINT_SERVER_BLOCKENTITY_MESSAGES) { + logger.info("[SERVER] LOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.serverBlockEntities.size()); + } }); ServerBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register((blockEntity, world) -> { this.serverBlockEntities.remove(blockEntity); - logger.info("[SERVER] UNLOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.serverBlockEntities.size()); + + if (PRINT_SERVER_BLOCKENTITY_MESSAGES) { + logger.info("[SERVER] UNLOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.serverBlockEntities.size()); + } }); ServerTickEvents.END_SERVER_TICK.register(minecraftServer -> { if (minecraftServer.getTicks() % 200 == 0) { int entities = 0; - logger.info("[SERVER] Tracked BlockEntities:" + this.serverBlockEntities.size() + " Ticked at: " + minecraftServer.getTicks() + "ticks"); + + if (PRINT_SERVER_BLOCKENTITY_MESSAGES) { + logger.info("[SERVER] Tracked BlockEntities:" + this.serverBlockEntities.size() + " Ticked at: " + minecraftServer.getTicks() + "ticks"); + } for (ServerWorld world : minecraftServer.getWorlds()) { int worldEntities = world.blockEntities.size(); - logger.info("[SERVER] Tracked BlockEntities in " + world.getRegistryKey().toString() + " - " + worldEntities); + + if (PRINT_SERVER_BLOCKENTITY_MESSAGES) { + logger.info("[SERVER] Tracked BlockEntities in " + world.getRegistryKey().toString() + " - " + worldEntities); + } + entities += worldEntities; } - logger.info("[SERVER] Actual Total BlockEntities: " + entities); + if (PRINT_SERVER_BLOCKENTITY_MESSAGES) { + logger.info("[SERVER] Actual Total BlockEntities: " + entities); + } if (entities != this.serverBlockEntities.size()) { + // Always print mismatches logger.error("[SERVER] Mismatch in tracked blockentities and actual blockentities"); } } diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java index 4bf9c0e47..02045f985 100644 --- a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java +++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java @@ -30,6 +30,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; * Tests related to the lifecycle of entities. */ public class ServerEntityLifecycleTests implements ModInitializer { + private static boolean PRINT_SERVER_ENTITY_MESSAGES = System.getProperty("fabric-lifecycle-events-testmod.printServerEntityMessages") != null; private List<Entity> serverEntities = new ArrayList<>(); @Override @@ -38,7 +39,10 @@ public class ServerEntityLifecycleTests implements ModInitializer { ServerEntityEvents.ENTITY_LOAD.register((entity, world) -> { this.serverEntities.add(entity); - logger.info("[SERVER] LOADED " + entity.toString() + " - Entities: " + this.serverEntities.size()); + + if (PRINT_SERVER_ENTITY_MESSAGES) { + logger.info("[SERVER] LOADED " + entity.toString() + " - Entities: " + this.serverEntities.size()); + } }); } } diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerLifecycleTests.java index 0e0888cce..59f5dfb3a 100644 --- a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerLifecycleTests.java +++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerLifecycleTests.java @@ -21,6 +21,7 @@ import org.apache.logging.log4j.Logger; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; /** * Tests related to the lifecycle of a server. @@ -41,5 +42,9 @@ public class ServerLifecycleTests implements ModInitializer { ServerLifecycleEvents.SERVER_STOPPED.register(server -> { LOGGER.info("Stopped Server!"); }); + + ServerWorldEvents.LOAD.register((server, world) -> { + LOGGER.info("Loaded world " + world.getRegistryKey().getValue().toString()); + }); } } diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerResourceReloadTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerResourceReloadTests.java new file mode 100644 index 000000000..c7537ba45 --- /dev/null +++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerResourceReloadTests.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.test.event.lifecycle; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; + +public class ServerResourceReloadTests implements ModInitializer { + public static final Logger LOGGER = LogManager.getLogger("LifecycleEventsTest"); + + @Override + public void onInitialize() { + ServerLifecycleEvents.START_DATA_PACK_RELOAD.register((server, serverResourceManager) -> { + LOGGER.info("PREPARING FOR RELOAD"); + }); + + ServerLifecycleEvents.END_DATA_PACK_RELOAD.register((server, serverResourceManager, success) -> { + if (success) { + LOGGER.info("FINISHED RELOAD on {}", Thread.currentThread()); + } else { + // Failure can be tested by trying to disable the vanilla datapack + LOGGER.error("FAILED TO RELOAD on {}", Thread.currentThread()); + } + }); + } +} diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientBlockEntityLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientBlockEntityLifecycleTests.java index 51424dc60..94202d6a9 100644 --- a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientBlockEntityLifecycleTests.java +++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientBlockEntityLifecycleTests.java @@ -31,6 +31,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.test.event.lifecycle.ServerLifecycleTests; public class ClientBlockEntityLifecycleTests implements ClientModInitializer { + private static boolean PRINT_CLIENT_BLOCKENTITY_MESSAGES = System.getProperty("fabric-lifecycle-events-testmod.printClientBlockEntityMessages") != null; private List<BlockEntity> clientBlockEntities = new ArrayList<>(); private int clientTicks; @@ -40,22 +41,33 @@ public class ClientBlockEntityLifecycleTests implements ClientModInitializer { ClientBlockEntityEvents.BLOCK_ENTITY_LOAD.register((blockEntity, world) -> { this.clientBlockEntities.add(blockEntity); - logger.info("[CLIENT]" + " LOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.clientBlockEntities.size()); + + if (PRINT_CLIENT_BLOCKENTITY_MESSAGES) { + logger.info("[CLIENT]" + " LOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.clientBlockEntities.size()); + } }); ClientBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register((blockEntity, world) -> { this.clientBlockEntities.remove(blockEntity); - logger.info("[CLIENT]" + " UNLOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.clientBlockEntities.size()); + + if (PRINT_CLIENT_BLOCKENTITY_MESSAGES) { + logger.info("[CLIENT]" + " UNLOADED " + Registry.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.clientBlockEntities.size()); + } }); ClientTickEvents.END_CLIENT_TICK.register(client -> { if (this.clientTicks++ % 200 == 0 && client.world != null) { final int blockEntities = client.world.blockEntities.size(); - logger.info("[CLIENT] Tracked BlockEntities:" + this.clientBlockEntities.size() + " Ticked at: " + this.clientTicks + "ticks"); - logger.info("[CLIENT] Actual BlockEntities: " + client.world.blockEntities.size()); + + if (PRINT_CLIENT_BLOCKENTITY_MESSAGES) { + logger.info("[CLIENT] Tracked BlockEntities:" + this.clientBlockEntities.size() + " Ticked at: " + this.clientTicks + "ticks"); + logger.info("[CLIENT] Actual BlockEntities: " + client.world.blockEntities.size()); + } if (blockEntities != this.clientBlockEntities.size()) { - logger.error("[CLIENT] Mismatch in tracked blockentities and actual blockentities"); + if (PRINT_CLIENT_BLOCKENTITY_MESSAGES) { + logger.error("[CLIENT] Mismatch in tracked blockentities and actual blockentities"); + } } } }); diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientEntityLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientEntityLifecycleTests.java index 350ba0709..f764e4a64 100644 --- a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientEntityLifecycleTests.java +++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientEntityLifecycleTests.java @@ -38,6 +38,7 @@ import net.fabricmc.fabric.test.event.lifecycle.ServerLifecycleTests; */ @Environment(EnvType.CLIENT) public class ClientEntityLifecycleTests implements ClientModInitializer { + private static boolean PRINT_CLIENT_ENTITY_MESSAGES = System.getProperty("fabric-lifecycle-events-testmod.printClientEntityMessages") != null; private List<Entity> clientEntities = new ArrayList<>(); private int clientTicks; @@ -47,21 +48,31 @@ public class ClientEntityLifecycleTests implements ClientModInitializer { ClientEntityEvents.ENTITY_LOAD.register((entity, world) -> { this.clientEntities.add(entity); - logger.info("[CLIENT]" + " LOADED " + Registry.ENTITY_TYPE.getId(entity.getType()).toString() + " - Entities: " + this.clientEntities.size()); + + if (PRINT_CLIENT_ENTITY_MESSAGES) { + logger.info("[CLIENT]" + " LOADED " + Registry.ENTITY_TYPE.getId(entity.getType()).toString() + " - Entities: " + this.clientEntities.size()); + } }); ClientEntityEvents.ENTITY_UNLOAD.register((entity, world) -> { this.clientEntities.remove(entity); - logger.info("[CLIENT]" + " UNLOADED " + Registry.ENTITY_TYPE.getId(entity.getType()).toString() + " - Entities: " + this.clientEntities.size()); + + if (PRINT_CLIENT_ENTITY_MESSAGES) { + logger.info("[CLIENT]" + " UNLOADED " + Registry.ENTITY_TYPE.getId(entity.getType()).toString() + " - Entities: " + this.clientEntities.size()); + } }); ClientTickEvents.END_CLIENT_TICK.register(client -> { if (this.clientTicks++ % 200 == 0 && client.world != null) { final int entities = Iterables.toArray(client.world.getEntities(), Entity.class).length; - logger.info("[CLIENT] Tracked Entities:" + this.clientEntities.size() + " Ticked at: " + this.clientTicks + "ticks"); - logger.info("[CLIENT] Actual Entities: " + entities); + + if (PRINT_CLIENT_ENTITY_MESSAGES) { + logger.info("[CLIENT] Tracked Entities:" + this.clientEntities.size() + " Ticked at: " + this.clientTicks + "ticks"); + logger.info("[CLIENT] Actual Entities: " + entities); + } if (entities != this.clientEntities.size()) { + // Always print mismatches logger.error("[CLIENT] Mismatch in tracked entities and actual entities"); } } diff --git a/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json b/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json index 8fe00cbdf..46fb08365 100644 --- a/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json @@ -13,7 +13,8 @@ "net.fabricmc.fabric.test.event.lifecycle.ServerBlockEntityLifecycleTests", "net.fabricmc.fabric.test.event.lifecycle.ServerEntityLifecycleTests", "net.fabricmc.fabric.test.event.lifecycle.ServerLifecycleTests", - "net.fabricmc.fabric.test.event.lifecycle.ServerTickTests" + "net.fabricmc.fabric.test.event.lifecycle.ServerTickTests", + "net.fabricmc.fabric.test.event.lifecycle.ServerResourceReloadTests" ], "client": [ "net.fabricmc.fabric.test.event.lifecycle.client.ClientBlockEntityLifecycleTests",