Skip to content

Commit

Permalink
PayloadTypeRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
modmuss50 committed Jan 18, 2024
1 parent e4edcd6 commit 5f5ea97
Show file tree
Hide file tree
Showing 19 changed files with 384 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@
import net.minecraft.resource.ResourcePackManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.TestCommand;
import net.minecraft.test.GameTestBatch;
import net.minecraft.test.TestContext;
import net.minecraft.test.TestFailureLogger;
import net.minecraft.test.TestFunction;
import net.minecraft.test.TestFunctions;
import net.minecraft.test.TestServer;
import net.minecraft.test.TestUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.level.storage.LevelStorage;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void onCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) {

if (!handled && payload instanceof RetainedPayload retained && retained.buf().refCnt() > 0) {
// Duplicate the vanilla log message, as we cancel further processing.
LOGGER.warn("Unknown custom packet payload: {}", payload.getKey().id());
LOGGER.warn("Unknown custom packet payload: {}", payload.getId().id());

retained.buf().skipBytes(retained.buf().readableBytes());
retained.buf().release();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.fabricmc.fabric.api.networking.v1;

import net.fabricmc.fabric.impl.networking.CustomPayloadTypeProvider;

import net.minecraft.network.PacketByteBuf;

public interface FabricCustomPayloadPacketCodec<B extends PacketByteBuf> {
void fabric_setPacketCodecProvider(CustomPayloadTypeProvider<B> customPayloadTypeProvider);
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ default void sendPacket(CustomPayload payload) {
// payload.write(buf);
// TODO 1.20.5
assert false;
sendPacket(payload.getKey().id(), buf);
sendPacket(payload.getId().id(), buf);
}

/**
Expand Down Expand Up @@ -111,7 +111,7 @@ default void sendPacket(CustomPayload payload, @Nullable GenericFutureListener<?
// payload.write(buf);
// TODO 1.20.5
assert false;
sendPacket(payload.getKey().id(), buf, callback);
sendPacket(payload.getId().id(), buf, callback);
}

/**
Expand Down Expand Up @@ -143,7 +143,7 @@ default void sendPacket(CustomPayload payload, @Nullable PacketCallbacks callbac
// payload.write(buf);
// TODO 1.20.5
assert false;
sendPacket(payload.getKey().id(), buf, callback);
sendPacket(payload.getId().id(), buf, callback);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package net.fabricmc.fabric.api.networking.v1;

import net.fabricmc.fabric.impl.networking.PayloadTypeRegistryImpl;

import org.jetbrains.annotations.Nullable;

import net.minecraft.network.NetworkSide;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.RegistryByteBuf;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.util.Identifier;

public interface PayloadTypeRegistry<B extends PacketByteBuf> {
<T extends CustomPayload> CustomPayload.Type<B, T> register(CustomPayload.Id<T> id, PacketCodec<B, T> codec);

@Nullable
CustomPayload.Type<B, ? extends CustomPayload> get(Identifier id);

@Nullable
<T extends CustomPayload> CustomPayload.Type<B, T> get(CustomPayload.Id<T> id);

static PayloadTypeRegistry<PacketByteBuf> configuration(NetworkSide side) {
return switch (side) {
case SERVERBOUND -> PayloadTypeRegistryImpl.CONFIGURATION_C2S;
case CLIENTBOUND -> PayloadTypeRegistryImpl.CONFIGURATION_S2C;
};
}

static PayloadTypeRegistry<RegistryByteBuf> play(NetworkSide side) {
return switch (side) {
case SERVERBOUND -> PayloadTypeRegistryImpl.PLAY_C2S;
case CLIENTBOUND -> PayloadTypeRegistryImpl.PLAY_S2C;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ protected void registerPendingChannels(ChannelInfoHolder holder, NetworkState st

// always supposed to handle async!
public boolean handle(ResolvablePayload resolvable) {
Identifier channelName = resolvable.getKey().id();;
Identifier channelName = resolvable.getId().id();
this.logger.debug("Handling inbound packet from channel with name \"{}\"", channelName);

// Handle reserved packets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public CommonRegisterPayload(PacketByteBuf buf) {
// }

@Override
public Type<? extends CustomPayload> getKey() {
public Id<? extends CustomPayload> getId() {
// TODO 1.20.5
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public CommonVersionPayload(PacketByteBuf buf) {
// }

@Override
public Type<? extends CustomPayload> getKey() {
public Id<? extends CustomPayload> getId() {
// TODO 1.20.5
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.fabricmc.fabric.impl.networking;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.util.Identifier;

public interface CustomPayloadTypeProvider<B extends PacketByteBuf> {
CustomPayload.Type<B, ? extends CustomPayload> get(B packetByteBuf, Identifier identifier);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package net.fabricmc.fabric.impl.networking;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;

import org.jetbrains.annotations.Nullable;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.RegistryByteBuf;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.util.Identifier;

import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;

public class PayloadTypeRegistryImpl<B extends PacketByteBuf> implements PayloadTypeRegistry<B> {
public static PayloadTypeRegistry<PacketByteBuf> CONFIGURATION_C2S = new PayloadTypeRegistryImpl<>(NetworkState.CONFIGURATION, NetworkSide.SERVERBOUND);
public static PayloadTypeRegistry<PacketByteBuf> CONFIGURATION_S2C = new PayloadTypeRegistryImpl<>(NetworkState.CONFIGURATION, NetworkSide.CLIENTBOUND);
public static PayloadTypeRegistry<RegistryByteBuf> PLAY_C2S = new PayloadTypeRegistryImpl<>(NetworkState.PLAY, NetworkSide.SERVERBOUND);
public static PayloadTypeRegistry<RegistryByteBuf> PLAY_S2C = new PayloadTypeRegistryImpl<>(NetworkState.PLAY, NetworkSide.CLIENTBOUND);

private final Map<Identifier, CustomPayload.Type<B, ? extends CustomPayload>> packetTypes = new HashMap<>();
private final NetworkState state;
private final NetworkSide side;

private PayloadTypeRegistryImpl(NetworkState state, NetworkSide side) {
this.state = state;
this.side = side;
}

@Override
public <T extends CustomPayload> CustomPayload.Type<B, T> register(CustomPayload.Id<T> id, PacketCodec<B, T> codec) {
Objects.requireNonNull(id, "id");
Objects.requireNonNull(codec, "codec");

final var payloadType = new CustomPayload.Type<>(id, codec);

if (packetTypes.containsKey(id.id())) {
throw new IllegalArgumentException("Packet type " + id + " is already registered!");
}

packetTypes.put(id.id(), payloadType);
return payloadType;
}

@Override
@Nullable
public CustomPayload.Type<B, ? extends CustomPayload> get(Identifier id) {
return packetTypes.get(id);
}

@Override
@Nullable
public <T extends CustomPayload> CustomPayload.Type<B, T> get(CustomPayload.Id<T> id) {
//noinspection unchecked
return (CustomPayload.Type<B, T>) packetTypes.get(id.id());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public ResolvedPayload resolve(@Nullable PacketType<?> type) {
}

@Override
public Type<? extends CustomPayload> getKey() {
public Id<? extends CustomPayload> getId() {
// TODO 1.20.5
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public ResolvedPayload resolve(@Nullable PacketType<?> type) {
// }

@Override
public Type<? extends CustomPayload> getKey() {
public Id<? extends CustomPayload> getId() {
// TODO 1.20.5
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public PacketByteBuf buffer() {
}

@Override
public Type<? extends CustomPayload> getKey() {
public Id<? extends CustomPayload> getId() {
// TODO 1.20.5
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,43 @@

package net.fabricmc.fabric.mixin.networking;

import org.spongepowered.asm.mixin.Final;
import java.util.List;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import net.minecraft.network.NetworkSide;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.RegistryByteBuf;
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.NetworkingImpl;
import net.fabricmc.fabric.impl.networking.payload.PayloadHelper;
import net.fabricmc.fabric.api.networking.v1.FabricCustomPayloadPacketCodec;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;

@Mixin(CustomPayloadC2SPacket.class)
public class CustomPayloadC2SPacketMixin {
@Shadow
@Final
private static int MAX_PAYLOAD_SIZE;

@Inject(
method = "readPayload",
at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/c2s/common/CustomPayloadC2SPacket;readUnknownPayload(Lnet/minecraft/util/Identifier;Lnet/minecraft/network/PacketByteBuf;)Lnet/minecraft/network/packet/UnknownCustomPayload;"),
cancellable = true
@WrapOperation(
method = "<clinit>",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/network/packet/CustomPayload;createCodec(Lnet/minecraft/network/packet/CustomPayload$CodecFactory;Ljava/util/List;)Lnet/minecraft/network/codec/PacketCodec;"
)
)
private static void readPayload(Identifier id, PacketByteBuf buf, CallbackInfoReturnable<CustomPayload> cir) {
cir.setReturnValue(PayloadHelper.readCustom(id, buf, MAX_PAYLOAD_SIZE, NetworkingImpl.FACTORY_RETAIN.get()));
private static PacketCodec<PacketByteBuf, CustomPayload> wrapCodec(CustomPayload.CodecFactory<PacketByteBuf> unknownCodecFactory, List<CustomPayload.Type<PacketByteBuf, ?>> types, Operation<PacketCodec<PacketByteBuf, CustomPayload>> original) {
PacketCodec<PacketByteBuf, CustomPayload> codec = original.call(unknownCodecFactory, types);
FabricCustomPayloadPacketCodec<PacketByteBuf> fabricCodec = (FabricCustomPayloadPacketCodec<PacketByteBuf>) codec;
fabricCodec.fabric_setPacketCodecProvider((packetByteBuf, identifier) -> {
// CustomPayloadC2SPacket does not have a separate codec for play/configuration. We know if the packetByteBuf is a PacketByteBuf we are in the play phase.
if (packetByteBuf instanceof RegistryByteBuf) {
return (CustomPayload.Type<PacketByteBuf, ? extends CustomPayload>) (Object) PayloadTypeRegistry.play(NetworkSide.SERVERBOUND).get(identifier);
}

return PayloadTypeRegistry.configuration(NetworkSide.SERVERBOUND).get(identifier);
});
return codec;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.fabricmc.fabric.mixin.networking;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.util.Identifier;

import net.fabricmc.fabric.api.networking.v1.FabricCustomPayloadPacketCodec;
import net.fabricmc.fabric.impl.networking.CustomPayloadTypeProvider;

import org.spongepowered.asm.mixin.injection.Coerce;

@Mixin(targets = "net/minecraft/network/packet/CustomPayload$1")
public abstract class CustomPayloadPacketCodecMixin<B extends PacketByteBuf> implements PacketCodec<B, CustomPayload>, FabricCustomPayloadPacketCodec<B> {
@Unique
private CustomPayloadTypeProvider<B> customPayloadTypeProvider;

@Override
public void fabric_setPacketCodecProvider(CustomPayloadTypeProvider<B> customPayloadTypeProvider) {
if (this.customPayloadTypeProvider != null) {
throw new IllegalStateException("Payload codec provider is already set!");
}

this.customPayloadTypeProvider = customPayloadTypeProvider;
}

@WrapOperation(method = {
"encode(Lnet/minecraft/network/PacketByteBuf;Lnet/minecraft/network/packet/CustomPayload$Id;Lnet/minecraft/network/packet/CustomPayload;)V",
"decode(Lnet/minecraft/network/PacketByteBuf;)Lnet/minecraft/network/packet/CustomPayload;"
}, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/CustomPayload$1;getCodec(Lnet/minecraft/util/Identifier;)Lnet/minecraft/network/codec/PacketCodec;"))
private PacketCodec<B, ? extends CustomPayload> wrapGetCodec(@Coerce PacketCodec<B, CustomPayload> instance, Identifier identifier, Operation<PacketCodec<B, CustomPayload>> original, B packetByteBuf) {
if (customPayloadTypeProvider == null) {
throw new IllegalStateException("Payload codec provider is not set!");
}

CustomPayload.Type<B, ? extends CustomPayload> payloadType = customPayloadTypeProvider.get(packetByteBuf, identifier);

if (payloadType != null) {
return payloadType.codec();
}

return original.call(instance, identifier);
}
}
Loading

0 comments on commit 5f5ea97

Please sign in to comment.