mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-22 15:47:57 -05:00
Fix network api accumulating connection handlers and not firing
some disconnect events
This commit is contained in:
parent
8d89ed54f2
commit
f86e309fe5
18 changed files with 68 additions and 100 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<H> {
|
|||
// 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<Identifier, H> handlers = new HashMap<>();
|
||||
private final AtomicBoolean disconnected = new AtomicBoolean(); // blocks redundant disconnect notifications
|
||||
|
||||
protected AbstractNetworkAddon(GlobalReceiverRegistry<H> receiver, String description) {
|
||||
this.receiver = receiver;
|
||||
|
@ -124,7 +126,13 @@ public abstract class AbstractNetworkAddon<H> {
|
|||
|
||||
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.
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -110,11 +110,15 @@ public final class ClientLoginNetworkAddon extends AbstractNetworkAddon<ClientLo
|
|||
}
|
||||
|
||||
@Override
|
||||
public void invokeDisconnectEvent() {
|
||||
protected void invokeDisconnectEvent() {
|
||||
ClientLoginConnectionEvents.DISCONNECT.invoker().onLoginDisconnect(this.handler, this.client);
|
||||
this.receiver.endSession(this);
|
||||
}
|
||||
|
||||
public void handlePlayTransition() {
|
||||
this.receiver.endSession(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReservedChannel(Identifier channelName) {
|
||||
return false;
|
||||
|
|
|
@ -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 ClientLoginNetworkHandlerExtensions {
|
||||
ClientLoginNetworkAddon getAddon();
|
||||
}
|
|
@ -41,6 +41,7 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
|||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.impl.networking.ChannelInfoHolder;
|
||||
import net.fabricmc.fabric.impl.networking.GlobalReceiverRegistry;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkingImpl;
|
||||
import net.fabricmc.fabric.mixin.networking.accessor.ConnectScreenAccessor;
|
||||
import net.fabricmc.fabric.mixin.networking.accessor.MinecraftClientAccessor;
|
||||
|
@ -52,11 +53,11 @@ public final class ClientNetworkingImpl {
|
|||
private static ClientPlayNetworkAddon currentPlayAddon;
|
||||
|
||||
public static ClientPlayNetworkAddon getAddon(ClientPlayNetworkHandler handler) {
|
||||
return ((ClientPlayNetworkHandlerExtensions) handler).getAddon();
|
||||
return (ClientPlayNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon();
|
||||
}
|
||||
|
||||
public static ClientLoginNetworkAddon getAddon(ClientLoginNetworkHandler handler) {
|
||||
return ((ClientLoginNetworkHandlerExtensions) handler).getAddon();
|
||||
return (ClientLoginNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon();
|
||||
}
|
||||
|
||||
public static Packet<?> createPlayC2SPacket(Identifier channelName, PacketByteBuf buf) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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<ServerLo
|
|||
}
|
||||
|
||||
@Override
|
||||
public void invokeDisconnectEvent() {
|
||||
protected void invokeDisconnectEvent() {
|
||||
ServerLoginConnectionEvents.DISCONNECT.invoker().onLoginDisconnect(this.handler, this.server);
|
||||
this.receiver.endSession(this);
|
||||
}
|
||||
|
||||
public void handlePlayTransition() {
|
||||
this.receiver.endSession(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReservedChannel(Identifier channelName) {
|
||||
return false;
|
||||
|
|
|
@ -1,21 +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.server;
|
||||
|
||||
public interface ServerLoginNetworkHandlerExtensions {
|
||||
ServerLoginNetworkAddon getAddon();
|
||||
}
|
|
@ -19,19 +19,25 @@ package net.fabricmc.fabric.impl.networking.server;
|
|||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
||||
import net.minecraft.server.network.ServerLoginNetworkHandler;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerLoginNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.fabricmc.fabric.impl.networking.GlobalReceiverRegistry;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions;
|
||||
|
||||
public final class ServerNetworkingImpl {
|
||||
public static final GlobalReceiverRegistry<ServerLoginNetworking.LoginQueryResponseHandler> LOGIN = new GlobalReceiverRegistry<>();
|
||||
public static final GlobalReceiverRegistry<ServerPlayNetworking.PlayChannelHandler> 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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<Identifier> getPendingChannelsNames() {
|
||||
return this.playChannels;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue