From 01d9a51c610eb9f28fa22767839c6609acda1275 Mon Sep 17 00:00:00 2001 From: fishshi <2855691008@qq.com> Date: Wed, 13 Nov 2024 02:16:14 +0800 Subject: [PATCH] Add AFTER_CLIENT_WORLD_CHANGE (#4173) * add AFTER_CLIENT_WORLD_CHANGE * fix * move * add description to README and change class to final with a private constructor * revert the event name --- fabric-lifecycle-events-v1/README.md | 5 ++ .../event/lifecycle/v1/ClientWorldEvents.java | 48 +++++++++++++++++++ .../client/MinecraftClientMixin.java | 10 ++++ .../client/ClientLifecycleTests.java | 9 ++++ 4 files changed, 72 insertions(+) create mode 100644 fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientWorldEvents.java diff --git a/fabric-lifecycle-events-v1/README.md b/fabric-lifecycle-events-v1/README.md index 3911c28ee..979ff365e 100644 --- a/fabric-lifecycle-events-v1/README.md +++ b/fabric-lifecycle-events-v1/README.md @@ -62,6 +62,11 @@ Currently, this contains events related to when the Minecraft Client is starting Events related to ticking of a Minecraft client. There are events that indicate the beginning and end of the tick for the client and the `ClientWorld` if in game. +## `ClientWorldEvents` + +Events related to the lifecycle a `ClientWorld`. +Currently, this contains an event which is called after `ClientWorld` has been changed. + ## `ClientChunkEvents` Events related to the lifecycle of chunks on a Minecraft client. diff --git a/fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientWorldEvents.java b/fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientWorldEvents.java new file mode 100644 index 000000000..332058177 --- /dev/null +++ b/fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientWorldEvents.java @@ -0,0 +1,48 @@ +/* + * 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.client.event.lifecycle.v1; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.world.ClientWorld; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +public final class ClientWorldEvents { + private ClientWorldEvents() { + } + + /** + * An event which is called after the client world has been changed. + */ + public static final Event<AfterClientWorldChange> AFTER_CLIENT_WORLD_CHANGE = EventFactory.createArrayBacked(AfterClientWorldChange.class, callbacks -> (client, world) -> { + for (AfterClientWorldChange callback : callbacks) { + callback.afterWorldChange(client, world); + } + }); + + @FunctionalInterface + public interface AfterClientWorldChange { + /** + * Called after the client world has been changed. + * + * @param client the client instance + * @param world the new world instance + */ + void afterWorldChange(MinecraftClient client, ClientWorld world); + } +} diff --git a/fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java b/fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java index e0277d6b5..f0e4a73f3 100644 --- a/fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java +++ b/fabric-lifecycle-events-v1/src/client/java/net/fabricmc/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java @@ -22,9 +22,11 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.world.ClientWorld; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientWorldEvents; @Mixin(MinecraftClient.class) public abstract class MinecraftClientMixin { @@ -48,4 +50,12 @@ public abstract class MinecraftClientMixin { private void onStart(CallbackInfo ci) { ClientLifecycleEvents.CLIENT_STARTED.invoker().onClientStarted((MinecraftClient) (Object) this); } + + @Inject(method = "setWorld", at = @At("TAIL")) + private void afterClientWorldChange(ClientWorld world, CallbackInfo ci) { + if (world != null) { + MinecraftClient client = (MinecraftClient) (Object) this; + ClientWorldEvents.AFTER_CLIENT_WORLD_CHANGE.invoker().afterWorldChange(client, world); + } + } } diff --git a/fabric-lifecycle-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientLifecycleTests.java index 5d1f3f8eb..04d8cc728 100644 --- a/fabric-lifecycle-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientLifecycleTests.java +++ b/fabric-lifecycle-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/event/lifecycle/client/ClientLifecycleTests.java @@ -16,10 +16,15 @@ package net.fabricmc.fabric.test.event.lifecycle.client; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientWorldEvents; public final class ClientLifecycleTests implements ClientModInitializer { + private static final Logger LOGGER = LoggerFactory.getLogger(ClientLifecycleTests.class); private boolean startCalled; private boolean stopCalled; @@ -44,5 +49,9 @@ public final class ClientLifecycleTests implements ClientModInitializer { stopCalled = true; System.out.println("Client has started stopping!"); }); + + ClientWorldEvents.AFTER_CLIENT_WORLD_CHANGE.register((client, world) -> { + LOGGER.info("Client world changed to {}", world.getRegistryKey().getValue()); + }); } }