mirror of
https://github.com/FabricMC/fabric.git
synced 2025-09-06 19:36:26 +00:00
[1.20.5] Misc networking cleanup (#3594)
* Misc networking cleanup * Dont invoke event twice * Review tweaks
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 java.util.Collections;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientCommonNetworkHandler;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.AbstractChanneledNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.GlobalReceiverRegistry;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.RegistrationPayload;
|
||||
|
||||
abstract class ClientCommonNetworkAddon<H, T extends ClientCommonNetworkHandler> extends AbstractChanneledNetworkAddon<H> {
|
||||
protected final T handler;
|
||||
protected final MinecraftClient client;
|
||||
|
||||
protected boolean isServerReady = false;
|
||||
|
||||
protected ClientCommonNetworkAddon(GlobalReceiverRegistry<H> receiver, ClientConnection connection, String description, T handler, MinecraftClient client) {
|
||||
super(receiver, connection, description);
|
||||
this.handler = handler;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void onServerReady() {
|
||||
this.isServerReady = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleRegistration(Identifier channelName) {
|
||||
// If we can already send packets, immediately send the register packet for this channel
|
||||
if (this.isServerReady) {
|
||||
final RegistrationPayload payload = this.createRegistrationPayload(RegistrationPayload.REGISTER, Collections.singleton(channelName));
|
||||
|
||||
if (payload != null) {
|
||||
this.sendPacket(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleUnregistration(Identifier channelName) {
|
||||
// If we can already send packets, immediately send the unregister packet for this channel
|
||||
if (this.isServerReady) {
|
||||
final RegistrationPayload payload = this.createRegistrationPayload(RegistrationPayload.UNREGISTER, Collections.singleton(channelName));
|
||||
|
||||
if (payload != null) {
|
||||
this.sendPacket(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReservedChannel(Identifier channelName) {
|
||||
return NetworkingImpl.isReservedCommonChannel(channelName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void schedule(Runnable task) {
|
||||
client.execute(task);
|
||||
}
|
||||
}
|
@@ -16,7 +16,6 @@
|
||||
|
||||
package net.fabricmc.fabric.impl.networking.client;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -31,23 +30,17 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationConnectio
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationNetworking;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.impl.networking.AbstractChanneledNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.ChannelInfoHolder;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.RegistrationPayload;
|
||||
import net.fabricmc.fabric.mixin.networking.client.accessor.ClientCommonNetworkHandlerAccessor;
|
||||
import net.fabricmc.fabric.mixin.networking.client.accessor.ClientConfigurationNetworkHandlerAccessor;
|
||||
|
||||
public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetworkAddon<ClientConfigurationNetworking.ConfigurationPayloadHandler<?>> {
|
||||
private final ClientConfigurationNetworkHandler handler;
|
||||
private final MinecraftClient client;
|
||||
public final class ClientConfigurationNetworkAddon extends ClientCommonNetworkAddon<ClientConfigurationNetworking.ConfigurationPayloadHandler<?>, ClientConfigurationNetworkHandler> {
|
||||
private final ContextImpl context;
|
||||
private boolean sentInitialRegisterPacket;
|
||||
|
||||
public ClientConfigurationNetworkAddon(ClientConfigurationNetworkHandler handler, MinecraftClient client) {
|
||||
super(ClientNetworkingImpl.CONFIGURATION, ((ClientCommonNetworkHandlerAccessor) handler).getConnection(), "ClientPlayNetworkAddon for " + ((ClientConfigurationNetworkHandlerAccessor) handler).getProfile().getName());
|
||||
this.handler = handler;
|
||||
this.client = client;
|
||||
super(ClientNetworkingImpl.CONFIGURATION, ((ClientCommonNetworkHandlerAccessor) handler).getConnection(), "ClientPlayNetworkAddon for " + ((ClientConfigurationNetworkHandlerAccessor) handler).getProfile().getName(), handler, client);
|
||||
this.context = new ContextImpl(this);
|
||||
|
||||
// Must register pending channels via lateinit
|
||||
@@ -59,10 +52,6 @@ public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetw
|
||||
ClientConfigurationConnectionEvents.INIT.invoker().onConfigurationInit(this.handler, this.client);
|
||||
}
|
||||
|
||||
public void onServerReady() {
|
||||
// Do nothing for now
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receiveRegistration(boolean register, RegistrationPayload payload) {
|
||||
super.receiveRegistration(register, payload);
|
||||
@@ -79,12 +68,6 @@ public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetw
|
||||
}
|
||||
|
||||
// impl details
|
||||
|
||||
@Override
|
||||
protected void schedule(Runnable task) {
|
||||
MinecraftClient.getInstance().execute(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> createPacket(CustomPayload packet) {
|
||||
return ClientPlayNetworking.createC2SPacket(packet);
|
||||
@@ -100,30 +83,6 @@ public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetw
|
||||
C2SConfigurationChannelEvents.UNREGISTER.invoker().onChannelUnregister(this.handler, this, this.client, ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleRegistration(Identifier channelName) {
|
||||
// If we can already send packets, immediately send the register packet for this channel
|
||||
if (this.sentInitialRegisterPacket) {
|
||||
final RegistrationPayload payload = this.createRegistrationPayload(RegistrationPayload.REGISTER, Collections.singleton(channelName));
|
||||
|
||||
if (payload != null) {
|
||||
this.sendPacket(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleUnregistration(Identifier channelName) {
|
||||
// If we can already send packets, immediately send the unregister packet for this channel
|
||||
if (this.sentInitialRegisterPacket) {
|
||||
final RegistrationPayload payload = this.createRegistrationPayload(RegistrationPayload.UNREGISTER, Collections.singleton(channelName));
|
||||
|
||||
if (payload != null) {
|
||||
this.sendPacket(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleReady() {
|
||||
ClientConfigurationConnectionEvents.READY.invoker().onConfigurationReady(this.handler, this.client);
|
||||
ClientNetworkingImpl.setClientConfigurationAddon(null);
|
||||
@@ -134,11 +93,6 @@ public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetw
|
||||
ClientConfigurationConnectionEvents.DISCONNECT.invoker().onConfigurationDisconnect(this.handler, this.client);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReservedChannel(Identifier channelName) {
|
||||
return NetworkingImpl.isReservedCommonChannel(channelName);
|
||||
}
|
||||
|
||||
public ChannelInfoHolder getChannelInfoHolder() {
|
||||
return (ChannelInfoHolder) ((ClientCommonNetworkHandlerAccessor) handler).getConnection();
|
||||
}
|
||||
|
@@ -16,7 +16,6 @@
|
||||
|
||||
package net.fabricmc.fabric.impl.networking.client;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
@@ -34,23 +33,15 @@ import net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.impl.networking.AbstractChanneledNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.ChannelInfoHolder;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.RegistrationPayload;
|
||||
|
||||
public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<ClientPlayNetworking.PlayPayloadHandler<?>> {
|
||||
private final ClientPlayNetworkHandler handler;
|
||||
private final MinecraftClient client;
|
||||
private final ClientPlayNetworking.Context context;
|
||||
private boolean sentInitialRegisterPacket;
|
||||
public final class ClientPlayNetworkAddon extends ClientCommonNetworkAddon<ClientPlayNetworking.PlayPayloadHandler<?>, ClientPlayNetworkHandler> {
|
||||
private final ContextImpl context;
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public ClientPlayNetworkAddon(ClientPlayNetworkHandler handler, MinecraftClient client) {
|
||||
super(ClientNetworkingImpl.PLAY, handler.getConnection(), "ClientPlayNetworkAddon for " + handler.getProfile().getName());
|
||||
this.handler = handler;
|
||||
this.client = client;
|
||||
super(ClientNetworkingImpl.PLAY, handler.getConnection(), "ClientPlayNetworkAddon for " + handler.getProfile().getName(), handler, client);
|
||||
this.context = new ContextImpl(client, client.player, this);
|
||||
|
||||
// Must register pending channels via lateinit
|
||||
@@ -62,6 +53,7 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
||||
ClientPlayConnectionEvents.INIT.invoker().onPlayInit(this.handler, this.client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerReady() {
|
||||
try {
|
||||
ClientPlayConnectionEvents.JOIN.invoker().onPlayReady(this.handler, this, this.client);
|
||||
@@ -71,7 +63,7 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
||||
|
||||
// The client cannot send any packets, including `minecraft:register` until after GameJoinS2CPacket is received.
|
||||
this.sendInitialChannelRegistrationPacket();
|
||||
this.sentInitialRegisterPacket = true;
|
||||
super.onServerReady();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,12 +74,6 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
||||
}
|
||||
|
||||
// impl details
|
||||
|
||||
@Override
|
||||
protected void schedule(Runnable task) {
|
||||
MinecraftClient.getInstance().execute(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> createPacket(CustomPayload packet) {
|
||||
return ClientPlayNetworking.createC2SPacket(packet);
|
||||
@@ -103,40 +89,11 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
||||
C2SPlayChannelEvents.UNREGISTER.invoker().onChannelUnregister(this.handler, this, this.client, ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleRegistration(Identifier channelName) {
|
||||
// If we can already send packets, immediately send the register packet for this channel
|
||||
if (this.sentInitialRegisterPacket) {
|
||||
final RegistrationPayload payload = this.createRegistrationPayload(RegistrationPayload.REGISTER, Collections.singleton(channelName));
|
||||
|
||||
if (payload != null) {
|
||||
this.sendPacket(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleUnregistration(Identifier channelName) {
|
||||
// If we can already send packets, immediately send the unregister packet for this channel
|
||||
if (this.sentInitialRegisterPacket) {
|
||||
final RegistrationPayload payload = this.createRegistrationPayload(RegistrationPayload.UNREGISTER, Collections.singleton(channelName));
|
||||
|
||||
if (payload != null) {
|
||||
this.sendPacket(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invokeDisconnectEvent() {
|
||||
ClientPlayConnectionEvents.DISCONNECT.invoker().onPlayDisconnect(this.handler, this.client);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReservedChannel(Identifier channelName) {
|
||||
return NetworkingImpl.isReservedCommonChannel(channelName);
|
||||
}
|
||||
|
||||
private record ContextImpl(MinecraftClient client, ClientPlayerEntity player, PacketSender responseSender) implements ClientPlayNetworking.Context {
|
||||
}
|
||||
}
|
||||
|
@@ -42,6 +42,11 @@ import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
* @param <H> the channel handler type
|
||||
*/
|
||||
public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAddon<H> implements PacketSender, CommonPacketHandler {
|
||||
// The maximum number of channels that a connecting client can register.
|
||||
private static final int MAX_CHANNELS = Integer.getInteger("fabric.networking.maxChannels", 8192);
|
||||
// The maximum length of a channel name a connecting client can use, 128 is the default and minimum value.
|
||||
private static final int MAX_CHANNEL_NAME_LENGTH = Math.max(Integer.getInteger("fabric.networking.maxChannelNameLength", GlobalReceiverRegistry.DEFAULT_CHANNEL_NAME_MAX_LENGTH), GlobalReceiverRegistry.DEFAULT_CHANNEL_NAME_MAX_LENGTH);
|
||||
|
||||
protected final ClientConnection connection;
|
||||
protected final GlobalReceiverRegistry<H> receiver;
|
||||
protected final Set<Identifier> sendableChannels;
|
||||
@@ -127,10 +132,22 @@ public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAd
|
||||
}
|
||||
|
||||
void register(List<Identifier> ids) {
|
||||
this.sendableChannels.addAll(ids);
|
||||
ids.forEach(this::registerChannel);
|
||||
schedule(() -> this.invokeRegisterEvent(ids));
|
||||
}
|
||||
|
||||
private void registerChannel(Identifier id) {
|
||||
if (this.sendableChannels.size() >= MAX_CHANNELS) {
|
||||
throw new IllegalArgumentException("Cannot register more than " + MAX_CHANNELS + " channels");
|
||||
}
|
||||
|
||||
if (id.toString().length() > MAX_CHANNEL_NAME_LENGTH) {
|
||||
throw new IllegalArgumentException("Channel name is too long");
|
||||
}
|
||||
|
||||
this.sendableChannels.add(id);
|
||||
}
|
||||
|
||||
void unregister(List<Identifier> ids) {
|
||||
this.sendableChannels.removeAll(ids);
|
||||
schedule(() -> this.invokeUnregisterEvent(ids));
|
||||
|
@@ -34,6 +34,7 @@ import net.minecraft.network.NetworkSide;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public final class GlobalReceiverRegistry<H> {
|
||||
public static final int DEFAULT_CHANNEL_NAME_MAX_LENGTH = 128;
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalReceiverRegistry.class);
|
||||
|
||||
private final NetworkSide side;
|
||||
@@ -216,6 +217,10 @@ public final class GlobalReceiverRegistry<H> {
|
||||
if (payloadTypeRegistry.get(channelName) == null) {
|
||||
throw new IllegalArgumentException(String.format("Cannot register handler as no payload type has been registered with name \"%s\" for %s %s", channelName, side, phase));
|
||||
}
|
||||
|
||||
if (channelName.toString().length() > DEFAULT_CHANNEL_NAME_MAX_LENGTH) {
|
||||
throw new IllegalArgumentException(String.format("Cannot register handler for channel with name \"%s\" as it exceeds the maximum length of 128 characters", channelName));
|
||||
}
|
||||
}
|
||||
|
||||
public NetworkPhase getPhase() {
|
||||
|
@@ -32,7 +32,6 @@ import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.api.networking.v1.S2CConfigurationChannelEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.fabricmc.fabric.impl.networking.AbstractChanneledNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.ChannelInfoHolder;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkingImpl;
|
||||
@@ -117,7 +116,7 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw
|
||||
|
||||
@Override
|
||||
public Packet<?> createPacket(CustomPayload packet) {
|
||||
return ServerPlayNetworking.createS2CPacket(packet);
|
||||
return ServerConfigurationNetworking.createS2CPacket(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user