diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerLoginNetworking.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerLoginNetworking.java index 2a4b37fde..e295113c0 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerLoginNetworking.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerLoginNetworking.java @@ -28,7 +28,6 @@ import net.minecraft.server.network.ServerLoginNetworkHandler; import net.minecraft.util.Identifier; import net.fabricmc.fabric.api.client.networking.v1.ClientLoginNetworking; -import net.fabricmc.fabric.impl.networking.server.ServerLoginNetworkHandlerExtensions; import net.fabricmc.fabric.impl.networking.server.ServerNetworkingImpl; import net.fabricmc.fabric.mixin.networking.accessor.ServerLoginNetworkHandlerAccessor; @@ -98,7 +97,7 @@ public final class ServerLoginNetworking { public static boolean registerReceiver(ServerLoginNetworkHandler networkHandler, Identifier channelName, LoginQueryResponseHandler responseHandler) { Objects.requireNonNull(networkHandler, "Network handler cannot be null"); - return ((ServerLoginNetworkHandlerExtensions) networkHandler).getAddon().registerChannel(channelName, responseHandler); + return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, responseHandler); } /** @@ -113,7 +112,7 @@ public final class ServerLoginNetworking { public static ServerLoginNetworking.LoginQueryResponseHandler unregisterReceiver(ServerLoginNetworkHandler networkHandler, Identifier channelName) { Objects.requireNonNull(networkHandler, "Network handler cannot be null"); - return ((ServerLoginNetworkHandlerExtensions) networkHandler).getAddon().unregisterChannel(channelName); + return ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(channelName); } // Helper methods diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java index f58967a49..eab7d1494 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java @@ -30,7 +30,6 @@ import net.minecraft.util.Identifier; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.impl.networking.server.ServerNetworkingImpl; -import net.fabricmc.fabric.impl.networking.server.ServerPlayNetworkHandlerExtensions; /** * Offers access to play stage server-side networking functionalities. @@ -106,7 +105,7 @@ public final class ServerPlayNetworking { public static boolean registerReceiver(ServerPlayNetworkHandler networkHandler, Identifier channelName, PlayChannelHandler channelHandler) { Objects.requireNonNull(networkHandler, "Network handler cannot be null"); - return ((ServerPlayNetworkHandlerExtensions) networkHandler).getAddon().registerChannel(channelName, channelHandler); + return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, channelHandler); } /** diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/AbstractNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/AbstractNetworkAddon.java index 956cf9c39..16ca10e75 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/AbstractNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/AbstractNetworkAddon.java @@ -21,6 +21,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -44,6 +45,7 @@ public abstract class AbstractNetworkAddon { // Sync map should be fine as there is little read write competition // All access to this map is guarded by the lock private final Map handlers = new HashMap<>(); + private final AtomicBoolean disconnected = new AtomicBoolean(); // blocks redundant disconnect notifications protected AbstractNetworkAddon(GlobalReceiverRegistry receiver, String description) { this.receiver = receiver; @@ -124,7 +126,13 @@ public abstract class AbstractNetworkAddon { protected abstract void handleUnregistration(Identifier channelName); - public abstract void invokeDisconnectEvent(); + public final void handleDisconnect() { + if (disconnected.compareAndSet(false, true)) { + invokeDisconnectEvent(); + } + } + + protected abstract void invokeDisconnectEvent(); /** * Checks if a channel is considered a "reserved" channel. diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkHandlerExtensions.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/NetworkHandlerExtensions.java similarity index 81% rename from fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkHandlerExtensions.java rename to fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/NetworkHandlerExtensions.java index b06729e47..99b1a2a04 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkHandlerExtensions.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/NetworkHandlerExtensions.java @@ -14,8 +14,8 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.networking.server; +package net.fabricmc.fabric.impl.networking; -public interface ServerPlayNetworkHandlerExtensions { - ServerPlayNetworkAddon getAddon(); +public interface NetworkHandlerExtensions { + AbstractNetworkAddon getAddon(); } diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientLoginNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientLoginNetworkAddon.java index e7a33b577..e847c7602 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientLoginNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientLoginNetworkAddon.java @@ -110,11 +110,15 @@ public final class ClientLoginNetworkAddon extends AbstractNetworkAddon createPlayC2SPacket(Identifier channelName, PacketByteBuf buf) { diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientPlayNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientPlayNetworkAddon.java index f7cbed9fc..57362960e 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientPlayNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientPlayNetworkAddon.java @@ -144,7 +144,7 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon< } @Override - public void invokeDisconnectEvent() { + protected void invokeDisconnectEvent() { ClientPlayConnectionEvents.DISCONNECT.invoker().onPlayDisconnect(this.handler, this.client); this.receiver.endSession(this); } diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientPlayNetworkHandlerExtensions.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientPlayNetworkHandlerExtensions.java deleted file mode 100644 index 75698d33c..000000000 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/client/ClientPlayNetworkHandlerExtensions.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.impl.networking.client; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Environment(EnvType.CLIENT) -public interface ClientPlayNetworkHandlerExtensions { - ClientPlayNetworkAddon getAddon(); -} diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerLoginNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerLoginNetworkAddon.java index 778f878af..e7ec7cf01 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerLoginNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerLoginNetworkAddon.java @@ -39,9 +39,9 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerLoginNetworkHandler; import net.minecraft.util.Identifier; +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.PacketSender; import net.fabricmc.fabric.api.networking.v1.ServerLoginConnectionEvents; -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.ServerLoginNetworking; import net.fabricmc.fabric.impl.networking.AbstractNetworkAddon; import net.fabricmc.fabric.mixin.networking.accessor.LoginQueryResponseC2SPacketAccessor; @@ -193,11 +193,15 @@ public final class ServerLoginNetworkAddon extends AbstractNetworkAddon LOGIN = new GlobalReceiverRegistry<>(); public static final GlobalReceiverRegistry PLAY = new GlobalReceiverRegistry<>(); public static ServerPlayNetworkAddon getAddon(ServerPlayNetworkHandler handler) { - return ((ServerPlayNetworkHandlerExtensions) handler).getAddon(); + return (ServerPlayNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon(); + } + + public static ServerLoginNetworkAddon getAddon(ServerLoginNetworkHandler handler) { + return (ServerLoginNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon(); } public static Packet createPlayC2SPacket(Identifier channel, PacketByteBuf buf) { diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java index 333226772..43cb0738b 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java @@ -136,7 +136,7 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon< } @Override - public void invokeDisconnectEvent() { + protected void invokeDisconnectEvent() { ServerPlayConnectionEvents.DISCONNECT.invoker().onPlayDisconnect(this.handler, this.server); this.receiver.endSession(this); } diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ClientConnectionMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ClientConnectionMixin.java index 049adb70d..ee72347f8 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ClientConnectionMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ClientConnectionMixin.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.Collections; import java.util.concurrent.ConcurrentHashMap; +import io.netty.channel.ChannelHandlerContext; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import org.spongepowered.asm.mixin.Mixin; @@ -40,6 +41,7 @@ import net.minecraft.util.Identifier; import net.fabricmc.fabric.impl.networking.ChannelInfoHolder; import net.fabricmc.fabric.impl.networking.DisconnectPacketSource; +import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions; import net.fabricmc.fabric.impl.networking.PacketCallbackListener; @Mixin(ClientConnection.class) @@ -81,6 +83,11 @@ abstract class ClientConnectionMixin implements ChannelInfoHolder { } } + @Inject(method = "channelInactive", at = @At("HEAD")) + private void handleDisconnect(ChannelHandlerContext channelHandlerContext, CallbackInfo ci) throws Exception { + ((NetworkHandlerExtensions) packetListener).getAddon().handleDisconnect(); + } + @Override public Collection getPendingChannelsNames() { return this.playChannels; diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerLoginNetworkHandlerMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerLoginNetworkHandlerMixin.java index 03b7f59ea..fa506ebef 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerLoginNetworkHandlerMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerLoginNetworkHandlerMixin.java @@ -31,15 +31,16 @@ import net.minecraft.network.packet.s2c.login.LoginDisconnectS2CPacket; import net.minecraft.network.packet.s2c.login.LoginQueryRequestS2CPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerLoginNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.fabricmc.fabric.impl.networking.DisconnectPacketSource; +import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions; import net.fabricmc.fabric.impl.networking.PacketCallbackListener; import net.fabricmc.fabric.impl.networking.server.ServerLoginNetworkAddon; -import net.fabricmc.fabric.impl.networking.server.ServerLoginNetworkHandlerExtensions; @Mixin(ServerLoginNetworkHandler.class) -abstract class ServerLoginNetworkHandlerMixin implements ServerLoginNetworkHandlerExtensions, DisconnectPacketSource, PacketCallbackListener { +abstract class ServerLoginNetworkHandlerMixin implements NetworkHandlerExtensions, DisconnectPacketSource, PacketCallbackListener { @Shadow @Final private MinecraftServer server; @@ -78,7 +79,12 @@ abstract class ServerLoginNetworkHandlerMixin implements ServerLoginNetworkHandl @Inject(method = "onDisconnected", at = @At("HEAD")) private void handleDisconnection(Text reason, CallbackInfo ci) { - this.addon.invokeDisconnectEvent(); + this.addon.handleDisconnect(); + } + + @Inject(method = "addToServer", at = @At("HEAD")) + private void handlePlayTransitionNormal(ServerPlayerEntity player, CallbackInfo ci) { + this.addon.handlePlayTransition(); } @Override diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java index 0dcce2a67..82490eb6b 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java @@ -33,12 +33,12 @@ import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.text.Text; import net.fabricmc.fabric.impl.networking.DisconnectPacketSource; +import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions; import net.fabricmc.fabric.impl.networking.server.ServerPlayNetworkAddon; -import net.fabricmc.fabric.impl.networking.server.ServerPlayNetworkHandlerExtensions; // We want to apply a bit earlier than other mods which may not use us in order to prevent refCount issues @Mixin(value = ServerPlayNetworkHandler.class, priority = 999) -abstract class ServerPlayNetworkHandlerMixin implements ServerPlayNetworkHandlerExtensions, DisconnectPacketSource { +abstract class ServerPlayNetworkHandlerMixin implements NetworkHandlerExtensions, DisconnectPacketSource { @Shadow @Final private MinecraftServer server; @@ -65,7 +65,7 @@ abstract class ServerPlayNetworkHandlerMixin implements ServerPlayNetworkHandler @Inject(method = "onDisconnected", at = @At("HEAD")) private void handleDisconnection(Text reason, CallbackInfo ci) { - this.addon.invokeDisconnectEvent(); + this.addon.handleDisconnect(); } @Override diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientLoginNetworkHandlerMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientLoginNetworkHandlerMixin.java index 56f09539b..62b9dc5cd 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientLoginNetworkHandlerMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientLoginNetworkHandlerMixin.java @@ -31,12 +31,12 @@ import net.minecraft.text.Text; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions; import net.fabricmc.fabric.impl.networking.client.ClientLoginNetworkAddon; -import net.fabricmc.fabric.impl.networking.client.ClientLoginNetworkHandlerExtensions; @Environment(EnvType.CLIENT) @Mixin(ClientLoginNetworkHandler.class) -abstract class ClientLoginNetworkHandlerMixin implements ClientLoginNetworkHandlerExtensions { +abstract class ClientLoginNetworkHandlerMixin implements NetworkHandlerExtensions { @Shadow @Final private MinecraftClient client; @@ -58,7 +58,12 @@ abstract class ClientLoginNetworkHandlerMixin implements ClientLoginNetworkHandl @Inject(method = "onDisconnected", at = @At("HEAD")) private void invokeLoginDisconnectEvent(Text reason, CallbackInfo ci) { - this.addon.invokeDisconnectEvent(); + this.addon.handleDisconnect(); + } + + @Inject(method = "onLoginSuccess", at = @At("HEAD")) + private void handlePlayTransition(CallbackInfo ci) { + addon.handlePlayTransition(); } @Override diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java index 655145457..6e42328b8 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java @@ -31,14 +31,14 @@ import net.minecraft.text.Text; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions; import net.fabricmc.fabric.impl.networking.client.ClientNetworkingImpl; import net.fabricmc.fabric.impl.networking.client.ClientPlayNetworkAddon; -import net.fabricmc.fabric.impl.networking.client.ClientPlayNetworkHandlerExtensions; // We want to apply a bit earlier than other mods which may not use us in order to prevent refCount issues @Environment(EnvType.CLIENT) @Mixin(value = ClientPlayNetworkHandler.class, priority = 999) -abstract class ClientPlayNetworkHandlerMixin implements ClientPlayNetworkHandlerExtensions { +abstract class ClientPlayNetworkHandlerMixin implements NetworkHandlerExtensions { @Shadow private MinecraftClient client; @@ -67,7 +67,7 @@ abstract class ClientPlayNetworkHandlerMixin implements ClientPlayNetworkHandler @Inject(method = "onDisconnected", at = @At("HEAD")) private void handleDisconnection(Text reason, CallbackInfo ci) { - this.addon.invokeDisconnectEvent(); + this.addon.handleDisconnect(); } @Override