From 1c213d9cca6c9f1e25214415ec5ae815daf768e8 Mon Sep 17 00:00:00 2001 From: Mekal Covic <46117728+valoeghese@users.noreply.github.com> Date: Sat, 8 May 2021 22:21:44 +1300 Subject: [PATCH] Lifecycle Events v1 (#38) * 1.0.0 lifecycle events start * update existing events to v1 * lifecycle v1 good * fix * fix my workspaces and update config api to use halfmaven * shut up compileTestJava --- build.gradle | 10 +- gradle.properties | 4 +- legacy-config-v0/build.gradle | 2 +- legacy-lifecycle-events-v0/build.gradle | 6 - legacy-lifecycle-events-v1/build.gradle | 6 + .../lifecycle/ClientLifecycleEvents.java | 66 ++++++++++ .../event/lifecycle/ClientTickCallback.java | 12 +- .../lifecycle/CommonLifecycleEvents.java | 53 ++++++++ .../DedicatedServerTickCallback.java | 12 +- .../lifecycle/ServerLifecycleEvents.java | 115 ++++++++++++++++++ .../mixin/event/lifecycle/MixinMinecraft.java | 22 +++- .../event/lifecycle/MixinMinecraftServer.java | 12 +- .../event/lifecycle/MixinPlayerManager.java | 66 ++++++++++ .../src/main/resources/fabric.mod.json | 0 .../legacy-lifecycle-events.mixins.json | 3 +- .../test/LifecycleEventsTest.java | 36 ++++++ .../test/LifecycleEventsTestServer.java | 41 +++++++ .../src/test/resources/fabric.mod.json | 35 ++++++ .../mixin/texture/MixinItemRenderer.java | 2 +- .../test/TexturesTest.java | 14 ++- settings.gradle | 2 +- 21 files changed, 479 insertions(+), 40 deletions(-) delete mode 100644 legacy-lifecycle-events-v0/build.gradle create mode 100644 legacy-lifecycle-events-v1/build.gradle create mode 100644 legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientLifecycleEvents.java rename {legacy-lifecycle-events-v0 => legacy-lifecycle-events-v1}/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientTickCallback.java (82%) create mode 100644 legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/CommonLifecycleEvents.java rename {legacy-lifecycle-events-v0 => legacy-lifecycle-events-v1}/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/DedicatedServerTickCallback.java (81%) create mode 100644 legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ServerLifecycleEvents.java rename {legacy-lifecycle-events-v0 => legacy-lifecycle-events-v1}/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraft.java (68%) rename {legacy-lifecycle-events-v0 => legacy-lifecycle-events-v1}/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraftServer.java (79%) create mode 100644 legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinPlayerManager.java rename {legacy-lifecycle-events-v0 => legacy-lifecycle-events-v1}/src/main/resources/fabric.mod.json (100%) rename {legacy-lifecycle-events-v0 => legacy-lifecycle-events-v1}/src/main/resources/legacy-lifecycle-events.mixins.json (81%) create mode 100644 legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTest.java create mode 100644 legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTestServer.java create mode 100644 legacy-lifecycle-events-v1/src/test/resources/fabric.mod.json diff --git a/build.gradle b/build.gradle index 335092dd..8e7e189a 100644 --- a/build.gradle +++ b/build.gradle @@ -73,6 +73,10 @@ allprojects { name = 'Jitpack' url 'https://jitpack.io/' } + maven { + name = 'HalfOf2' + url = 'https://storage.googleapis.com/devan-maven/' + } } configurations { @@ -94,11 +98,9 @@ allprojects { //to change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings loom.fromCommit('minecraft-cursed-legacy/Plasma', "build.${project.plasma_build}") {spec -> - spec.version = "b1.7.3-${project.plasma_build}" - } + mappings "io.github.minecraft-cursed-legacy:plasma:b1.7.3-build.${project.plasma_build}" - modImplementation("com.github.minecraft-cursed-legacy:cursed-fabric-loader:${project.loader_version}") { + modImplementation("io.github.minecraft-cursed-legacy:cursed-fabric-loader:${project.loader_version}") { transitive false //Avoid leaking Loader's dependencies forwards } diff --git a/gradle.properties b/gradle.properties index 78e1ffcc..82c36f6d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,10 +3,10 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties minecraft_version=b1.7.3 - loader_version=5ce86c8 + loader_version=1.0.0 plasma_build=18 # Mod Properties - mod_version = 1.0.6 + mod_version = 1.1.0 maven_group = io.github.minecraftcursedlegacy archives_base_name = cursed-legacy-api diff --git a/legacy-config-v0/build.gradle b/legacy-config-v0/build.gradle index 84a0cd16..b98e3cbf 100644 --- a/legacy-config-v0/build.gradle +++ b/legacy-config-v0/build.gradle @@ -5,7 +5,7 @@ apply plugin: 'java-library' moduleDependencies(project, 'legacy-api-base') dependencies { - include api('com.github.valoeghese:ZoesteriaConfig:1.3.6') + include api('valoeghese:ZoesteriaConfig:1.3.6') } minecraft { diff --git a/legacy-lifecycle-events-v0/build.gradle b/legacy-lifecycle-events-v0/build.gradle deleted file mode 100644 index 757d36db..00000000 --- a/legacy-lifecycle-events-v0/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -archivesBaseName = 'legacy-lifecycle-events-v0' -version = getSubprojectVersion(project, '0.6.3') - -moduleDependencies(project, 'legacy-api-base') -dependencies { -} diff --git a/legacy-lifecycle-events-v1/build.gradle b/legacy-lifecycle-events-v1/build.gradle new file mode 100644 index 00000000..9ed221db --- /dev/null +++ b/legacy-lifecycle-events-v1/build.gradle @@ -0,0 +1,6 @@ +archivesBaseName = 'legacy-lifecycle-events-v1' +version = getSubprojectVersion(project, '1.0.0') + +moduleDependencies(project, 'legacy-api-base') +dependencies { +} diff --git a/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientLifecycleEvents.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientLifecycleEvents.java new file mode 100644 index 00000000..15c37d90 --- /dev/null +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientLifecycleEvents.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 The Cursed Legacy Team. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.github.minecraftcursedlegacy.api.event.lifecycle; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.client.Minecraft; + +/** + * Lifecycle events for the client. + * @since 1.1.0 + */ +@Environment(EnvType.CLIENT) +public class ClientLifecycleEvents { + /** + * Event for the start of the client tick. + */ + public static final Event START_TICK = EventFactory.createArrayBacked(Tick.class, + listeners -> client -> { + for (Tick listener : listeners) { + listener.onClientTick(client); + } + }); + + /** + * Event for the end of the client tick. + */ + public static final Event END_TICK = EventFactory.createArrayBacked(Tick.class, + listeners -> client -> { + for (Tick listener : listeners) { + listener.onClientTick(client); + } + }); + + @FunctionalInterface + public interface Tick { + /** + * Called when the client ticks. + * @param client the minecraft client instance. + */ + void onClientTick(Minecraft client); + } +} diff --git a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientTickCallback.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientTickCallback.java similarity index 82% rename from legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientTickCallback.java rename to legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientTickCallback.java index 72aa2266..1e3dd8c5 100644 --- a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientTickCallback.java +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ClientTickCallback.java @@ -24,20 +24,16 @@ package io.github.minecraftcursedlegacy.api.event.lifecycle; import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.client.Minecraft; /** * Callback for ticks on the client. + * @deprecated use {@linkplain ClientLifecycleEvents#END_TICK} instead. */ @FunctionalInterface -public interface ClientTickCallback { - Event EVENT = EventFactory.createArrayBacked(ClientTickCallback.class, - listeners -> client -> { - for (ClientTickCallback listener : listeners) { - listener.onClientTick(client); - } - }); +@Deprecated +public interface ClientTickCallback extends ClientLifecycleEvents.Tick { + Event EVENT = ClientLifecycleEvents.END_TICK; /** * Called when the client ticks. diff --git a/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/CommonLifecycleEvents.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/CommonLifecycleEvents.java new file mode 100644 index 00000000..55be7a72 --- /dev/null +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/CommonLifecycleEvents.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 The Cursed Legacy Team. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.github.minecraftcursedlegacy.api.event.lifecycle; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.entity.player.Player; + +/** + * Collection of common events that pertain to the game lifecycle. + * @since 1.1.0 + */ +public class CommonLifecycleEvents { + /** + * Event for the player respawning. + */ + public static final Event PLAYER_RESPAWN = EventFactory.createArrayBacked(PlayerRespawn.class, + listeners -> player -> { + for (PlayerRespawn listener : listeners) { + listener.onRespawn(player); + } + }); + + @FunctionalInterface + public interface PlayerRespawn { + /** + * Called after the player respawns. + * @param player the player that has respawned. + */ + void onRespawn(Player player); + } +} diff --git a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/DedicatedServerTickCallback.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/DedicatedServerTickCallback.java similarity index 81% rename from legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/DedicatedServerTickCallback.java rename to legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/DedicatedServerTickCallback.java index 3fd0833c..8d70a87a 100644 --- a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/DedicatedServerTickCallback.java +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/DedicatedServerTickCallback.java @@ -24,20 +24,16 @@ package io.github.minecraftcursedlegacy.api.event.lifecycle; import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.server.MinecraftServer; /** * Callback for ticks on the dedicated server. Does *not* run in singleplayer! + * @deprecated use {@linkplain ServerLifecycleEvents#END_TICK} instead. */ @FunctionalInterface -public interface DedicatedServerTickCallback { - Event EVENT = EventFactory.createArrayBacked(DedicatedServerTickCallback.class, - listeners -> server -> { - for (DedicatedServerTickCallback listener : listeners) { - listener.onServerTick(server); - } - }); +@Deprecated +public interface DedicatedServerTickCallback extends ServerLifecycleEvents.Tick { + Event EVENT = ServerLifecycleEvents.END_TICK; /** * Called when the dedicated server ticks. diff --git a/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ServerLifecycleEvents.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ServerLifecycleEvents.java new file mode 100644 index 00000000..4e5cd688 --- /dev/null +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/api/event/lifecycle/ServerLifecycleEvents.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020 The Cursed Legacy Team. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.github.minecraftcursedlegacy.api.event.lifecycle; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerLoginPacketHandler; +import net.minecraft.server.player.ServerPlayer; + +/** + * Lifecycle events for the server. + * @since 1.1.0 + * @apiNote Remember: None of these events run in singleplayer! + */ +@Environment(EnvType.SERVER) +public class ServerLifecycleEvents { + /** + * Event for the start of the dedicated server tick. + */ + public static final Event START_TICK = EventFactory.createArrayBacked(Tick.class, + listeners -> server -> { + for (Tick listener : listeners) { + listener.onServerTick(server); + } + }); + + /** + * Event for the end of the dedicated server tick. + */ + public static final Event END_TICK = EventFactory.createArrayBacked(Tick.class, + listeners -> server -> { + for (Tick listener : listeners) { + listener.onServerTick(server); + } + }); + + /** + * Event for a player logging in to the server. + */ + public static final Event PLAYER_LOGIN = EventFactory.createArrayBacked(PlayerLogin.class, + listeners -> (player, packetHandler) -> { + for (PlayerLogin listener : listeners) { + listener.onPlayerLogin(player, packetHandler); + + // In case a mod's listener has disconnected the player for some reason + // This is the equivalent of cancelling the login, but with vanilla functionality handling it. + if (packetHandler.closed) { + break; + } + } + }); + + /** + * Event for a player being disconnected / disconnecting from the server + */ + public static final Event PLAYER_DISCONNECT = EventFactory.createArrayBacked(PlayerDisconnect.class, + listeners -> player -> { + for (PlayerDisconnect listener : listeners) { + listener.onPlayerDisconnect(player); + } + }); + + @FunctionalInterface + public interface Tick { + /** + * Called when the dedicated server ticks. + * @param server the dedicated server instance. + */ + void onServerTick(MinecraftServer server); + } + + @FunctionalInterface + public interface PlayerLogin { + /** + * Called when a player successfully logs in to the server. + * @param player the player that has just logged in. + * @param packetHandler the login packetHandler. + * @apiNote {@linkplain ServerLoginPacketHandler#drop(String)} can be used to prevent the player connecting. + */ + void onPlayerLogin(ServerPlayer player, ServerLoginPacketHandler packetHandler); + } + + @FunctionalInterface + public interface PlayerDisconnect { + /** + * Called when a player disconnects from the server. + * @param player the player that has disconnected. + */ + void onPlayerDisconnect(ServerPlayer player); + } +} diff --git a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraft.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraft.java similarity index 68% rename from legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraft.java rename to legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraft.java index 9178be39..a062592e 100644 --- a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraft.java +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraft.java @@ -24,17 +24,33 @@ package io.github.minecraftcursedlegacy.mixin.event.lifecycle; 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 io.github.minecraftcursedlegacy.api.event.lifecycle.ClientTickCallback; +import io.github.minecraftcursedlegacy.api.event.lifecycle.ClientLifecycleEvents; +import io.github.minecraftcursedlegacy.api.event.lifecycle.CommonLifecycleEvents; import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.AbstractClientPlayer; @Mixin(Minecraft.class) public class MixinMinecraft { + @Shadow + private AbstractClientPlayer player; + + @Inject(at = @At("HEAD"), method = "tick") + private void onStartTick(CallbackInfo info) { + ClientLifecycleEvents.START_TICK.invoker().onClientTick((Minecraft) (Object) this); + } + @Inject(at = @At("RETURN"), method = "tick") - private void onTick(CallbackInfo info) { - ClientTickCallback.EVENT.invoker().onClientTick((Minecraft) (Object) this); + private void onEndTick(CallbackInfo info) { + ClientLifecycleEvents.END_TICK.invoker().onClientTick((Minecraft) (Object) this); + } + + @Inject(at = @At("RETURN"), method = "respawn") + private void onRespawn(boolean flag, int i, CallbackInfo info) { + CommonLifecycleEvents.PLAYER_RESPAWN.invoker().onRespawn(this.player); } } diff --git a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraftServer.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraftServer.java similarity index 79% rename from legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraftServer.java rename to legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraftServer.java index e915709f..8956e5f0 100644 --- a/legacy-lifecycle-events-v0/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraftServer.java +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinMinecraftServer.java @@ -28,14 +28,18 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import io.github.minecraftcursedlegacy.api.event.lifecycle.DedicatedServerTickCallback; +import io.github.minecraftcursedlegacy.api.event.lifecycle.ServerLifecycleEvents; import net.minecraft.server.MinecraftServer; @Mixin(MinecraftServer.class) public class MixinMinecraftServer { - // MinecraftServer#tick() + @Inject(at = @At("HEAD"), method = "tick") + private void onStartTick(CallbackInfo info) { + ServerLifecycleEvents.START_TICK.invoker().onServerTick((MinecraftServer) (Object) this); + } + @Inject(at = @At("RETURN"), method = "tick") - private void onTick(CallbackInfo info) { - DedicatedServerTickCallback.EVENT.invoker().onServerTick((MinecraftServer) (Object) this); + private void onEndTick(CallbackInfo info) { + ServerLifecycleEvents.END_TICK.invoker().onServerTick((MinecraftServer) (Object) this); } } diff --git a/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinPlayerManager.java b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinPlayerManager.java new file mode 100644 index 00000000..87ba5f4a --- /dev/null +++ b/legacy-lifecycle-events-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/event/lifecycle/MixinPlayerManager.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 The Cursed Legacy Team. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.github.minecraftcursedlegacy.mixin.event.lifecycle; + +import javax.annotation.Nullable; + +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.CallbackInfoReturnable; + +import io.github.minecraftcursedlegacy.api.event.lifecycle.CommonLifecycleEvents; +import io.github.minecraftcursedlegacy.api.event.lifecycle.ServerLifecycleEvents; +import net.minecraft.server.network.ServerLoginPacketHandler; +import net.minecraft.server.player.PlayerManager; +import net.minecraft.server.player.ServerPlayer; + +@Mixin(PlayerManager.class) +public class MixinPlayerManager { + @Inject(at = @At("RETURN"), method = "connectPlayer", cancellable = true) + private void onConnectPlayer(ServerLoginPacketHandler handler, String name, CallbackInfoReturnable info) { + @Nullable + ServerPlayer player = info.getReturnValue(); + + if (player != null) { + ServerLifecycleEvents.PLAYER_LOGIN.invoker().onPlayerLogin(player, handler); + + // If disconnected, the player has not joined due to a mod cancelling the join. + if (handler.closed) { + info.setReturnValue(null); + } + } + } + + @Inject(at = @At("RETURN"), method = "respawn") + private void onRespawn(ServerPlayer player, int dimensionId, CallbackInfoReturnable info) { + CommonLifecycleEvents.PLAYER_RESPAWN.invoker().onRespawn(info.getReturnValue()); + } + + @Inject(at = @At("RETURN"), method = "updateDimension") // this method is named incorrectly in the current mappings. Should be renamed by the next mapping update. + private void onDisconnect(ServerPlayer player, CallbackInfo info) { + ServerLifecycleEvents.PLAYER_DISCONNECT.invoker().onPlayerDisconnect(player); + } +} diff --git a/legacy-lifecycle-events-v0/src/main/resources/fabric.mod.json b/legacy-lifecycle-events-v1/src/main/resources/fabric.mod.json similarity index 100% rename from legacy-lifecycle-events-v0/src/main/resources/fabric.mod.json rename to legacy-lifecycle-events-v1/src/main/resources/fabric.mod.json diff --git a/legacy-lifecycle-events-v0/src/main/resources/legacy-lifecycle-events.mixins.json b/legacy-lifecycle-events-v1/src/main/resources/legacy-lifecycle-events.mixins.json similarity index 81% rename from legacy-lifecycle-events-v0/src/main/resources/legacy-lifecycle-events.mixins.json rename to legacy-lifecycle-events-v1/src/main/resources/legacy-lifecycle-events.mixins.json index 7ade8161..c432b4cd 100644 --- a/legacy-lifecycle-events-v0/src/main/resources/legacy-lifecycle-events.mixins.json +++ b/legacy-lifecycle-events-v1/src/main/resources/legacy-lifecycle-events.mixins.json @@ -6,7 +6,8 @@ "MixinMinecraft" ], "server": [ - "MixinMinecraftServer" + "MixinMinecraftServer", + "MixinPlayerManager" ], "injectors": { "defaultRequire": 1 diff --git a/legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTest.java b/legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTest.java new file mode 100644 index 00000000..39f023e1 --- /dev/null +++ b/legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 The Cursed Legacy Team. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.github.minecraftcursedlegacy.test; + +import io.github.minecraftcursedlegacy.api.event.lifecycle.CommonLifecycleEvents; +import net.fabricmc.api.ModInitializer; + +public class LifecycleEventsTest implements ModInitializer { + @Override + public void onInitialize() { + CommonLifecycleEvents.PLAYER_RESPAWN.register(player -> { + System.out.println("Player has respawned: " + player.name); + }); + } +} diff --git a/legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTestServer.java b/legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTestServer.java new file mode 100644 index 00000000..c23b9986 --- /dev/null +++ b/legacy-lifecycle-events-v1/src/test/java/io/github/minecraftcursedlegacy/test/LifecycleEventsTestServer.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 The Cursed Legacy Team. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package io.github.minecraftcursedlegacy.test; + +import io.github.minecraftcursedlegacy.api.event.lifecycle.ServerLifecycleEvents; +import net.fabricmc.api.DedicatedServerModInitializer; + +public class LifecycleEventsTestServer implements DedicatedServerModInitializer { + @Override + public void onInitializeServer() { + ServerLifecycleEvents.PLAYER_LOGIN.register((player, packetHandler) -> { + System.out.println("Player has joined: " + player.name); + //packetHandler.drop("U R Bad"); Uncomment this line to test login packet dropping + }); + + ServerLifecycleEvents.PLAYER_DISCONNECT.register(player -> { + System.out.println("Player has left the game: " + player.name); + }); + } +} diff --git a/legacy-lifecycle-events-v1/src/test/resources/fabric.mod.json b/legacy-lifecycle-events-v1/src/test/resources/fabric.mod.json new file mode 100644 index 00000000..6843ca63 --- /dev/null +++ b/legacy-lifecycle-events-v1/src/test/resources/fabric.mod.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "id": "legacy-lifecycle-events-test", + "version": "${version}", + + "name": "Lifecycle Events Test Mod", + "description": "Test mod for the lifecycle events api", + "authors": [ + "The Cursed Legacy Team" + ], + "contact": { + "issues": "https://github.com/minecraft-cursed-legacy/Cursed-Legacy-API/issues", + "sources": "https://github.com/minecraft-cursed-legacy/Cursed-Legacy-API" + }, + + "license": "MIT", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "init": [ + "io.github.minecraftcursedlegacy.test.LifecycleEventsTest" + ], + "server": [ + "io.github.minecraftcursedlegacy.test.LifecycleEventsTestServer" + ] + }, + + "depends": { + "fabricloader": "*", + "legacy-api-base": "*", + "legacy-lifecycle-events": "*", + "minecraft": "1.0.0-beta.7.3" + } +} diff --git a/legacy-textures-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/texture/MixinItemRenderer.java b/legacy-textures-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/texture/MixinItemRenderer.java index 8d5ee894..7e2d57ec 100644 --- a/legacy-textures-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/texture/MixinItemRenderer.java +++ b/legacy-textures-v1/src/main/java/io/github/minecraftcursedlegacy/mixin/texture/MixinItemRenderer.java @@ -38,7 +38,7 @@ @Mixin(ItemRenderer.class) abstract class MixinItemRenderer extends EntityRenderer { - @Inject(method = "render", + @Inject(method = "method_1484", at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/Tessellator;INSTANCE:Lnet/minecraft/client/render/Tessellator;", opcode = Opcodes.GETSTATIC) ) private void fixAtlas(ItemEntity entity, double x, double y, double z, float entityYaw, float partialTicks, CallbackInfo info) { diff --git a/legacy-textures-v1/src/test/java/io/github/minecraftcursedlegacy/test/TexturesTest.java b/legacy-textures-v1/src/test/java/io/github/minecraftcursedlegacy/test/TexturesTest.java index 94dffd26..3cccbbf6 100644 --- a/legacy-textures-v1/src/test/java/io/github/minecraftcursedlegacy/test/TexturesTest.java +++ b/legacy-textures-v1/src/test/java/io/github/minecraftcursedlegacy/test/TexturesTest.java @@ -61,7 +61,7 @@ public void onInitialize() { betterCross = Registries.TILE.register(new Id("legacy-textures-test:malachite_grass"), id -> new TallGrassTile(id).name("malachiteGrass")); TileItems.registerTileItem(new Id("legacy-textures-test:malachite_grass"), betterCross); - cube = Registries.TILE.register(new Id("legacy-textures-test:cursed_legacy_block"), id -> new BasicTile(id, false).name("cursedLegacyBlock")); + cube = Registries.TILE.register(new Id("legacy-textures-test:cursed_legacy_block"), id -> new BasicTile(id).name("cursedLegacyBlock")); TileItems.registerTileItem(new Id("legacy-textures-test:cursed_legacy_block"), cube); redgrass = Registries.TILE.register(new Id("legacy-textures-test:red_grass"), id -> new CustomGrassBlockTile(id).name("redGrass")); @@ -82,6 +82,12 @@ public void onInitialize() { Translations.addTileTranslation(redgrass, "Red Grass"); } + static class BasicItem extends ItemType { + BasicItem(int i) { + super(i); + } + } + static class TallGrassTile extends PlantTile { TallGrassTile(int id) { super(id, 69); @@ -110,4 +116,10 @@ static class CustomGrassBlockTile extends Tile { // I would extend GrassTile but this.sounds(GRASS_SOUNDS); } } + + class BasicTile extends Tile { + BasicTile(int i) { + super(i, 69, Material.DIRT); + } + } } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 9b981151..27357881 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,7 +18,7 @@ include 'legacy-attached-data-v1' include 'legacy-commands-v1' include 'legacy-config-v0' include 'legacy-interaction-events-v0' -include 'legacy-lifecycle-events-v0' +include 'legacy-lifecycle-events-v1' include 'legacy-networking-v0' include 'legacy-recipes-v0' include 'legacy-registries-v1'