mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
Avoid serializing object-based payload into PacketByteBuf
on the main thread (#3407)
* channeled network addon refactor
* checkstyle
* fix junit tests
* convert TypedPayload <-> UntypedPayload if necessary
* assert payload size
* add vm arg to force serialization
* change log level to info and make it single line
(cherry picked from commit 6225d43a70
)
This commit is contained in:
parent
aaf9c9690c
commit
bd733d6b9f
23 changed files with 565 additions and 362 deletions
|
@ -32,9 +32,11 @@ import net.minecraft.util.thread.ThreadExecutor;
|
|||
import net.fabricmc.fabric.api.networking.v1.FabricPacket;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketType;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientConfigurationNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientNetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.TypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
import net.fabricmc.fabric.mixin.networking.client.accessor.ClientCommonNetworkHandlerAccessor;
|
||||
|
||||
/**
|
||||
|
@ -71,7 +73,7 @@ public final class ClientConfigurationNetworking {
|
|||
* @see ClientConfigurationNetworking#registerReceiver(Identifier, ConfigurationChannelHandler)
|
||||
*/
|
||||
public static boolean registerGlobalReceiver(Identifier channelName, ConfigurationChannelHandler channelHandler) {
|
||||
return ClientNetworkingImpl.CONFIGURATION.registerGlobalReceiver(channelName, channelHandler);
|
||||
return ClientNetworkingImpl.CONFIGURATION.registerGlobalReceiver(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,29 +90,7 @@ public final class ClientConfigurationNetworking {
|
|||
* @see ClientConfigurationNetworking#registerReceiver(PacketType, ConfigurationPacketHandler)
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerGlobalReceiver(PacketType<T> type, ConfigurationPacketHandler<T> handler) {
|
||||
return registerGlobalReceiver(type.getId(), new ConfigurationChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public ConfigurationPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftClient client, ClientConfigurationNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
|
||||
if (client.isOnThread()) {
|
||||
// Do not submit to the render thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
handler.receive(packet, sender);
|
||||
} else {
|
||||
client.execute(() -> {
|
||||
if (((ClientCommonNetworkHandlerAccessor) networkHandler).getConnection().isOpen()) handler.receive(packet, sender);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return ClientNetworkingImpl.CONFIGURATION.registerGlobalReceiver(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +106,7 @@ public final class ClientConfigurationNetworking {
|
|||
*/
|
||||
@Nullable
|
||||
public static ClientConfigurationNetworking.ConfigurationChannelHandler unregisterGlobalReceiver(Identifier channelName) {
|
||||
return ClientNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(channelName);
|
||||
return unwrapUntyped(ClientNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(channelName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,10 +122,8 @@ public final class ClientConfigurationNetworking {
|
|||
* @see ClientConfigurationNetworking#unregisterReceiver(PacketType)
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> ClientConfigurationNetworking.ConfigurationPacketHandler<T> unregisterGlobalReceiver(PacketType<T> type) {
|
||||
ConfigurationChannelHandler handler = ClientNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(type.getId());
|
||||
return handler instanceof ConfigurationChannelHandlerProxy<?> proxy ? (ConfigurationPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
return unwrapTyped(ClientNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(type.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,7 +157,7 @@ public final class ClientConfigurationNetworking {
|
|||
final ClientConfigurationNetworkAddon addon = ClientNetworkingImpl.getClientConfigurationAddon();
|
||||
|
||||
if (addon != null) {
|
||||
return addon.registerChannel(channelName, channelHandler);
|
||||
return addon.registerChannel(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Cannot register receiver while not configuring!");
|
||||
|
@ -201,29 +179,13 @@ public final class ClientConfigurationNetworking {
|
|||
* @see ClientPlayConnectionEvents#INIT
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerReceiver(PacketType<T> type, ConfigurationPacketHandler<T> handler) {
|
||||
return registerReceiver(type.getId(), new ConfigurationChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public ConfigurationPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
final ClientConfigurationNetworkAddon addon = ClientNetworkingImpl.getClientConfigurationAddon();
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftClient client, ClientConfigurationNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
if (addon != null) {
|
||||
return addon.registerChannel(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
if (client.isOnThread()) {
|
||||
// Do not submit to the render thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
handler.receive(packet, sender);
|
||||
} else {
|
||||
client.execute(() -> {
|
||||
if (((ClientCommonNetworkHandlerAccessor) networkHandler).getConnection().isOpen()) handler.receive(packet, sender);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
throw new IllegalStateException("Cannot register receiver while not configuring!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,7 +202,7 @@ public final class ClientConfigurationNetworking {
|
|||
final ClientConfigurationNetworkAddon addon = ClientNetworkingImpl.getClientConfigurationAddon();
|
||||
|
||||
if (addon != null) {
|
||||
return addon.unregisterChannel(channelName);
|
||||
return unwrapUntyped(addon.unregisterChannel(channelName));
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Cannot unregister receiver while not configuring!");
|
||||
|
@ -257,10 +219,14 @@ public final class ClientConfigurationNetworking {
|
|||
* @throws IllegalStateException if the client is not connected to a server
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> ClientConfigurationNetworking.ConfigurationPacketHandler<T> unregisterReceiver(PacketType<T> type) {
|
||||
ConfigurationChannelHandler handler = unregisterReceiver(type.getId());
|
||||
return handler instanceof ConfigurationChannelHandlerProxy<?> proxy ? (ConfigurationPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
final ClientConfigurationNetworkAddon addon = ClientNetworkingImpl.getClientConfigurationAddon();
|
||||
|
||||
if (addon != null) {
|
||||
return unwrapTyped(addon.unregisterChannel(type.getId()));
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Cannot unregister receiver while not configuring!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -394,6 +360,48 @@ public final class ClientConfigurationNetworking {
|
|||
private ClientConfigurationNetworking() {
|
||||
}
|
||||
|
||||
private static ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> wrapUntyped(ConfigurationChannelHandler actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(null, actualHandler, (client, handler, payload, responseSender) -> {
|
||||
actualHandler.receive(client, handler, ((UntypedPayload) payload).buffer(), responseSender);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends FabricPacket> ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> wrapTyped(PacketType<T> type, ConfigurationPacketHandler<T> actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(type, actualHandler, (client, handler, payload, responseSender) -> {
|
||||
T packet = (T) ((TypedPayload) payload).packet();
|
||||
|
||||
if (client.isOnThread()) {
|
||||
// Do not submit to the render thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
actualHandler.receive(packet, responseSender);
|
||||
} else {
|
||||
client.execute(() -> {
|
||||
if (((ClientCommonNetworkHandlerAccessor) handler).getConnection().isOpen()) {
|
||||
actualHandler.receive(packet, responseSender);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ConfigurationChannelHandler unwrapUntyped(@Nullable ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof ConfigurationChannelHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static <T extends FabricPacket> ConfigurationPacketHandler<T> unwrapTyped(@Nullable ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof ConfigurationPacketHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ConfigurationChannelHandler {
|
||||
/**
|
||||
|
@ -421,14 +429,6 @@ public final class ClientConfigurationNetworking {
|
|||
void receive(MinecraftClient client, ClientConfigurationNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal packet handler that works as a proxy between old and new API.
|
||||
* @param <T> the type of the packet
|
||||
*/
|
||||
private interface ConfigurationChannelHandlerProxy<T extends FabricPacket> extends ConfigurationChannelHandler {
|
||||
ConfigurationPacketHandler<T> getOriginalHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* A thread-safe packet handler utilizing {@link FabricPacket}.
|
||||
* @param <T> the type of the packet
|
||||
|
|
|
@ -36,6 +36,9 @@ import net.fabricmc.fabric.api.networking.v1.PacketType;
|
|||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientNetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientPlayNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.TypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
|
||||
/**
|
||||
* Offers access to play stage client-side networking functionalities.
|
||||
|
@ -73,7 +76,7 @@ public final class ClientPlayNetworking {
|
|||
* @see ClientPlayNetworking#registerReceiver(Identifier, PlayChannelHandler)
|
||||
*/
|
||||
public static boolean registerGlobalReceiver(Identifier channelName, PlayChannelHandler channelHandler) {
|
||||
return ClientNetworkingImpl.PLAY.registerGlobalReceiver(channelName, channelHandler);
|
||||
return ClientNetworkingImpl.PLAY.registerGlobalReceiver(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,29 +93,7 @@ public final class ClientPlayNetworking {
|
|||
* @see ClientPlayNetworking#registerReceiver(PacketType, PlayPacketHandler)
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerGlobalReceiver(PacketType<T> type, PlayPacketHandler<T> handler) {
|
||||
return registerGlobalReceiver(type.getId(), new PlayChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public PlayPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftClient client, ClientPlayNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
|
||||
if (client.isOnThread()) {
|
||||
// Do not submit to the render thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
handler.receive(packet, client.player, sender);
|
||||
} else {
|
||||
client.execute(() -> {
|
||||
if (networkHandler.getConnection().isOpen()) handler.receive(packet, client.player, sender);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return ClientNetworkingImpl.PLAY.registerGlobalReceiver(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +109,7 @@ public final class ClientPlayNetworking {
|
|||
*/
|
||||
@Nullable
|
||||
public static PlayChannelHandler unregisterGlobalReceiver(Identifier channelName) {
|
||||
return ClientNetworkingImpl.PLAY.unregisterGlobalReceiver(channelName);
|
||||
return unwrapUntyped(ClientNetworkingImpl.PLAY.unregisterGlobalReceiver(channelName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,10 +125,8 @@ public final class ClientPlayNetworking {
|
|||
* @see ClientPlayNetworking#unregisterReceiver(PacketType)
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> PlayPacketHandler<T> unregisterGlobalReceiver(PacketType<T> type) {
|
||||
PlayChannelHandler handler = ClientNetworkingImpl.PLAY.unregisterGlobalReceiver(type.getId());
|
||||
return handler instanceof PlayChannelHandlerProxy<?> proxy ? (PlayPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
return unwrapTyped(ClientNetworkingImpl.PLAY.unregisterGlobalReceiver(type.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,7 +160,7 @@ public final class ClientPlayNetworking {
|
|||
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
|
||||
|
||||
if (addon != null) {
|
||||
return addon.registerChannel(channelName, channelHandler);
|
||||
return addon.registerChannel(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Cannot register receiver while not in game!");
|
||||
|
@ -203,29 +182,13 @@ public final class ClientPlayNetworking {
|
|||
* @see ClientPlayConnectionEvents#INIT
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerReceiver(PacketType<T> type, PlayPacketHandler<T> handler) {
|
||||
return registerReceiver(type.getId(), new PlayChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public PlayPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftClient client, ClientPlayNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
if (addon != null) {
|
||||
return addon.registerChannel(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
if (client.isOnThread()) {
|
||||
// Do not submit to the render thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
handler.receive(packet, client.player, sender);
|
||||
} else {
|
||||
client.execute(() -> {
|
||||
if (networkHandler.getConnection().isOpen()) handler.receive(packet, client.player, sender);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
throw new IllegalStateException("Cannot register receiver while not in game!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,7 +205,7 @@ public final class ClientPlayNetworking {
|
|||
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
|
||||
|
||||
if (addon != null) {
|
||||
return addon.unregisterChannel(channelName);
|
||||
return unwrapUntyped(addon.unregisterChannel(channelName));
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Cannot unregister receiver while not in game!");
|
||||
|
@ -259,10 +222,14 @@ public final class ClientPlayNetworking {
|
|||
* @throws IllegalStateException if the client is not connected to a server
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> PlayPacketHandler<T> unregisterReceiver(PacketType<T> type) {
|
||||
PlayChannelHandler handler = unregisterReceiver(type.getId());
|
||||
return handler instanceof PlayChannelHandlerProxy<?> proxy ? (PlayPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
|
||||
|
||||
if (addon != null) {
|
||||
return unwrapTyped(addon.unregisterChannel(type.getId()));
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Cannot unregister receiver while not in game!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -402,6 +369,46 @@ public final class ClientPlayNetworking {
|
|||
private ClientPlayNetworking() {
|
||||
}
|
||||
|
||||
private static ResolvablePayload.Handler<ClientPlayNetworkAddon.Handler> wrapUntyped(PlayChannelHandler actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(null, actualHandler, (client, handler, payload, responseSender) -> {
|
||||
actualHandler.receive(client, handler, ((UntypedPayload) payload).buffer(), responseSender);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends FabricPacket> ResolvablePayload.Handler<ClientPlayNetworkAddon.Handler> wrapTyped(PacketType<T> type, PlayPacketHandler<T> actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(type, actualHandler, (client, handler, payload, responseSender) -> {
|
||||
T packet = (T) ((TypedPayload) payload).packet();
|
||||
|
||||
if (client.isOnThread()) {
|
||||
// Do not submit to the render thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
actualHandler.receive(packet, client.player, responseSender);
|
||||
} else {
|
||||
client.execute(() -> {
|
||||
if (handler.getConnection().isOpen()) actualHandler.receive(packet, client.player, responseSender);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PlayChannelHandler unwrapUntyped(@Nullable ResolvablePayload.Handler<ClientPlayNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof PlayChannelHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static <T extends FabricPacket> PlayPacketHandler<T> unwrapTyped(@Nullable ResolvablePayload.Handler<ClientPlayNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof PlayPacketHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PlayChannelHandler {
|
||||
/**
|
||||
|
@ -429,14 +436,6 @@ public final class ClientPlayNetworking {
|
|||
void receive(MinecraftClient client, ClientPlayNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal packet handler that works as a proxy between old and new API.
|
||||
* @param <T> the type of the packet
|
||||
*/
|
||||
private interface PlayChannelHandlerProxy<T extends FabricPacket> extends PlayChannelHandler {
|
||||
PlayPacketHandler<T> getOriginalHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* A thread-safe packet handler utilizing {@link FabricPacket}.
|
||||
* @param <T> the type of the packet
|
||||
|
|
|
@ -28,17 +28,18 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import net.fabricmc.fabric.api.client.networking.v1.C2SConfigurationChannelEvents;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationConnectionEvents;
|
||||
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.FabricPacket;
|
||||
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.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvedPayload;
|
||||
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.ConfigurationChannelHandler> {
|
||||
public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetworkAddon<ClientConfigurationNetworkAddon.Handler> {
|
||||
private final ClientConfigurationNetworkHandler handler;
|
||||
private final MinecraftClient client;
|
||||
private boolean sentInitialRegisterPacket;
|
||||
|
@ -62,8 +63,8 @@ public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetw
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void receiveRegistration(boolean register, PacketByteBuf buf) {
|
||||
super.receiveRegistration(register, buf);
|
||||
protected void receiveRegistration(boolean register, ResolvablePayload resolvable) {
|
||||
super.receiveRegistration(register, resolvable);
|
||||
|
||||
if (register && !this.sentInitialRegisterPacket) {
|
||||
this.sendInitialChannelRegistrationPacket();
|
||||
|
@ -71,19 +72,9 @@ public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetw
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an incoming packet.
|
||||
*
|
||||
* @param payload the payload to handle
|
||||
* @return true if the packet has been handled
|
||||
*/
|
||||
public boolean handle(PacketByteBufPayload payload) {
|
||||
return this.handle(payload.id(), payload.data());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receive(ClientConfigurationNetworking.ConfigurationChannelHandler handler, PacketByteBuf buf) {
|
||||
handler.receive(this.client, this.handler, buf, this);
|
||||
protected void receive(Handler handler, ResolvedPayload payload) {
|
||||
handler.receive(this.client, this.handler, payload, this);
|
||||
}
|
||||
|
||||
// impl details
|
||||
|
@ -155,4 +146,8 @@ public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetw
|
|||
public ChannelInfoHolder getChannelInfoHolder() {
|
||||
return (ChannelInfoHolder) ((ClientCommonNetworkHandlerAccessor) handler).getConnection();
|
||||
}
|
||||
|
||||
public interface Handler {
|
||||
void receive(MinecraftClient client, ClientConfigurationNetworkHandler handler, ResolvedPayload payload, PacketSender responseSender);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientLoginNetworking;
|
|||
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.FabricPacket;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.impl.networking.CommonPacketsImpl;
|
||||
import net.fabricmc.fabric.impl.networking.CommonRegisterPayload;
|
||||
|
@ -47,14 +46,18 @@ import net.fabricmc.fabric.impl.networking.CommonVersionPayload;
|
|||
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.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.TypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
import net.fabricmc.fabric.mixin.networking.client.accessor.ConnectScreenAccessor;
|
||||
import net.fabricmc.fabric.mixin.networking.client.accessor.MinecraftClientAccessor;
|
||||
|
||||
public final class ClientNetworkingImpl {
|
||||
public static final GlobalReceiverRegistry<ClientLoginNetworking.LoginQueryRequestHandler> LOGIN = new GlobalReceiverRegistry<>(NetworkState.LOGIN);
|
||||
public static final GlobalReceiverRegistry<ClientConfigurationNetworking.ConfigurationChannelHandler> CONFIGURATION = new GlobalReceiverRegistry<>(NetworkState.CONFIGURATION);
|
||||
public static final GlobalReceiverRegistry<ClientPlayNetworking.PlayChannelHandler> PLAY = new GlobalReceiverRegistry<>(NetworkState.PLAY);
|
||||
public static final GlobalReceiverRegistry<ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler>> CONFIGURATION = new GlobalReceiverRegistry<>(NetworkState.CONFIGURATION);
|
||||
public static final GlobalReceiverRegistry<ResolvablePayload.Handler<ClientPlayNetworkAddon.Handler>> PLAY = new GlobalReceiverRegistry<>(NetworkState.PLAY);
|
||||
|
||||
private static ClientPlayNetworkAddon currentPlayAddon;
|
||||
private static ClientConfigurationNetworkAddon currentConfigurationAddon;
|
||||
|
||||
|
@ -71,16 +74,17 @@ public final class ClientNetworkingImpl {
|
|||
}
|
||||
|
||||
public static Packet<ServerCommonPacketListener> createC2SPacket(Identifier channelName, PacketByteBuf buf) {
|
||||
return new CustomPayloadC2SPacket(new PacketByteBufPayload(channelName, buf));
|
||||
return new CustomPayloadC2SPacket(new UntypedPayload(channelName, buf));
|
||||
}
|
||||
|
||||
public static Packet<ServerCommonPacketListener> createC2SPacket(FabricPacket packet) {
|
||||
Objects.requireNonNull(packet, "Packet cannot be null");
|
||||
Objects.requireNonNull(packet.getType(), "Packet#getType cannot return null");
|
||||
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
packet.write(buf);
|
||||
return createC2SPacket(packet.getType().getId(), buf);
|
||||
ResolvedPayload payload = new TypedPayload(packet);
|
||||
if (NetworkingImpl.FORCE_PACKET_SERIALIZATION) payload = payload.resolve(null);
|
||||
|
||||
return new CustomPayloadC2SPacket(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,12 +33,13 @@ 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.FabricPacket;
|
||||
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.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvedPayload;
|
||||
|
||||
public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<ClientPlayNetworking.PlayChannelHandler> {
|
||||
public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<ClientPlayNetworkAddon.Handler> {
|
||||
private final ClientPlayNetworkHandler handler;
|
||||
private final MinecraftClient client;
|
||||
private boolean sentInitialRegisterPacket;
|
||||
|
@ -71,19 +72,9 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
|||
this.sentInitialRegisterPacket = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an incoming packet.
|
||||
*
|
||||
* @param payload the payload to handle
|
||||
* @return true if the packet has been handled
|
||||
*/
|
||||
public boolean handle(PacketByteBufPayload payload) {
|
||||
return this.handle(payload.id(), payload.data());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receive(ClientPlayNetworking.PlayChannelHandler handler, PacketByteBuf buf) {
|
||||
handler.receive(this.client, this.handler, buf, this);
|
||||
protected void receive(Handler handler, ResolvedPayload payload) {
|
||||
handler.receive(this.client, this.handler, payload, this);
|
||||
}
|
||||
|
||||
// impl details
|
||||
|
@ -146,4 +137,8 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
|||
protected boolean isReservedChannel(Identifier channelName) {
|
||||
return NetworkingImpl.isReservedCommonChannel(channelName);
|
||||
}
|
||||
|
||||
public interface Handler {
|
||||
void receive(MinecraftClient client, ClientPlayNetworkHandler handler, ResolvedPayload payload, PacketSender responseSender);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,14 @@ import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket;
|
|||
import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientConfigurationNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientPlayNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.RetainedPayload;
|
||||
|
||||
@Mixin(ClientCommonNetworkHandler.class)
|
||||
public abstract class ClientCommonNetworkHandlerMixin implements NetworkHandlerExtensions {
|
||||
@Inject(method = "onCustomPayload(Lnet/minecraft/network/packet/s2c/common/CustomPayloadS2CPacket;)V", at = @At("HEAD"), cancellable = true)
|
||||
public void onCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) {
|
||||
if (packet.payload() instanceof PacketByteBufPayload payload) {
|
||||
if (packet.payload() instanceof ResolvablePayload payload) {
|
||||
boolean handled;
|
||||
|
||||
if (this.getAddon() instanceof ClientPlayNetworkAddon addon) {
|
||||
|
@ -46,8 +47,11 @@ public abstract class ClientCommonNetworkHandlerMixin implements NetworkHandlerE
|
|||
|
||||
if (handled) {
|
||||
ci.cancel();
|
||||
} else {
|
||||
payload.data().skipBytes(payload.data().readableBytes());
|
||||
} else if (payload instanceof RetainedPayload retained && retained.buf().refCnt() > 0) {
|
||||
// Vanilla forces to use the render thread for its payloads,
|
||||
// that means this method can get called multiple times.
|
||||
retained.buf().skipBytes(retained.buf().readableBytes());
|
||||
retained.buf().release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@ import net.minecraft.server.network.ServerConfigurationNetworkHandler;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.thread.ThreadExecutor;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.TypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerConfigurationNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerNetworkingImpl;
|
||||
import net.fabricmc.fabric.mixin.networking.accessor.ServerCommonNetworkHandlerAccessor;
|
||||
|
||||
|
@ -68,7 +72,7 @@ public final class ServerConfigurationNetworking {
|
|||
* @see ServerConfigurationNetworking#registerReceiver(ServerConfigurationNetworkHandler, Identifier, ConfigurationChannelHandler)
|
||||
*/
|
||||
public static boolean registerGlobalReceiver(Identifier channelName, ConfigurationChannelHandler channelHandler) {
|
||||
return ServerNetworkingImpl.CONFIGURATION.registerGlobalReceiver(channelName, channelHandler);
|
||||
return ServerNetworkingImpl.CONFIGURATION.registerGlobalReceiver(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,18 +89,7 @@ public final class ServerConfigurationNetworking {
|
|||
* @see ServerConfigurationNetworking#registerReceiver(ServerConfigurationNetworkHandler, PacketType, ConfigurationPacketHandler)
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerGlobalReceiver(PacketType<T> type, ConfigurationPacketHandler<T> handler) {
|
||||
return registerGlobalReceiver(type.getId(), new ConfigurationChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public ConfigurationPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftServer server, ServerConfigurationNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
handler.receive(packet, networkHandler, sender);
|
||||
}
|
||||
});
|
||||
return ServerNetworkingImpl.CONFIGURATION.registerGlobalReceiver(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,7 +105,7 @@ public final class ServerConfigurationNetworking {
|
|||
*/
|
||||
@Nullable
|
||||
public static ServerConfigurationNetworking.ConfigurationChannelHandler unregisterGlobalReceiver(Identifier channelName) {
|
||||
return ServerNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(channelName);
|
||||
return unwrapUntyped(ServerNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(channelName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,10 +121,8 @@ public final class ServerConfigurationNetworking {
|
|||
* @see ServerConfigurationNetworking#unregisterReceiver(ServerConfigurationNetworkHandler, PacketType)
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> ServerConfigurationNetworking.ConfigurationPacketHandler<T> unregisterGlobalReceiver(PacketType<T> type) {
|
||||
ConfigurationChannelHandler handler = ServerNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(type.getId());
|
||||
return handler instanceof ConfigurationChannelHandlerProxy<?> proxy ? (ConfigurationPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
return unwrapTyped(ServerNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(type.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,7 +161,7 @@ public final class ServerConfigurationNetworking {
|
|||
public static boolean registerReceiver(ServerConfigurationNetworkHandler networkHandler, Identifier channelName, ConfigurationChannelHandler channelHandler) {
|
||||
Objects.requireNonNull(networkHandler, "Network handler cannot be null");
|
||||
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, channelHandler);
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,18 +182,7 @@ public final class ServerConfigurationNetworking {
|
|||
* @see ServerPlayConnectionEvents#INIT
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerReceiver(ServerConfigurationNetworkHandler networkHandler, PacketType<T> type, ConfigurationPacketHandler<T> handler) {
|
||||
return registerReceiver(networkHandler, type.getId(), new ConfigurationChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public ConfigurationPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftServer server, ServerConfigurationNetworkHandler networkHandler2, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
handler.receive(packet, networkHandler2, sender);
|
||||
}
|
||||
});
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,7 +197,7 @@ public final class ServerConfigurationNetworking {
|
|||
public static ServerConfigurationNetworking.ConfigurationChannelHandler unregisterReceiver(ServerConfigurationNetworkHandler networkHandler, Identifier channelName) {
|
||||
Objects.requireNonNull(networkHandler, "Network handler cannot be null");
|
||||
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(channelName);
|
||||
return unwrapUntyped(ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(channelName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,10 +210,8 @@ public final class ServerConfigurationNetworking {
|
|||
* or it was not registered using {@link #registerReceiver(ServerConfigurationNetworkHandler, PacketType, ConfigurationPacketHandler)}
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> ServerConfigurationNetworking.ConfigurationPacketHandler<T> unregisterReceiver(ServerConfigurationNetworkHandler networkHandler, PacketType<T> type) {
|
||||
ConfigurationChannelHandler handler = unregisterReceiver(networkHandler, type.getId());
|
||||
return handler instanceof ConfigurationChannelHandlerProxy<?> proxy ? (ConfigurationPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
return unwrapTyped(ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(type.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -372,6 +350,35 @@ public final class ServerConfigurationNetworking {
|
|||
private ServerConfigurationNetworking() {
|
||||
}
|
||||
|
||||
private static ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> wrapUntyped(ConfigurationChannelHandler actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(null, actualHandler, (server, handler, payload, responseSender) -> {
|
||||
actualHandler.receive(server, handler, ((UntypedPayload) payload).buffer(), responseSender);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends FabricPacket> ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> wrapTyped(PacketType<T> type, ConfigurationPacketHandler<T> actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(type, actualHandler, (server, handler, payload, responseSender) -> {
|
||||
T packet = (T) ((TypedPayload) payload).packet();
|
||||
actualHandler.receive(packet, handler, responseSender);
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ConfigurationChannelHandler unwrapUntyped(@Nullable ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof ConfigurationChannelHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static <T extends FabricPacket> ConfigurationPacketHandler<T> unwrapTyped(@Nullable ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof ConfigurationPacketHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ConfigurationChannelHandler {
|
||||
/**
|
||||
|
@ -399,14 +406,6 @@ public final class ServerConfigurationNetworking {
|
|||
void receive(MinecraftServer server, ServerConfigurationNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal packet handler that works as a proxy between old and new API.
|
||||
* @param <T> the type of the packet
|
||||
*/
|
||||
private interface ConfigurationChannelHandlerProxy<T extends FabricPacket> extends ConfigurationChannelHandler {
|
||||
ConfigurationPacketHandler<T> getOriginalHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* A thread-safe packet handler utilizing {@link FabricPacket}.
|
||||
* @param <T> the type of the packet
|
||||
|
|
|
@ -30,7 +30,11 @@ import net.minecraft.server.network.ServerPlayerEntity;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.thread.ThreadExecutor;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.TypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerNetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerPlayNetworkAddon;
|
||||
|
||||
/**
|
||||
* Offers access to play stage server-side networking functionalities.
|
||||
|
@ -83,7 +87,7 @@ public final class ServerPlayNetworking {
|
|||
* @see ServerPlayNetworking#registerReceiver(ServerPlayNetworkHandler, Identifier, PlayChannelHandler)
|
||||
*/
|
||||
public static boolean registerGlobalReceiver(Identifier channelName, PlayChannelHandler channelHandler) {
|
||||
return ServerNetworkingImpl.PLAY.registerGlobalReceiver(channelName, channelHandler);
|
||||
return ServerNetworkingImpl.PLAY.registerGlobalReceiver(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,29 +104,7 @@ public final class ServerPlayNetworking {
|
|||
* @see ServerPlayNetworking#registerReceiver(ServerPlayNetworkHandler, PacketType, PlayPacketHandler)
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerGlobalReceiver(PacketType<T> type, PlayPacketHandler<T> handler) {
|
||||
return registerGlobalReceiver(type.getId(), new PlayChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public PlayPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftServer server, ServerPlayerEntity player, ServerPlayNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
|
||||
if (server.isOnThread()) {
|
||||
// Do not submit to the server thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
handler.receive(packet, player, sender);
|
||||
} else {
|
||||
server.execute(() -> {
|
||||
if (networkHandler.isConnectionOpen()) handler.receive(packet, player, sender);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return ServerNetworkingImpl.PLAY.registerGlobalReceiver(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +120,7 @@ public final class ServerPlayNetworking {
|
|||
*/
|
||||
@Nullable
|
||||
public static PlayChannelHandler unregisterGlobalReceiver(Identifier channelName) {
|
||||
return ServerNetworkingImpl.PLAY.unregisterGlobalReceiver(channelName);
|
||||
return unwrapUntyped(ServerNetworkingImpl.PLAY.unregisterGlobalReceiver(channelName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,10 +136,8 @@ public final class ServerPlayNetworking {
|
|||
* @see ServerPlayNetworking#unregisterReceiver(ServerPlayNetworkHandler, PacketType)
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> PlayPacketHandler<T> unregisterGlobalReceiver(PacketType<T> type) {
|
||||
PlayChannelHandler handler = ServerNetworkingImpl.PLAY.unregisterGlobalReceiver(type.getId());
|
||||
return handler instanceof PlayChannelHandlerProxy<?> proxy ? (PlayPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
return unwrapTyped(ServerNetworkingImpl.PLAY.unregisterGlobalReceiver(type.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -196,7 +176,7 @@ public final class ServerPlayNetworking {
|
|||
public static boolean registerReceiver(ServerPlayNetworkHandler networkHandler, Identifier channelName, PlayChannelHandler channelHandler) {
|
||||
Objects.requireNonNull(networkHandler, "Network handler cannot be null");
|
||||
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, channelHandler);
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, wrapUntyped(channelHandler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,29 +197,7 @@ public final class ServerPlayNetworking {
|
|||
* @see ServerPlayConnectionEvents#INIT
|
||||
*/
|
||||
public static <T extends FabricPacket> boolean registerReceiver(ServerPlayNetworkHandler networkHandler, PacketType<T> type, PlayPacketHandler<T> handler) {
|
||||
return registerReceiver(networkHandler, type.getId(), new PlayChannelHandlerProxy<T>() {
|
||||
@Override
|
||||
public PlayPacketHandler<T> getOriginalHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(MinecraftServer server, ServerPlayerEntity player, ServerPlayNetworkHandler networkHandler2, PacketByteBuf buf, PacketSender sender) {
|
||||
T packet = type.read(buf);
|
||||
|
||||
if (server.isOnThread()) {
|
||||
// Do not submit to the server thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
handler.receive(packet, player, sender);
|
||||
} else {
|
||||
server.execute(() -> {
|
||||
if (networkHandler2.isConnectionOpen()) handler.receive(packet, player, sender);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(type.getId(), wrapTyped(type, handler));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,7 +212,7 @@ public final class ServerPlayNetworking {
|
|||
public static PlayChannelHandler unregisterReceiver(ServerPlayNetworkHandler networkHandler, Identifier channelName) {
|
||||
Objects.requireNonNull(networkHandler, "Network handler cannot be null");
|
||||
|
||||
return ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(channelName);
|
||||
return unwrapUntyped(ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(channelName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,10 +225,8 @@ public final class ServerPlayNetworking {
|
|||
* or it was not registered using {@link #registerReceiver(ServerPlayNetworkHandler, PacketType, PlayPacketHandler)}
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FabricPacket> PlayPacketHandler<T> unregisterReceiver(ServerPlayNetworkHandler networkHandler, PacketType<T> type) {
|
||||
PlayChannelHandler handler = unregisterReceiver(networkHandler, type.getId());
|
||||
return handler instanceof PlayChannelHandlerProxy<?> proxy ? (PlayPacketHandler<T>) proxy.getOriginalHandler() : null;
|
||||
return unwrapTyped(ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(type.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -468,6 +424,46 @@ public final class ServerPlayNetworking {
|
|||
private ServerPlayNetworking() {
|
||||
}
|
||||
|
||||
private static ResolvablePayload.Handler<ServerPlayNetworkAddon.Handler> wrapUntyped(PlayChannelHandler actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(null, actualHandler, (server, player, handler, payload, responseSender) -> {
|
||||
actualHandler.receive(server, player, handler, ((UntypedPayload) payload).buffer(), responseSender);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends FabricPacket> ResolvablePayload.Handler<ServerPlayNetworkAddon.Handler> wrapTyped(PacketType<T> type, PlayPacketHandler<T> actualHandler) {
|
||||
return new ResolvablePayload.Handler<>(type, actualHandler, (server, player, handler, payload, responseSender) -> {
|
||||
T packet = (T) ((TypedPayload) payload).packet();
|
||||
|
||||
if (server.isOnThread()) {
|
||||
// Do not submit to the server thread if we're already running there.
|
||||
// Normally, packets are handled on the network IO thread - though it is
|
||||
// not guaranteed (for example, with 1.19.4 S2C packet bundling)
|
||||
// Since we're handling it right now, connection check is redundant.
|
||||
actualHandler.receive(packet, player, responseSender);
|
||||
} else {
|
||||
server.execute(() -> {
|
||||
if (handler.isConnectionOpen()) actualHandler.receive(packet, player, responseSender);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PlayChannelHandler unwrapUntyped(@Nullable ResolvablePayload.Handler<ServerPlayNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof PlayChannelHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static <T extends FabricPacket> PlayPacketHandler<T> unwrapTyped(@Nullable ResolvablePayload.Handler<ServerPlayNetworkAddon.Handler> handler) {
|
||||
if (handler == null) return null;
|
||||
if (handler.actual() instanceof PlayPacketHandler actual) return actual;
|
||||
return null;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PlayChannelHandler {
|
||||
/**
|
||||
|
@ -496,14 +492,6 @@ public final class ServerPlayNetworking {
|
|||
void receive(MinecraftServer server, ServerPlayerEntity player, ServerPlayNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal packet handler that works as a proxy between old and new API.
|
||||
* @param <T> the type of the packet
|
||||
*/
|
||||
private interface PlayChannelHandlerProxy<T extends FabricPacket> extends PlayChannelHandler {
|
||||
PlayPacketHandler<T> getOriginalHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* A thread-safe packet handler utilizing {@link FabricPacket}.
|
||||
* @param <T> the type of the packet
|
||||
|
|
|
@ -40,20 +40,23 @@ import net.minecraft.util.InvalidIdentifierException;
|
|||
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
|
||||
/**
|
||||
* A network addon which is aware of the channels the other side may receive.
|
||||
*
|
||||
* @param <H> the channel handler type
|
||||
*/
|
||||
public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAddon<H> implements PacketSender, CommonPacketHandler {
|
||||
public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAddon<ResolvablePayload.Handler<H>> implements PacketSender, CommonPacketHandler {
|
||||
protected final ClientConnection connection;
|
||||
protected final GlobalReceiverRegistry<H> receiver;
|
||||
protected final GlobalReceiverRegistry<ResolvablePayload.Handler<H>> receiver;
|
||||
protected final Set<Identifier> sendableChannels;
|
||||
|
||||
protected int commonVersion = -1;
|
||||
|
||||
protected AbstractChanneledNetworkAddon(GlobalReceiverRegistry<H> receiver, ClientConnection connection, String description) {
|
||||
protected AbstractChanneledNetworkAddon(GlobalReceiverRegistry<ResolvablePayload.Handler<H>> receiver, ClientConnection connection, String description) {
|
||||
super(receiver, description);
|
||||
this.connection = connection;
|
||||
this.receiver = receiver;
|
||||
|
@ -70,28 +73,30 @@ public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAd
|
|||
}
|
||||
|
||||
// always supposed to handle async!
|
||||
protected boolean handle(Identifier channelName, PacketByteBuf buf) {
|
||||
public boolean handle(ResolvablePayload resolvable) {
|
||||
Identifier channelName = resolvable.id();
|
||||
this.logger.debug("Handling inbound packet from channel with name \"{}\"", channelName);
|
||||
|
||||
// Handle reserved packets
|
||||
if (NetworkingImpl.REGISTER_CHANNEL.equals(channelName)) {
|
||||
this.receiveRegistration(true, buf);
|
||||
this.receiveRegistration(true, resolvable);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NetworkingImpl.UNREGISTER_CHANNEL.equals(channelName)) {
|
||||
this.receiveRegistration(false, buf);
|
||||
this.receiveRegistration(false, resolvable);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable H handler = this.getHandler(channelName);
|
||||
@Nullable ResolvablePayload.Handler<H> handler = this.getHandler(channelName);
|
||||
|
||||
if (handler == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
this.receive(handler, buf);
|
||||
ResolvedPayload resolved = resolvable.resolve(handler.type());
|
||||
this.receive(handler.internal(), resolved);
|
||||
} catch (Throwable ex) {
|
||||
this.logger.error("Encountered exception while handling in channel with name \"{}\"", channelName, ex);
|
||||
throw ex;
|
||||
|
@ -100,7 +105,7 @@ public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAd
|
|||
return true;
|
||||
}
|
||||
|
||||
protected abstract void receive(H handler, PacketByteBuf buf);
|
||||
protected abstract void receive(H handler, ResolvedPayload payload);
|
||||
|
||||
protected void sendInitialChannelRegistrationPacket() {
|
||||
final PacketByteBuf buf = this.createRegistrationPacket(this.getReceivableChannels());
|
||||
|
@ -133,7 +138,10 @@ public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAd
|
|||
}
|
||||
|
||||
// wrap in try with res (buf)
|
||||
protected void receiveRegistration(boolean register, PacketByteBuf buf) {
|
||||
protected void receiveRegistration(boolean register, ResolvablePayload resolvable) {
|
||||
UntypedPayload payload = (UntypedPayload) resolvable.resolve(null);
|
||||
PacketByteBuf buf = payload.buffer();
|
||||
|
||||
List<Identifier> ids = new ArrayList<>();
|
||||
StringBuilder active = new StringBuilder();
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ public final class GlobalReceiverRegistry<H> {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public H unregisterGlobalReceiver(Identifier channelName) {
|
||||
Objects.requireNonNull(channelName, "Channel name cannot be null");
|
||||
|
||||
|
|
|
@ -21,10 +21,23 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.payload.TypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
public final class NetworkingImpl {
|
||||
public static final String MOD_ID = "fabric-networking-api-v1";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
|
||||
/**
|
||||
* Force {@link TypedPayload} to be serialized into {@link UntypedPayload}, mimicking remote connection.
|
||||
*
|
||||
* <p>Defaults to {@code true} in dev env and {@code false} in production.
|
||||
*/
|
||||
public static final boolean FORCE_PACKET_SERIALIZATION = Boolean.parseBoolean(System.getProperty(
|
||||
"fabric-api.networking.force-packet-serialization",
|
||||
Boolean.toString(FabricLoader.getInstance().isDevelopmentEnvironment())));
|
||||
|
||||
/**
|
||||
* Id of packet used to register supported channels.
|
||||
*/
|
||||
|
@ -38,4 +51,10 @@ public final class NetworkingImpl {
|
|||
public static boolean isReservedCommonChannel(Identifier channelName) {
|
||||
return channelName.equals(REGISTER_CHANNEL) || channelName.equals(UNREGISTER_CHANNEL);
|
||||
}
|
||||
|
||||
static {
|
||||
if (FORCE_PACKET_SERIALIZATION) {
|
||||
LOGGER.info("Force Packet Serialization is enabled to mimic remote connection on single player, this is the default behaviour on dev env. Add -Dfabric-api.networking.force-packet-serialization=false JVM arg to disable it.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.payload;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketType;
|
||||
|
||||
public sealed interface ResolvablePayload extends CustomPayload permits ResolvedPayload, RetainedPayload {
|
||||
/**
|
||||
* Resolve the payload to one of the resolved types.
|
||||
*
|
||||
* @return {@link UntypedPayload} if type is {@code null}, {@link TypedPayload} if otherwise.
|
||||
*/
|
||||
ResolvedPayload resolve(@Nullable PacketType<?> type);
|
||||
|
||||
/**
|
||||
* @param type the packet type, if it has any
|
||||
* @param actual the public handler that exposed to API consumer
|
||||
* @param internal the internal handler
|
||||
*/
|
||||
record Handler<H>(@Nullable PacketType<?> type, Object actual, H internal) {
|
||||
}
|
||||
}
|
|
@ -16,13 +16,5 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.networking.payload;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public record PacketByteBufPayload(Identifier id, PacketByteBuf data) implements CustomPayload {
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
PayloadHelper.write(buf, data());
|
||||
}
|
||||
public sealed interface ResolvedPayload extends ResolvablePayload permits TypedPayload, UntypedPayload {
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.payload;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketType;
|
||||
|
||||
public record RetainedPayload(Identifier id, PacketByteBuf buf) implements ResolvablePayload {
|
||||
@Override
|
||||
public ResolvedPayload resolve(@Nullable PacketType<?> type) {
|
||||
try {
|
||||
if (type == null) {
|
||||
PacketByteBuf copy = PacketByteBufs.create();
|
||||
copy.writeBytes(buf);
|
||||
return new UntypedPayload(this.id, copy);
|
||||
} else {
|
||||
TypedPayload typed = new TypedPayload(type.read(buf));
|
||||
int dangling = buf.readableBytes();
|
||||
|
||||
if (dangling > 0) {
|
||||
throw new IllegalStateException("Found " + dangling + " extra bytes when reading packet " + id);
|
||||
}
|
||||
|
||||
return typed;
|
||||
}
|
||||
} finally {
|
||||
buf.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
throw new UnsupportedOperationException("RetainedPayload shouldn't be used to send");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.payload;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.FabricPacket;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketType;
|
||||
|
||||
public record TypedPayload(FabricPacket packet) implements ResolvedPayload {
|
||||
@Override
|
||||
public ResolvedPayload resolve(@Nullable PacketType<?> type) {
|
||||
if (type == null) {
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
write(buf);
|
||||
return new UntypedPayload(packet.getType().getId(), buf);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
packet.write(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier id() {
|
||||
return packet.getType().getId();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.payload;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketType;
|
||||
|
||||
public record UntypedPayload(Identifier id, PacketByteBuf buffer) implements ResolvedPayload {
|
||||
@Override
|
||||
public ResolvedPayload resolve(@Nullable PacketType<?> type) {
|
||||
if (type == null) {
|
||||
return this;
|
||||
} else {
|
||||
TypedPayload typed = new TypedPayload(type.read(buffer));
|
||||
int dangling = buffer.readableBytes();
|
||||
|
||||
if (dangling > 0) {
|
||||
throw new IllegalStateException("Found " + dangling + " extra bytes when reading packet " + id);
|
||||
}
|
||||
|
||||
return typed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
buf.writeBytes(buffer);
|
||||
}
|
||||
}
|
|
@ -29,17 +29,18 @@ import net.minecraft.server.network.ServerConfigurationNetworkHandler;
|
|||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.FabricPacket;
|
||||
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;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvedPayload;
|
||||
import net.fabricmc.fabric.mixin.networking.accessor.ServerCommonNetworkHandlerAccessor;
|
||||
|
||||
public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetworkAddon<ServerConfigurationNetworking.ConfigurationChannelHandler> {
|
||||
public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetworkAddon<ServerConfigurationNetworkAddon.Handler> {
|
||||
private final ServerConfigurationNetworkHandler handler;
|
||||
private final MinecraftServer server;
|
||||
private RegisterState registerState = RegisterState.NOT_SENT;
|
||||
|
@ -83,8 +84,8 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void receiveRegistration(boolean register, PacketByteBuf buf) {
|
||||
super.receiveRegistration(register, buf);
|
||||
protected void receiveRegistration(boolean register, ResolvablePayload resolvable) {
|
||||
super.receiveRegistration(register, resolvable);
|
||||
|
||||
if (register && registerState == RegisterState.SENT) {
|
||||
// We received the registration packet, thus we know this is a modded client, continue with configuration.
|
||||
|
@ -101,19 +102,9 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an incoming packet.
|
||||
*
|
||||
* @param payload the payload to handle
|
||||
* @return true if the packet has been handled
|
||||
*/
|
||||
public boolean handle(PacketByteBufPayload payload) {
|
||||
return this.handle(payload.id(), payload.data());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receive(ServerConfigurationNetworking.ConfigurationChannelHandler handler, PacketByteBuf buf) {
|
||||
handler.receive(this.server, this.handler, buf, this);
|
||||
protected void receive(Handler handler, ResolvedPayload payload) {
|
||||
handler.receive(this.server, this.handler, payload, this);
|
||||
}
|
||||
|
||||
// impl details
|
||||
|
@ -192,4 +183,8 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw
|
|||
public ChannelInfoHolder getChannelInfoHolder() {
|
||||
return (ChannelInfoHolder) ((ServerCommonNetworkHandlerAccessor) handler).getConnection();
|
||||
}
|
||||
|
||||
public interface Handler {
|
||||
void receive(MinecraftServer server, ServerConfigurationNetworkHandler handler, ResolvedPayload payload, PacketSender responseSender);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,18 +29,19 @@ import net.minecraft.server.network.ServerPlayNetworkHandler;
|
|||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.FabricPacket;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking;
|
||||
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;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.NetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.TypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
|
||||
public final class ServerNetworkingImpl {
|
||||
public static final GlobalReceiverRegistry<ServerLoginNetworking.LoginQueryResponseHandler> LOGIN = new GlobalReceiverRegistry<>(NetworkState.LOGIN);
|
||||
public static final GlobalReceiverRegistry<ServerConfigurationNetworking.ConfigurationChannelHandler> CONFIGURATION = new GlobalReceiverRegistry<>(NetworkState.CONFIGURATION);
|
||||
public static final GlobalReceiverRegistry<ServerPlayNetworking.PlayChannelHandler> PLAY = new GlobalReceiverRegistry<>(NetworkState.PLAY);
|
||||
public static final GlobalReceiverRegistry<ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler>> CONFIGURATION = new GlobalReceiverRegistry<>(NetworkState.CONFIGURATION);
|
||||
public static final GlobalReceiverRegistry<ResolvablePayload.Handler<ServerPlayNetworkAddon.Handler>> PLAY = new GlobalReceiverRegistry<>(NetworkState.PLAY);
|
||||
|
||||
public static ServerPlayNetworkAddon getAddon(ServerPlayNetworkHandler handler) {
|
||||
return (ServerPlayNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon();
|
||||
|
@ -55,15 +56,16 @@ public final class ServerNetworkingImpl {
|
|||
}
|
||||
|
||||
public static Packet<ClientCommonPacketListener> createS2CPacket(Identifier channel, PacketByteBuf buf) {
|
||||
return new CustomPayloadS2CPacket(new PacketByteBufPayload(channel, buf));
|
||||
return new CustomPayloadS2CPacket(new UntypedPayload(channel, buf));
|
||||
}
|
||||
|
||||
public static Packet<ClientCommonPacketListener> createS2CPacket(FabricPacket packet) {
|
||||
Objects.requireNonNull(packet, "Packet cannot be null");
|
||||
Objects.requireNonNull(packet.getType(), "Packet#getType cannot return null");
|
||||
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
packet.write(buf);
|
||||
return createS2CPacket(packet.getType().getId(), buf);
|
||||
ResolvedPayload payload = new TypedPayload(packet);
|
||||
if (NetworkingImpl.FORCE_PACKET_SERIALIZATION) payload = payload.resolve(null);
|
||||
|
||||
return new CustomPayloadS2CPacket(payload);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,18 +25,20 @@ import net.minecraft.network.PacketByteBuf;
|
|||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.FabricPacket;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.api.networking.v1.S2CPlayChannelEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
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;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvedPayload;
|
||||
|
||||
public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<ServerPlayNetworking.PlayChannelHandler> {
|
||||
public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<ServerPlayNetworkAddon.Handler> {
|
||||
private final ServerPlayNetworkHandler handler;
|
||||
private final MinecraftServer server;
|
||||
private boolean sentInitialRegisterPacket;
|
||||
|
@ -62,19 +64,9 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
|||
this.sentInitialRegisterPacket = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an incoming packet.
|
||||
*
|
||||
* @param payload the payload to handle
|
||||
* @return true if the packet has been handled
|
||||
*/
|
||||
public boolean handle(PacketByteBufPayload payload) {
|
||||
return this.handle(payload.id(), payload.data());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receive(ServerPlayNetworking.PlayChannelHandler handler, PacketByteBuf buf) {
|
||||
handler.receive(this.server, this.handler.player, this.handler, buf, this);
|
||||
protected void receive(Handler handler, ResolvedPayload payload) {
|
||||
handler.receive(this.server, this.handler.player, this.handler, payload, this);
|
||||
}
|
||||
|
||||
// impl details
|
||||
|
@ -137,4 +129,8 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<
|
|||
protected boolean isReservedChannel(Identifier channelName) {
|
||||
return NetworkingImpl.isReservedCommonChannel(channelName);
|
||||
}
|
||||
|
||||
public interface Handler {
|
||||
void receive(MinecraftServer server, ServerPlayerEntity player, ServerPlayNetworkHandler handler, ResolvedPayload payload, PacketSender responseSender);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ import net.minecraft.network.packet.CustomPayload;
|
|||
import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PayloadHelper;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.impl.networking.payload.RetainedPayload;
|
||||
|
||||
@Mixin(CustomPayloadC2SPacket.class)
|
||||
public class CustomPayloadC2SPacketMixin {
|
||||
|
@ -43,6 +43,13 @@ public class CustomPayloadC2SPacketMixin {
|
|||
cancellable = true
|
||||
)
|
||||
private static void readPayload(Identifier id, PacketByteBuf buf, CallbackInfoReturnable<CustomPayload> cir) {
|
||||
cir.setReturnValue(new PacketByteBufPayload(id, PayloadHelper.read(buf, MAX_PAYLOAD_SIZE)));
|
||||
int size = buf.readableBytes();
|
||||
|
||||
if (size < 0 || size > MAX_PAYLOAD_SIZE) {
|
||||
throw new IllegalArgumentException("Payload may not be larger than " + MAX_PAYLOAD_SIZE + " bytes");
|
||||
}
|
||||
|
||||
cir.setReturnValue(new RetainedPayload(id, PacketByteBufs.retainedSlice(buf)));
|
||||
buf.skipBytes(size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ import net.minecraft.network.packet.CustomPayload;
|
|||
import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PayloadHelper;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.impl.networking.payload.RetainedPayload;
|
||||
|
||||
@Mixin(CustomPayloadS2CPacket.class)
|
||||
public class CustomPayloadS2CPacketMixin {
|
||||
|
@ -43,6 +43,13 @@ public class CustomPayloadS2CPacketMixin {
|
|||
cancellable = true
|
||||
)
|
||||
private static void readPayload(Identifier id, PacketByteBuf buf, CallbackInfoReturnable<CustomPayload> cir) {
|
||||
cir.setReturnValue(new PacketByteBufPayload(id, PayloadHelper.read(buf, MAX_PAYLOAD_SIZE)));
|
||||
int size = buf.readableBytes();
|
||||
|
||||
if (size < 0 || size > MAX_PAYLOAD_SIZE) {
|
||||
throw new IllegalArgumentException("Payload may not be larger than " + MAX_PAYLOAD_SIZE + " bytes");
|
||||
}
|
||||
|
||||
cir.setReturnValue(new RetainedPayload(id, PacketByteBufs.retainedSlice(buf)));
|
||||
buf.skipBytes(size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket;
|
|||
import net.minecraft.server.network.ServerCommonNetworkHandler;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.RetainedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerConfigurationNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerPlayNetworkAddon;
|
||||
|
||||
|
@ -34,7 +35,7 @@ import net.fabricmc.fabric.impl.networking.server.ServerPlayNetworkAddon;
|
|||
public abstract class ServerCommonNetworkHandlerMixin implements NetworkHandlerExtensions {
|
||||
@Inject(method = "onCustomPayload", at = @At("HEAD"), cancellable = true)
|
||||
private void handleCustomPayloadReceivedAsync(CustomPayloadC2SPacket packet, CallbackInfo ci) {
|
||||
if (packet.payload() instanceof PacketByteBufPayload payload) {
|
||||
if (packet.payload() instanceof ResolvablePayload payload) {
|
||||
boolean handled;
|
||||
|
||||
if (getAddon() instanceof ServerPlayNetworkAddon addon) {
|
||||
|
@ -47,8 +48,9 @@ public abstract class ServerCommonNetworkHandlerMixin implements NetworkHandlerE
|
|||
|
||||
if (handled) {
|
||||
ci.cancel();
|
||||
} else {
|
||||
payload.data().skipBytes(payload.data().readableBytes());
|
||||
} else if (payload instanceof RetainedPayload retained) {
|
||||
retained.buf().skipBytes(retained.buf().readableBytes());
|
||||
retained.buf().release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,11 +47,9 @@ import net.minecraft.network.packet.CustomPayload;
|
|||
import net.minecraft.server.network.ServerConfigurationNetworkHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
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.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking;
|
||||
import net.fabricmc.fabric.impl.networking.ChannelInfoHolder;
|
||||
import net.fabricmc.fabric.impl.networking.CommonPacketHandler;
|
||||
import net.fabricmc.fabric.impl.networking.CommonPacketsImpl;
|
||||
|
@ -59,6 +57,8 @@ import net.fabricmc.fabric.impl.networking.CommonRegisterPayload;
|
|||
import net.fabricmc.fabric.impl.networking.CommonVersionPayload;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientConfigurationNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.client.ClientNetworkingImpl;
|
||||
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
|
||||
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerConfigurationNetworkAddon;
|
||||
import net.fabricmc.fabric.impl.networking.server.ServerNetworkingImpl;
|
||||
|
||||
|
@ -101,14 +101,14 @@ public class CommonPacketTests {
|
|||
// Test handling the version packet on the client
|
||||
@Test
|
||||
void handleVersionPacketClient() {
|
||||
ClientConfigurationNetworking.ConfigurationChannelHandler packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
// Receive a packet from the server
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
buf.writeIntArray(new int[]{1, 2, 3});
|
||||
|
||||
packetHandler.receive(null, clientNetworkHandler, buf, packetSender);
|
||||
packetHandler.internal().receive(null, clientNetworkHandler, new UntypedPayload(null, buf), packetSender);
|
||||
|
||||
// Assert the entire packet was read
|
||||
assertEquals(0, buf.readableBytes());
|
||||
|
@ -124,7 +124,7 @@ public class CommonPacketTests {
|
|||
// Test handling the version packet on the client, when the server sends unsupported versions
|
||||
@Test
|
||||
void handleVersionPacketClientUnsupported() {
|
||||
ClientConfigurationNetworking.ConfigurationChannelHandler packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
// Receive a packet from the server
|
||||
|
@ -132,7 +132,7 @@ public class CommonPacketTests {
|
|||
buf.writeIntArray(new int[]{2, 3}); // We only support version 1
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () -> {
|
||||
packetHandler.receive(null, clientNetworkHandler, buf, packetSender);
|
||||
packetHandler.internal().receive(null, clientNetworkHandler, new UntypedPayload(null, buf), packetSender);
|
||||
});
|
||||
|
||||
// Assert the entire packet was read
|
||||
|
@ -142,14 +142,14 @@ public class CommonPacketTests {
|
|||
// Test handling the version packet on the server
|
||||
@Test
|
||||
void handleVersionPacketServer() {
|
||||
ServerConfigurationNetworking.ConfigurationChannelHandler packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
// Receive a packet from the client
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
buf.writeIntArray(new int[]{1, 2, 3});
|
||||
|
||||
packetHandler.receive(null, serverNetworkHandler, buf, null);
|
||||
packetHandler.internal().receive(null, serverNetworkHandler, new UntypedPayload(null, buf), null);
|
||||
|
||||
// Assert the entire packet was read
|
||||
assertEquals(0, buf.readableBytes());
|
||||
|
@ -159,7 +159,7 @@ public class CommonPacketTests {
|
|||
// Test handling the version packet on the server unsupported version
|
||||
@Test
|
||||
void handleVersionPacketServerUnsupported() {
|
||||
ServerConfigurationNetworking.ConfigurationChannelHandler packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonVersionPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
// Receive a packet from the client
|
||||
|
@ -167,7 +167,7 @@ public class CommonPacketTests {
|
|||
buf.writeIntArray(new int[]{3}); // Server only supports version 1
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () -> {
|
||||
packetHandler.receive(null, serverNetworkHandler, buf, packetSender);
|
||||
packetHandler.internal().receive(null, serverNetworkHandler, new UntypedPayload(null, buf), packetSender);
|
||||
});
|
||||
|
||||
// Assert the entire packet was read
|
||||
|
@ -177,7 +177,7 @@ public class CommonPacketTests {
|
|||
// Test handing the play registry packet on the client configuration handler
|
||||
@Test
|
||||
void handlePlayRegistryClient() {
|
||||
ClientConfigurationNetworking.ConfigurationChannelHandler packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
when(clientAddon.getNegotiatedVersion()).thenReturn(1);
|
||||
|
@ -188,7 +188,7 @@ public class CommonPacketTests {
|
|||
buf.writeString("play"); // Target phase
|
||||
buf.writeCollection(List.of(new Identifier("fabric", "test")), PacketByteBuf::writeIdentifier);
|
||||
|
||||
packetHandler.receive(null, clientNetworkHandler, buf, packetSender);
|
||||
packetHandler.internal().receive(null, clientNetworkHandler, new UntypedPayload(null, buf), packetSender);
|
||||
|
||||
// Assert the entire packet was read
|
||||
assertEquals(0, buf.readableBytes());
|
||||
|
@ -205,7 +205,7 @@ public class CommonPacketTests {
|
|||
// Test handling the configuration registry packet on the client configuration handler
|
||||
@Test
|
||||
void handleConfigurationRegistryClient() {
|
||||
ClientConfigurationNetworking.ConfigurationChannelHandler packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ClientConfigurationNetworkAddon.Handler> packetHandler = ClientNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
when(clientAddon.getNegotiatedVersion()).thenReturn(1);
|
||||
|
@ -217,7 +217,7 @@ public class CommonPacketTests {
|
|||
buf.writeString("configuration"); // Target phase
|
||||
buf.writeCollection(List.of(new Identifier("fabric", "test")), PacketByteBuf::writeIdentifier);
|
||||
|
||||
packetHandler.receive(null, clientNetworkHandler, buf, packetSender);
|
||||
packetHandler.internal().receive(null, clientNetworkHandler, new UntypedPayload(null, buf), packetSender);
|
||||
|
||||
// Assert the entire packet was read
|
||||
assertEquals(0, buf.readableBytes());
|
||||
|
@ -234,7 +234,7 @@ public class CommonPacketTests {
|
|||
// Test handing the play registry packet on the server configuration handler
|
||||
@Test
|
||||
void handlePlayRegistryServer() {
|
||||
ServerConfigurationNetworking.ConfigurationChannelHandler packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
when(serverAddon.getNegotiatedVersion()).thenReturn(1);
|
||||
|
@ -245,7 +245,7 @@ public class CommonPacketTests {
|
|||
buf.writeString("play"); // Target phase
|
||||
buf.writeCollection(List.of(new Identifier("fabric", "test")), PacketByteBuf::writeIdentifier);
|
||||
|
||||
packetHandler.receive(null, serverNetworkHandler, buf, packetSender);
|
||||
packetHandler.internal().receive(null, serverNetworkHandler, new UntypedPayload(null, buf), packetSender);
|
||||
|
||||
// Assert the entire packet was read
|
||||
assertEquals(0, buf.readableBytes());
|
||||
|
@ -255,7 +255,7 @@ public class CommonPacketTests {
|
|||
// Test handing the configuration registry packet on the server configuration handler
|
||||
@Test
|
||||
void handleConfigurationRegistryServer() {
|
||||
ServerConfigurationNetworking.ConfigurationChannelHandler packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
ResolvablePayload.Handler<ServerConfigurationNetworkAddon.Handler> packetHandler = ServerNetworkingImpl.CONFIGURATION.getHandler(CommonRegisterPayload.PACKET_ID);
|
||||
assertNotNull(packetHandler);
|
||||
|
||||
when(serverAddon.getNegotiatedVersion()).thenReturn(1);
|
||||
|
@ -266,7 +266,7 @@ public class CommonPacketTests {
|
|||
buf.writeString("configuration"); // Target phase
|
||||
buf.writeCollection(List.of(new Identifier("fabric", "test")), PacketByteBuf::writeIdentifier);
|
||||
|
||||
packetHandler.receive(null, serverNetworkHandler, buf, packetSender);
|
||||
packetHandler.internal().receive(null, serverNetworkHandler, new UntypedPayload(null, buf), packetSender);
|
||||
|
||||
// Assert the entire packet was read
|
||||
assertEquals(0, buf.readableBytes());
|
||||
|
|
Loading…
Reference in a new issue