Skip to content

Commit

Permalink
Add context objects
Browse files Browse the repository at this point in the history
  • Loading branch information
modmuss50 committed Jan 22, 2024
1 parent 08bc285 commit 829406b
Show file tree
Hide file tree
Showing 23 changed files with 179 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import java.util.Objects;
import java.util.Set;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.util.Identifier;
import net.minecraft.util.thread.ThreadExecutor;
Expand Down Expand Up @@ -57,14 +57,14 @@ public final class ClientConfigurationNetworking {
* A global receiver is registered to all connections, in the present and future.
*
* <p>If a handler is already registered for the {@code type}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterGlobalReceiver(CustomPayload.Type)} to unregister the existing handler.
* Use {@link #unregisterGlobalReceiver(CustomPayload.Id)} to unregister the existing handler.
*
* @param type the packet type
* @param handler the handler
* @return false if a handler is already registered to the channel
* @throws IllegalArgumentException if the codec for {@code type} has not been {@linkplain PayloadTypeRegistry#configurationS2C() registered} yet
* @see ClientConfigurationNetworking#unregisterGlobalReceiver(CustomPayload.Type)
* @see ClientConfigurationNetworking#registerReceiver(CustomPayload.Type, ConfigurationPayloadHandler)
* @see ClientConfigurationNetworking#unregisterGlobalReceiver(CustomPayload.Id)
* @see ClientConfigurationNetworking#registerReceiver(CustomPayload.Id, ConfigurationPayloadHandler)
*/
public static <T extends CustomPayload> boolean registerGlobalReceiver(CustomPayload.Id<T> type, ConfigurationPayloadHandler<T> handler) {
return ClientNetworkingImpl.CONFIGURATION.registerGlobalReceiver(type.id(), handler);
Expand All @@ -76,15 +76,15 @@ public static <T extends CustomPayload> boolean registerGlobalReceiver(CustomPay
*
* <p>The {@code type} is guaranteed not to have an associated handler after this call.
*
* @param type the packet type
* @param id the packet id
* @return the previous handler, or {@code null} if no handler was bound to the channel,
* or it was not registered using {@link #registerGlobalReceiver(CustomPayload.Id, ConfigurationPayloadHandler)}
* @see ClientConfigurationNetworking#registerGlobalReceiver(CustomPayload.Id, ConfigurationPayloadHandler)
* @see ClientConfigurationNetworking#unregisterReceiver(Identifier)
*/
@Nullable
public static ClientConfigurationNetworking.ConfigurationPayloadHandler<?> unregisterGlobalReceiver(CustomPayload.Type<PacketByteBuf, ?> type) {
return ClientNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(type.id().id());
public static ClientConfigurationNetworking.ConfigurationPayloadHandler<?> unregisterGlobalReceiver(CustomPayload.Id<?> id) {
return ClientNetworkingImpl.CONFIGURATION.unregisterGlobalReceiver(id.id());
}

/**
Expand All @@ -106,18 +106,18 @@ public static Set<Identifier> getGlobalReceivers() {
* <p>For example, if you only register a receiver using this method when a {@linkplain ClientLoginNetworking#registerGlobalReceiver(Identifier, ClientLoginNetworking.LoginQueryRequestHandler)}
* login query has been received, you should use {@link ClientPlayConnectionEvents#INIT} to register the channel handler.
*
* @param type the packet type
* @param id the payload id
* @param handler the handler
* @return {@code false} if a handler is already registered for the type
* @throws IllegalArgumentException if the codec for {@code type} has not been {@linkplain PayloadTypeRegistry#configurationS2C() registered} yet
* @throws IllegalStateException if the client is not connected to a server
* @see ClientPlayConnectionEvents#INIT
*/
public static <T extends CustomPayload> boolean registerReceiver(CustomPayload.Type<PacketByteBuf, T> type, ConfigurationPayloadHandler<T> handler) {
public static <T extends CustomPayload> boolean registerReceiver(CustomPayload.Id<T> id, ConfigurationPayloadHandler<T> handler) {
final ClientConfigurationNetworkAddon addon = ClientNetworkingImpl.getClientConfigurationAddon();

if (addon != null) {
return addon.registerChannel(type.id().id(), handler);
return addon.registerChannel(id.id(), handler);
}

throw new IllegalStateException("Cannot register receiver while not configuring!");
Expand All @@ -130,7 +130,7 @@ public static <T extends CustomPayload> boolean registerReceiver(CustomPayload.T
*
* @param id the payload id to unregister
* @return the previous handler, or {@code null} if no handler was bound to the channel,
* or it was not registered using {@link #registerReceiver(CustomPayload.Type, ConfigurationPayloadHandler)}
* or it was not registered using {@link #registerReceiver(CustomPayload.Id, ConfigurationPayloadHandler)}
* @throws IllegalStateException if the client is not connected to a server
*/
@Nullable
Expand Down Expand Up @@ -265,9 +265,17 @@ public interface ConfigurationPayloadHandler<T extends CustomPayload> {
* }</pre>
*
* @param payload the packet payload
* @param responseSender the packet sender
* @param context the configuration networking context
* @see CustomPayload
*/
void receive(T payload, PacketSender responseSender);
void receive(T payload, Context context);
}

@ApiStatus.NonExtendable
public interface Context {
/**
* @return The packet sender
*/
PacketSender responseSender();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Objects;
import java.util.Set;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import net.minecraft.client.MinecraftClient;
Expand Down Expand Up @@ -274,10 +275,27 @@ public interface PlayPayloadHandler<T extends CustomPayload> {
* <p>The network handler can be accessed via {@link ClientPlayerEntity#networkHandler}.
*
* @param payload the packet payload
* @param player the player that received the payload
* @param responseSender the payload sender
* @param context the play networking context
* @see CustomPayload
*/
void receive(T payload, ClientPlayerEntity player, PacketSender responseSender);
void receive(T payload, Context context);
}

@ApiStatus.NonExtendable
public interface Context {
/**
* @return The MinecraftClient instance
*/
MinecraftClient client();

/**
* @return The player that received the payload
*/
ClientPlayerEntity player();

/**
* @return The packet sender
*/
PacketSender responseSender();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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.PacketSender;
import net.fabricmc.fabric.impl.networking.AbstractChanneledNetworkAddon;
import net.fabricmc.fabric.impl.networking.ChannelInfoHolder;
import net.fabricmc.fabric.impl.networking.NetworkingImpl;
Expand All @@ -40,12 +41,14 @@
public final class ClientConfigurationNetworkAddon extends AbstractChanneledNetworkAddon<ClientConfigurationNetworking.ConfigurationPayloadHandler<?>> {
private final ClientConfigurationNetworkHandler handler;
private final MinecraftClient client;
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;
this.context = new ContextImpl(this);

// Must register pending channels via lateinit
this.registerPendingChannels((ChannelInfoHolder) this.connection, NetworkPhase.CONFIGURATION);
Expand All @@ -72,7 +75,7 @@ protected void receiveRegistration(boolean register, RegistrationPayload payload

@Override
protected void receive(ClientConfigurationNetworking.ConfigurationPayloadHandler<?> handler, CustomPayload payload) {
((ClientConfigurationNetworking.ConfigurationPayloadHandler) handler).receive(payload, this);
((ClientConfigurationNetworking.ConfigurationPayloadHandler) handler).receive(payload, this.context);
}

// impl details
Expand Down Expand Up @@ -139,4 +142,7 @@ protected boolean isReservedChannel(Identifier channelName) {
public ChannelInfoHolder getChannelInfoHolder() {
return (ChannelInfoHolder) ((ClientCommonNetworkHandlerAccessor) handler).getConnection();
}

private record ContextImpl(PacketSender responseSender) implements ClientConfigurationNetworking.Context {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,13 @@ public static void clientInit() {
});

// Version packet
ClientConfigurationNetworking.registerGlobalReceiver(CommonVersionPayload.ID, (payload, responseSender) -> {
int negotiatedVersion = handleVersionPacket(payload, responseSender);
ClientConfigurationNetworking.registerGlobalReceiver(CommonVersionPayload.ID, (payload, context) -> {
int negotiatedVersion = handleVersionPacket(payload, context.responseSender());
ClientNetworkingImpl.getClientConfigurationAddon().onCommonVersionPacket(negotiatedVersion);
});

// Register packet
ClientConfigurationNetworking.registerGlobalReceiver(CommonRegisterPayload.ID, (payload, responseSender) -> {
ClientConfigurationNetworking.registerGlobalReceiver(CommonRegisterPayload.ID, (payload, context) -> {
ClientConfigurationNetworkAddon addon = ClientNetworkingImpl.getClientConfigurationAddon();

if (CommonRegisterPayload.PLAY_PHASE.equals(payload.phase())) {
Expand All @@ -158,10 +158,10 @@ public static void clientInit() {

addon.getChannelInfoHolder().getPendingChannelsNames(NetworkPhase.PLAY).addAll(payload.channels());
NetworkingImpl.LOGGER.debug("Received accepted channels from the server");
responseSender.sendPacket(new CommonRegisterPayload(addon.getNegotiatedVersion(), CommonRegisterPayload.PLAY_PHASE, ClientPlayNetworking.getGlobalReceivers()));
context.responseSender().sendPacket(new CommonRegisterPayload(addon.getNegotiatedVersion(), CommonRegisterPayload.PLAY_PHASE, ClientPlayNetworking.getGlobalReceivers()));
} else {
addon.onCommonRegisterPacket(payload);
responseSender.sendPacket(addon.createRegisterPayload());
context.responseSender().sendPacket(addon.createRegisterPayload());
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.network.NetworkPhase;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.Packet;
Expand All @@ -32,6 +33,7 @@
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;
Expand All @@ -40,6 +42,7 @@
public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<ClientPlayNetworking.PlayPayloadHandler<?>> {
private final ClientPlayNetworkHandler handler;
private final MinecraftClient client;
private final ClientPlayNetworking.Context context;
private boolean sentInitialRegisterPacket;

private static final Logger LOGGER = LogUtils.getLogger();
Expand All @@ -48,6 +51,7 @@ public ClientPlayNetworkAddon(ClientPlayNetworkHandler handler, MinecraftClient
super(ClientNetworkingImpl.PLAY, handler.getConnection(), "ClientPlayNetworkAddon for " + handler.getProfile().getName());
this.handler = handler;
this.client = client;
this.context = new ContextImpl(client, client.player, this);

// Must register pending channels via lateinit
this.registerPendingChannels((ChannelInfoHolder) this.connection, NetworkPhase.PLAY);
Expand All @@ -73,7 +77,7 @@ public void onServerReady() {
@Override
protected void receive(ClientPlayNetworking.PlayPayloadHandler<?> handler, CustomPayload payload) {
this.client.execute(() -> {
((ClientPlayNetworking.PlayPayloadHandler) handler).receive(payload, client.player, ClientPlayNetworkAddon.this);
((ClientPlayNetworking.PlayPayloadHandler) handler).receive(payload, context);
});
}

Expand Down Expand Up @@ -132,4 +136,7 @@ protected void invokeDisconnectEvent() {
protected boolean isReservedChannel(Identifier channelName) {
return NetworkingImpl.isReservedCommonChannel(channelName);
}

private record ContextImpl(MinecraftClient client, ClientPlayerEntity player, PacketSender responseSender) implements ClientPlayNetworking.Context {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Objects;
import java.util.Set;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import net.minecraft.network.listener.ClientCommonPacketListener;
Expand Down Expand Up @@ -259,10 +260,22 @@ public interface ConfigurationPacketHandler<T extends CustomPayload> {
*
*
* @param payload the packet payload
* @param networkHandler the network handler
* @param responseSender the packet sender
* @param context the configuration networking context
* @see CustomPayload
*/
void receive(T payload, ServerConfigurationNetworkHandler networkHandler, PacketSender responseSender);
void receive(T payload, Context context);
}

@ApiStatus.NonExtendable
public interface Context {
/**
* @return The ServerConfigurationNetworkHandler instance
*/
ServerConfigurationNetworkHandler networkHandler();

/**
* @return The packet sender
*/
PacketSender responseSender();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import java.util.Objects;
import java.util.Set;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.listener.ClientCommonPacketListener;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.Packet;
Expand All @@ -43,7 +43,7 @@
*
* <h2>Packet object-based API</h2>
*
* <p>This class provides a registration method, utilizing packet objects, {@link #registerGlobalReceiver(CustomPayload.Type, PlayPayloadHandler)}.
* <p>This class provides a registration method, utilizing packet objects, {@link #registerGlobalReceiver(CustomPayload.Id, PlayPayloadHandler)}.
* This handler executes the callback in the server thread, ensuring thread safety.
*
* <p>This payload object-based API involves three classes:
Expand Down Expand Up @@ -73,8 +73,8 @@ public final class ServerPlayNetworking {
* @throws IllegalArgumentException if the codec for {@code type} has not been {@linkplain PayloadTypeRegistry#playC2S() registered} yet
* @see ServerPlayNetworking#unregisterGlobalReceiver(Identifier)
*/
public static <T extends CustomPayload> boolean registerGlobalReceiver(CustomPayload.Type<RegistryByteBuf, T> type, PlayPayloadHandler<T> handler) {
return ServerNetworkingImpl.PLAY.registerGlobalReceiver(type.id().id(), handler);
public static <T extends CustomPayload> boolean registerGlobalReceiver(CustomPayload.Id<T> type, PlayPayloadHandler<T> handler) {
return ServerNetworkingImpl.PLAY.registerGlobalReceiver(type.id(), handler);
}

/**
Expand All @@ -85,8 +85,8 @@ public static <T extends CustomPayload> boolean registerGlobalReceiver(CustomPay
*
* @param id the payload id
* @return the previous handler, or {@code null} if no handler was bound to the channel,
* or it was not registered using {@link #registerGlobalReceiver(CustomPayload.Type, PlayPayloadHandler)}
* @see ServerPlayNetworking#registerGlobalReceiver(CustomPayload.Type, PlayPayloadHandler)
* or it was not registered using {@link #registerGlobalReceiver(CustomPayload.Id, PlayPayloadHandler)}
* @see ServerPlayNetworking#registerGlobalReceiver(CustomPayload.Id, PlayPayloadHandler)
* @see ServerPlayNetworking#unregisterReceiver(ServerPlayNetworkHandler, Identifier)
*/
@Nullable
Expand All @@ -106,7 +106,7 @@ public static Set<Identifier> getGlobalReceivers() {

/**
* Registers a handler for a payload type.
* This method differs from {@link ServerPlayNetworking#registerGlobalReceiver(CustomPayload.Type, PlayPayloadHandler)} since
* This method differs from {@link ServerPlayNetworking#registerGlobalReceiver(CustomPayload.Id, PlayPayloadHandler)} since
* the channel handler will only be applied to the player represented by the {@link ServerPlayNetworkHandler}.
*
* <p>For example, if you only register a receiver using this method when a {@linkplain ServerLoginNetworking#registerGlobalReceiver(Identifier, ServerLoginNetworking.LoginQueryResponseHandler)}
Expand Down Expand Up @@ -317,10 +317,22 @@ public interface PlayPayloadHandler<T extends CustomPayload> {
* and {@link ServerPlayerEntity#networkHandler}, respectively.
*
* @param payload the packet payload
* @param player the player that received the packet
* @param responseSender the packet sender
* @param context the play networking context
* @see CustomPayload
*/
void receive(T payload, ServerPlayerEntity player, PacketSender responseSender);
void receive(T payload, Context context);
}

@ApiStatus.NonExtendable
public interface Context {
/**
* @return The player that received the packet
*/
ServerPlayerEntity player();

/**
* @return The packet sender
*/
PacketSender responseSender();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ public boolean registerChannel(Identifier channelName, H handler) {
Objects.requireNonNull(handler, "Packet handler cannot be null");
assertNotReserved(channelName);

receiver.assertPayloadType(channelName);

Lock lock = this.lock.writeLock();
lock.lock();

Expand Down
Loading

0 comments on commit 829406b

Please sign in to comment.