diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientBlockEntityEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientBlockEntityEvents.java index ec901429b..eff510dd8 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientBlockEntityEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientBlockEntityEvents.java @@ -78,10 +78,12 @@ public final class ClientBlockEntityEvents { } }); + @FunctionalInterface public interface Load { void onLoad(BlockEntity blockEntity, ClientWorld world); } + @FunctionalInterface public interface Unload { void onUnload(BlockEntity blockEntity, ClientWorld world); } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientChunkEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientChunkEvents.java index 7ce0387ad..ad5350c68 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientChunkEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientChunkEvents.java @@ -78,10 +78,12 @@ public final class ClientChunkEvents { } }); + @FunctionalInterface public interface Load { void onChunkLoad(ClientWorld world, WorldChunk chunk); } + @FunctionalInterface public interface Unload { void onChunkUnload(ClientWorld world, WorldChunk chunk); } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientEntityEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientEntityEvents.java index c8ced1a4b..f4ee6d837 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientEntityEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientEntityEvents.java @@ -78,10 +78,12 @@ public final class ClientEntityEvents { } }); + @FunctionalInterface public interface Load { void onLoad(Entity entity, ClientWorld world); } + @FunctionalInterface public interface Unload { void onUnload(Entity entity, ClientWorld world); } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientLifecycleEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientLifecycleEvents.java index 88ce5cac4..045e29824 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientLifecycleEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientLifecycleEvents.java @@ -51,10 +51,12 @@ public final class ClientLifecycleEvents { } }); + @FunctionalInterface public interface ClientStarted { void onClientStarted(MinecraftClient client); } + @FunctionalInterface public interface ClientStopping { void onClientStopping(MinecraftClient client); } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientTickEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientTickEvents.java index 07b3eb9c1..5eb0d52b0 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientTickEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientTickEvents.java @@ -120,18 +120,22 @@ public final class ClientTickEvents { } }); + @FunctionalInterface public interface StartTick { void onStartTick(MinecraftClient client); } + @FunctionalInterface public interface EndTick { void onEndTick(MinecraftClient client); } + @FunctionalInterface public interface StartWorldTick { void onStartTick(ClientWorld world); } + @FunctionalInterface public interface EndWorldTick { void onEndTick(ClientWorld world); } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java index 5418bfb1b..0527aa071 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java @@ -75,10 +75,12 @@ public final class ServerBlockEntityEvents { } }); + @FunctionalInterface public interface Load { void onLoad(BlockEntity blockEntity, ServerWorld world); } + @FunctionalInterface public interface Unload { void onUnload(BlockEntity blockEntity, ServerWorld world); } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java index af495363e..0d2515e46 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java @@ -75,10 +75,12 @@ public final class ServerChunkEvents { } }); + @FunctionalInterface public interface Load { void onChunkLoad(ServerWorld world, WorldChunk chunk); } + @FunctionalInterface public interface Unload { void onChunkUnload(ServerWorld world, WorldChunk chunk); } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java index 9166bf0f4..ab0333cb4 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java @@ -53,6 +53,7 @@ public final class ServerEntityEvents { } }); + @FunctionalInterface public interface Load { void onLoad(Entity entity, ServerWorld world); } 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 50bf8a507..e6f04acc4 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 @@ -96,26 +96,32 @@ public final class ServerLifecycleEvents { } }); + @FunctionalInterface public interface ServerStarting { void onServerStarting(MinecraftServer server); } + @FunctionalInterface public interface ServerStarted { void onServerStarted(MinecraftServer server); } + @FunctionalInterface public interface ServerStopping { void onServerStopping(MinecraftServer server); } + @FunctionalInterface public interface ServerStopped { void onServerStopped(MinecraftServer server); } + @FunctionalInterface public interface StartDataPackReload { void startDataPackReload(MinecraftServer server, ServerResourceManager serverResourceManager); } + @FunctionalInterface public interface EndDataPackReload { /** * Called after data packs on a Minecraft server have been reloaded. diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerTickEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerTickEvents.java index 9b9d2662f..c4200cc1b 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerTickEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerTickEvents.java @@ -117,18 +117,22 @@ public final class ServerTickEvents { } }); + @FunctionalInterface public interface StartTick { void onStartTick(MinecraftServer server); } + @FunctionalInterface public interface EndTick { void onEndTick(MinecraftServer server); } + @FunctionalInterface public interface StartWorldTick { void onStartTick(ServerWorld world); } + @FunctionalInterface public interface EndWorldTick { void onEndTick(ServerWorld world); } 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 index ca47bed62..29da25965 100644 --- 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 @@ -35,10 +35,28 @@ public final class ServerWorldEvents { } }); + /** + * Called before a world is unloaded by a Minecraft server. + * + * <p>This typically occurs after a server has {@link ServerLifecycleEvents#SERVER_STOPPING started shutting down}. + * Mods which allow dynamic world (un)registration should use this event so mods can let go of world handles when a world is removed. + */ + public static final Event<Unload> UNLOAD = EventFactory.createArrayBacked(Unload.class, callbacks -> (server, world) -> { + for (Unload callback : callbacks) { + callback.onWorldUnload(server, world); + } + }); + + @FunctionalInterface public interface Load { void onWorldLoad(MinecraftServer server, ServerWorld world); } + @FunctionalInterface + public interface Unload { + void onWorldUnload(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 ff62491f4..d5f6e46d8 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 @@ -96,6 +96,11 @@ public abstract class MinecraftServerMixin { return result; } + @Inject(method = "shutdown", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;close()V", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILEXCEPTION) + private void onUnloadWorldAtShutdown(CallbackInfo ci, Iterator<ServerWorld> worlds, ServerWorld world) { + ServerWorldEvents.UNLOAD.invoker().onWorldUnload((MinecraftServer) (Object) this, world); + } + @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); 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 59f5dfb3a..d773930e7 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 @@ -46,5 +46,9 @@ public class ServerLifecycleTests implements ModInitializer { ServerWorldEvents.LOAD.register((server, world) -> { LOGGER.info("Loaded world " + world.getRegistryKey().getValue().toString()); }); + + ServerWorldEvents.UNLOAD.register((server, world) -> { + LOGGER.info("Unloaded world " + world.getRegistryKey().getValue().toString()); + }); } }